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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|