<> <> <> <> 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 <> 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; <<>> <> IF LOOPHOLE[@frames[i + 1], LONG POINTER TO PrincOps.Frame].accesslink = gfh THEN {ok _ FALSE; EXIT} ENDLOOP; ReleaseFrameHeapSnapshot[]; }; END.