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.Threading;
|
|
|
|
using System.Runtime.CompilerServices;
|
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
internal unsafe class BootstrapMemory : Allocator
|
2008-03-05 09:52:00 -05:00
|
|
|
{
|
|
|
|
|
|
|
|
// WARNING: don't initialize any static fields in this class
|
|
|
|
// without manually running the class constructor at startup!
|
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
private static UIntPtr allocPtr;
|
|
|
|
private static UIntPtr limitPtr;
|
2008-03-05 09:52:00 -05:00
|
|
|
|
|
|
|
[PreInitRefCounts]
|
2008-11-17 18:29:00 -05:00
|
|
|
#if !SINGULARITY // Needed before Bartok runtime is initialized
|
2008-03-05 09:52:00 -05:00
|
|
|
[NoStackLinkCheck]
|
|
|
|
#endif
|
2008-11-17 18:29:00 -05:00
|
|
|
[NoBarriers]
|
2008-03-05 09:52:00 -05:00
|
|
|
internal static void Initialize(UIntPtr systemMemorySize) {
|
2008-11-17 18:29:00 -05:00
|
|
|
allocPtr = MemoryManager.AllocateMemory(systemMemorySize);
|
|
|
|
limitPtr = allocPtr + systemMemorySize;
|
2008-03-05 09:52:00 -05:00
|
|
|
if(GC.gcType != GCType.NullCollector) {
|
2008-11-17 18:29:00 -05:00
|
|
|
PageManager.SetStaticDataPages(allocPtr, systemMemorySize);
|
2008-03-05 09:52:00 -05:00
|
|
|
#if !SINGULARITY
|
2008-11-17 18:29:00 -05:00
|
|
|
PageTable.SetProcess(PageTable.Page(allocPtr),
|
2008-03-05 09:52:00 -05:00
|
|
|
PageTable.PageCount(systemMemorySize));
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
[NoBarriers]
|
|
|
|
private static UIntPtr AllocateBlock(UIntPtr bytes, uint alignment)
|
|
|
|
{
|
|
|
|
UIntPtr startPtr =
|
|
|
|
Allocator.AlignedAllocationPtr(allocPtr, limitPtr, alignment);
|
|
|
|
allocPtr = startPtr + bytes;
|
|
|
|
if (allocPtr > limitPtr) {
|
|
|
|
VTable.DebugPrint("Out of BootstrapMemory");
|
|
|
|
VTable.DebugBreak();
|
|
|
|
}
|
|
|
|
return startPtr + PreHeader.Size;
|
|
|
|
}
|
|
|
|
|
|
|
|
[NoBarriers]
|
2008-03-05 09:52:00 -05:00
|
|
|
[ManualRefCounts]
|
2008-11-17 18:29:00 -05:00
|
|
|
#if !SINGULARITY // Needed before Bartok runtime is initialized
|
|
|
|
[NoStackLinkCheckTrans]
|
2008-03-05 09:52:00 -05:00
|
|
|
#endif
|
|
|
|
internal static Object Allocate(VTable vtable) {
|
|
|
|
UIntPtr numBytes = ObjectLayout.ObjectSize(vtable);
|
2008-11-17 18:29:00 -05:00
|
|
|
UIntPtr objectAddr = AllocateBlock(numBytes, vtable.baseAlignment);
|
2008-03-05 09:52:00 -05:00
|
|
|
Object result = Magic.fromAddress(objectAddr);
|
|
|
|
#if REFERENCE_COUNTING_GC
|
2008-11-17 18:29:00 -05:00
|
|
|
uint refState = vtable.isAcyclicRefType ?
|
2008-03-05 09:52:00 -05:00
|
|
|
(ReferenceCountingCollector.
|
2008-11-17 18:29:00 -05:00
|
|
|
acyclicFlagMask | 2) : 2;
|
|
|
|
result.REF_STATE = refState &
|
2008-03-05 09:52:00 -05:00
|
|
|
~ReferenceCountingCollector.countingONFlagMask;
|
|
|
|
#elif DEFERRED_REFERENCE_COUNTING_GC
|
2008-11-17 18:29:00 -05:00
|
|
|
uint refState = vtable.isAcyclicRefType ?
|
2008-03-05 09:52:00 -05:00
|
|
|
(DeferredReferenceCountingCollector.
|
|
|
|
acyclicFlagMask |
|
|
|
|
DeferredReferenceCountingCollector.
|
|
|
|
markFlagMask) :
|
|
|
|
DeferredReferenceCountingCollector.
|
|
|
|
markFlagMask;
|
2008-11-17 18:29:00 -05:00
|
|
|
result.REF_STATE = refState &
|
2008-03-05 09:52:00 -05:00
|
|
|
~DeferredReferenceCountingCollector.countingONFlagMask;
|
|
|
|
#endif
|
2008-11-17 18:29:00 -05:00
|
|
|
Barrier.BootstrapInitObject(result, vtable);
|
2008-03-05 09:52:00 -05:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
[NoBarriers]
|
2008-03-05 09:52:00 -05:00
|
|
|
[ManualRefCounts]
|
2008-11-17 18:29:00 -05:00
|
|
|
#if !SINGULARITY // Needed before Bartok runtime is initialized
|
|
|
|
[NoStackLinkCheckTrans]
|
2008-03-05 09:52:00 -05:00
|
|
|
#endif
|
|
|
|
internal static Object Allocate(VTable vtable, uint count) {
|
|
|
|
UIntPtr numBytes = ObjectLayout.ArraySize(vtable, count);
|
2008-11-17 18:29:00 -05:00
|
|
|
UIntPtr objectAddr = AllocateBlock(numBytes, vtable.baseAlignment);
|
2008-03-05 09:52:00 -05:00
|
|
|
Array result = Magic.toArray(Magic.fromAddress(objectAddr));
|
|
|
|
#if REFERENCE_COUNTING_GC
|
2008-11-17 18:29:00 -05:00
|
|
|
uint refState = vtable.isAcyclicRefType ?
|
2008-03-05 09:52:00 -05:00
|
|
|
(ReferenceCountingCollector.
|
2008-11-17 18:29:00 -05:00
|
|
|
acyclicFlagMask | 2) : 2;
|
|
|
|
result.REF_STATE = refState &
|
2008-03-05 09:52:00 -05:00
|
|
|
~ReferenceCountingCollector.countingONFlagMask;
|
|
|
|
#elif DEFERRED_REFERENCE_COUNTING_GC
|
2008-11-17 18:29:00 -05:00
|
|
|
uint refState = vtable.isAcyclicRefType ?
|
2008-03-05 09:52:00 -05:00
|
|
|
(DeferredReferenceCountingCollector.
|
|
|
|
acyclicFlagMask |
|
|
|
|
DeferredReferenceCountingCollector.
|
|
|
|
markFlagMask) :
|
|
|
|
DeferredReferenceCountingCollector.
|
|
|
|
markFlagMask;
|
2008-11-17 18:29:00 -05:00
|
|
|
result.REF_STATE = refState &
|
2008-03-05 09:52:00 -05:00
|
|
|
~DeferredReferenceCountingCollector.countingONFlagMask;
|
|
|
|
#endif
|
2008-11-17 18:29:00 -05:00
|
|
|
Barrier.BootstrapInitObject(result, vtable);
|
2008-03-05 09:52:00 -05:00
|
|
|
result.InitializeVectorLength((int) count);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
[NoBarriers]
|
2008-03-05 09:52:00 -05:00
|
|
|
[PreInitRefCounts]
|
|
|
|
#if !SINGULARITY
|
2008-11-17 18:29:00 -05:00
|
|
|
[NoStackLinkCheckTrans]
|
2008-03-05 09:52:00 -05:00
|
|
|
#endif
|
|
|
|
internal static Object Allocate(Type t) {
|
2008-11-17 18:29:00 -05:00
|
|
|
return Allocate(Magic.toRuntimeType(t));
|
2008-03-05 09:52:00 -05:00
|
|
|
}
|
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
[NoBarriers]
|
2008-03-05 09:52:00 -05:00
|
|
|
[PreInitRefCounts]
|
|
|
|
#if !SINGULARITY
|
2008-11-17 18:29:00 -05:00
|
|
|
[NoStackLinkCheckTrans]
|
2008-03-05 09:52:00 -05:00
|
|
|
#endif
|
|
|
|
internal static Object Allocate(Type t, uint count) {
|
2008-11-17 18:29:00 -05:00
|
|
|
return Allocate(Magic.toRuntimeType(t), count);
|
2008-03-05 09:52:00 -05:00
|
|
|
}
|
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
[NoBarriers]
|
2008-03-05 09:52:00 -05:00
|
|
|
[PreInitRefCounts]
|
|
|
|
#if !SINGULARITY
|
2008-11-17 18:29:00 -05:00
|
|
|
[NoStackLinkCheckTrans]
|
2008-03-05 09:52:00 -05:00
|
|
|
#endif
|
|
|
|
internal static Object Allocate(RuntimeType t) {
|
|
|
|
return Allocate(t.classVtable);
|
|
|
|
}
|
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
[NoBarriers]
|
2008-03-05 09:52:00 -05:00
|
|
|
[PreInitRefCounts]
|
|
|
|
#if !SINGULARITY
|
2008-11-17 18:29:00 -05:00
|
|
|
[NoStackLinkCheckTrans]
|
2008-03-05 09:52:00 -05:00
|
|
|
#endif
|
|
|
|
internal static Object Allocate(RuntimeType t, uint count) {
|
|
|
|
return Allocate(t.classVtable, count);
|
|
|
|
}
|
|
|
|
|
|
|
|
internal static void Truncate() {
|
2008-11-17 18:29:00 -05:00
|
|
|
UIntPtr allocLimit = PageTable.PagePad(allocPtr);
|
|
|
|
UIntPtr unusedSize = limitPtr - allocLimit;
|
2008-03-05 09:52:00 -05:00
|
|
|
if(GC.gcType != GCType.NullCollector) {
|
|
|
|
PageManager.ReleaseUnusedPages(PageTable.Page(allocLimit),
|
|
|
|
PageTable.PageCount(unusedSize),
|
|
|
|
true);
|
|
|
|
}
|
2008-11-17 18:29:00 -05:00
|
|
|
limitPtr = allocLimit;
|
2008-03-05 09:52:00 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|