Leopold Toetsch wrote:

> Nattfodd wrote:
>
>> Leopold Toetsch wrote:
>
>
>>> 1) pmc_bodies have to be variable sized
>>
>>
>> Oh, I believed that we would use variable-sized pmc only if the gc
>> proved to work really well.
>
>
> Well, with fixed sized bodies, we don't need the extra indirection.
>
> But I really like to have a more flexible object layout. Have a look
> at Parrot sources and draw a picture of an object with 2 attributes,
> or a FixedSizedXXArray or a Sub PMC ... All the interesting, needed
> and heavily used data are hanging off some extra pointers inside
> malloced structures. I just want that to be (in) the body.
>
>> Then we use a doubly linked list, but that should be no problem. The
>> structure becomes something like :
>
>
> Well, gc_gms has already this layout, with prev and next pointers
> inside the gc_header. But in gc_gms it is needed, because you can't
> move the PMC memory w/o indirection pointer into a different object
> generation.
>
> But I consider 4 words for GC + 1 indirection pointer as a very big
> overhead, even compared to the current situation. So I'd really not
> like to have these 2 extra pointers, and I don't think that they are
> needed.

I believe that if we want variable-sized body, we need at least one next
(or pmc_size) pointer in the header.
Unless there is some way to know where all the PMC* are, we could then
use two passes and need the nb_pmc words only during the gc run : first
pass is look at all the PMC* and copy PMC->pmc_body in a sorted array.
Then run through that array and that will tell us where all the gc
objects are.
That's adding some extra runtime for gc and we still need much space,
but we can free it at the end of the gc run.

I we can't know where all the PMC* are, then I think we need a next
pointer, but can still apply the previous trick to spare the prev pointer.

Do you see any other solution that could avoid prev and next ?

>
>>> There is no need for any extra todo-list to mark the children of
>>> objects.
>>
>>
>>
>> ???
>> I believe that was pretty much what was described in the document. What
>> I called "pointers an object has to other objects" is simply its
>> contents.
>
>
> You write in the pod:
> * Mark all elements of the root set and add them to a queue (or a
> stack, whatever) somewhere
>
> But it isn't really clear what you are trying to achieve here.

Sorry, this is crap, because I didn't know how exactly the root set was
to be treated. But the queue thing (which I'll remove entirely) is just
saying "iterate over the root set and mark its elements".

>
>> So you mean that we allocate :
>>
>> | xxx[aggregates]xxx...     ...[free space]... 
>> ...xxx[non-aggregates]xxx |
>
>
> Yep.
>
>> Or rather, as I thought :
>>
>> | ...[free space]... ...xxx[some aggregate][its contents][some
>> aggregate][its contents]xxx |
>
>
> That's probably suboptinal for ususal cases like filling an array with
> some values.
>
>>> c) a write barrier checks pointer stores into aggregates (by just
>>> comparing 2 memory addresses - basically)
>>
>>
>> Another question I had is how do we know when there is such a pointer
>> store ? It can happen at other moments than object allocation, right ?
>
>
> Well, that is exactly what the write barrier is for. Grep for
> WRITE_BARRIER in the parrot sources.

Thanks, I think I understand much better how everything is going on.

>
>>>  we can do either:
>>>  - make aggregate younger (move to left)
>>>  - make stored-into object older (move to right)
>>>  - remember in IGP
>>> d) if we have to extend the allocation area, we usually we'll have to
>>> move all existing objects "up", either by a full GC run or by just
>>> copying, because you'll get usually higher memory regions from the OS.
>>
>
>> Hum, I hadn't thought of this problem.
>
>
> You should :-)

As soon as we agree on the gc_object structure, I'll make a second
version of gmc_for_dummies.pod.

Thank you very much for your help !

Regards,
Alexandre

Reply via email to