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

184 lines
5.7 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 System.Runtime.CompilerServices;
#if SINGULARITY
using Microsoft.Singularity;
#endif
// REVIEW: This should probably only be on the mixin types to
// CalleeSaveRegisters, but it seems to be lost if put there.
[AccessedByRuntime("referenced from halforgc.asm")]
internal struct CalleeSaveRegisters
{
internal void DebugTrace()
{
// Placeholder for an override method
}
internal UIntPtr GetFramePointer()
{
// Placeholder for an override method
return UIntPtr.Zero;
}
}
internal unsafe struct CalleeSaveLocations {
#if SINGULARITY_KERNEL
internal void SetCalleeSaves(ThreadContext *context)
{
// Placeholder for an override method
}
#endif
internal void SetCalleeSaves(CalleeSaveRegisters *calleeSaveRegisters)
{
// Placeholder for an override method
}
internal void ClearCalleeSaves()
{
// Placeholder for an override method
}
[PreInitRefCounts]
internal void ScanLiveRegs(UIntPtr mask,
NonNullReferenceVisitor referenceVisitor)
{
// Placeholder for an override method
}
internal void PopFrame(UIntPtr *framePointer,
UIntPtr calleeSaveMask,
bool framePointerOmitted,
bool hasTransitionRecord)
{
// Placeholder for an override method
}
internal void ClearFrame(UIntPtr calleeSaveMask,
bool framePointerOmitted)
{
// Placeholder for an override method
}
internal UIntPtr GetFramePointer()
{
// Placeholder for an override method
return UIntPtr.Zero;
}
internal struct RegLocation
{
[Inline]
internal void SetCalleeReg(UIntPtr *regField)
{
this.pending = false;
this.value = *regField;
this.head = regField;
*regField = UIntPtr.Zero;
}
internal void ClearCalleeReg()
{
VTable.Deny(this.pending);
UIntPtr *scan = this.head;
while (scan != null) {
UIntPtr temp = *scan;
*scan = value;
scan = (UIntPtr *) temp;
}
this.head = null;
}
[PreInitRefCounts]
internal void ScanLiveReg(uint kind,
NonNullReferenceVisitor visitor)
{
switch (kind) {
case 0: {
// Value is not a traceable heap pointer
break;
}
case 1: {
// Value is a pointer variable
VTable.Deny(this.head == null);
if (value != UIntPtr.Zero) {
fixed (UIntPtr *valueField = &this.value) {
visitor.Visit(valueField);
}
}
ClearCalleeReg();
break;
}
case 2: {
// Value is unchanged since function entry
VTable.Deny(this.pending);
this.pending = true;
break;
}
case 3:
default: {
VTable.NotReached("ScanLiveReg 3 or default");
break;
}
}
}
internal void PopFrameReg(ref UIntPtr *calleeSaveStart)
{
if (this.head != null && !this.pending) {
ClearCalleeReg();
}
if (this.head == null) {
this.value = *calleeSaveStart;
} else {
VTable.Assert(this.pending, "pending should be true");
VTable.Assert(*calleeSaveStart == this.value,
"values are not equal");
}
this.pending = false;
*calleeSaveStart = (UIntPtr) this.head;
this.head = calleeSaveStart;
calleeSaveStart--;
}
internal void ClearFrameReg() {
UIntPtr *scan = this.head;
while (scan != null) {
UIntPtr temp = *scan;
*scan = value;
scan = (UIntPtr *) temp;
}
this.head = null;
this.pending = false;
this.value = UIntPtr.Zero;
}
internal bool pending;
internal UIntPtr value;
internal UIntPtr *head;
}
CalleeSaveLocations.RegLocation FramePointer;
}
}