[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