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

188 lines
6.0 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 Microsoft.Bartok.Options;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading;
internal unsafe class BrooksCMSBarrierTest: UniversalWriteBarrier {
internal static BrooksCMSBarrierTest instance;
internal static bool allowFastPath;
[NoBarriers]
internal static new void Initialize()
{
BrooksCMSBarrierTest.instance =
(BrooksCMSBarrierTest)
BootstrapMemory.Allocate(typeof(BrooksCMSBarrierTest));
}
[RequiredByBartok]
[MixinConditional("BrooksCMSBarrierTest")]
[Mixin(typeof(PreHeader))]
internal struct BrooksPreHeader {
internal MultiUseWord muw;
[SelfPoint]
internal Object forward;
}
[MixinConditional("BrooksCMSBarrierTest")]
[Mixin(typeof(Object))]
internal class BrooksObject: System.Object {
internal new BrooksPreHeader preHeader;
}
internal static BrooksObject MixinObject(Object o) {
return (BrooksObject)o;
}
[NoBarriers]
internal static Object Forward(Object o)
{
Object result=MixinObject(o).preHeader.forward;
VTable.Assert(result == o);
return result;
}
[NoBarriers]
internal static Object ForwardNullable(Object o)
{
if (o==null) {
return null;
} else {
return Forward(o);
}
}
[NoBarriers]
[Inline]
protected override Object ForwardImpl(Object o, int mask)
{
if ((mask&BarrierMask.PathSpec.AllowFast)!=0) {
return o;
} else {
if ((mask&BarrierMask.Forward.Nullable)!=0 && o == null) {
return null;
} else {
return Forward(o);
}
}
}
[ForceInline]
[NoBarriers]
protected override bool AllowFastPathImpl()
{
return allowFastPath;
}
[ForceInline]
[NoBarriers]
protected override void InitObjectImpl(Object o, VTable vtable)
{
MyInitObject(o, vtable);
}
internal static new void BootstrapInitObjectImpl(Object o,
VTable vtable)
{
MyInitObject(o, vtable);
}
[ForceInline]
[NoBarriers]
private static void MyInitObject(Object o, VTable vtable)
{
MixinObject(o).preHeader.forward = o;
o.vtable = vtable;
}
[ForceInline]
[NoBarriers]
protected override Object AtomicSwapImpl(ref Object reference,
Object value,
int mask)
{
CMSMarking.ReferenceCheck(ref reference, value, 0);
UIntPtr resultAddr =
Interlocked.Exchange(Magic.toPointer(ref reference),
Magic.addressOf(value));
return Magic.fromAddress(resultAddr);
}
[ForceInline]
[NoBarriers]
protected override Object AtomicCompareAndSwapImpl(ref Object loc,
Object newVal,
Object comp,
int mask)
{
CMSMarking.ReferenceCheck(ref loc, newVal, 0);
newVal = ForwardNullable(newVal);
for (;;) {
Object oldVal = loc;
Object commitVal;
if (oldVal == comp ||
ForwardNullable(oldVal) == ForwardNullable(comp)) {
commitVal = newVal;
} else {
// still CAS but only to get a memory barrier
commitVal = oldVal;
}
if (Interlocked.CompareExchange(ref loc,
commitVal, oldVal)
== oldVal) {
return oldVal;
}
}
}
[ForceInline]
[NoBarriers]
protected override bool EqImpl(Object a, Object b, int mask)
{
if ((mask&BarrierMask.PathSpec.AllowFast)!=0) {
return a == b;
} else {
return a == b || ForwardNullable(a) == ForwardNullable(b);
}
}
[ForceInline]
[NoBarriers]
[NoStackLinkCheckTrans]
protected override void WriteImpl(UIntPtr *location,
Object value,
int mask)
{
CMSMarking.ReferenceCheck(location, value, 0);
*location = Magic.addressOf(value);
}
[ForceInline]
[NoBarriers]
[NoStackLinkCheckTrans]
protected override void WriteImplByRef(ref Object location,
Object value,
int mask)
{
CMSMarking.ReferenceCheck(ref location, value, 0);
location = value;
}
}
}