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: BOOLFALSE;
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: BOOLTRUE] = {
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.