singrdk/base/Imported/Bartok/runtime/shared/GCs/AllCardsWriteBarrier.cs

144 lines
5.4 KiB
C#

//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
/*******************************************************************/
/* WARNING */
/* This file should be identical in the Bartok and Singularity */
/* depots. Master copy resides in Bartok Depot. Changes should be */
/* made to Bartok Depot and propagated to Singularity Depot. */
/*******************************************************************/
namespace System.GCs {
using Microsoft.Bartok.Runtime;
using System.Runtime.CompilerServices;
using System.Threading;
//[NoBarriers]
internal unsafe class AllCardsWriteBarrier : RefWriteBarrier
{
internal static AllCardsWriteBarrier instance;
[NoBarriers]
internal static new void Initialize() {
AllCardsWriteBarrier.instance = (AllCardsWriteBarrier)
BootstrapMemory.Allocate(typeof(AllCardsWriteBarrier));
}
[Inline]
[NoBarriers]
protected override void StoreStaticFieldImpl(ref Object staticField,
Object value,
int mask)
{
// No need to mark the card for a static field.
staticField = value;
}
protected override void CopyStructImpl(Object srcObj,
Object dstObj,
VTable vtable,
UIntPtr srcPtr,
UIntPtr dstPtr)
{
CopyStructWithBarrier(vtable, srcPtr, dstPtr);
}
[Inline]
protected override Object AtomicSwapImpl(ref Object reference,
Object value,
int mask)
{
UIntPtr resultAddr =
Interlocked.Exchange(Magic.toPointer(ref reference),
Magic.addressOf(value));
RecordReference(Magic.toPointer(ref reference), value);
return Magic.fromAddress(resultAddr);
}
[Inline]
protected override
Object AtomicCompareAndSwapImpl(ref Object reference,
Object newValue,
Object comparand,
int mask)
{
UIntPtr resultAddr =
Interlocked.CompareExchange(Magic.toPointer(ref reference),
Magic.addressOf(newValue),
Magic.addressOf(comparand));
RecordReference(Magic.toPointer(ref reference), newValue);
return Magic.fromAddress(resultAddr);
}
[Inline]
protected override void CloneImpl(Object srcObject, Object dstObject)
{
CloneNoBarrier(srcObject, dstObject);
RecordClone(dstObject);
}
// 'offset' is not relative to the lower bound, but is a count
// of elements from the first element in the array.
protected override void ArrayZeroImpl(Array array,
int offset,
int length)
{
ArrayZeroNoBarrier(array, offset, length);
}
// 'offset' is not relative to the lower bound, but is a count
// of elements from the first element in the array.
protected override void ArrayCopyImpl(Array srcArray, int srcOffset,
Array dstArray, int dstOffset,
int length)
{
if ((length > 1000) || ((length << 2) >= dstArray.Length)) {
ArrayCopyNoBarrier(srcArray, srcOffset,
dstArray, dstOffset,
length);
RecordClone(dstArray);
} else {
ArrayCopyWithBarrier(srcArray, srcOffset,
dstArray, dstOffset,
length);
}
}
[Inline]
protected override void WriteImpl(UIntPtr *location,
Object value,
int mask)
{
*location = Magic.addressOf(value);
RecordReference(location, value);
}
[Inline]
protected override void WriteImplByRef(ref Object location,
Object value,
int mask)
{
WriteImpl(Magic.toPointer(ref location), value, mask);
}
[Inline]
private static void RecordClone(Object clone) {
GenerationalGCData.installedRemSet.RecordClonedObject(clone);
}
[Inline]
private static void RecordReference(UIntPtr *location,
Object value)
{
GenerationalGCData.
installedRemSet.RecordReference(location, value);
}
}
}