singrdk/base/Kernel/Bartok/GCs/Allocator.cs

118 lines
3.8 KiB
C#

/*******************************************************************/
/* 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. */
/*******************************************************************/
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
namespace System.GCs
{
using Microsoft.Bartok.Runtime;
using System.Runtime.CompilerServices;
[NoCCtor]
internal class Allocator
{
[Inline]
[NoHeapAllocation]
internal static unsafe void WriteAlignment(UIntPtr addr)
{
*(UIntPtr*)addr = ALIGNMENT_TOKEN;
}
[Inline]
[NoHeapAllocation]
internal static unsafe bool IsAlignmentMarkerAddr(UIntPtr addr)
{
return (*(UIntPtr*)addr == ALIGNMENT_TOKEN);
}
[Inline]
[NoHeapAllocation]
internal static unsafe bool IsAlignment(UIntPtr obj)
{
return *(UIntPtr*)(obj - PreHeader.Size) == ALIGNMENT_TOKEN;
}
[Inline]
[NoHeapAllocation]
internal static UIntPtr SkipAlignment(UIntPtr obj)
{
while (IsAlignment(obj)) {
obj += UIntPtr.Size;
}
return obj;
}
// Pads the allocation to the appropriate alignment.
[Inline]
internal static UIntPtr AlignedAllocationPtr(UIntPtr startAddr,
UIntPtr limitAddr,
uint alignment)
{
if (alignment > UIntPtr.Size) {
uint alignmentMask = alignment - 1;
int offset = PreHeader.Size + PostHeader.Size;
while (((startAddr + offset) & alignmentMask) != 0 &&
startAddr < limitAddr) {
Allocator.WriteAlignment(startAddr);
startAddr += UIntPtr.Size;
}
}
return startAddr;
}
[Inline]
internal static UIntPtr AlignedObjectPtr(UIntPtr startAddr,
uint alignment)
{
if (alignment > UIntPtr.Size) {
uint alignmentMask = alignment - 1;
int offset = PostHeader.Size;
while (((startAddr + offset) & alignmentMask) != 0) {
Allocator.WriteAlignment(startAddr- PreHeader.Size);
startAddr += UIntPtr.Size;
}
}
return startAddr;
}
[NoHeapAllocation]
internal static unsafe UIntPtr * GetObjectVTableAddress
(UIntPtr potentialObject) {
UIntPtr vtableAddr = potentialObject + Magic.OffsetOfVTable;
return (UIntPtr *) vtableAddr;
}
[NoHeapAllocation]
internal static unsafe UIntPtr GetObjectVTable
(UIntPtr potentialObject) {
return *GetObjectVTableAddress(potentialObject);
}
[NoHeapAllocation]
internal static unsafe void SetObjectVTable(UIntPtr potentialObject,
UIntPtr vtable) {
*GetObjectVTableAddress(potentialObject) = vtable;
}
[NoHeapAllocation]
internal static bool IsZeroVTable(UIntPtr addr) {
return GetObjectVTable(addr) == UIntPtr.Zero;
}
private static UIntPtr ALIGNMENT_TOKEN{
[Inline]
[NoHeapAllocation]
get { return ~((UIntPtr)3u); }
}
}
}