// // 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 { // This is the struct that we should use when traversing the stack. // It can be created from the encoded information in the stack // descriptor table. internal struct FrameDescriptor { internal const uint ESCAPE32_TAG = 0x0; internal const uint ESCAPE16_TAG = 0x1; internal const uint ESCAPE8_TAG = 0x2; internal const uint COMPRESSED_MASK_TAG = 0x3; internal bool isFramePointerOmitted; internal bool hasTransitionRecord; internal bool hasPinnedVariables; internal uint argumentCount; internal uint argumentTag; internal UIntPtr argumentMaskOrTable; internal UIntPtr calleeSaveValueMask; internal UIntPtr calleeSaveMask; internal int frameSize; internal int inBetweenSlotsAbove; internal int inBetweenSlotsBelow; internal unsafe FrameDescriptor(CompressedFrameDescriptor smallDescriptor) { if (smallDescriptor.IsCompressed()) { this.argumentCount = smallDescriptor.StackArgSize(); this.hasPinnedVariables = false; this.hasTransitionRecord = smallDescriptor.HasTransitionRecord(); if (smallDescriptor.IsFramePointerOmitted()) { this.isFramePointerOmitted = true; this.argumentTag = COMPRESSED_MASK_TAG; this.argumentMaskOrTable = smallDescriptor.ArgumentMaskNoFP(); this.calleeSaveValueMask = smallDescriptor.CalleeSaveValueMaskNoFP(); this.calleeSaveMask = smallDescriptor.CalleeSaveMaskNoFP(); this.inBetweenSlotsAbove = smallDescriptor.InBetweenSlotsAboveNoFP(); this.inBetweenSlotsBelow = smallDescriptor.InBetweenSlotsBelowNoFP(); this.frameSize = smallDescriptor.FrameSizeNoFP(); } else { this.isFramePointerOmitted = false; this.argumentTag = COMPRESSED_MASK_TAG; this.argumentMaskOrTable = smallDescriptor.ArgumentMaskWithFP(); this.calleeSaveValueMask = smallDescriptor.CalleeSaveValueMaskWithFP(); this.calleeSaveMask = smallDescriptor.CalleeSaveMaskWithFP(); this.inBetweenSlotsAbove = smallDescriptor.InBetweenSlotsAboveWithFP(); this.inBetweenSlotsBelow = smallDescriptor.InBetweenSlotsBelowWithFP(); this.frameSize = 0; } } else { this.argumentCount = 0; OverflowFrameDescriptor *overflow = smallDescriptor.OverflowDescriptor(); this.hasTransitionRecord = smallDescriptor.HasTransitionRecord(overflow); if (smallDescriptor.IsFramePointerOmitted(overflow)) { this.isFramePointerOmitted = true; this.argumentTag = smallDescriptor.EntrySizeNoFP(overflow); this.argumentMaskOrTable = (UIntPtr) (&overflow->variableData); this.calleeSaveMask = smallDescriptor.CalleeSaveMaskNoFP(overflow); this.calleeSaveValueMask = smallDescriptor.CalleeSaveValueMaskNoFP(overflow); this.inBetweenSlotsAbove = 0; this.inBetweenSlotsBelow = 0; this.frameSize = smallDescriptor.FrameSizeNoFP(overflow); this.hasPinnedVariables = smallDescriptor.HasPinnedPointersNoFP(overflow); } else { this.isFramePointerOmitted = false; this.argumentTag = smallDescriptor.EntrySizeWithFP(overflow); this.argumentMaskOrTable = (UIntPtr) (&overflow->variableData); this.calleeSaveMask = smallDescriptor.CalleeSaveMaskWithFP(overflow); this.calleeSaveValueMask = smallDescriptor.CalleeSaveValueMaskWithFP(overflow); this.inBetweenSlotsAbove = 0; this.inBetweenSlotsBelow = 0; this.frameSize = 0; this.hasPinnedVariables = smallDescriptor.HasPinnedPointersWithFP(overflow); } } } } internal struct CompressedFrameDescriptorTemplate { internal bool IsCompressed() { return true; } internal bool IsFramePointerOmitted() { return true; } internal bool HasTransitionRecord() { return true; } internal uint StackArgSize() { return 0;} internal UIntPtr ArgumentMaskNoFP() { return UIntPtr.Zero;} internal UIntPtr CalleeSaveValueMaskNoFP() { return UIntPtr.Zero; } internal UIntPtr CalleeSaveMaskNoFP() { return UIntPtr.Zero;} internal int FrameSizeNoFP() { return 0; } internal int InBetweenSlotsAboveNoFP() { return 0; } internal int InBetweenSlotsBelowNoFP() { return 0; } internal UIntPtr ArgumentMaskWithFP() { return UIntPtr.Zero; } internal UIntPtr CalleeSaveValueMaskWithFP() { return UIntPtr.Zero; } internal UIntPtr CalleeSaveMaskWithFP() { return UIntPtr.Zero; } internal int InBetweenSlotsAboveWithFP() { return 0; } internal int InBetweenSlotsBelowWithFP() { return 0; } internal unsafe OverflowFrameDescriptor *OverflowDescriptor() { return null; } internal unsafe bool IsFramePointerOmitted(OverflowFrameDescriptor *overflow) { return true; } internal unsafe bool HasTransitionRecord(OverflowFrameDescriptor *overflow) { return true; } internal unsafe UIntPtr CalleeSaveValueMaskNoFP(OverflowFrameDescriptor *overflow) { return UIntPtr.Zero; } internal unsafe UIntPtr CalleeSaveMaskNoFP(OverflowFrameDescriptor *overflow) { return UIntPtr.Zero; } internal unsafe bool HasPinnedPointersNoFP(OverflowFrameDescriptor *overflow) { return true; } internal unsafe int FrameSizeNoFP(OverflowFrameDescriptor *overflow) { return 0; } internal unsafe uint EntrySizeNoFP(OverflowFrameDescriptor *overflow) { return 0; } internal unsafe UIntPtr CalleeSaveValueMaskWithFP(OverflowFrameDescriptor *overflow) { return UIntPtr.Zero; } internal unsafe UIntPtr CalleeSaveMaskWithFP(OverflowFrameDescriptor *overflow) { return UIntPtr.Zero; } internal unsafe bool HasPinnedPointersWithFP(OverflowFrameDescriptor *overflow) { return true; } internal unsafe uint EntrySizeWithFP(OverflowFrameDescriptor *overflow) { return 0; } internal unsafe void ExpandDescriptor(OverflowFrameDescriptor *overflow, ref FrameDescriptor res) {} } }