[svn:parrot] r39810 - in branches/context_pmc: include/parrot lib/Parrot/Pmc2c src src/gc src/ops src/pmc

whiteknight at svn.parrot.org whiteknight at svn.parrot.org
Sat Jun 27 19:39:11 UTC 2009


Author: whiteknight
Date: Sat Jun 27 19:39:09 2009
New Revision: 39810
URL: https://trac.parrot.org/parrot/changeset/39810

Log:
[context_pmc] flesh out the new PMC type a little bit more, and start making the switch. Obviously haven't gotten very far

Modified:
   branches/context_pmc/include/parrot/interpreter.h
   branches/context_pmc/lib/Parrot/Pmc2c/PCCMETHOD.pm
   branches/context_pmc/src/debug.c
   branches/context_pmc/src/gc/alloc_register.c
   branches/context_pmc/src/gc/alloc_resources.c
   branches/context_pmc/src/gc/mark_sweep.c
   branches/context_pmc/src/global.c
   branches/context_pmc/src/ops/core.ops
   branches/context_pmc/src/ops/pic.ops
   branches/context_pmc/src/ops/var.ops
   branches/context_pmc/src/pmc/context.pmc
   branches/context_pmc/src/pmc/continuation.pmc
   branches/context_pmc/src/pmc/exception.pmc
   branches/context_pmc/src/pmc/lexpad.pmc
   branches/context_pmc/src/pmc/parrotinterpreter.pmc
   branches/context_pmc/src/pmc/sub.pmc
   branches/context_pmc/src/scheduler.c

Modified: branches/context_pmc/include/parrot/interpreter.h
==============================================================================
--- branches/context_pmc/include/parrot/interpreter.h	Sat Jun 27 19:09:28 2009	(r39809)
+++ branches/context_pmc/include/parrot/interpreter.h	Sat Jun 27 19:39:09 2009	(r39810)
@@ -186,48 +186,6 @@
     INTVAL       *regs_i;
 } Regs_ni;
 
-struct Parrot_Context {
-    /* common header with Interp_Context */
-    struct Parrot_Context *caller_ctx;      /* caller context */
-    Regs_ni                bp;              /* pointers to FLOATVAL & INTVAL */
-    Regs_ps                bp_ps;           /* pointers to PMC & STR */
-
-    /* end common header */
-    INTVAL                n_regs_used[4];   /* INSP in PBC points to Sub */
-    PMC                   *lex_pad;         /* LexPad PMC */
-    struct Parrot_Context *outer_ctx;       /* outer context, if a closure */
-
-    /* new call scheme and introspective variables */
-    PMC      *current_sub;           /* the Sub we are executing */
-
-    /* for now use a return continuation PMC */
-    PMC      *handlers;              /* local handlers for the context */
-    PMC      *current_cont;          /* the return continuation PMC */
-    PMC      *current_object;        /* current object if a method call */
-    PMC      *current_namespace;     /* The namespace we're currently in */
-    PMC      *results_signature;     /* non-const results signature PMC */
-    opcode_t *current_pc;            /* program counter of Sub invocation */
-    opcode_t *current_results;       /* ptr into code with get_results opcode */
-
-    /* deref the constants - we need it all the time */
-    struct PackFile_Constant **constants;
-
-    INTVAL                 current_HLL;     /* see also src/hll.c */
-    size_t                 regs_mem_size;   /* memory occupied by registers */
-    int                    ref_count;       /* how often refered to */
-    int                    gc_mark;         /* marked in gc run */
-
-    UINTVAL                warns;           /* Keeps track of what warnings
-                                             * have been activated */
-    UINTVAL                errors;          /* fatals that can be turned off */
-    UINTVAL                trace_flags;
-    UINTVAL                recursion_depth; /* Sub call recursion depth */
-
-    /* code->prederefed.code - code->base.data in opcodes
-     * to simplify conversion between code ptrs in e.g. invoke */
-    size_t pred_offset;
-};
-
 struct _Thread_data;    /* in thread.h */
 struct _Caches;         /* caches .h */
 
@@ -243,21 +201,7 @@
     size_t n_allocated;                 /* allocated size of it */
 } Prederef;
 
-
-/*
- * This is an 'inlined' copy of the first 3 Context items for
- * faster access of registers mainly
- * During a context switch a 3 pointers are set
- */
-typedef struct Interp_Context {
-    /* common header */
-    struct Parrot_Context *state;       /* context  */
-    Regs_ni                bp;          /* pointers to FLOATVAL & INTVAL */
-    Regs_ps                bp_ps;       /* pointers to PMC & STR */
-    /* end common header */
-} Interp_Context;
-
-#define CONTEXT(interp) ((interp)->ctx.state)
+#define CONTEXT(interp) ((interp)->ctx)
 
 #define CHUNKED_CTX_MEM 0           /* no longer works, but will be reinstated
                                      * some day; see src/register.c for details.
@@ -294,7 +238,7 @@
 
 /* The actual interpreter structure */
 struct parrot_interp_t {
-    struct Interp_Context ctx;
+    PMC * ctx;
     context_mem           ctx_mem;            /* ctx memory managment */
 
     struct Arenas *arena_base;                /* Pointer to this interpreter's

Modified: branches/context_pmc/lib/Parrot/Pmc2c/PCCMETHOD.pm
==============================================================================
--- branches/context_pmc/lib/Parrot/Pmc2c/PCCMETHOD.pm	Sat Jun 27 19:09:28 2009	(r39809)
+++ branches/context_pmc/lib/Parrot/Pmc2c/PCCMETHOD.pm	Sat Jun 27 19:39:09 2009	(r39810)
@@ -394,16 +394,17 @@
     PMC      * const _param_sig   = pmc_new(interp, enum_class_FixedIntegerArray);
     PMC      *_return_sig         = PMCNULL;
 
-    Parrot_Context *_caller_ctx   = CONTEXT(interp);
+    PMC *_caller_ctx              = CONTEXT(interp);
     PMC * const _ret_cont         = new_ret_continuation_pmc(interp, NULL);
-    Parrot_Context *_ctx          = Parrot_push_context(interp, _n_regs_used);
+    PMC *_ctx                     = pmc_new_init(interp, enum_class_Context, CONTEXT(interp));
     PMC *_ccont                   = PMCNULL;
+    VTABLE_set_pointer(inter, _ctx, _n_regs_used);
 
 $set_params
     UNUSED(_return_indexes);
 
-    if (_caller_ctx) {
-        _ccont = _caller_ctx->current_cont;
+    if (!PMC_IS_NULL(_caller_ctx)) {
+        _ccont = PARROT_CONTEXT(_caller_ctx)->current_cont;
     }
     else {
         /* there is no point calling Parrot_ex_throw_from_c_args here, because
@@ -411,8 +412,8 @@
         exit_fatal(1, "No caller_ctx for continuation \%p.", _ccont);
     }
 
-    _ctx->current_cont            = _ret_cont;
-    PMC_cont(_ret_cont)->from_ctx = _ctx;
+    PARROT_CONTEXT(_ctx)->current_cont = _ret_cont;
+    PMC_cont(_ret_cont)->from_ctx      = _ctx;
 
     _current_args                 = interp->current_args;
     interp->current_args         = NULL;
@@ -429,9 +430,8 @@
 
     if (PObj_get_FLAGS(_ccont) & SUB_FLAG_TAILCALL) {
         PObj_get_FLAGS(_ccont) &= ~SUB_FLAG_TAILCALL;
-        --_ctx->recursion_depth;
-        _ctx->caller_ctx      = _caller_ctx->caller_ctx;
-        Parrot_free_context(interp, _caller_ctx, 1);
+        --PARROT_CONTEXT(_ctx)->recursion_depth;
+        PARROT_CONTEXT(_ctx)->caller_ctx = PARROT_CONTEXT(_caller_ctx)->caller_ctx;
         interp->current_args = NULL;
     }
     /* BEGIN PARMS SCOPE */
@@ -458,7 +458,7 @@
         $e_post->emit( <<"END", __FILE__, __LINE__ + 1 );
 $method_returns
 
-    if (! _caller_ctx) {
+    if (PMC_IS_NULL(_caller_ctx)) {
         /* there is no point calling Parrot_ex_throw_from_c_args here, because
            PDB_backtrace can't deal with a missing to_ctx either. */
         exit_fatal(1, "No caller_ctx for continuation \%p.", _ccont);
@@ -466,7 +466,7 @@
 
     interp->returns_signature = _return_sig;
     parrot_pass_args(interp, _ctx, _caller_ctx, _return_indexes,
-        _caller_ctx->current_results, PARROT_PASS_RESULTS);
+        PARROT_CONTEXT(_caller_ctx)->current_results, PARROT_PASS_RESULTS);
 END
     }
     $e_post->emit( <<"END", __FILE__, __LINE__ + 1 );
@@ -476,7 +476,7 @@
     no_return:
     PObj_live_CLEAR(_param_sig);
     PObj_live_CLEAR(_return_sig);
-    Parrot_pop_context(interp);
+    VTABLE_pop_pmc(interp, CONTEXT(interp));
 END
     $self->return_type('void');
     $self->parameters('');

Modified: branches/context_pmc/src/debug.c
==============================================================================
--- branches/context_pmc/src/debug.c	Sat Jun 27 19:09:28 2009	(r39809)
+++ branches/context_pmc/src/debug.c	Sat Jun 27 19:39:09 2009	(r39810)
@@ -2176,7 +2176,7 @@
 PDB_check_condition(PARROT_INTERP, ARGIN(const PDB_condition_t *condition))
 {
     ASSERT_ARGS(PDB_check_condition)
-    Parrot_Context *ctx = CONTEXT(interp);
+    PMC *ctx = CONTEXT(interp);
 
     TRACEDEB_MSG("PDB_check_condition");
 
@@ -3441,7 +3441,7 @@
 
     /* information about the current sub */
     PMC              *sub = interpinfo_p(interp, CURRENT_SUB);
-    Parrot_Context   *ctx = CONTEXT(interp);
+    PMC   *ctx = CONTEXT(interp);
 
     if (!PMC_IS_NULL(sub)) {
         str = Parrot_Context_infostr(interp, ctx);

Modified: branches/context_pmc/src/gc/alloc_register.c
==============================================================================
--- branches/context_pmc/src/gc/alloc_register.c	Sat Jun 27 19:09:28 2009	(r39809)
+++ branches/context_pmc/src/gc/alloc_register.c	Sat Jun 27 19:39:09 2009	(r39810)
@@ -17,87 +17,8 @@
 
 */
 
-#include "parrot/parrot.h"
-#include "parrot/register.h"
-#include "../pmc/pmc_sub.h"
-
-/* HEADERIZER HFILE: include/parrot/register.h */
-
-/* HEADERIZER BEGIN: static */
-/* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
-
-static void clear_regs(PARROT_INTERP, ARGMOD(Parrot_Context *ctx))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        FUNC_MODIFIES(*ctx);
-
-static void init_context(PARROT_INTERP,
-    ARGMOD(Parrot_Context *ctx),
-    ARGIN_NULLOK(const Parrot_Context *old))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        FUNC_MODIFIES(*ctx);
-
-#define ASSERT_ARGS_clear_regs __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(ctx)
-#define ASSERT_ARGS_init_context __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(ctx)
-/* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
-/* HEADERIZER END: static */
 
 
-/*
-=head2 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
-
-=cut
-
-*/
-
-/*
-=head2 Context and register frame allocation
-
-There are two allocation strategies: chunked memory and malloced with a free
-list.
-
- CHUNKED_CTX_MEM = 1
-
-C<ctx_mem.data> is a pointer to an allocated chunk of memory.  The pointer
-C<ctx_mem.free> holds the next usable location. With (full) continuations the
-C<ctx_mem.free> pointer can't be moved below the C<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. C<ctx_mem.free> is used as a free list of
-reusable items.
-
-=cut
-
-*/
-
-#define CTX_ALLOC_SIZE 0x20000
-
-#define ALIGNED_CTX_SIZE (((sizeof (Parrot_Context) + NUMVAL_SIZE - 1) \
-        / NUMVAL_SIZE) * NUMVAL_SIZE)
 
 /*
 
@@ -113,15 +34,7 @@
 
 */
 
-#define SLOT_CHUNK_SIZE 8
 
-#define ROUND_ALLOC_SIZE(size) ((((size) + SLOT_CHUNK_SIZE - 1) \
-        / SLOT_CHUNK_SIZE) * SLOT_CHUNK_SIZE)
-#define CALCULATE_SLOT_NUM(size) ((size) / SLOT_CHUNK_SIZE)
-
-#if CHUNKED_CTX_MEM
- #  error "Non-working code removed."
-#endif
 
 /*
 
@@ -133,47 +46,6 @@
 
 */
 
