diff --git a/src/lib/system/darwin/clang/Console.Mod b/src/lib/system/darwin/clang/Console.Mod new file mode 100644 index 00000000..e523ef7b --- /dev/null +++ b/src/lib/system/darwin/clang/Console.Mod @@ -0,0 +1,86 @@ +MODULE Console; (* J. Templ, 29-June-96 *) + + (* output to Unix standard output device based Write system call *) + + IMPORT SYSTEM; + + VAR line: ARRAY 128 OF CHAR; + pos: INTEGER; + + PROCEDURE -Write(adr, n: LONGINT) + "write(1/*stdout*/, adr, n)"; + + PROCEDURE -read(VAR ch: CHAR): LONGINT + "read(0/*stdin*/, ch, 1)"; + + PROCEDURE Flush*(); + BEGIN + Write(SYSTEM.ADR(line), pos); pos := 0; + END Flush; + + PROCEDURE Char*(ch: CHAR); + BEGIN + IF pos = LEN(line) THEN Flush() END ; + line[pos] := ch; INC(pos); + IF ch = 0AX THEN Flush() END + END Char; + + PROCEDURE String*(s: ARRAY OF CHAR); + VAR i: INTEGER; + BEGIN i := 0; + WHILE s[i] # 0X DO Char(s[i]); INC(i) END + END String; + + PROCEDURE Int*(i, n: LONGINT); + VAR s: ARRAY 32 OF CHAR; i1, k: LONGINT; + BEGIN + IF i = SYSTEM.LSH(LONG(LONG(1)), SIZE(LONGINT)*8 - 1) THEN + IF SIZE(LONGINT) = 8 THEN s := "8085774586302733229"; k := 19 + ELSE s := "8463847412"; k := 10 + END + ELSE + i1 := ABS(i); + s[0] := CHR(i1 MOD 10 + ORD("0")); i1 := i1 DIV 10; k := 1; + WHILE i1 > 0 DO s[k] := CHR(i1 MOD 10 + ORD("0")); i1 := i1 DIV 10; INC(k) END + END ; + IF i < 0 THEN s[k] := "-"; INC(k) END ; + WHILE n > k DO Char(" "); DEC(n) END ; + WHILE k > 0 DO DEC(k); Char(s[k]) END + END Int; + + PROCEDURE Ln*; + BEGIN Char(0AX); (* Unix end-of-line *) + END Ln; + + PROCEDURE Bool*(b: BOOLEAN); + BEGIN IF b THEN String("TRUE") ELSE String("FALSE") END + END Bool; + + PROCEDURE Hex*(i: LONGINT); + VAR k, n: LONGINT; + BEGIN + k := -28; + WHILE k <= 0 DO + n := ASH(i, k) MOD 16; + IF n <= 9 THEN Char(CHR(ORD("0") + n)) ELSE Char(CHR(ORD("A") - 10 + n)) END ; + INC(k, 4) + END + END Hex; + + PROCEDURE Read*(VAR ch: CHAR); + VAR n: LONGINT; + BEGIN Flush(); + n := read(ch); + IF n # 1 THEN ch := 0X END + END Read; + + PROCEDURE ReadLine*(VAR line: ARRAY OF CHAR); + VAR i: LONGINT; ch: CHAR; + BEGIN Flush(); + i := 0; Read(ch); + WHILE (i < LEN(line) - 1) & (ch # 0AX) & (ch # 0X) DO line[i] := ch; INC(i); Read(ch) END ; + line[i] := 0X + END ReadLine; + +BEGIN pos := 0; +END Console. diff --git a/src/lib/system/darwin/clang/SYSTEM.Mod b/src/lib/system/darwin/clang/SYSTEM.Mod new file mode 100644 index 00000000..6fc08dcf --- /dev/null +++ b/src/lib/system/darwin/clang/SYSTEM.Mod @@ -0,0 +1,520 @@ +(* +* voc (jet backend) runtime system, Version 1.1 +* +* Copyright (c) Software Templ, 1994, 1995, 1996 +* +* Module SYSTEM is subject to change any time without prior notification. +* Software Templ disclaims all warranties with regard to module SYSTEM, +* in particular shall Software Templ not be liable for any damage resulting +* from inappropriate use or modification of module SYSTEM. +*) + +MODULE SYSTEM; (* J. Templ, 31.5.95 *) + + IMPORT SYSTEM; (*must not import other modules*) + + CONST + ModNameLen = 20; + CmdNameLen = 24; + SZL = SIZE(LONGINT); + Unit = 4*SZL; (* smallest possible heap block *) + nofLists = 9; (* number of free_lists *) + heapSize0 = 8000*Unit; (* startup heap size *) + + (* all blocks look the same: + free blocks describe themselves: size = Unit + tag = &tag++ + ->blksize + sentinel = -SZL + next + *) + + (* heap chunks *) + nextChnkOff = 0; (* next heap chunk, sorted ascendingly! *) + endOff = SZL; (* end of heap chunk *) + blkOff = 3*SZL; (* first block in a chunk *) + + (* heap blocks *) + tagOff = 0; (* block starts with tag *) + sizeOff = SZL; (* block size in free block relative to block start *) + sntlOff = 2*SZL; (* pointer offset table sentinel in free block relative to block start *) + nextOff = 3*SZL; (* next pointer in free block relative to block start *) + NoPtrSntl = LONG(LONG(-SZL)); + + + TYPE + ModuleName = ARRAY ModNameLen OF CHAR; + CmdName = ARRAY CmdNameLen OF CHAR; + + Module = POINTER TO ModuleDesc; + Cmd = POINTER TO CmdDesc; + EnumProc = PROCEDURE(P: PROCEDURE(p: SYSTEM.PTR)); + ModuleDesc = RECORD + next: Module; + name: ModuleName; + refcnt: LONGINT; + cmds: Cmd; + types: LONGINT; + enumPtrs: EnumProc; + reserved1, reserved2: LONGINT + END ; + + Command = PROCEDURE; + + CmdDesc = RECORD + next: Cmd; + name: CmdName; + cmd: Command + END ; + + Finalizer = PROCEDURE(obj: SYSTEM.PTR); + + FinNode = POINTER TO FinDesc; + FinDesc = RECORD + next: FinNode; + obj: LONGINT; (* weak pointer *) + marked: BOOLEAN; + finalize: Finalizer; + END ; + + VAR + (* the list of loaded (=initialization started) modules *) + modules*: SYSTEM.PTR; + + freeList: ARRAY nofLists + 1 OF LONGINT; (* dummy, 16, 32, 48, 64, 80, 96, 112, 128, sentinel *) + bigBlocks, allocated*: LONGINT; + firstTry: BOOLEAN; + + (* extensible heap *) + heap, (* the sorted list of heap chunks *) + heapend, (* max possible pointer value (used for stack collection) *) + heapsize*: LONGINT; (* the sum of all heap chunk sizes *) + + (* finalization candidates *) + fin: FinNode; + + (* garbage collector locking *) + gclock*: SHORTINT; + + + PROCEDURE -malloc(size: LONGINT): LONGINT "(LONGINT)malloc(size)"; + PROCEDURE -Lock() "Lock"; + PROCEDURE -Unlock() "Unlock"; + PROCEDURE -Mainfrm(): LONGINT "SYSTEM_mainfrm"; +(* + PROCEDURE TAS*(VAR flag:BOOLEAN): BOOLEAN; (* added for compatibility with ulmSYSTEM module; noch *) + VAR oldflag : BOOLEAN; + BEGIN + oldflag := flag; + flag := TRUE; + RETURN oldflag; + END TAS; +*) + PROCEDURE REGMOD*(VAR name: ModuleName; enumPtrs: EnumProc): SYSTEM.PTR; + VAR m: Module; + BEGIN + IF name = "SYSTEM" THEN (* cannot use NEW *) + SYSTEM.NEW(m, SIZE(ModuleDesc)); m.cmds := NIL + ELSE NEW(m) + END ; + COPY(name, m.name); m.refcnt := 0; m.enumPtrs := enumPtrs; m.next := SYSTEM.VAL(Module, modules); + modules := m; + RETURN m + END REGMOD; + + PROCEDURE REGCMD*(m: Module; VAR name: CmdName; cmd: Command); + VAR c: Cmd; + BEGIN NEW(c); + COPY(name, c.name); c.cmd := cmd; c.next := m.cmds; m.cmds := c + END REGCMD; + + PROCEDURE REGTYP*(m: Module; typ: LONGINT); + BEGIN SYSTEM.PUT(typ, m.types); m.types := typ + END REGTYP; + + PROCEDURE INCREF*(m: Module); + BEGIN INC(m.refcnt) + END INCREF; + + PROCEDURE NewChunk(blksz: LONGINT): LONGINT; + VAR chnk: LONGINT; + BEGIN + chnk := malloc(blksz + blkOff); + IF chnk # 0 THEN + SYSTEM.PUT(chnk + endOff, chnk + (blkOff + blksz)); + SYSTEM.PUT(chnk + blkOff, chnk + (blkOff + sizeOff)); + SYSTEM.PUT(chnk + (blkOff + sizeOff), blksz); + SYSTEM.PUT(chnk + (blkOff + sntlOff), NoPtrSntl); + SYSTEM.PUT(chnk + (blkOff + nextOff), bigBlocks); + bigBlocks := chnk + blkOff; + INC(heapsize, blksz) + END ; + RETURN chnk + END NewChunk; + + PROCEDURE ExtendHeap(blksz: LONGINT); + VAR size, chnk, j, next: LONGINT; + BEGIN + IF blksz > 10000*Unit THEN size := blksz + ELSE size := 10000*Unit (* additional heuristics *) + END ; + chnk := NewChunk(size); + IF chnk # 0 THEN + (*sorted insertion*) + IF chnk < heap THEN + SYSTEM.PUT(chnk, heap); heap := chnk + ELSE + j := heap; SYSTEM.GET(j, next); + WHILE (next # 0) & (chnk > next) DO j := next; SYSTEM.GET(j, next) END ; + SYSTEM.PUT(chnk, next); SYSTEM.PUT(j, chnk) + END ; + IF next = 0 THEN SYSTEM.GET(chnk + endOff, heapend) END + END + END ExtendHeap; + + PROCEDURE ^GC*(markStack: BOOLEAN); + + PROCEDURE NEWREC*(tag: LONGINT): SYSTEM.PTR; + VAR i, i0, di, blksz, restsize, t, adr, end, next, prev: LONGINT; new: SYSTEM.PTR; + BEGIN + Lock(); + SYSTEM.GET(tag, blksz); + ASSERT(blksz MOD Unit = 0); + i0 := blksz DIV Unit; i := i0; + IF i < nofLists THEN adr := freeList[i]; + WHILE adr = 0 DO INC(i); adr := freeList[i] END + END ; + IF i < nofLists THEN (* unlink *) + SYSTEM.GET(adr + nextOff, next); + freeList[i] := next; + IF i # i0 THEN (* split *) + di := i - i0; restsize := di * Unit; end := adr + restsize; + SYSTEM.PUT(end + sizeOff, blksz); + SYSTEM.PUT(end + sntlOff, NoPtrSntl); + SYSTEM.PUT(end, end + sizeOff); + SYSTEM.PUT(adr + sizeOff, restsize); + SYSTEM.PUT(adr + nextOff, freeList[di]); + freeList[di] := adr; + INC(adr, restsize) + END + ELSE + adr := bigBlocks; prev := 0; + LOOP + IF adr = 0 THEN + IF firstTry THEN + GC(TRUE); INC(blksz, Unit); + IF (heapsize - allocated - blksz) * 4 < heapsize THEN + (* heap is still almost full; expand to avoid thrashing *) + ExtendHeap((allocated + blksz) DIV (3*Unit) * (4*Unit) - heapsize) + END ; + firstTry := FALSE; new := NEWREC(tag); firstTry := TRUE; + IF new = NIL THEN + (* depending on the fragmentation, the heap may not have been extended by + the anti-thrashing heuristics above *) + ExtendHeap((allocated + blksz) DIV (3*Unit) * (4*Unit) - heapsize); + new := NEWREC(tag); (* will find a free block if heap has been expanded properly *) + END ; + Unlock(); RETURN new + ELSE + Unlock(); RETURN NIL + END + END ; + SYSTEM.GET(adr+sizeOff, t); + IF t >= blksz THEN EXIT END ; + prev := adr; SYSTEM.GET(adr + nextOff, adr) + END ; + restsize := t - blksz; end := adr + restsize; + SYSTEM.PUT(end + sizeOff, blksz); + SYSTEM.PUT(end + sntlOff, NoPtrSntl); + SYSTEM.PUT(end, end + sizeOff); + IF restsize > nofLists * Unit THEN (*resize*) + SYSTEM.PUT(adr + sizeOff, restsize) + ELSE (*unlink*) + SYSTEM.GET(adr + nextOff, next); + IF prev = 0 THEN bigBlocks := next + ELSE SYSTEM.PUT(prev + nextOff, next); + END ; + IF restsize > 0 THEN (*move*) + di := restsize DIV Unit; + SYSTEM.PUT(adr + sizeOff, restsize); + SYSTEM.PUT(adr + nextOff, freeList[di]); + freeList[di] := adr + END + END ; + INC(adr, restsize) + END ; + i := adr + 4*SZL; end := adr + blksz; + WHILE i < end DO (*deliberately unrolled*) + SYSTEM.PUT(i, LONG(LONG(0))); + SYSTEM.PUT(i + SZL, LONG(LONG(0))); + SYSTEM.PUT(i + 2*SZL, LONG(LONG(0))); + SYSTEM.PUT(i + 3*SZL, LONG(LONG(0))); + INC(i, 4*SZL) + END ; + SYSTEM.PUT(adr + nextOff, LONG(LONG(0))); + SYSTEM.PUT(adr, tag); + SYSTEM.PUT(adr + sizeOff, LONG(LONG(0))); + SYSTEM.PUT(adr + sntlOff, LONG(LONG(0))); + INC(allocated, blksz); + Unlock(); + RETURN SYSTEM.VAL(SYSTEM.PTR, adr + SZL) + END NEWREC; + + PROCEDURE NEWBLK*(size: LONGINT): SYSTEM.PTR; + VAR blksz, tag: LONGINT; new: SYSTEM.PTR; + BEGIN + Lock(); + blksz := (size + (4*SZL + Unit - 1)) DIV Unit * Unit; (*size + tag + meta + blksz + sntnl + UnitAlignment*) + new := NEWREC(SYSTEM.ADR(blksz)); + tag := SYSTEM.VAL(LONGINT, new) + blksz - 3*SZL; + SYSTEM.PUT(tag - SZL, LONG(LONG(0))); (*reserved for meta info*) + SYSTEM.PUT(tag, blksz); + SYSTEM.PUT(tag + SZL, NoPtrSntl); + SYSTEM.PUT(SYSTEM.VAL(LONGINT, new) - SZL, tag); + Unlock(); + RETURN new + END NEWBLK; + + PROCEDURE Mark(q: LONGINT); + VAR p, tag, fld, n, offset, tagbits: LONGINT; + BEGIN + IF q # 0 THEN SYSTEM.GET(q - SZL, tagbits); + IF ~ODD(tagbits) THEN + SYSTEM.PUT(q - SZL, tagbits + 1); + p := 0; tag := tagbits + SZL; + LOOP + SYSTEM.GET(tag, offset); + IF offset < 0 THEN + SYSTEM.PUT(q - SZL, tag + offset + 1); + IF p = 0 THEN EXIT END ; + n := q; q := p; + SYSTEM.GET(q - SZL, tag); DEC(tag, 1); + SYSTEM.GET(tag, offset); fld := q + offset; + SYSTEM.GET(fld, p); SYSTEM.PUT(fld, n) + ELSE + fld := q + offset; + SYSTEM.GET(fld, n); + IF n # 0 THEN + SYSTEM.GET(n - SZL, tagbits); + IF ~ODD(tagbits) THEN + SYSTEM.PUT(n - SZL, tagbits + 1); + SYSTEM.PUT(q - SZL, tag + 1); + SYSTEM.PUT(fld, p); p := q; q := n; + tag := tagbits + END + END + END ; + INC(tag, SZL) + END + END + END + END Mark; + + PROCEDURE MarkP(p: SYSTEM.PTR); (* for compatibility with EnumPtrs in ANSI mode *) + BEGIN + Mark(SYSTEM.VAL(LONGINT, p)) + END MarkP; + + PROCEDURE Scan; + VAR chnk, adr, end, start, tag, i, size, freesize: LONGINT; + BEGIN bigBlocks := 0; i := 1; + WHILE i < nofLists DO freeList[i] := 0; INC(i) END ; + freesize := 0; allocated := 0; chnk := heap; + WHILE chnk # 0 DO + adr := chnk + blkOff; SYSTEM.GET(chnk + endOff, end); + WHILE adr < end DO + SYSTEM.GET(adr, tag); + IF ODD(tag) THEN (*marked*) + IF freesize > 0 THEN + start := adr - freesize; + SYSTEM.PUT(start, start+SZL); + SYSTEM.PUT(start+sizeOff, freesize); + SYSTEM.PUT(start+sntlOff, NoPtrSntl); + i := freesize DIV Unit; freesize := 0; + IF i < nofLists THEN SYSTEM.PUT(start + nextOff, freeList[i]); freeList[i] := start + ELSE SYSTEM.PUT(start + nextOff, bigBlocks); bigBlocks := start + END + END ; + DEC(tag, 1); + SYSTEM.PUT(adr, tag); + SYSTEM.GET(tag, size); + INC(allocated, size); + INC(adr, size) + ELSE (*unmarked*) + SYSTEM.GET(tag, size); + INC(freesize, size); + INC(adr, size) + END + END ; + IF freesize > 0 THEN (*collect last block*) + start := adr - freesize; + SYSTEM.PUT(start, start+SZL); + SYSTEM.PUT(start+sizeOff, freesize); + SYSTEM.PUT(start+sntlOff, NoPtrSntl); + i := freesize DIV Unit; freesize := 0; + IF i < nofLists THEN SYSTEM.PUT(start + nextOff, freeList[i]); freeList[i] := start + ELSE SYSTEM.PUT(start + nextOff, bigBlocks); bigBlocks := start + END + END ; + SYSTEM.GET(chnk, chnk) + END + END Scan; + + PROCEDURE Sift (l, r: LONGINT; VAR a: ARRAY OF LONGINT); + VAR i, j, x: LONGINT; + BEGIN j := l; x := a[j]; + LOOP i := j; j := 2*j + 1; + IF (j < r) & (a[j] < a[j+1]) THEN INC(j) END; + IF (j > r) OR (a[j] <= x) THEN EXIT END; + a[i] := a[j] + END; + a[i] := x + END Sift; + + PROCEDURE HeapSort (n: LONGINT; VAR a: ARRAY OF LONGINT); + VAR l, r, x: LONGINT; + BEGIN l := n DIV 2; r := n - 1; + WHILE l > 0 DO DEC(l); Sift(l, r, a) END; + WHILE r > 0 DO x := a[0]; a[0] := a[r]; a[r] := x; DEC(r); Sift(l, r, a) END + END HeapSort; + + PROCEDURE MarkCandidates(n: LONGINT; VAR cand: ARRAY OF LONGINT); + VAR chnk, adr, tag, next, lim, lim1, i, ptr, size: LONGINT; + BEGIN + chnk := heap; i := 0; lim := cand[n-1]; + WHILE (chnk # 0 ) & (chnk < lim) DO + adr := chnk + blkOff; + SYSTEM.GET(chnk + endOff, lim1); + IF lim < lim1 THEN lim1 := lim END ; + WHILE adr < lim1 DO + SYSTEM.GET(adr, tag); + IF ODD(tag) THEN (*already marked*) + SYSTEM.GET(tag-1, size); INC(adr, size) + ELSE + SYSTEM.GET(tag, size); + ptr := adr + SZL; + WHILE cand[i] < ptr DO INC(i) END ; + IF i = n THEN RETURN END ; + next := adr + size; + IF cand[i] < next THEN Mark(ptr) END ; + adr := next + END + END ; + SYSTEM.GET(chnk, chnk) + END + END MarkCandidates; + + PROCEDURE CheckFin; + VAR n: FinNode; tag: LONGINT; + BEGIN n := fin; + WHILE n # NIL DO + SYSTEM.GET(n.obj - SZL, tag); + IF ~ODD(tag) THEN n.marked := FALSE; Mark(n.obj) + ELSE n.marked := TRUE + END ; + n := n.next + END + END CheckFin; + + PROCEDURE Finalize; + VAR n, prev: FinNode; + BEGIN n := fin; prev := NIL; + WHILE n # NIL DO + IF ~n.marked THEN + IF n = fin THEN fin := fin.next ELSE prev.next := n.next END ; + n.finalize(SYSTEM.VAL(SYSTEM.PTR, n.obj)); + (* new nodes may have been pushed in n.finalize, therefore: *) + IF prev = NIL THEN n := fin ELSE n := n.next END + ELSE prev := n; n := n.next + END + END + END Finalize; + + PROCEDURE FINALL*; + VAR n: FinNode; + BEGIN + WHILE fin # NIL DO + n := fin; fin := fin.next; + n.finalize(SYSTEM.VAL(SYSTEM.PTR, n.obj)) + END + END FINALL; + + PROCEDURE MarkStack(n: LONGINT; VAR cand: ARRAY OF LONGINT); + VAR + frame: SYSTEM.PTR; + inc, nofcand: LONGINT; + sp, p, stack0, ptr: LONGINT; + align: RECORD ch: CHAR; p: SYSTEM.PTR END ; + BEGIN + IF n > 0 THEN MarkStack(n-1, cand); (* flush register windows by means of recursive calls *) + IF n > 100 THEN RETURN END (* prevent tail recursion optimization *) + END ; + IF n = 0 THEN + nofcand := 0; sp := SYSTEM.ADR(frame); + stack0 := Mainfrm(); + (* check for minimum alignment of pointers *) + inc := SYSTEM.ADR(align.p) - SYSTEM.ADR(align); + IF sp > stack0 THEN inc := -inc END ; + WHILE sp # stack0 DO + SYSTEM.GET(sp, p); + IF (p > heap) & (p < heapend) THEN + IF nofcand = LEN(cand) THEN HeapSort(nofcand, cand); MarkCandidates(nofcand, cand); nofcand := 0 END ; + cand[nofcand] := p; INC(nofcand) + END ; + INC(sp, inc) + END ; + IF nofcand > 0 THEN HeapSort(nofcand, cand); MarkCandidates(nofcand, cand) END + END + END MarkStack; + + PROCEDURE GC*(markStack: BOOLEAN); + VAR + m: Module; + i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14, i15, i16, i17, i18, i19, i20, i21, i22, i23: LONGINT; + cand: ARRAY 10000 OF LONGINT; + BEGIN + IF (gclock = 0) OR (gclock = 1) & ~markStack THEN + Lock(); + m := SYSTEM.VAL(Module, modules); + WHILE m # NIL DO + IF m.enumPtrs # NIL THEN m.enumPtrs(MarkP) END ; + m := m^.next + END ; + IF markStack THEN + (* generate register pressure to force callee saved registers to memory; + may be simplified by inlining OS calls or processor specific instructions + *) + i0 := -100; i1 := -101; i2 := -102; i3 := -103; i4 := -104; i5 := -105; i6 := -106; i7 := -107; + i8 := 1; i9 := 2; i10 := 3; i11 := 4; i12 := 5; i13 := 6; i14 := 7; i15 := 8; + i16 := 9; i17 := 10; i18 := 11; i19 := 12; i20 := 13; i21 := 14; i22 := 15; i23 := 16; + LOOP INC(i0, 1); INC(i1, 2); INC(i2, 3); INC(i3, 4); INC(i4, 5); INC(i5, 6); INC(i6, 7); INC(i7, 8); + INC(i8, 9); INC(i9, 10); INC(i10, 11); INC(i11, 12); INC(i12, 13); INC(i13, 14); INC(i14, 15); INC(i15, 16); + INC(i16, 17); INC(i17, 18); INC(i18, 19); INC(i19, 20); INC(i20, 21); INC(i21, 22); INC(i22, 23); INC(i23, 24); + IF (i0 = -99) & (i15 = 24) THEN MarkStack(32, cand); EXIT END + END ; + IF i0 + i1 + i2 + i3 + i4 + i5 + i6 + i7 + i8 + i9 + i10 + i11 + i12 + i13 + i14 + i15 + + i16 + i17 + i18 + i19 + i20 + i21 + i22 + i23 > 10000 THEN RETURN (* use all variables *) + END ; + END; + CheckFin; + Scan; + Finalize; + Unlock() + END + END GC; + + PROCEDURE REGFIN*(obj: SYSTEM.PTR; finalize: Finalizer); + VAR f: FinNode; + BEGIN NEW(f); + f.obj := SYSTEM.VAL(LONGINT, obj); f.finalize := finalize; f.marked := TRUE; f.next := fin; fin := f + END REGFIN; + + PROCEDURE InitHeap; (* initialized before body to enable NEW, SYSTEM.NEW *) + BEGIN + heap := NewChunk(heapSize0); + SYSTEM.GET(heap + endOff, heapend); + SYSTEM.PUT(heap, LONG(LONG(0))); + allocated := 0; firstTry := TRUE; freeList[nofLists] := 1; gclock := 0 + END InitHeap; + +END SYSTEM.