-- HeapPack.Mesa Edited by: Bruce on August 29, 1980 1:27 PM
DIRECTORY
DebugFormat USING [Fob, Foo],
DOutput USING [Text],
DHeap USING [Zero],
Init USING [FlushCaches],
Inline USING [LongNumber],
Pc USING [CtxLink],
State USING [DNode, Get, Handle, NodeHandle, NodeType],
Storage USING [Expand, Free, Node, Prune],
Table USING [WordsFree];
HeapPack: PROGRAM
IMPORTS DOutput, Init, DHeap, State, Storage, Table
EXPORTS DHeap, Init, Pc =
BEGIN OPEN DebugFormat;
MoreHeapSpace: CARDINAL = 7;
NotInHeap: PUBLIC SIGNAL = CODE;
InvalidNodeType: ERROR = CODE;
FreeContextList: PUBLIC PROC [p: Pc.CtxLink] =
BEGIN
next: Pc.CtxLink;
FOR p ← p, next UNTIL p = NIL DO next ← p.link; Storage.Free[p] ENDLOOP;
END;
AllocFob: PUBLIC PROCEDURE RETURNS [f: Foo] =
BEGIN
f ← MyAlloc[SIZE[Fob],fobs];
DHeap.Zero[f, SIZE[Fob]];
END;
TopLevel: PUBLIC PROC = {MyFree[fobs]; [] ← Storage.Prune[]; CheckSymTabLength[]};
FreeFobs: PUBLIC PROC = {MyFree[fobs]};
CheckSymTabLength: PUBLIC PROC =
BEGIN
IF Table.WordsFree[] < 300 THEN
BEGIN
DOutput.Text[" Resetting symbol table! "L];
Init.FlushCaches[flushSymbols];
END;
END;
-- utilities
FreeLong: PUBLIC PROC [p: LONG POINTER] =
BEGIN OPEN Inline;
ln: LongNumber ← LOOPHOLE[p];
IF ln.highbits # 0 THEN {SIGNAL NotInHeap; RETURN};
Storage.Free[LOOPHOLE[ln.lowbits]]
END;
Initialize: PUBLIC PROC = BEGIN Storage.Expand[MoreHeapSpace] END;
FreeEverything: PUBLIC PROC = {FreeFobs[]};
MyAlloc: PROC [nwords: CARDINAL, nt: State.NodeType] RETURNS [POINTER] =
BEGIN
h: State.Handle ← State.Get[];
root: POINTER TO State.NodeHandle ← SELECT nt FROM
fobs => @h.fobs,
ENDCASE => ERROR InvalidNodeType;
n: State.NodeHandle ← Storage.Node[SIZE[State.DNode]];
n↑ ← [link: root↑, node: Storage.Node[nwords]];
root↑ ← n;
RETURN[n.node];
END;
MyFree: PROCEDURE [nt: State.NodeType] =
BEGIN
h: State.Handle ← State.Get[];
first: POINTER TO State.NodeHandle ← SELECT nt FROM
fobs => @h.fobs,
ENDCASE => ERROR InvalidNodeType;
i, next: State.NodeHandle;
FOR i ← first↑, next UNTIL i = NIL DO
next ← i.link;
SELECT nt FROM
fobs =>
BEGIN
f: Foo ← i.node;
IF ~f.there THEN FreeLong[f.addr.base];
END;
ENDCASE;
Storage.Free[i.node]; Storage.Free[i];
ENDLOOP;
IF first↑ # NIL THEN first↑ ← NIL;
END;
END.