-/*
-
-=item C<void destroy_context(PARROT_INTERP)>
-
-Frees allocated context memory.
-
-=cut
-
-*/
-
-void
-destroy_context(PARROT_INTERP)
-{
-    ASSERT_ARGS(destroy_context)
-    Parrot_Context *context = CONTEXT(interp);
-    int             slot;
-
-    while (context) {
-        Parrot_Context * const prev = context->caller_ctx;
-
-        /* always collect the parentmost context in the parentmost interp*/
-        if (!prev && !interp->parent_interpreter)
-            context->ref_count = 1;
-
-        Parrot_free_context(interp, context, 1);
-
-        context = prev;
-    }
-
-    /* clear freed contexts */
-    for (slot = 0; slot < interp->ctx_mem.n_free_slots; ++slot) {
-        void *ptr = interp->ctx_mem.free_list[slot];
-        while (ptr) {
-            void * const next = *(void **) ptr;
-            mem_sys_free(ptr);
-            ptr = next;
-        }
-        interp->ctx_mem.free_list[slot] = NULL;
-    }
-    mem_sys_free(interp->ctx_mem.free_list);
-}
 
 
 /*
@@ -191,305 +63,17 @@
 {
     ASSERT_ARGS(create_initial_context)
     static INTVAL   num_regs[] = {32, 32, 32, 32};
-    Parrot_Context *ignored;
-
-    /* Create some initial free_list slots. */
-
-#define INITIAL_FREE_SLOTS 8
-    interp->ctx_mem.n_free_slots = INITIAL_FREE_SLOTS;
-    interp->ctx_mem.free_list    = mem_allocate_n_zeroed_typed(INITIAL_FREE_SLOTS, void *);
 
     /* For now create context with 32 regs each. Some src tests (and maybe
      * other extenders) assume the presence of these registers */
