[Oberon] Dynamically sized allocation with NEW()

Andreas Pirklbauer andreas_pirklbauer at yahoo.com
Tue Jan 15 18:36:56 CET 2019


   > Can we also toy with some allocation templates based on NEW(p);
   >
   > MODULE Heap;
   >   IMPORT S := SYSTEM;
   >
   > TYPE
   >   Size = INTEGER;
   >  Block = INTEGER;
   >
   >  Buf16 = POINTER TO S16;
   >  Buf32 = POINTER TO S32;
   >   Buf64 = POINTER TO S64;
   >  Buf128 = POINTER TO S128;
   >  Buf256 = POINTER TO S256;
   > ...

Of course you can. This would effectively mimic what NEW(p, len) is doing...

Kernel.New:

	  PROCEDURE New*(VAR ptr: LONGINT; tag, len, elemsize: LONGINT);
	    (*called by NEW via MT[0]; ptr is a pointer; tag is a pointer or blktyp; len and elemsize describe arrays*)
	    VAR p, size, lim: LONGINT;
	  BEGIN
	    IF len < 0 THEN (*record*) SYSTEM.GET(tag, size); (*size already converted for heap allocation with 8 byte prefix*)
	      IF size = 32 THEN GetBlock32(p)
	      ELSIF size = 64 THEN GetBlock64(p)
	      ELSIF size = 128 THEN GetBlock128(p)
	      ELSE GetBlock(p, (size+255) DIV 256 * 256)
	      END ;
	      IF p = 0 THEN ptr := 0
	      ELSE ptr := p+8; SYSTEM.PUT(p, tag); lim := p + size; INC(p, 4); INC(allocated, size);
	        WHILE p < lim DO SYSTEM.PUT(p, 0); INC(p, 4) END
	      END
	    ELSIF len > 0 THEN (*array*) size := len*elemsize; (*convert size for heap allocation with 24 byte prefix*)
	      IF size <= 8 THEN size := 32; GetBlock32(p)
	      ELSIF size <= 40 THEN size := 64; GetBlock64(p)
	      ELSIF size <= 104 THEN size := 128; GetBlock128(p)
	      ELSE size := (size+279) DIV 256 * 256; GetBlock(p, size)
	      END ;
	      IF p = 0 THEN ptr := 0
	      ELSE ptr := p+8;
	        IF tag > 7 THEN (*array of record*) INC(tag) END ;
	        SYSTEM.PUT(p, tag); SYSTEM.PUT(p+4, 0); SYSTEM.PUT(p+8, len); SYSTEM.PUT(p+12, elemsize);
	        SYSTEM.PUT(p+16, size); lim := p + size; INC(p, 20); INC(allocated, size);
	        WHILE p < lim DO SYSTEM.PUT(p, 0); INC(p, 4) END
	      END
	    ELSE ptr := 0
	    END
	  END New;

You can, if you want, even be more fine-grained than NEW(p, len). However, in the case of fonts,
you really don’t need all that many sizes. Most raster sizes are between 1KB and 2KB.

Alternatively, you may use [3], but it is not officially supported. So many ways to do the same thing..

[3] https://github.com/andreaspirklbauer/Oberon-generic-heap-allocation


More information about the Oberon mailing list