184 lines
5.7 KiB
C#
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;
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|