-    ignored = Parrot_set_new_context(interp, num_regs);
-    UNUSED(ignored);
-}
-
-
-/*
-
-=item C<void parrot_gc_context(PARROT_INTERP)>
-
-Cleans up dead context memory; called by the garbage collector.  This only
-applies in the chunked context memory scheme.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-void
-parrot_gc_context(PARROT_INTERP)
-{
-    ASSERT_ARGS(parrot_gc_context)
-#if CHUNKED_CTX_MEM
-    Parrot_Context ctx;
-    ASSERT_ARGS(parrot_gc_context)
-
-    if (!interp->ctx_mem.threshold)
-        return;
-    LVALUE_CAST(char *, ctx.bp) = interp->ctx_mem.threshold
-                                - sizeof (parrot_regs_t);
-#else
-    UNUSED(interp);
-#endif
-}
-
-
-/*
-
-=item C<static void clear_regs(PARROT_INTERP, Parrot_Context *ctx)>
-
-Clears all registers in a context.  PMC and STRING registers contain PMCNULL
-and NULL, respectively.  Integer and float registers contain negative flag
-values, for debugging purposes.
-
-=cut
-
-*/
-
-static void
-clear_regs(PARROT_INTERP, ARGMOD(Parrot_Context *ctx))
-{
-    ASSERT_ARGS(clear_regs)
-    int i;
-
-    /* NULL out registers - P/S have to be NULL for GC
-     *
-     * if the architecture has 0x := NULL and 0.0 we could memset too
-     */
-
-    for (i = 0; i < ctx->n_regs_used[REGNO_PMC]; i++) {
-        CTX_REG_PMC(ctx, i) = PMCNULL;
-    }
-
-    for (i = 0; i < ctx->n_regs_used[REGNO_STR]; i++) {
-        CTX_REG_STR(ctx, i) = NULL;
-    }
-
-    if (Interp_debug_TEST(interp, PARROT_REG_DEBUG_FLAG)) {
-        /* depending on -D40 we set int and num to be identifiable garbage values */
-        for (i = 0; i < ctx->n_regs_used[REGNO_INT]; i++) {
-            CTX_REG_INT(ctx, i) = -999;
-        }
-        for (i = 0; i < ctx->n_regs_used[REGNO_NUM]; i++) {
-            CTX_REG_NUM(ctx, i) = -99.9;
-        }
-    }
-}
-
-
-/*
-
-=item C<static void init_context(PARROT_INTERP, Parrot_Context *ctx, const
-Parrot_Context *old)>
-
-Initializes a freshly allocated or recycled context.
-
-=cut
-
-*/
-
-static void
-init_context(PARROT_INTERP, ARGMOD(Parrot_Context *ctx),
-        ARGIN_NULLOK(const Parrot_Context *old))
-{
-    ASSERT_ARGS(init_context)
-    ctx->ref_count         = 0;
-    ctx->gc_mark           = 0;
-    ctx->current_results   = NULL;
-    ctx->results_signature = NULL;
-    ctx->lex_pad           = PMCNULL;
-    ctx->outer_ctx         = NULL;
-    ctx->current_cont      = NULL;
-    ctx->current_object    = NULL;
-    ctx->handlers          = PMCNULL;
-    ctx->caller_ctx        = NULL;
-
-    if (old) {
-        /* some items should better be COW copied */
-        ctx->constants         = old->constants;
-        ctx->warns             = old->warns;
-        ctx->errors            = old->errors;
-        ctx->trace_flags       = old->trace_flags;
-        ctx->pred_offset       = old->pred_offset;
-        ctx->current_HLL       = old->current_HLL;
-        ctx->current_namespace = old->current_namespace;
-        /* end COW */
-        ctx->recursion_depth   = old->recursion_depth;
-    }
-    else {
-        ctx->constants         = NULL;
-        ctx->warns             = 0;
-        ctx->errors            = 0;
-        ctx->trace_flags       = 0;
-        ctx->pred_offset       = 0;
-        ctx->current_HLL       = 0;
-        ctx->current_namespace = PMCNULL;
-        ctx->recursion_depth   = 0;
-    }
-
-    /* other stuff is set inside Sub.invoke */
-    clear_regs(interp, ctx);
-}
-
-
-/*
-
-=item C<Parrot_Context * Parrot_push_context(PARROT_INTERP, const INTVAL
-*n_regs_used)>
-
-Creates and sets the current context to a new context, remembering the old
-context in C<caller_ctx>.  Suitable to use with C<Parrot_pop_context>.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-Parrot_Context *
-Parrot_push_context(PARROT_INTERP, ARGIN(const INTVAL *n_regs_used))
-{
-    ASSERT_ARGS(Parrot_push_context)
-    Parrot_Context * const old = CONTEXT(interp);
-    Parrot_Context * const ctx = Parrot_set_new_context(interp, n_regs_used);
-
-    ctx->caller_ctx  = old;
-
-    /* doesn't change */
-    ctx->current_sub = old->current_sub;
-
-    /* copy more ? */
-    return ctx;
-}
-
-
-/*
-
-=item C<void Parrot_pop_context(PARROT_INTERP)>
-
-Frees the context created with C<Parrot_push_context> and restores the previous
-context (the caller context).
-
-=cut
-
-*/
-
-PARROT_EXPORT
-void
-Parrot_pop_context(PARROT_INTERP)
-{
-    ASSERT_ARGS(Parrot_pop_context)
-    Parrot_Context * const ctx = CONTEXT(interp);
-    Parrot_Context * const old = ctx->caller_ctx;
-
-    ctx->ref_count = 0;
-    Parrot_free_context(interp, ctx, 0);
-
-    /* restore old, set cached interpreter base pointers */
-    CONTEXT(interp)      = old;
-    interp->ctx.bp       = old->bp;
-    interp->ctx.bp_ps    = old->bp_ps;
+     CONTEXT(interp) = pmc_new(interp, enum_class_Context);
+     VTABLE_set_pointer(interp, CONTEXT(interp));
 }
 
 
 /*
 
-=item C<Parrot_Context * Parrot_alloc_context(PARROT_INTERP, const INTVAL
-*number_regs_used, Parrot_Context *old)>
-
-Allocates and returns a new context.  Does not set this new context as the
-current context. Note that the register usage C<n_regs_used> is copied.  Use
-the init flag to indicate whether you want to initialize the new context
-(setting its default values and clearing its registers).
-
-=cut
-
-*/
-
-PARROT_CANNOT_RETURN_NULL
-PARROT_WARN_UNUSED_RESULT
-Parrot_Context *
-Parrot_alloc_context(PARROT_INTERP, ARGIN(const INTVAL *number_regs_used),
-    ARGIN_NULLOK(Parrot_Context *old))
-{
-    ASSERT_ARGS(Parrot_alloc_context)
-    Parrot_Context *ctx;
-    void *p;
-
-    const size_t size_i = sizeof (INTVAL)   * number_regs_used[REGNO_INT];
-    const size_t size_n = sizeof (FLOATVAL) * number_regs_used[REGNO_NUM];
-    const size_t size_s = sizeof (STRING *) * number_regs_used[REGNO_STR];
-    const size_t size_p = sizeof (PMC *)    * number_regs_used[REGNO_PMC];
-
-    const size_t size_nip      = size_n + size_i + size_p;
-    const size_t all_regs_size = size_n + size_i + size_p + size_s;
-    const size_t reg_alloc     = ROUND_ALLOC_SIZE(all_regs_size);
-    const int    slot          = CALCULATE_SLOT_NUM(reg_alloc);
-
-    /*
-     * If slot is beyond the end of the allocated list, extend the list to
-     * allocate more slots.
-     */
-    if (slot >= interp->ctx_mem.n_free_slots) {
-        const int extend_size = slot + 1;
-        int i;
-
-        mem_realloc_n_typed(interp->ctx_mem.free_list, extend_size, void *);
-        for (i = interp->ctx_mem.n_free_slots; i < extend_size; ++i)
-            interp->ctx_mem.free_list[i] = NULL;
-        interp->ctx_mem.n_free_slots = extend_size;
-    }
-
-    /*
-     * The free_list contains a linked list of pointers for each size (slot
-     * index). Pop off an available context of the desired size from free_list.
-     * If no contexts of the desired size are available, allocate a new one.
-     */
-    ctx = (Parrot_Context *)interp->ctx_mem.free_list[slot];
-
-    if (ctx) {
-        /*
-         * Store the next pointer from the linked list for this size (slot
-         * index) in free_list. On "*(void **) ctx", C won't dereference a void
-         * * pointer (untyped), so type cast ctx to void ** (a dereference-able
-         * type) then dereference it to get a void *. Store the dereferenced
-         * value (the next pointer in the linked list) in free_list.
-         */
-        interp->ctx_mem.free_list[slot] = *(void **)ctx;
-    }
-    else {
-        const size_t to_alloc = reg_alloc + ALIGNED_CTX_SIZE;
-        ctx                   = (Parrot_Context *)mem_sys_allocate(to_alloc);
-    }
-
-    ctx->n_regs_used[REGNO_INT] = number_regs_used[REGNO_INT];
-    ctx->n_regs_used[REGNO_NUM] = number_regs_used[REGNO_NUM];
-    ctx->n_regs_used[REGNO_STR] = number_regs_used[REGNO_STR];
-    ctx->n_regs_used[REGNO_PMC] = number_regs_used[REGNO_PMC];
-
-    ctx->regs_mem_size = reg_alloc;
-
-    /* regs start past the context */
-    p   = (void *) ((char *)ctx + ALIGNED_CTX_SIZE);
-
-    /* ctx.bp points to I0, which has Nx on the left */
-    ctx->bp.regs_i = (INTVAL *)((char *)p + size_n);
-
-    /* ctx.bp_ps points to S0, which has Px on the left */
-    ctx->bp_ps.regs_s = (STRING **)((char *)p + size_nip);
-
-    init_context(interp, ctx, old);
-
-    return ctx;
-}
-
-
-/*
-
-=item C<Parrot_Context * Parrot_set_new_context(PARROT_INTERP, const INTVAL
+=item C<PMC * Parrot_set_new_context(PARROT_INTERP, const INTVAL
 *number_regs_used)>
 
 Allocates and returns a new context as the current context.  Note that the
@@ -501,210 +85,18 @@
 
 PARROT_CANNOT_RETURN_NULL
 PARROT_WARN_UNUSED_RESULT
-Parrot_Context *
+PMC *
 Parrot_set_new_context(PARROT_INTERP, ARGIN(const INTVAL *number_regs_used))
 {
     ASSERT_ARGS(Parrot_set_new_context)
-    Parrot_Context *old = CONTEXT(interp);
-    Parrot_Context *ctx = Parrot_alloc_context(interp, number_regs_used, old);
-
-    CONTEXT(interp)          = ctx;
-    interp->ctx.bp.regs_i    = ctx->bp.regs_i;
-    interp->ctx.bp_ps.regs_s = ctx->bp_ps.regs_s;
-
+    PMC *old = CONTEXT(interp);
+    PMC *ctx = pmc_new(interp, enum_class_Context);
+    VTABLE_set_pointer(interp, ctx, number_regs_used);
+    VTABLE_push_pmc(interp, CONTEXT(interp), ctx);
     return ctx;
 }
 
 
-/*
-
-=item C<void Parrot_free_context(PARROT_INTERP, Parrot_Context *ctx, int deref)>
-
-Frees the context if its reference count is zero.  If C<deref>
-is true, then reduce the reference count prior to determining
-if the context should be freed.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-void
-Parrot_free_context(PARROT_INTERP, ARGMOD(Parrot_Context *ctx), int deref)
-{
-    ASSERT_ARGS(Parrot_free_context)
-    /*
-     * The context structure has a reference count, initially 0.
-     * This field is incremented when something outside of the normal
-     * calling chain (such as a continuation or outer scope) wants to
-     * preserve the context.  The field is decremented when
-     * Parrot_free_context is called with the C<deref> flag set true.
-     */
-    if (deref) {
-        ctx->ref_count--;
-    }
-
-    if (ctx->ref_count <= 0) {
-        void *ptr;
-        int slot;
-
-#ifndef NDEBUG
-        if (Interp_debug_TEST(interp, PARROT_CTX_DESTROY_DEBUG_FLAG)
-            && ctx->current_sub) {
-            /* can't probably Parrot_io_eprintf here */
-            Parrot_sub *doomed;
-            PMC_get_sub(interp, ctx->current_sub, doomed);
-
-            if (doomed) {
-                fprintf(stderr, "[free  ctx %p of sub '%s']\n",
-                        (void *)ctx,
-                        (doomed->name == (void*)0xdeadbeef
-                        ? "???"
-                        : (char*)doomed->name->strstart));
-            }
-            else {
-                Parrot_ex_throw_from_c_args(interp, NULL, 1,
-                        "NULL doomed sub detected in Parrot_free_context");
-            }
-        }
-#endif
-
-        if (ctx->outer_ctx)
-            Parrot_free_context(interp, ctx->outer_ctx, 1);
-
-        ctx->n_regs_used[REGNO_INT] = 0;
-        ctx->n_regs_used[REGNO_NUM] = 0;
-        ctx->n_regs_used[REGNO_STR] = 0;
-        ctx->n_regs_used[REGNO_PMC] = 0;
-
-        /* don't put the same context on the free list multiple times; we don't
-         * have the re-use versus multiple ref count semantics right yet */
-        if (ctx->ref_count < 0)
-            return;
-
-        /* force the reference count negative to indicate a dead context
-         * so mark_context (src/sub.c) can report it */
-        ctx->ref_count--;
-
-        ptr             = ctx;
-        slot            = CALCULATE_SLOT_NUM(ctx->regs_mem_size);
-
-        PARROT_ASSERT(slot < interp->ctx_mem.n_free_slots);
-        *(void **)ptr                   = interp->ctx_mem.free_list[slot];
-        interp->ctx_mem.free_list[slot] = ptr;
-    }
-}
-
-
-/*
-
-=item C<void Parrot_set_context_threshold(PARROT_INTERP, Parrot_Context *ctx)>
-
-Marks the context as possible threshold.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-void
-Parrot_set_context_threshold(SHIM_INTERP, SHIM(Parrot_Context *ctx))
-{
-    ASSERT_ARGS(Parrot_set_context_threshold)
-    /* nothing to do */
-}
-
-/*
-
-=back
-
-=head2 Register Stack Functions
-
-=over 4
-
-=cut
-
-=item C<void Parrot_clear_i(PARROT_INTERP)>
-
-Sets all integer registers in the current context to 0.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-void
-Parrot_clear_i(PARROT_INTERP)
-{
-    ASSERT_ARGS(Parrot_clear_i)
-    int i;
-    for (i = 0; i < CONTEXT(interp)->n_regs_used[REGNO_INT]; ++i)
-        REG_INT(interp, i) = 0;
-}
-
-
-/*
-
-=item C<void Parrot_clear_s(PARROT_INTERP)>
-
-Sets all STRING registers in the current context to NULL.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-void
-Parrot_clear_s(PARROT_INTERP)
-{
-    ASSERT_ARGS(Parrot_clear_s)
-    int i;
-    for (i = 0; i < CONTEXT(interp)->n_regs_used[REGNO_STR]; ++i)
-        REG_STR(interp, i) = NULL;
-}
-
-
-/*
-
-=item C<void Parrot_clear_p(PARROT_INTERP)>
-
-Sets all PMC registers in the current context to NULL.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-void
-Parrot_clear_p(PARROT_INTERP)
-{
-    ASSERT_ARGS(Parrot_clear_p)
-    int i;
-    for (i = 0; i < CONTEXT(interp)->n_regs_used[REGNO_PMC]; ++i)
-        REG_PMC(interp, i) = PMCNULL;
-}
-
-
-/*
-
-=item C<void Parrot_clear_n(PARROT_INTERP)>
-
-Sets all number registers in the current context to 0.0.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-void
-Parrot_clear_n(PARROT_INTERP)
-{
-    ASSERT_ARGS(Parrot_clear_n)
-    int i;
-    for (i = 0; i < CONTEXT(interp)->n_regs_used[REGNO_NUM]; ++i)
-        REG_NUM(interp, i) = 0.0;
-}
-
 
 /*
 

Modified: branches/context_pmc/src/gc/alloc_resources.c
==============================================================================
--- branches/context_pmc/src/gc/alloc_resources.c	Sat Jun 27 19:09:28 2009	(r39809)
+++ branches/context_pmc/src/gc/alloc_resources.c	Sat Jun 27 19:39:09 2009	(r39810)
@@ -21,6 +21,7 @@
 
 #include "parrot/parrot.h"
 #include "gc_private.h"
+#include "../pmc/pmc_context.h"
 
 
 #define RECLAMATION_FACTOR 0.20
@@ -262,7 +263,7 @@
     int i;
     static char reg[10];
 
-    Parrot_Context* const ctx = CONTEXT(interp);
+    Parrot_Context_attributes * const ctx = PARROT_CONTEXT(CONTEXT(interp));
 
     for (i = 0; i < ctx->n_regs_used[REGNO_STR]; ++i) {
         PObj * const obj = (PObj *) CTX_REG_STR(interp, ctx, i);

Modified: branches/context_pmc/src/gc/mark_sweep.c
==============================================================================
--- branches/context_pmc/src/gc/mark_sweep.c	Sat Jun 27 19:09:28 2009	(r39809)
+++ branches/context_pmc/src/gc/mark_sweep.c	Sat Jun 27 19:39:09 2009	(r39810)
@@ -161,7 +161,7 @@
 {
     ASSERT_ARGS(Parrot_gc_trace_root)
     Arenas           * const arena_base = interp->arena_base;
-    Parrot_Context   *ctx;
+    PMC   *ctx;
     PObj             *obj;
 
     /* note: adding locals here did cause increased GC runs */
