Post by August KarlstromPost by thuttIt's a complication for the garbage collector to have dynamic arrays.
Once you have dynamic arrays, you probably want to support
multidimensional arrays, and then you want them to be of records,
pointers and other arrays.
At least, the GC already supports records of pointers to records.
Post by thuttThe GC has to be completely redesigned to handle this, and the
original Oberon system did not support this at all.
I thought an extra for-loop in the GC for arrays would do the trick,
as it will when manually freeing an array of pointers in e.g. C.
August
Well, the complication in the GC implemenation is significant, but
easily achievable once your heap block descriptors have been fully
flushed out. So, to sum things up:
1. You need to come up with block descriptors for each type of
thing which can be allocated on the heap.
a) record
b) array of integral type (real, integer, char)
c) array of record with no pointers
d) system blocks (not collected)
e) ...
When I did my Oberon system back in the early to mid-90s, I had
11 different types of things which can be allocated on the heap.
Here's the constants I defined for each type of block that can
allocated:
DescFlagsRecord* = 0;
DescFlagsDynArray0* = 1;
DescFlagsDynArray1* = 2;
DescFlagsDynArray2* = 3;
DescFlagsDynArray3* = 4;
DescFlagsDynArray4* = 5;
DescFlagsDynArray5* = 6;
DescFlagsStaticArray0* =7;
DescFlagsStaticArray1* = 8;
DescFlagsStaticArray2* = 9;
DescNofArrayType = 10;
(* element is a simple or procedure type *)
SimpleElemSet* = {DescFlagsDynArray0,
DescFlagsDynArray3,
DescFlagsStaticArray0};
(* element is a pointer type *)
PointerElemSet* = {DescFlagsDynArray1,
DescFlagsDynArray4,
DescFlagsStaticArray1};
(* element is a record type *)
RecordElemSet* = {DescFlagsDynArray2,
DescFlagsDynArray5,
DescFlagsStaticArray2};
That's not altogether the most descriptive information without
the printed documentation, but it should give you an idea of the
maximal amount of types that can be allocated on the heap. If
you're inclined, you can try to figure out the 11 different
types of objects.
2. Compiler must create a descriptor for each of the items in
number 1.
3. Linker / load must handle fixups to the items in number 2.
This should 'just work' if your compiler is written well.
4. Allocator must be updated to handle multi-dimensional arrays.
This is done in the compiler & the runtime system. The heap
allocator must not only calculate the amount of memory required
for each allocation of a multi-dimensional array, but it must
also update the block descriptor to indicate the 'actual' length
of each array index.
5. For runtime checking, the compiler must generate code to use
the block descriptor when determining if the index is
out-of-bounds.
6. GC must be updated to handle all the types of blocks that can
occur in the heap.
It's a lot of work, and it's tedious.
Oberon-2 has always supported multidimensional arrays on the heap, but
the early ETH systems did not GC blocks allocated for such items. I
spent a significant amount of time developing the system so that it
would actually collect those blocks.
thutt
Reformed Oberon Paladin, VHDL novice
--
Every person new to soldering will try to
catch a falling soldering iron exactly once.