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

193 lines
7.2 KiB
C#
Raw Permalink Normal View History

2008-11-17 18:29:00 -05:00
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
2008-03-05 09:52:00 -05:00
/*******************************************************************/
/* 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;
2008-11-17 18:29:00 -05:00
//[NoBarriers]
internal unsafe class GenerationalWriteBarrier : RefWriteBarrier
2008-03-05 09:52:00 -05:00
{
internal static GenerationalWriteBarrier instance;
2008-11-17 18:29:00 -05:00
[NoBarriers]
2008-03-05 09:52:00 -05:00
internal static new void Initialize() {
GenerationalWriteBarrier.instance = (GenerationalWriteBarrier)
BootstrapMemory.Allocate(typeof(GenerationalWriteBarrier));
}
[Inline]
2008-11-17 18:29:00 -05:00
[NoBarriers]
2008-03-05 09:52:00 -05:00
protected override void StoreStaticFieldImpl(ref Object staticField,
2008-11-17 18:29:00 -05:00
Object value,
int mask)
2008-03-05 09:52:00 -05:00
{
// No need to perform a ReferenceCheck here!
2008-11-17 18:29:00 -05:00
staticField = value;
2008-03-05 09:52:00 -05:00
}
2008-11-17 18:29:00 -05:00
protected override void CopyStructImpl(Object srcObj,
Object dstObj,
VTable vtable,
2008-03-05 09:52:00 -05:00
UIntPtr srcPtr,
UIntPtr dstPtr)
{
CopyStructWithBarrier(vtable, srcPtr, dstPtr);
}
[Inline]
protected override Object AtomicSwapImpl(ref Object reference,
2008-11-17 18:29:00 -05:00
Object value,
int mask)
2008-03-05 09:52:00 -05:00
{
2008-11-17 18:29:00 -05:00
UIntPtr *ptr=Magic.toPointer(ref reference);
2008-03-05 09:52:00 -05:00
UIntPtr resultAddr =
2008-11-17 18:29:00 -05:00
Interlocked.Exchange(ptr,
2008-03-05 09:52:00 -05:00
Magic.addressOf(value));
2008-11-17 18:29:00 -05:00
ReferenceCheck(ptr, value);
2008-03-05 09:52:00 -05:00
return Magic.fromAddress(resultAddr);
}
[Inline]
protected override
Object AtomicCompareAndSwapImpl(ref Object reference,
Object newValue,
2008-11-17 18:29:00 -05:00
Object comparand,
int mask)
2008-03-05 09:52:00 -05:00
{
2008-11-17 18:29:00 -05:00
UIntPtr *ptr=Magic.toPointer(ref reference);
2008-03-05 09:52:00 -05:00
UIntPtr resultAddr =
2008-11-17 18:29:00 -05:00
Interlocked.CompareExchange(ptr,
2008-03-05 09:52:00 -05:00
Magic.addressOf(newValue),
Magic.addressOf(comparand));
2008-11-17 18:29:00 -05:00
ReferenceCheck(ptr, newValue);
2008-03-05 09:52:00 -05:00
return Magic.fromAddress(resultAddr);
}
[Inline]
protected override void CloneImpl(Object srcObject, Object dstObject)
{
CloneNoBarrier(srcObject, dstObject);
ReferenceCheck(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);
ReferenceCheck(dstArray);
} else {
ArrayCopyWithBarrier(srcArray, srcOffset,
dstArray, dstOffset,
length);
}
}
[Inline]
2008-11-17 18:29:00 -05:00
protected override void WriteImpl(UIntPtr *location,
Object value,
int mask)
{
WriteImplNoMask(location, value);
}
[RequiredByBartok]
[Inline]
private static void WriteImplNoMask(UIntPtr *location,
Object value)
2008-03-05 09:52:00 -05:00
{
*location = Magic.addressOf(value);
ReferenceCheck(location, value);
}
2008-11-17 18:29:00 -05:00
[Inline]
protected override void WriteImplByRef(ref Object location,
Object value,
int mask)
{
WriteImpl(Magic.toPointer(ref location), value, mask);
}
2008-03-05 09:52:00 -05:00
[Inline]
private static void ReferenceCheck(Object obj) {
PageType pageType =
PageTable.Type(PageTable.Page(Magic.addressOf(obj)));
2008-11-17 18:29:00 -05:00
if (GenerationalGCData.MAX_GENERATION == PageType.Owner1) {
2008-03-05 09:52:00 -05:00
if (pageType == PageType.Owner1) {
2008-11-17 18:29:00 -05:00
GenerationalGCData.
2008-03-05 09:52:00 -05:00
installedRemSet.RecordClonedObject(obj);
}
} else {
2008-11-17 18:29:00 -05:00
if (pageType != GenerationalGCData.nurseryGeneration) {
GenerationalGCData.
2008-03-05 09:52:00 -05:00
installedRemSet.RecordClonedObject(obj);
}
}
}
[Inline]
private static void ReferenceCheck(UIntPtr *addr, Object value)
{
PageType addrType = PageTable.Type(PageTable.Page((UIntPtr) addr));
2008-11-17 18:29:00 -05:00
if (GenerationalGCData.MAX_GENERATION == PageType.Owner1) {
2008-03-05 09:52:00 -05:00
if (addrType != PageType.Owner1) {
return;
} else {
ReferenceCheck(addrType, addr, value);
}
} else {
if (PageTable.IsLiveGcPage(addrType)){
ReferenceCheck(addrType, addr, value);
}
}
}
[NoInline]
private static void ReferenceCheck(PageType addrType, UIntPtr *addr,
Object value) {
VTable.Assert(PageTable.IsGcPage(addrType));
if (GC.remsetType == RemSetType.Cards) {
2008-11-17 18:29:00 -05:00
GenerationalGCData.
2008-03-05 09:52:00 -05:00
installedRemSet.RecordReference(addr, value);
return;
}
UIntPtr valueAddr = Magic.addressOf(value);
PageType valType = PageTable.Type(PageTable.Page(valueAddr));
if (PageTable.IsGcPage(valType) && (addrType > valType)){
2008-11-17 18:29:00 -05:00
GenerationalGCData.
2008-03-05 09:52:00 -05:00
installedRemSet.RecordReference(addr, value);
}
}
}
}