@@ -191,8 +191,7 @@
         Parrot_gc_mark_PObj_alive(interp, obj);
 
     /* mark the current context. */
-    ctx = CONTEXT(interp);
-    mark_context(interp, ctx);
+    Parrot_gc_mark_PObj_alive(interp, CONTEXT(interp));
 
     /* mark the dynamic environment. */
     mark_stack(interp, interp->dynamic_env);

Modified: branches/context_pmc/src/global.c
==============================================================================
--- branches/context_pmc/src/global.c	Sat Jun 27 19:09:28 2009	(r39809)
+++ branches/context_pmc/src/global.c	Sat Jun 27 19:39:09 2009	(r39810)
@@ -742,7 +742,7 @@
 Parrot_find_name_op(PARROT_INTERP, ARGIN(STRING *name), SHIM(void *next))
 {
     ASSERT_ARGS(Parrot_find_name_op)
-    Parrot_Context * const ctx = CONTEXT(interp);
+    PMC * const ctx = CONTEXT(interp);
     PMC * const lex_pad = Parrot_find_pad(interp, name, ctx);
     PMC *g;
 

Modified: branches/context_pmc/src/ops/core.ops
==============================================================================
--- branches/context_pmc/src/ops/core.ops	Sat Jun 27 19:09:28 2009	(r39809)
+++ branches/context_pmc/src/ops/core.ops	Sat Jun 27 19:39:09 2009	(r39810)
@@ -605,7 +605,7 @@
 
 op get_params(inconst PMC) :flow {
     opcode_t * const _this = CUR_OPCODE;
-    Parrot_Context *caller_ctx, *ctx;
+    PMC * caller_ctx, *ctx;
     PMC * ccont;
     PMC * const signature = $1;
     INTVAL argc;
@@ -613,9 +613,9 @@
 
     interp->current_params = _this;
     ctx = CONTEXT(interp);
-    ccont = ctx->current_cont;
+    ccont = PARROT_CONTEXT(ctx)->current_cont;
 
-    caller_ctx = ctx->caller_ctx;
+    caller_ctx = PARROT_CONTEXT(ctx)->caller_ctx;
 
     src_indexes = interp->current_args;
     dst_indexes = interp->current_params;
@@ -639,7 +639,7 @@
 
 op set_returns(inconst PMC) :flow {
     opcode_t * const _this = CUR_OPCODE;
-    Parrot_Context *ctx;
+    PMC *ctx;
     PMC *ccont;
     PMC *signature = $1;
     INTVAL argc;
@@ -647,12 +647,12 @@
 
     interp->current_returns = _this;
     ctx = CONTEXT(interp);
-    ccont = ctx->current_cont;
+    ccont = PARROT_CONTEXT(ctx)->current_cont;
 
     if (PMC_cont(ccont)->address) {
         /* Call is from runops_fromc */
-        Parrot_Context * const caller_ctx = PMC_cont(ccont)->to_ctx;
-        if (! caller_ctx) {
+        PMC * const caller_ctx = PMC_cont(ccont)->to_ctx;
+        if (PMC_IS_NULL(caller_ctx)) {
             /* there is no point calling Parrot_ex_throw_..., because
                PDB_backtrace can't deal with a missing to_ctx either. */
             exit_fatal(1, "No caller_ctx for continuation %p.", ccont);
@@ -666,10 +666,10 @@
 
         parrot_pass_args(interp, ctx, caller_ctx, src_indexes, dest_indexes, PARROT_PASS_RESULTS);
     }
-    else if (ctx->caller_ctx->results_signature) {
-    /* We have a dynamic result signature, from pcc_invoke */
-        parrot_pass_args(interp, ctx, ctx->caller_ctx, interp->current_returns,
-                ctx->caller_ctx->current_results, PARROT_PASS_RESULTS);
+    else if (PARROT_CONTEXT(PARROT_CONTEXT(ctx)->caller_ctx)->results_signature) {
+        /* We have a dynamic result signature, from pcc_invoke */
+        parrot_pass_args(interp, ctx, PARROT_CONTEXT(ctx)->caller_ctx, interp->current_returns,
+                PARROT_CONTEXT(PARROT_CONTEXT(ctx)->caller_ctx)->current_results, PARROT_PASS_RESULTS);
     }
     argc = VTABLE_elements(interp, signature);
     goto OFFSET(argc + 2);

Modified: branches/context_pmc/src/ops/pic.ops
==============================================================================
--- branches/context_pmc/src/ops/pic.ops	Sat Jun 27 19:09:28 2009	(r39809)
+++ branches/context_pmc/src/ops/pic.ops	Sat Jun 27 19:39:09 2009	(r39810)
@@ -132,7 +132,7 @@
     PMC *sig, *ccont;
     opcode_t *src_pc;
     void **src_pred;
-    Parrot_Context *caller_ctx, *ctx;
+    PMC *caller_ctx, *ctx;
     int n;
 
     /* avoid load dependencies - intermix derefs
@@ -183,13 +183,13 @@
     PMC *sig, *ccont;
     opcode_t *dest_pc;
     void **dest_pred;
-    Parrot_Context *caller_ctx, *ctx;
+    PMC *caller_ctx, *ctx;
     Parrot_cont *cc;
     int n;
 
     ctx = CONTEXT(interp);
     mic = (Parrot_MIC *) cur_opcode[1];
-    ccont = ctx->current_cont;
+    ccont = PARROT_CONTEXT(ctx)->current_cont;
     cc = PMC_cont(ccont);
     if (!cc->address) {
         interp->current_returns = CUR_OPCODE;
@@ -239,7 +239,7 @@
     Parrot_MIC *mic;
     Parrot_PIC_lru *lru;
     void *args[6];      /* RT#42355 ARG_MAX */
-    Parrot_Context *ctx;
+    PMC *ctx;
     opcode_t *pc;
     void **pred_pc;
     INTVAL i, n_args, *sig_bits;
@@ -248,9 +248,9 @@
     ctx = CONTEXT(interp);
     mic = (Parrot_MIC *) cur_opcode[1];
     /* get_results */
-    pc = ctx->current_results;
+    pc = PARROT_CONTEXT(ctx)->current_results;
     if (pc) {
-        pred_pc = (void**) pc - ctx->pred_offset;
+        pred_pc = (void**) pc - PARROT_CONTEXT(ctx)->pred_offset;
         sig = (PMC*)(pred_pc[1]);
         ASSERT_SIG_PMC(sig);
         PARROT_ASSERT(VTABLE_elements(interp, sig) <= 1);

Modified: branches/context_pmc/src/ops/var.ops
==============================================================================
--- branches/context_pmc/src/ops/var.ops	Sat Jun 27 19:09:28 2009	(r39809)
+++ branches/context_pmc/src/ops/var.ops	Sat Jun 27 19:39:09 2009	(r39810)
@@ -39,7 +39,7 @@
 =cut
 
 op store_lex(in STR, invar PMC) {
-    Parrot_Context   * const ctx      = CONTEXT(interp);
+    PMC              * const ctx      = CONTEXT(interp);
     STRING           * const lex_name = $1;
     PMC              * const lex_pad  = Parrot_find_pad(interp, lex_name, ctx);
 
@@ -64,7 +64,7 @@
 =cut
 
 op find_lex(out PMC, in STR) {
-    Parrot_Context   * const ctx      = CONTEXT(interp);
+    PMC              * const ctx      = CONTEXT(interp);
     STRING           * const lex_name = $2;
     PMC              * const lex_pad  = Parrot_find_pad(interp, lex_name, ctx);
 
@@ -94,10 +94,12 @@
 
 op find_caller_lex(out PMC, in STR) {
     STRING         * const lex_name = $2;
-    Parrot_Context * ctx            = CONTEXT(interp);
+    PMC            * ctx            = CONTEXT(interp);
     PMC            * result         = PMCNULL;
 
-    for (ctx = ctx->caller_ctx; ctx && PMC_IS_NULL(result); ctx = ctx->caller_ctx) {
+    for (ctx = PARROT_CONTEXT(ctx)->caller_ctx;
+         !PMC_IS_NULL(ctx) && PMC_IS_NULL(result);
+         ctx = PARROT_CONTEXT(ctx)->caller_ctx) {
         PMC * const lex_pad = Parrot_find_pad(interp, lex_name, ctx);
         if (!PMC_IS_NULL(lex_pad)) {
             result = VTABLE_get_pmc_keyed_str(interp, lex_pad, lex_name);

Modified: branches/context_pmc/src/pmc/context.pmc
==============================================================================
--- branches/context_pmc/src/pmc/context.pmc	Sat Jun 27 19:09:28 2009	(r39809)
+++ branches/context_pmc/src/pmc/context.pmc	Sat Jun 27 19:39:09 2009	(r39810)
@@ -18,46 +18,342 @@
 
 */
 
-pmclass Context {
+/*
+=head2 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
+
+=cut
+
+*/
+
+/*
+=head2 Context and register frame allocation
+
+There are two allocation strategies: chunked memory and malloced with a free
+list.
+
+ CHUNKED_CTX_MEM = 1
+
+C<ctx_mem.data> is a pointer to an allocated chunk of memory.  The pointer
+C<ctx_mem.free> holds the next usable location. With (full) continuations the
+C<ctx_mem.free> pointer can't be moved below the C<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.
 
-    ATTR PMC     caller_ctx   /* caller context */
-    ATTR Regs_ni bp;          /* pointers to FLOATVAL & INTVAL */
-    ATTR Regs_ps bp_ps;       /* pointers to PMC & STR */
+ CHUNKED_CTX_MEM = 0
+
+Context/register memory is malloced. C<ctx_mem.free> is used as a free list of
+reusable items.
+
+=cut
+
+*/
+
+
+#include "parrot/parrot.h"
+#include "parrot/register.h"
+#include "pmc_sub.h"
+
+#define SLOT_CHUNK_SIZE 8
+
+#define ROUND_ALLOC_SIZE(size) ((((size) + SLOT_CHUNK_SIZE - 1) \
+        / SLOT_CHUNK_SIZE) * SLOT_CHUNK_SIZE)
+#define CALCULATE_SLOT_NUM(size) ((size) / SLOT_CHUNK_SIZE)
+
+#if CHUNKED_CTX_MEM
+ #  error "Non-working code removed."
+#endif
+
+#define CTX_ALLOC_SIZE 0x20000
+
+#define ALIGNED_CTX_SIZE (((sizeof (Parrot_Context) + NUMVAL_SIZE - 1) \
+        / NUMVAL_SIZE) * NUMVAL_SIZE)
+
+
+/*
+
+=item C<static void clear_regs(PARROT_INTERP, Parrot_Context *ctx)>
+
+Clears all registers in a context.  PMC and STRING registers contain PMCNULL
+and NULL, respectively.  Integer and float registers contain negative flag
+values, for debugging purposes.
+
+=cut
+
+*/
+
+static void
+clear_regs(PARROT_INTERP, ARGMOD(Parrot_Context *ctx))
+{
+    ASSERT_ARGS(clear_regs)
+    int i;
+
+    /* NULL out registers - P/S have to be NULL for GC
+     *
+     * if the architecture has 0x := NULL and 0.0 we could memset too
+     */
+
+    for (i = 0; i < ctx->n_regs_used[REGNO_PMC]; i++) {
+        CTX_REG_PMC(ctx, i) = PMCNULL;
+    }
+
+    for (i = 0; i < ctx->n_regs_used[REGNO_STR]; i++) {
+        CTX_REG_STR(ctx, i) = NULL;
+    }
+
+    if (Interp_debug_TEST(interp, PARROT_REG_DEBUG_FLAG)) {
+        /* depending on -D40 we set int and num to be identifiable garbage values */
+        for (i = 0; i < ctx->n_regs_used[REGNO_INT]; i++) {
+            CTX_REG_INT(ctx, i) = -999;
+        }
+        for (i = 0; i < ctx->n_regs_used[REGNO_NUM]; i++) {
+            CTX_REG_NUM(ctx, i) = -99.9;
+        }
+    }
+}
+
+
+pmclass Context {
+    ATTR PMC      *caller_ctx   /* caller context */
+    ATTR Regs_ni   bp;          /* pointers to FLOATVAL & INTVAL */
+    ATTR Regs_ps   bp_ps;       /* pointers to PMC & STR */
+    ATTR void *    regs;        /* register storage */
 
     /* end common header */
-    ATTR INTVAL n_regs_used[4];   /* INSP in PBC points to Sub */
-    ATTR PMC    lex_pad;         /* LexPad PMC */
-    ATTR PMC    outer_ctx;       /* outer context, if a closure */
+    ATTR INTVAL    n_regs_used[4];   /* INSP in PBC points to Sub */
+    ATTR PMC      *lex_pad;         /* LexPad PMC */
+    ATTR PMC      *outer_ctx;       /* outer context, if a closure */
 
     /* new call scheme and introspective variables */
-    ATTR PMC      current_sub;           /* the Sub we are executing */
+    ATTR PMC      *current_sub;           /* the Sub we are executing */
 
     /* for now use a return continuation PMC */
-    ATTR PMC      handlers;              /* local handlers for the context */
-    ATTR PMC      current_cont;          /* the return continuation PMC */
-    ATTR PMC      current_object;        /* current object if a method call */
-    ATTR PMC      current_namespace;     /* The namespace we're currently in */
-    ATTR PMC      results_signature;     /* non-const results signature PMC */
+    ATTR PMC      *handlers;              /* local handlers for the context */
+    ATTR PMC      *current_cont;          /* the return continuation PMC */
+    ATTR PMC      *current_object;        /* current object if a method call */
+    ATTR PMC      *current_namespace;     /* The namespace we're currently in */
+    ATTR PMC      *results_signature;     /* non-const results signature PMC */
     ATTR opcode_t *current_pc;            /* program counter of Sub invocation */
     ATTR opcode_t *current_results;       /* ptr into code with get_results opcode */
 
     /* deref the constants - we need it all the time */
-    ATTR struct PackFile_Constant **constants;
+    ATTR struct    PackFile_Constant **constants;
 
-    ATTR INTVAL  current_HLL;     /* see also src/hll.c */
-    ATTR size_t  regs_mem_size;   /* memory occupied by registers */
-    ATTR int     ref_count;       /* how often refered to */
-    ATTR int     gc_mark;         /* marked in gc run */
+    ATTR INTVAL    current_HLL;     /* see also src/hll.c */
+    ATTR size_t    regs_mem_size;   /* memory occupied by registers */
+    ATTR int       ref_count;       /* how often refered to */
+    ATTR int       gc_mark;         /* marked in gc run */
 
-    ATTR UINTVAL warns;           /* Keeps track of what warnings
+    ATTR UINTVAL   warns;           /* Keeps track of what warnings
                                              * have been activated */
-    ATTR UINTVAL errors;          /* fatals that can be turned off */
-    ATTR UINTVAL trace_flags;
-    ATTR UINTVAL recursion_depth; /* Sub call recursion depth */
+    ATTR UINTVAL   errors;          /* fatals that can be turned off */
+    ATTR UINTVAL   trace_flags;
+    ATTR UINTVAL   recursion_depth; /* Sub call recursion depth */
 
     /* code->prederefed.code - code->base.data in opcodes
      * to simplify conversion between code ptrs in e.g. invoke */
-    ATTR size_t pred_offset;
+    ATTR size_t    pred_offset;
+
+    VTABLE void init() {
+        Parrot_Context_attributes * const ctx =
+            mem_alloc_typed(Parrot_Context_attributes);
+        ctx->current_results   = NULL;
+        ctx->results_signature = PMCNULL;
+        ctx->lex_pad           = PMCNULL;
+        ctx->outer_ctx         = PMCNULL;
+        ctx->current_cont      = PMCNULL;
+        ctx->current_object    = PMCNULL;
+        ctx->handlers          = PMCNULL;
+        ctx->caller_ctx        = PMCNULL;
+        ctx->current_pc        = PMCNULL;
+        PMC_data(SELF) = ctx;
+        PObj_active_destroy_SET(SELF);
+        PObj_custom_mark_SET(SELF);
+    }
+
+    VTABLE void init_pmc(PMC *old_ctx) {
+        Parrot_Context_attributes * const ctx =
+            mem_alloc_typed(Parrot_Context_attributes);
+        ctx->current_results   = NULL;
+        ctx->results_signature = PMCNULL;
+        ctx->lex_pad           = PMCNULL;
+        ctx->outer_ctx         = PMCNULL;
+        ctx->current_cont      = PMCNULL;
+        ctx->current_object    = PMCNULL;
+        ctx->handlers          = PMCNULL;
+        ctx->caller_ctx        = PMCNULL;
+        ctx->current_pc        = PMCNULL;
+        ctx->current_namespace = PMCNULL;
+        PMC_data(SELF) = ctx;
+        PObj_active_destroy_SET(SELF);
+        PObj_custom_mark_SET(SELF);
+
+        if (!PMC_IS_NULL(old_ctx)) {
+            Parrot_Context_attributes * const old = PARROT_CONTEXT(old_ctx);
+            /* some items should better be COW copied */
+            ctx->constants         = old->constants;
+            ctx->warns             = old->warns;
+            ctx->errors            = old->errors;
+            ctx->trace_flags       = old->trace_flags;
+            ctx->pred_offset       = old->pred_offset;
+            ctx->current_HLL       = old->current_HLL;
+            ctx->current_namespace = old->current_namespace;
+            /* end COW */
+            ctx->recursion_depth   = old->recursion_depth;
+        }
+        else {
+            ctx->constants         = NULL;
+            ctx->warns             = 0;
+            ctx->errors            = 0;
+            ctx->trace_flags       = 0;
+            ctx->pred_offset       = 0;
+            ctx->current_HLL       = 0;
+            ctx->recursion_depth   = 0;
+        }
+        clear_regs(interp, ctx);
+    }
+
+    VTABLE void mark() {
+        Parrot_Context_attributes * const data = PARROT_CONTEXT(SELF);
+        if (data) {
+            if (data->caller_ctx)
+                Parrot_gc_mark_PObj_alive(interp, data->caller_ctx);
+            if (data->lex_pad)
+                Parrot_gc_mark_PObj_alive(interp, data->lex_pad);
+            if (data->outer_ctx)
+                Parrot_gc_mark_PObj_alive(interp, data->outer_ctx);
+            if (data->handlers)
+                Parrot_gc_mark_PObj_alive(interp, data->handlers);
+            if (data->current_sub)
+                Parrot_gc_mark_PObj_alive(interp, data->current_sub);
+            if (data->current_cont)
+                Parrot_gc_mark_PObj_alive(interp, data->current_cont);
+            if (data->current_object)
+                Parrot_gc_mark_PObj_alive(interp, data->current_object);
+            if (data->current_namespace)
+                Parrot_gc_mark_PObj_alive(interp, data->current_namespace);
+            if (data->results_signature)
+                Parrot_gc_mark_PObj_alive(interp, data->results_signature);
+        }
+    }
+
+/*
+
+=item C<void push_pmc(PMC *new)>
+
+Pushes the new context, and sets it as the current context
+
+=cut
+
+*/
+
+    VTABLE void push_pmc(PMC * new) {
+        PMC * const old = CONTEXT(interp);
+
+        PARROT_CONTEXT(SELF)->caller_ctx  = old;
+
+        /* doesn't change */
+        PARROT_CONTEXT(SELF)->current_sub = PARROT_CONTEXT(old)->current_sub;
+    }
+
+/*
+
+=item C<PMC * pop_pmc()>
+
+Pops SELF off the context list, and sets it's immediate parent as the
+current context
+
+*/
+
+    VTABLE PMC * pop_pmc() {
+        PMC * const ctx = CONTEXT(interp);
+        PMC * const old = ctx->caller_ctx;
+
+        /* restore old, set cached interpreter base pointers */
+        CONTEXT(interp)      = old;
+        interp->ctx.bp       = old->bp;
+        interp->ctx.bp_ps    = old->bp_ps;
+    }
+
+    VTABLE void set_integer_native(INTVAL val) {
+        INTVAL i;
+        INTVAL num_ints = PARROT_CONTEXT(SELF)->n_regs_used[REGNO_INT];
+        for (i = 0; i < num_ints; ++i)
+            VTABLE_set_integer_keyed_int(INTERP, SELF, i, val);
+    }
+
+    VTABLE void set_number_native(FLOATVAL val) {
+        INTVAL i;
+        INTVAL num_nums = PARROT_CONTEXT(SELF)->n_regs_used[REGNO_NUM];
+        for (i = 0; i < num_nums; ++i)
+            VTABLE_set_number_keyed_int(INTERP, SELF, i, val);
+    }
+
+    VTABLE void set_pmc(PMC * val) {
+        INTVAL i;
+        INTVAL num_pmcs = PARROT_CONTEXT(SELF)->n_regs_used[REGNO_PMC];
+        for (i = 0; i < num_nums; ++i)
+            VTABLE_set_pmc_keyed_int(INTERP, SELF, i, val);
+    }
+
+    VTABLE void set_string_native(STRING * val) {
+        INTVAL i;
+        INTVAL num_strs = PARROT_CONTEXT(SELF)->n_regs_used[REGNO_STR];
+        for (i = 0; i < num_strs; ++i)
+            VTABLE_set_string_keyed_int(INTERP, SELF, i, val);
+    }
+
+
+
+    VTABLE void set_pointer(void *number_regs_used) {
+        Parrot_Context_attributes * const ctx = PARROT_CONTEXT(SELF);
+        const size_t size_i = sizeof (INTVAL)   * number_regs_used[REGNO_INT];
+        const size_t size_n = sizeof (FLOATVAL) * number_regs_used[REGNO_NUM];
+        const size_t size_s = sizeof (STRING *) * number_regs_used[REGNO_STR];
+        const size_t size_p = sizeof (PMC *)    * number_regs_used[REGNO_PMC];
+
+        const size_t size_nip      = size_n + size_i + size_p;
+        const size_t all_regs_size = size_n + size_i + size_p + size_s;
+        const size_t reg_alloc     = ROUND_ALLOC_SIZE(all_regs_size);
+        const int    slot          = CALCULATE_SLOT_NUM(reg_alloc);
+
+        ctx->n_regs_used[REGNO_INT] = number_regs_used[REGNO_INT];
+        ctx->n_regs_used[REGNO_NUM] = number_regs_used[REGNO_NUM];
+        ctx->n_regs_used[REGNO_STR] = number_regs_used[REGNO_STR];
+        ctx->n_regs_used[REGNO_PMC] = number_regs_used[REGNO_PMC];
+
+        ctx->regs_mem_size = reg_alloc;
+        ctx->regs = (void *)mem_sys_allocate(reg_alloc);
+
+        /* ctx.bp points to I0, which has Nx on the left */
+        ctx->bp.regs_i = (INTVAL *)((char *)ctx->regs + size_n);
+        /* ctx.bp_ps points to S0, which has Px on the left */
+        ctx->bp_ps.regs_s = (STRING **)((char *)ctx_regs + size_nip);
+    }
+
+    VTABLE void destroy() {
+        Parrot_Context_attributes * const data = PARROT_CONTEXT(SELF);
+        if (data) {
+            if (data->regs)
+                mem_sys_free(data->regs);
+            mem_sys_free(data);
+        }
+    }
 }
 
 /*

Modified: branches/context_pmc/src/pmc/continuation.pmc
==============================================================================
--- branches/context_pmc/src/pmc/continuation.pmc	Sat Jun 27 19:09:28 2009	(r39809)
+++ branches/context_pmc/src/pmc/continuation.pmc	Sat Jun 27 19:39:09 2009	(r39810)
@@ -23,6 +23,7 @@
 
 #include "parrot/oplib/ops.h"
 #include "pmc_sub.h"
+#include "pmc_context.h"
 
 /*
 
@@ -228,8 +229,8 @@
 
     VTABLE opcode_t *invoke(void *next) {
         Parrot_cont      *cc           = PMC_cont(SELF);
-        Parrot_Context   *from_ctx     = CONTEXT(interp);
-        Parrot_Context   *to_ctx       = cc->to_ctx;
+        PMC   *from_ctx     = CONTEXT(interp);
+        PMC   *to_ctx       = cc->to_ctx;
         opcode_t         *pc           = cc->address;
         UNUSED(next)
 
@@ -249,7 +250,7 @@
              * therefore we have to block GC
              */
             opcode_t *src_indexes  = interp->current_args;
-            opcode_t *dest_indexes = to_ctx->current_results;
+            opcode_t *dest_indexes = PARROT_CONTEXT(to_ctx)->current_results;
             interp->current_args   = NULL;
 
             Parrot_block_GC_mark(INTERP);
@@ -293,7 +294,7 @@
 
     METHOD caller() {
         Parrot_cont *cc     = PMC_cont(SELF);
-        PMC         *caller = cc->to_ctx->current_sub;
+        PMC         *caller = PARROT_CONTEXT(cc->to_ctx)->current_sub;
         Parrot_sub  *sub;
 
         PMC_get_sub(INTERP, caller, sub);
@@ -315,7 +316,7 @@
 
     METHOD continuation() {
         Parrot_cont *cc   = PMC_cont(SELF);
-        PMC         *cont = cc->to_ctx->current_cont;
+        PMC         *cont = PARROT_CONTEXT(cc->to_ctx)->current_cont;
 
         if (cont)
             RETURN(PMC *cont);

Modified: branches/context_pmc/src/pmc/exception.pmc
==============================================================================
--- branches/context_pmc/src/pmc/exception.pmc	Sat Jun 27 19:09:28 2009	(r39809)
+++ branches/context_pmc/src/pmc/exception.pmc	Sat Jun 27 19:39:09 2009	(r39810)
@@ -51,6 +51,7 @@
 
 #include "parrot/exceptions.h"
 #include "pmc_sub.h"
+#include "pmc_context.h"
 
 pmclass Exception {
 
@@ -65,8 +66,8 @@
     ATTR PMC            *backtrace;    /* The backtrace of an exception. */
     ATTR INTVAL          handled;      /* Whether the exception has been handled. */
     ATTR PMC            *handler_iter; /* An iterator of handlers (for rethrow). */
-    ATTR Parrot_Context *handler_ctx;  /* A stored context for handler iterator. */
-    ATTR Parrot_Context *thrower;      /* The position we were at when thrown. */
+    ATTR PMC            *handler_ctx;  /* A stored context for handler iterator. */
+    ATTR PMC            *thrower;      /* The position we were at when thrown. */
 
 /*
 
@@ -99,6 +100,8 @@
         core_struct->resume       = PMCNULL;
         core_struct->backtrace    = PMCNULL;
         core_struct->handler_iter = PMCNULL;
+        core_struct->handler_ctx  = PMCNULL;
+        core_struct->thrower      = PMCNULL;
     }
 
 /*
@@ -161,6 +164,10 @@
             Parrot_gc_mark_PObj_alive(interp, (PObj *)core_struct->backtrace);
         if (core_struct->handler_iter)
             Parrot_gc_mark_PObj_alive(interp, (PObj *)core_struct->handler_iter);
+        if (core_struct->handler_ctx)
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)core_struct->handler_ctx);
+        if (core_struct->thrower)
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)core_struct->thrower);
     }
 
 /*
@@ -175,8 +182,6 @@
 
     VTABLE void destroy() {
         Parrot_Exception_attributes * const core_struct = PARROT_EXCEPTION(SELF);
-        if (core_struct->thrower)
-            Parrot_free_context(interp, core_struct->thrower, 1);
         if (core_struct)
             mem_sys_free(core_struct);
     }
@@ -495,11 +500,7 @@
     VTABLE void set_pointer(void *context) {
         Parrot_Exception_attributes * const core_struct = PARROT_EXCEPTION(SELF);
 
-        /* contexts are refcounted; increment and decrement appropriately */
-        if (core_struct->handler_ctx)
-            Parrot_free_context(interp, core_struct->handler_ctx, 1);
-        core_struct->handler_ctx = Parrot_context_ref(interp,
-                                       (Parrot_Context *)context);
+        core_struct->handler_ctx = (PMC *)context;
     }
 
 /*
@@ -661,11 +662,9 @@
             /* Ensure it's a ret cont, and extract the from_ctx.
              * XXX TT#596 - when we have Context PMCs, just take and set that. */
             if (VTABLE_isa(interp, value, CONST_STRING(interp, "Continuation"))) {
-                Parrot_Context *ctx = PMC_cont(value)->from_ctx;
-                if (ctx) {
-                    Parrot_context_ref(interp, ctx);
+                PMC *ctx = PMC_cont(value)->from_ctx;
+                if (!PMC_IS_NULL(ctx))
                     SET_ATTR_thrower(interp, SELF, ctx);
-                }
             }
         }
         else {
@@ -761,7 +760,7 @@
     METHOD backtrace() {
         PMC *result = pmc_new(interp, enum_class_ResizablePMCArray);
         PMC *resume;
-        Parrot_Context *cur_ctx;
+        PMC *cur_ctx;
         Parrot_cont    *cont;
 
         /* Get starting context, then loop over them. */
@@ -800,7 +799,7 @@
                         PackFile_ByteCode *seg = sub->seg;
                         opcode_t          *pc  = cont && cur_ctx == cont->to_ctx
                                                ? cont->address
-                                               : cur_ctx->current_pc;
+                                               : PARROT_CONTEXT(cur_ctx)->current_pc;
 
                         annotations = PackFile_Annotations_lookup(interp,
                                         seg->annotations, pc - seg->base.data,
@@ -815,7 +814,7 @@
 
                 /* Push frame and go to next caller. */
                 VTABLE_push_pmc(interp, result, frame);
-                cur_ctx = cur_ctx->caller_ctx;
+                cur_ctx = PARROT_CONTEXT(cur_ctx)->caller_ctx;
             }
         }
 

Modified: branches/context_pmc/src/pmc/lexpad.pmc
==============================================================================
--- branches/context_pmc/src/pmc/lexpad.pmc	Sat Jun 27 19:09:28 2009	(r39809)
+++ branches/context_pmc/src/pmc/lexpad.pmc	Sat Jun 27 19:39:09 2009	(r39810)
@@ -27,8 +27,8 @@
  */
 
 pmclass LexPad provides hash no_ro {
-    ATTR PMC                   *lexinfo;
-    ATTR struct Parrot_Context *ctx;
+    ATTR PMC *lexinfo;
+    ATTR PMC *ctx;
 
     VTABLE void init() {
         Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
@@ -82,7 +82,8 @@
             mem_allocate_zeroed_typed(Parrot_LexPad_attributes);
 
         PObj_active_destroy_SET(SELF);
-
+        PObj_custom_mark_SET(SELF);
+        attrs->ctx = PMCNULL;
         attrs->lexinfo = lexinfo;
         PMC_data(SELF) = attrs;
     }
@@ -91,8 +92,16 @@
         mem_sys_free(PMC_data(SELF));
     }
 
+    VTABLE void mark() {
+        Parrot_LexPad_attributes * const data = PARROT_LEXPAD(SELF);
+        if (data) {
+            if (data->ctx)
+                Parrot_gc_mark_PObj_alive(INTERP, (PObj *)data->ctx);
+        }
+    }
+
     VTABLE void set_pointer(void *ctx) {
-        SET_ATTR_ctx(INTERP, SELF, (struct Parrot_Context *)ctx);
+        SET_ATTR_ctx(INTERP, SELF, (PMC *)ctx);
     }
 
     VTABLE INTVAL elements() {
@@ -117,7 +126,7 @@
     VTABLE PMC *get_pmc_keyed_str(STRING *name) {
         PMC              * info;
         Hash             * hash;
-        Parrot_Context   * ctx;
+        PMC              * ctx;
         HashBucket       * b;
         INTVAL            regno;
 
@@ -142,7 +151,7 @@
     VTABLE void set_pmc_keyed_str(STRING *name, PMC *value) {
         PMC              * info;
         Hash             * hash;
-        Parrot_Context   * ctx;
+        PMC              * ctx;
         HashBucket       * b;
         INTVAL             regno;
 
@@ -169,6 +178,12 @@
         GET_ATTR_lexinfo(INTERP, SELF, lexinfo);
         RETURN(PMC *lexinfo);
     }
+
+    METHOD get_context() {
+        PMC * ctx;
+        GET_ATTR_ctx(INTERP, SELF, ctx);
+        RETURN(PMC *ctx);
+    }
 }
 
 

Modified: branches/context_pmc/src/pmc/parrotinterpreter.pmc
==============================================================================
--- branches/context_pmc/src/pmc/parrotinterpreter.pmc	Sat Jun 27 19:09:28 2009	(r39809)
+++ branches/context_pmc/src/pmc/parrotinterpreter.pmc	Sat Jun 27 19:39:09 2009	(r39810)
@@ -442,7 +442,7 @@
         STRING *s     = CONST_STRING(interp, "globals");
         int     level = 0;
 
-        Parrot_Context *ctx;
+        PMC *ctx;
 
         if (Parrot_str_equal(interp, item, s))
             return interp->root_namespace;
@@ -474,15 +474,15 @@
 
         if (outer) {
             for (; level; --level) {
-                ctx = ctx->outer_ctx;
-                if (!ctx)
+                ctx = PARROT_CONTEXT(ctx)->outer_ctx;
+                if (PMC_IS_NULL(ctx))
                     Parrot_ex_throw_from_c_args(interp, NULL,
                         CONTROL_ERROR, "No such outer depth");
             }
         }
         else {
             for (; level; --level) {
-                cont = ctx->current_cont;
+                cont = PARROT_CONTEXT(ctx)->current_cont;
 
                 if (PMC_IS_NULL(cont) || !PMC_cont(cont)->seg)
                     Parrot_ex_throw_from_c_args(interp, NULL,
@@ -497,45 +497,44 @@
         }
 
         if (item == outer)
-            return ctx->current_sub;
+            return PARROT_CONTEXT(ctx)->current_sub;
 
         s = CONST_STRING(interp, "sub");
 
         if (Parrot_str_equal(interp, item, s))
-            return ctx->current_sub;
+            return PARROT_CONTEXT(ctx)->current_sub;
 
         s = CONST_STRING(interp, "lexpad");
 
         if (Parrot_str_equal(interp, item, s))
-            return ctx->lex_pad;
+            return PARROT_CONTEXT(ctx)->lex_pad;
 
         s = CONST_STRING(interp, "namespace");
 
         if (Parrot_str_equal(interp, item, s))
-            return ctx->current_namespace;
+            return PARROT_CONTEXT(ctx)->current_namespace;
 
         s = CONST_STRING(interp, "continuation");
 
         if (Parrot_str_equal(interp, item, s))
-            return VTABLE_clone(interp, ctx->current_cont);
+            return VTABLE_clone(interp, PARROT_CONTEXT(ctx)->current_cont);
 
         s = CONST_STRING(interp, "annotations");
 
         if (Parrot_str_equal(interp, item, s)) {
             Parrot_sub *sub;
-            PMC        *sub_pmc = ctx->current_sub;
+            PMC        *sub_pmc = PARROT_CONTEXT(ctx)->current_sub;
             PMC_get_sub(interp, sub_pmc, sub);
             if (ctx == CONTEXT(interp)) {
                 /* We can't know the current program counter for the currently
                  * executing sub, so can't return annotations for that. */
-                if (ctx == CONTEXT(interp))
-                    Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
-                            "Cannot get annotations at depth 0; use annotations op instead.");
+                Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
+                    "Cannot get annotations at depth 0; use annotations op instead.");
             }
             if (!PMC_IS_NULL(sub_pmc) && sub_pmc->vtable->base_type == enum_class_Sub &&
                     sub->seg->annotations) {
                 PackFile_ByteCode *seg = sub->seg;
-                opcode_t *pc = ctx->current_pc;
+                opcode_t *pc = PARROT_CONTEXT(ctx)->current_pc;
                 return PackFile_Annotations_lookup(interp,  seg->annotations,
                         pc - seg->base.data, NULL);
             }

Modified: branches/context_pmc/src/pmc/sub.pmc
==============================================================================
--- branches/context_pmc/src/pmc/sub.pmc	Sat Jun 27 19:09:28 2009	(r39809)
+++ branches/context_pmc/src/pmc/sub.pmc	Sat Jun 27 19:39:09 2009	(r39810)
@@ -92,11 +92,6 @@
         if (sub) {
             if (sub->arg_info)
                 mem_sys_free(sub->arg_info);
-            if (sub->ctx)
-                Parrot_free_context(INTERP, sub->ctx, 1);
-            if (sub->outer_ctx)
-                Parrot_free_context(INTERP, sub->outer_ctx, 1);
-
             mem_sys_free(sub);
         }
 
@@ -220,9 +215,9 @@
 
     VTABLE opcode_t *invoke(void *next) {
         Parrot_sub     *sub;
-        Parrot_Context *caller_ctx;
-        Parrot_Context *context;
-        Parrot_Context *c;
+        PMC *caller_ctx;
+        PMC *context;
+        PMC *c;
         PMC            *ccont;
         opcode_t       *pc;
 
@@ -264,14 +259,15 @@
 
         /* plain subroutine call
          * create new context, place it in interpreter */
-        context               = Parrot_set_new_context(INTERP, sub->n_regs_used);
-        context->current_sub  = SELF;
-        context->caller_ctx   = caller_ctx;
-        context->current_pc   = pc;
-        context->current_cont = ccont;
+        context               = pmc_new(INTERP, enum_class_Context);
+        VTABLE_set_pointer(INTERP, context, sub->n_regs_used);
+        PARROT_CONTEXT(context)->current_sub  = SELF;
+        PARROT_CONTEXT(context)->caller_ctx   = caller_ctx;
+        PARROT_CONTEXT(context)->current_pc   = pc;
+        PARROT_CONTEXT(context)->current_cont = ccont;
 
         /* check recursion/call depth */
-        if (++context->recursion_depth > INTERP->recursion_limit)
+        if (++PARROT_CONTEXT(context)->recursion_depth > INTERP->recursion_limit)
             Parrot_ex_throw_from_c_args(INTERP, next, CONTROL_ERROR,
                     "maximum recursion depth exceeded");
 
@@ -283,9 +279,7 @@
          * retcontinuation to a normal continuation.  */
         if (PObj_get_FLAGS(SELF) & SUB_FLAG_IS_OUTER) {
             /* release any previously held context */
-            if (sub->ctx)
-                Parrot_free_context(interp, sub->ctx, 1);
-            sub->ctx = Parrot_context_ref(interp, context);
+            sub->ctx = context;
             /* convert retcontinuation to a continuation */
             ccont->vtable = interp->vtables[enum_class_Continuation];
         }
@@ -314,7 +308,7 @@
 
         if (sub->outer_ctx) {
             /* set outer context */
-            context->outer_ctx = Parrot_context_ref(interp, sub->outer_ctx);
+            context->outer_ctx = sub->outer_ctx;
         }
         else {
             /* autoclose */
@@ -332,25 +326,24 @@
                 PMC_get_sub(INTERP, outer_pmc, outer_sub);
 
                 if (!outer_sub->ctx) {
-                    Parrot_Context * const dummy = Parrot_alloc_context(INTERP,
-                                                outer_sub->n_regs_used, NULL);
-                    dummy->current_sub    = outer_pmc;
+                    PMC * const dummy = pmc_new(INTERP, enum_class_Context);
+                    VTABLE_set_pointer(INTERP, dummy, outer_sub->n_regs_used);
+                    PARROT_CONTEXT(dummy)->current_sub    = outer_pmc;
 
                     if (!PMC_IS_NULL(outer_sub->lex_info)) {
-                        dummy->lex_pad = pmc_new_init(INTERP,
+                        PARROT_CONTEXT(dummy)->lex_pad = pmc_new_init(INTERP,
                                Parrot_get_ctx_HLL_type(interp, enum_class_LexPad),
                                outer_sub->lex_info);
-                        VTABLE_set_pointer(INTERP, dummy->lex_pad, dummy);
+                        VTABLE_set_pointer(INTERP, PARROT_CONTEXT(dummy)->lex_pad, dummy);
                     }
 
                     if (outer_sub->outer_ctx) {
-                        dummy->outer_ctx = Parrot_context_ref(interp,
-                                               outer_sub->outer_ctx);
+                        dummy->outer_ctx = outer_sub->outer_ctx);
                     }
-                    outer_sub->ctx = Parrot_context_ref(interp, dummy);
+                    outer_sub->ctx = dummy;
                 }
 
-                c->outer_ctx = Parrot_context_ref(interp, outer_sub->ctx);
+                c->outer_ctx = outer_sub->ctx;
             }
         }
 
@@ -367,9 +360,7 @@
                 --context->recursion_depth;
 
                 PObj_get_FLAGS(ccont) &= ~SUB_FLAG_TAILCALL;
-                context->caller_ctx    = caller_ctx->caller_ctx;
-
-                Parrot_free_context(INTERP, caller_ctx, 1);
+                context->caller_ctx    = PARROT_CONTEXT(caller_ctx)->caller_ctx;
             }
         }
 
@@ -395,13 +386,6 @@
         PObj_custom_mark_destroy_SETALL(ret);
 
         PMC_get_sub(INTERP, ret, sub);
-
-        /* release any previously held contexts */
-        if (sub->ctx)
-            Parrot_free_context(INTERP, sub->ctx, 1);
-        if (sub->outer_ctx)
-            Parrot_free_context(INTERP, sub->outer_ctx, 1);
-
         PMC_get_sub(INTERP, SELF, dest_sub);
 
         /* first set the sub struct, Parrot_str_copy may cause GC */
@@ -413,12 +397,6 @@
         /* Be sure not to share arg_info. */
         dest_sub->arg_info = NULL;
 
-        /* mark any newly held contexts */
-        if (sub->ctx)
-            Parrot_context_ref(INTERP, sub->ctx);
-        if (sub->outer_ctx)
-            Parrot_context_ref(INTERP, sub->outer_ctx);
-
         return ret;
     }
 
@@ -444,15 +422,6 @@
             PMC_get_sub(INTERP, SELF, my_sub);
             PMC_get_sub(INTERP, other, other_sub);
 
-            /* Increase reference count of destination before
-             * freeing the one in self, to avoid problems in
-             * case of self assignment */
-            if (other_sub->ctx)
-                Parrot_context_ref(interp, other_sub->ctx);
-            /* get rid of this context, if attached */
-            if (my_sub->ctx)
-                Parrot_free_context(INTERP, my_sub->ctx, 1);
-
             /* copy the sub struct */
             memmove(my_sub, other_sub, sizeof (Parrot_sub));
 
@@ -502,9 +471,9 @@
         if (sub->subid)
             Parrot_gc_mark_PObj_alive(INTERP, (PObj *) sub->subid);
         if (sub->ctx)
-            mark_context(interp, sub->ctx);
+            Parrot_gc_mark_PObj_alive(INTERP, (PObj *) sub->ctx);
         if (sub->outer_ctx)
-            mark_context(interp, sub->outer_ctx);
+            Parrot_gc_mark_PObj_alive(INTERP, (PObj *) sub->outer_ctx);
     }
 
 /*

Modified: branches/context_pmc/src/scheduler.c
==============================================================================
--- branches/context_pmc/src/scheduler.c	Sat Jun 27 19:09:28 2009	(r39809)
+++ branches/context_pmc/src/scheduler.c	Sat Jun 27 19:39:09 2009	(r39810)
@@ -22,6 +22,7 @@
 #include "pmc/pmc_scheduler.h"
 #include "pmc/pmc_task.h"
 #include "pmc/pmc_timer.h"
+#include "pmc/pmc_context.h"
 
 #include "scheduler.str"
 
@@ -849,9 +850,9 @@
      * for a handler
      */
     static int already_doing = 0;
-    static Parrot_Context * keep_context = NULL;
+    PMC * keep_context = NULL;
 
-    Parrot_Context *context;
+    PMC *context;
     PMC            *iter        = PMCNULL;
     STRING * const  handled_str = CONST_STRING(interp, "handled");
     STRING * const  iter_str    = CONST_STRING(interp, "handler_iter");
@@ -859,16 +860,16 @@
     if (already_doing) {
         Parrot_io_eprintf(interp,
             "** Exception caught while looking for a handler, trying next **\n");
-        if (! keep_context)
+        if (PMC_IS_NULL(keep_context))
             return NULL;
         /*
          * Note that we are now trying to handle the new exception,
          * not the initial task argument (exception or whatever).
          */
-        context = keep_context->caller_ctx;
-        keep_context = NULL;
-        if (context && !PMC_IS_NULL(context->handlers))
-            iter = VTABLE_get_iter(interp, context->handlers);
+        context = PARROT_CONTEXT(keep_context)->caller_ctx;
+        keep_context = PMCNULL;
+        if (!PMC_IS_NULL(context) && !PMC_IS_NULL(PARROT_CONTEXT(context)->handlers))
+            iter = VTABLE_get_iter(interp, PARROT_CONTEXT(context)->handlers);
         else
             iter = PMCNULL;
     }
@@ -881,12 +882,12 @@
     if (task->vtable->base_type == enum_class_Exception
     && VTABLE_get_integer_keyed_str(interp, task, handled_str) == -1) {
         iter    = VTABLE_get_attr_str(interp, task, iter_str);
-        context = (Parrot_Context *)VTABLE_get_pointer(interp, task);
+        context = VTABLE_get_pointer(interp, task);
     }
     else {
         context = CONTEXT(interp);
-        if (!PMC_IS_NULL(context->handlers))
-            iter = VTABLE_get_iter(interp, context->handlers);
+        if (!PMC_IS_NULL(PARROT_CONTEXT(context)->handlers))
+            iter = VTABLE_get_iter(interp, PARROT_CONTEXT(context)->handlers);
     }
 
     }
@@ -916,9 +917,9 @@
         }
 
         /* Continue the search in the next context up the chain. */
-        context = context->caller_ctx;
-        if (context && !PMC_IS_NULL(context->handlers))
-            iter = VTABLE_get_iter(interp, context->handlers);
+        context = PARROT_CONTEXT(context)->caller_ctx;
+        if (context && !PMC_IS_NULL(PARROT_CONTEXT(context)->handlers))
+            iter = VTABLE_get_iter(interp, PARROT_CONTEXT(context)->handlers);
         else
             iter = PMCNULL;
     }


More information about the parrot-commits mailing list