Ok, so I see now that reg_alloc is rounded up to a multiple of 8 by
the following two lines:

  /*code*/ const int slot = (reg_alloc + 7) >> 3;
  /*code*/ reg_alloc = slot << 3;

However, this still begs the question of what the slot variable is
for. Clearly it's being used as an index into
interp->ctx_mem.free_list; but its value, which is always set to
reg_alloc/8, seems to me to be rather arbitrary (either that or it has
some meaning but I just don't know any better).

So if slot (which equals reg_alloc/8) is greater than n_free_slots
then the array is resized to fit slot+1 void* types. The last element
(now indexed by slot by definition) is then stored in "ptr" and used
throughout the rest of the procedure.

QUESTION: For what purpose is the array resized to hold so many more
elements? e.g. if n_free_slots is 8 and slot is 80 then 72 extra
elements are allocated and the last one of them is used laster on as
the "ptr" variable; why is that? (This 8 and 80 example is actually the
case on my machine when create_initial_context calls
Parrot_alloc_context()).

If, on the other hand, slot is less than n_free_slots then slot is a
now seemingly random index into the free_list; the item at that index
is pulled out and used as the "ptr" varible.

QUESTION: Is that seemingly random indexing intended? Or is slot
always a well defined and in no way random value with some deeper
purpose? If so, that deeper purpose needs to be explained in a
comment.

On another note, there also seems to be some confusion as to what the
free_list actually is in the first place:

<quote-some-stuff>

  Chromatic wrote:
    I originally thought the free_list was an array of recycled
    contexts to avoid malloc() and free() pairs by reusing
    already-allocated-but-unused memory, but now I can't tell what it's
    doing.  I tried to change this into a linked list, but that failed
    with invalid reads.

  Joshua Isom responded:
    I thought it was a list of items to be freed, but that may be a
    different free_list sadly.  We have more than one in parrot.

</quote-some-stuff>

This definitely needs to be documented if it's not already. "typedef
struct _context_mem { ... } context_mem" in interpreter.h might be a
good place to put a brief descrpiton of how the free_list is meant to
be used.

-Patrick

On Apr 22, 2007, at 5:56 AM, Leopold Toetsch wrote:

Am Sonntag, 22. April 2007 09:11 schrieb Patrick Rutkowski:
I think Leo would be the best person to go to for an explanation,
especially if you plan to dramatically rework the code.

This is where I start not to understand.  Why reg_alloc + 7?  Why
shift left
and right by 3?

I'm not sure if it is actually doing anything that needs to be that
complicated to code that way.  It could be able to be written as:

    const int slot = (reg_alloc + 7) / 8; /* divide by eight for
some reason and round up on remainder */
reg_alloc = slot * 8; /* reg_alloc is now evenly divisible by 8 */

Sure. It's just rounding up to the next multpile of 8.

...  Now, slot is multiplied by sizeof(void*) later on,
which may be why it's divided by eight in the first place.

The rounding up happens to reduce the size of the free_list array.

The n = slot + 1 I find a little odd, because the number is already
rounded up, so it's rounding up and then adding an extra place of
memory.

This is for the extension of the free_list.

I do understand the purpose of the resizing code, but not how slot
relates to
it:

    if (slot >= interp->ctx_mem.n_free_slots) {

Well, if slot is beyond the end of the list, it's resized.

The *(void **) has been confusing me for a long time.

The free list per size (i.e. one slot) is a linked list of pointers.

I'd like to find a simpler scheme, if it's possible.  Otherwise,
I'd like to
figure out what's going on so we can at least explain it somehow.

Why? This is all rather straight-forward and can be found in any memory
allocator e.g. ins smallobjects.

leo

Reply via email to