NAME ^

src/gc/register.c - Register handling routines

DESCRIPTION ^

Parrot has 4 register sets, one for each of its basic types. The amount of registers in each set varies depending on the use counts of the respective subroutine and is determined by the PASM/PIR compiler in the register allocation pass (imcc/reg_alloc.c).

There is one register stack to support the saveall and restoreall opcodes. The former copies all registers to a newly allocated storage and points the register base pointers to this storage. In Parrot_pop_regs the register base pointers are restored to the previous values and the allocated register memory is discarded.

Context and register frame layout ^

    +----------++----+------+------------+----+
    | context  || N  |  I   |   P        |  S +
    +----------++----+------+------------+----+
    ^          ^     ^                   ^
    |          |     ctx.bp              ctx.bp_ps
    ctx.state  opt
               padding

Registers are addressed as usual via the register base pointer ctx.bp.

The macro CONTEXT() hides these details

Context and register frame allocation ^

There are two allocation strategies: chunked memory and malloced with a free list.

 CHUNKED_CTX_MEM = 1

ctx_mem.data is a pointer to an allocated chunk of memory. The pointer ctx_mem.free holds the next usable location. With (full) continuations the ctx_mem.free pointer can't be moved below the ctx_mem.threshold, which is the highest context pointer of all active continuations. [the code for this is incomplete; it had suffered some bit-rot and was getting in the way of maintaining the other case. -- rgr, 4-Feb-06.]

RT#46177 GC has to lower this threshold when collecting continuations.

 CHUNKED_CTX_MEM = 0

Context/register memory is malloced. ctx_mem.free is used as a free list of reusable items.

Round register allocation size up to the nearest multiple of 8. A granularity of 8 is arbitrary, it could have been some bigger power of 2. A "slot" is an index into the free_list array. Each slot in free_list has a linked list of pointers to already allocated contexts available for (re)use. The slot where an available context is stored corresponds to the size of the context.

Context and Register Allocation Functions ^

void destroy_context(PARROT_INTERP)

Free allocated context memory

void create_initial_context(PARROT_INTERP)

Create initial interpreter context.

PARROT_API void parrot_gc_context(PARROT_INTERP)

Cleanup dead context memory. Called by the garbage collector.

static void clear_regs(PARROT_INTERP, NOTNULL(parrot_context_t *ctx))

RT#48260: Not yet documented!!!

static void init_context(PARROT_INTERP, NOTNULL(parrot_context_t *ctx), ARGIN_NULLOK(const parrot_context_t *old))

RT#48260: Not yet documented!!!

PARROT_WARN_UNUSED_RESULT PARROT_CANNOT_RETURN_NULL struct Parrot_Context *Parrot_dup_context(PARROT_INTERP, ARGIN(const struct Parrot_Context *old))

Duplicate the passed context

PARROT_API PARROT_WARN_UNUSED_RESULT PARROT_CANNOT_RETURN_NULL struct Parrot_Context *Parrot_push_context(PARROT_INTERP, NOTNULL(INTVAL *n_regs_used))

Remember old context in caller_ctx, suitable to use with Parrot_pop_context.

PARROT_API void Parrot_pop_context(PARROT_INTERP)

Free the context created with Parrot_push_context and restore the previous context.

PARROT_CANNOT_RETURN_NULL PARROT_WARN_UNUSED_RESULT struct Parrot_Context *Parrot_alloc_context(PARROT_INTERP, NOTNULL(INTVAL *number_regs_used))

Allocate a new context and set the context pointer. Please note that the register usage n_regs_used is copied. The function returns the new context.

PARROT_API void Parrot_free_context(PARROT_INTERP, NOTNULL(struct Parrot_Context *ctxp), int re_use)

Free the context. If re_use is true, this function is called by a return continuation invoke, else from the destructor of a continuation.

PARROT_API void Parrot_set_context_threshold(PARROT_INTERP, NULLOK(struct Parrot_Context *ctxp))

Mark the context as possible threshold.

Register Stack Functions ^

void setup_register_stacks(PARROT_INTERP)

Set up the register stacks.

PARROT_API void Parrot_push_regs(PARROT_INTERP)

Save all registers onto the register stack.

PARROT_API void Parrot_pop_regs(PARROT_INTERP)

Restore all registers from register stack.

void mark_register_stack(PARROT_INTERP, NOTNULL(Stack_Chunk_t *chunk))

Marks the register stack and its registers as live.

PARROT_API void Parrot_clear_i(PARROT_INTERP)

RT#48260: Not yet documented!!!

PARROT_API void Parrot_clear_s(PARROT_INTERP)

RT#48260: Not yet documented!!!

PARROT_API void Parrot_clear_p(PARROT_INTERP)

RT#48260: Not yet documented!!!

PARROT_API void Parrot_clear_n(PARROT_INTERP)

RT#48260: Not yet documented!!!

SEE ALSO ^

include/parrot/register.h and src/stack_common.c


parrot