RTFrameHeapSnapshotImpl.Mesa
last edited May 27, 1983 2:09 pm by Paul Rovner
DIRECTORY
RTFrameHeapSnapshot USING[], -- EXPORTS only
PrincOps
USING
[Frame, FrameVec, GlobalFrameHandle, MaxFrameSize, stackDepth],
VMSideDoor USING[FrameMarker, FramesDescriptor, GetFrames, StateVectorDescriptor];
RTFrameHeapSnapshotImpl: MONITOR -- protects the frameHeap snapshot
IMPORTS VMSideDoor
EXPORTS RTFrameHeapSnapshot
= BEGIN
Variables protected by the monitor
snapshotInUse: BOOL ← FALSE;
snapshotReleased: CONDITION;
frames: VMSideDoor.FramesDescriptor;
stateVectors: VMSideDoor.StateVectorDescriptor;
AcquireFrameHeapSnapshot:
PUBLIC
ENTRY
PROC = {
ENABLE UNWIND => NULL;
WHILE snapshotInUse DO WAIT snapshotReleased ENDLOOP;
[frames, stateVectors] ← VMSideDoor.GetFrames[];
snapshotInUse ← TRUE;
};
ReleaseFrameHeapSnapshot:
PUBLIC
ENTRY
PROC = {
ENABLE UNWIND => NULL;
IF NOT snapshotInUse THEN ERROR;
snapshotInUse ← FALSE;
NOTIFY snapshotReleased;
};
MapUncountedBodies:
PUBLIC
PROC
[proc: PROC[d: LONG DESCRIPTOR FOR ARRAY OF WORD]] = {
size: [0..PrincOps.MaxFrameSize+1];
FOR i:
NAT ← 0, i + size
UNTIL i =
LENGTH[frames]
DO
size ←
WITH v:
LOOPHOLE[frames[i], VMSideDoor.FrameMarker]
SELECT
FROM
frame => PrincOps.FrameVec[v.fsi] + 1, -- size includes the fsi word
deadSpace => v.count + 1
ENDCASE => ERROR;
proc[DESCRIPTOR[@frames[i + 1], size-1]];
ENDLOOP;
FOR i:
NAT ← 0, i+1
UNTIL i =
LENGTH[stateVectors]
DO proc[
DESCRIPTOR[@stateVectors[i].stk,
MIN[stateVectors[i].stkptr + 1, PrincOps.stackDepth]]];
ENDLOOP;
};
CheckForModuleReplacement:
PUBLIC
PROC[gfh: PrincOps.GlobalFrameHandle]
RETURNS[ok: BOOL ← TRUE] = {
size: [0..PrincOps.MaxFrameSize+1];
AcquireFrameHeapSnapshot[];
FOR i:
NAT ← 0, i + size
UNTIL i =
LENGTH[frames]
DO
size ←
WITH v:
LOOPHOLE[frames[i], VMSideDoor.FrameMarker]
SELECT
FROM
frame => PrincOps.FrameVec[v.fsi] + 1, -- size includes the fsi word
deadSpace => v.count + 1
ENDCASE => ERROR;
CONSERVATIVE may not be a local frame, e.g. a long arg/return rec or a gf (other?)
IF
LOOPHOLE[@frames[i + 1],
LONG
POINTER
TO PrincOps.Frame].accesslink = gfh
THEN {ok ← FALSE; EXIT}
ENDLOOP;
ReleaseFrameHeapSnapshot[];
};
END.