[Oberon] Dynamically sized allocation with NEW()
Andreas Pirklbauer
andreas_pirklbauer at yahoo.com
Tue Jan 15 19:05:05 CET 2019
> PROCEDURE Alloc*(sz: Size; VAR b: Block)
> BEGIN
> IF sz < 16 THEN NEW(Buf16); b := S.VAL(Block, Buf16)
> ELSIF sz < 32 THEN NEW(Buf32); b := S.VAL(Block, Buf32)
> …
> ELSIF sz < 1024 THEN NEW(Buf1024); b := S.VAL(Block, Buf1024)
> ELSE b := NIL
> END
> END Alloc;
Yes, this is one way of doing it. But if you go down that path, you might as well
do the equivalent of what procedure Fonts.This is already doing, namely: to use
record extensions for the various font raster sizes (see Fonts.Mod):
IF NofBytes < 2300 THEN NEW(F) ELSE NEW(LF); F := LF END ; (*LF is an extension of F*)
So you could write something along the lines of...
IF sz < 16 THEN NEW(buf16); buf := buf16 (*Buf16 an extension of Buf*)
ELSIF sz < 32 THEN NEW(buf32); buf := buf32
…
where
TYPE
Buf = RECORD raster: ARRAY N0 OF BYTE END ;
Buf16 = RECORD(Buf) ext16: ARRAY N16 OF BYTE END ; (*extension - just like Fonts.LargeFont is an extension of Fonts.Font*)
Buf32 = RECORD(Buf) ext32: ARRAY N32 OF BYTE END ;
…
VAR
buf: Buf; buf16: Buf16; buf32: Buf32; …
…
I would also suggest to NOT use the sizes 16, 32, 64, but rather 24, 56, 120, etc, in order to to optimize heap layout.
Recall that procedure NEW adds 8 bytes to *every* allocated heap record (4 bytes for the mark field and 4 bytes for
the type tag), and NEW allocates in sizes 32, 64, 128 and n*256, so you want to have something along the lines
of …. (just carefully study ORG.BuildTD and Kernel.New of FPGA Oberon for the details):
s := size;
IF s <= 24 THEN NEW(buf24); buf := buf24 (*24+8 = 32*)
ELSIF s <= 56 THEN NEW(buf56); buf := buf56 (*56+8 = 64*)
ELSIF s <= 120 THEN NEW(buf120); buf := buf120 (*120+8 = 128*)
ELSE ...
END ;
...
With that you should be all set. And you can mimic NEW(p. len) - at least for the (few) font sizes that occur in practice.
More information about the Oberon
mailing list