123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- (* ported version of Minos to work with the ARM backend of the Fox Compiler Suite *)
- MODULE Heaps; (* originally called "MAU" *) (* Memory Allocation Unit; NW 15.12.2007*)
- (* These procedures must remain in this order!*)
- (*
- 001 2007-07-03 tt: Added this header and formatted Module
- 002 2007-09-04 tt: Added status info
- *)
- IMPORT SYSTEM, Board, Memory, Trace;
- CONST
- Initialize = Board.InitializeHeap;
- VAR
- heapStart : ADDRESS;
- heap : ADDRESS; (*origin of free space*)
- heapEnd : ADDRESS;
- PROCEDURE New*( VAR p: LONGINT; T: LONGINT ); (*1*)
- (*allocate record, add tag field of 1 word with offset -4*)
- VAR i, size: LONGINT;
- BEGIN
- p := heap + 4;
- SYSTEM.PUT( heap, T ); (*adr of type descriptor (tag) to tagfield of new record*)
- SYSTEM.GET( T, size ); (*obtain record size from type descriptor*)
- IF size MOD 4 # 0 THEN INC(size, 4 - size MOD 4) END;
- heap := p + size;
- (* Clear heap *)
- IF Initialize THEN Memory.Fill8(p, size, 0X) END;
- ASSERT(heap < heapEnd);
- ASSERT(heapStart <= heap);
- END New;
-
- PROCEDURE AllocH*(VAR a: LONGINT; len, elsize: LONGINT); (*2*)
- (*allocate open array on heap, prefix with size field of 1 word with offset -4*)
- VAR i, adr, size: LONGINT;
- BEGIN
- size := len * elsize + 4; adr := ADDRESSOF(a);
- SYSTEM.PUT(adr, heap - 12); (*address of array into descriptor*)
- SYSTEM.PUT(adr-4, len); (*length of array into descriptor*)
- SYSTEM.PUT(heap, size); (*size of block into header*)
- IF size MOD 4 # 0 THEN INC(size, 4 - size MOD 4) END;
- IF Initialize THEN Memory.Fill8(heap + 4, len * elsize, 0X) END;
- heap := heap + size;
- ASSERT(heap < heapEnd);
- ASSERT(heapStart <= heap);
- END AllocH;
- PROCEDURE AllocS*(VAR a: LONGINT; len, elsize: LONGINT); (*3*)
- (*allocate open array on stack*)
- VAR adr: LONGINT;
- BEGIN adr := ADDRESSOF(a); SYSTEM.SETSP(SYSTEM.SP() - len * elsize);
- SYSTEM.PUT(adr, SYSTEM.SP()); (*address of array into descriptor*)
- SYSTEM.PUT(adr-4, len) (*length of array into descriptor*)
- END AllocS;
-
- PROCEDURE Alloc*( VAR adr: LONGINT; size: LONGINT );
- (*allocate area from free space*)
- VAR
- i: LONGINT;
- BEGIN
- IF size MOD 4 # 0 THEN INC(size, 4 - size MOD 4) END;
- adr := heap;
- IF Initialize THEN Memory.Fill8(adr, size, 0X) END;
- (*INC (size, 4);*)
- (*SYSTEM.PUT (heap, size);*)
- heap := heap + size;
- ASSERT(heap < heapEnd);
- ASSERT(heapStart <= heap);
- END Alloc;
-
- PROCEDURE HeapSize*(): LONGINT;
- BEGIN
- RETURN heapEnd - heapStart
- END HeapSize;
-
- PROCEDURE Free*(): LONGINT;
- BEGIN
- RETURN heapEnd - heap
- END Free;
-
- (* PROCEDURES THAT ARE USED BY THE FOX COMPILER *)
-
- (** NewSys - Implementation of SYSTEM.NEW. **)
- PROCEDURE NewSys*(VAR pointer: ANY; size: SIZE; isRealtime: BOOLEAN);
- VAR
- pointerAsInteger: LONGINT;
- BEGIN
- Alloc(pointerAsInteger, size);
- pointer := SYSTEM.VAL(ANY, pointerAsInteger)
- END NewSys;
- (** NewRec - Implementation of NEW with a record.
- - this is essentially a wrapper that calls New(...) **)
- PROCEDURE NewRec*(VAR pointer: ANY; typeTag: ADDRESS; isRealtime: BOOLEAN);
- VAR
- pointerAsInteger: LONGINT;
- BEGIN
- New(pointerAsInteger, SYSTEM.VAL(LONGINT, typeTag));
- pointer := SYSTEM.VAL(ANY, pointerAsInteger)
- END NewRec;
- (** NewArr - Implementation of NEW with an array containing pointers. *)
- PROCEDURE NewArr*(VAR p: ANY; elemTag: ADDRESS; numElems, numDims: SIZE; isRealtime: BOOLEAN);
- VAR
- openArray: ARRAY 2 OF LONGINT;
- BEGIN
- AllocH(openArray[1], numElems * numDims, SYSTEM.GET32(elemTag));
- p := SYSTEM.VAL(ANY, openArray[1]);
- END NewArr;
-
- (* replacement for overcomplicated code emission -- at the cost of a slightly increased runtime cost *)
- PROCEDURE NewArray*(CONST a: ARRAY OF SIZE; tag: ADDRESS; staticElements, elementSize: SIZE; VAR dest: ANY);
- TYPE
- UnsafeArray= POINTER {UNSAFE,UNTRACED} TO UnsafeArrayDesc;
- UnsafeArrayDesc = RECORD
- header : ARRAY 3 OF ADDRESS;
- len: ARRAY 8 OF SIZE;
- END;
- VAR p: ANY; dim: SIZE;
-
- PROCEDURE GetSize(): SIZE;
- VAR i: SIZE; size: SIZE;
- BEGIN
- size := 1;
- FOR i := 0 TO dim-1 DO
- size := size * a[i];
- END;
- RETURN size*staticElements;
- END GetSize;
-
- PROCEDURE SetSizes(dest: UnsafeArray);
- VAR i: SIZE;
- BEGIN
- FOR i := 0 TO dim-1 DO
- dest.len[i] := a[dim-1-i];
- END;
- END SetSizes;
- BEGIN
- (* static elements is requred for this case : POINTER TO ARRAY OF ARRAY X OF RecordWithPointer *)
- dim := LEN( a,0 );
- IF tag = NIL THEN
- NewSys(p, GetSize() * elementSize + dim * SIZEOF(ADDRESS) + 3 *SIZEOF(ADDRESS) + (dim DIV 2) * 2 * SIZEOF(ADDRESS), FALSE);
- ELSE
- NewArr(p, tag, GetSize(), dim, FALSE);
- END;
- SetSizes(p);
- dest := p;
- END NewArray;
-
- PROCEDURE Show*();
- BEGIN
- Trace.String("Heap base : "); Trace.Hex( heapStart, -8 ); Trace.String("; heap "); Trace.Hex( heap, -8 ); Trace.String("; end "); Trace.Hex( heapEnd, -8 ); Trace.Ln;
- END Show;
- BEGIN
- (* Init heap, currently done manually *)
- heapStart := Board.HeapBase;
- heap := Board.HeapBase;
- heapEnd := Board.HeapEnd;
- END Heaps.
|