Efficient C implementation of expanded (Draft 3)

General Idea

We preserve the current layout of expanded and composite object. However instead of doing copy and allocation of expanded when used as local or passed as argument in the GC heap, we do them on the stack

Structure

Expanded structure

We generate for every expanded types a structure. For example if you have:

expanded class A
feature
	i: INTEGER
	s: STRING
	b: expanded class B
end

expanded class B
feature
	i: INTEGER
end

For class A we generate the following structure:

struct ex_A {
	char data [sizeof_object_of_type_A_with_overhead];
}

Updating a reference from an expanded object

We do the way we were doing it before. So the magic is in the RTAR macro which will go back to its parent. However we do not store the temporary address of the expanded attribute as a local controled by the GC. It is not needed. As we are guaranteed that no GC will be triggered while we access the attribute of the expanded attribute.

As a consequence we improve dramatically the access speed to attributes of expanded. In assembly language, we go from 4 instructions down to 2 and only one memory access to the top of the object in which the expanded attribute is located.

Calling feature on expanded object

When you do:

a: A
...
a.f (x)

If a is a local

struct ex_A a;
f (a.data + OVERHEAD, x);

If a is an attribute

EIF_REFERENCE Current;
f (Current + offsets_to_a, x);

Local stack management

When you have a local variable A which contains references, then we store it into the normal stack of local variable by doing something like:

struct ex_A object;
EIF_REFERENCE a = object.data + OVERHEAD; 
RTLR(?, a);

Because `a' is expanded for the compiler, then it is not going to be moved, so `a' will always point the the start of the object in `object.data'.

Assigning expanded attributes or locals

From a local to an attribute

struct ex_A object;
EIF_REFRENCE local = object.data + OVERHEAD;
EIF_REFERENCE obj;

memcpy (obj + offset_to_expanded_attribute, local, sizeofobject);

From an attribute to a local

struct ex_A object
EIF_REFERENCE local = object.data + OVERHEAD;
EIF_REFERENCE obj;

memcpy (local, obj + offset_to_expanded_attribute, sizeofobject);

Finalization optimization

No need to make space for OVERHEAD in structure that do not have references in them. In which case everything works just fine except that we do not have a reference to the subobject, but the skeleton knows where to find the expanded.

Then every call on the expanded without an overhead must be either inlined or a new body must be generated to take into account the missing header.