[svn:parrot] r41110 - in trunk: include/parrot src/call src/gc

whiteknight at svn.parrot.org whiteknight at svn.parrot.org
Mon Sep 7 13:22:35 UTC 2009


Author: whiteknight
Date: Mon Sep  7 13:22:34 2009
New Revision: 41110
URL: https://trac.parrot.org/parrot/changeset/41110

Log:
[ctx] move the context-related functions from src/gc/alloc_register.c to src/call/context.c

Modified:
   trunk/include/parrot/call.h
   trunk/include/parrot/pmc_freeze.h
   trunk/src/call/context.c
   trunk/src/gc/alloc_register.c

Modified: trunk/include/parrot/call.h
==============================================================================
--- trunk/include/parrot/call.h	Mon Sep  7 12:38:04 2009	(r41109)
+++ trunk/include/parrot/call.h	Mon Sep  7 13:22:34 2009	(r41110)
@@ -709,6 +709,22 @@
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 
 PARROT_EXPORT
+void Parrot_clear_i(PARROT_INTERP)
+        __attribute__nonnull__(1);
+
+PARROT_EXPORT
+void Parrot_clear_n(PARROT_INTERP)
+        __attribute__nonnull__(1);
+
+PARROT_EXPORT
+void Parrot_clear_p(PARROT_INTERP)
+        __attribute__nonnull__(1);
+
+PARROT_EXPORT
+void Parrot_clear_s(PARROT_INTERP)
+        __attribute__nonnull__(1);
+
+PARROT_EXPORT
 PARROT_CANNOT_RETURN_NULL
 struct PackFile_Constant ** Parrot_pcc_constants(PARROT_INTERP,
     ARGIN(PMC *ctx))
@@ -756,6 +772,14 @@
         __attribute__nonnull__(2);
 
 PARROT_EXPORT
+PARROT_CANNOT_RETURN_NULL
+FLOATVAL * Parrot_pcc_get_FLOATVAL_reg(PARROT_INTERP,
+    ARGIN(PMC *ctx),
+    UINTVAL idx)
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
 PARROT_CAN_RETURN_NULL
 PMC* Parrot_pcc_get_handlers(PARROT_INTERP, ARGIN(PMC *ctx))
         __attribute__nonnull__(1)
@@ -776,6 +800,14 @@
 
 PARROT_EXPORT
 PARROT_CANNOT_RETURN_NULL
+INTVAL * Parrot_pcc_get_INTVAL_reg(PARROT_INTERP,
+    ARGIN(PMC *ctx),
+    UINTVAL idx)
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
+PARROT_CANNOT_RETURN_NULL
 PMC* Parrot_pcc_get_lex_pad(PARROT_INTERP, ARGIN(PMC *ctx))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
@@ -819,6 +851,12 @@
         __attribute__nonnull__(2);
 
 PARROT_EXPORT
+PARROT_CANNOT_RETURN_NULL
+PMC ** Parrot_pcc_get_PMC_reg(PARROT_INTERP, ARGIN(PMC *ctx), UINTVAL idx)
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
 size_t Parrot_pcc_get_pred_offset(PARROT_INTERP, ARGIN(PMC *ctx))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
@@ -829,6 +867,23 @@
         __attribute__nonnull__(2);
 
 PARROT_EXPORT
+PARROT_CANNOT_RETURN_NULL
+Regs_ni* Parrot_pcc_get_regs_ni(PARROT_INTERP, ARGIN(PMC *ctx))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
+PARROT_CANNOT_RETURN_NULL
+Regs_ps* Parrot_pcc_get_regs_ps(PARROT_INTERP, ARGIN(PMC *ctx))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
+UINTVAL Parrot_pcc_get_regs_used(PARROT_INTERP, ARGIN(PMC *ctx), int type)
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
 PARROT_CAN_RETURN_NULL
 opcode_t* Parrot_pcc_get_results(PARROT_INTERP, ARGIN(PMC *ctx))
         __attribute__nonnull__(1)
@@ -849,6 +904,14 @@
         __attribute__nonnull__(2);
 
 PARROT_EXPORT
+PARROT_CANNOT_RETURN_NULL
+STRING ** Parrot_pcc_get_STRING_reg(PARROT_INTERP,
+    ARGIN(PMC *ctx),
+    UINTVAL idx)
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
 PARROT_CAN_RETURN_NULL
 PMC* Parrot_pcc_get_sub(PARROT_INTERP, ARGIN(PMC *ctx))
         __attribute__nonnull__(1)
@@ -940,6 +1003,32 @@
         __attribute__nonnull__(2);
 
 PARROT_EXPORT
+PARROT_CANNOT_RETURN_NULL
+void Parrot_pcc_set_regs_ni(PARROT_INTERP,
+    ARGIN(PMC *ctx),
+    ARGIN(Regs_ni *bp))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        __attribute__nonnull__(3);
+
+PARROT_EXPORT
+PARROT_CANNOT_RETURN_NULL
+void Parrot_pcc_set_regs_ps(PARROT_INTERP,
+    ARGIN(PMC *ctx),
+    ARGIN(Regs_ps *bp_ps))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        __attribute__nonnull__(3);
+
+PARROT_EXPORT
+void Parrot_pcc_set_regs_used(PARROT_INTERP,
+    ARGIN(PMC *ctx),
+    int type,
+    INTVAL num)
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
 void Parrot_pcc_set_results(PARROT_INTERP,
     ARGIN(PMC *ctx),
     ARGIN_NULLOK(opcode_t *pc))
@@ -1000,6 +1089,47 @@
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
+PARROT_EXPORT
+void Parrot_pop_context(PARROT_INTERP)
+        __attribute__nonnull__(1);
+
+PARROT_EXPORT
+PARROT_WARN_UNUSED_RESULT
+PARROT_CANNOT_RETURN_NULL
+PMC * Parrot_push_context(PARROT_INTERP, ARGIN(const INTVAL *n_regs_used))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+void create_initial_context(PARROT_INTERP)
+        __attribute__nonnull__(1);
+
+PARROT_CANNOT_RETURN_NULL
+PARROT_WARN_UNUSED_RESULT
+PMC * Parrot_alloc_context(PARROT_INTERP,
+    ARGIN(const INTVAL *number_regs_used),
+    ARGIN_NULLOK(PMC *old))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+size_t Parrot_pcc_calculate_context_size(SHIM_INTERP,
+    ARGIN(const UINTVAL *number_regs_used))
+        __attribute__nonnull__(2);
+
+PARROT_CANNOT_RETURN_NULL
+PARROT_WARN_UNUSED_RESULT
+PMC * Parrot_set_new_context(PARROT_INTERP,
+    ARGIN(const INTVAL *number_regs_used))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+#define ASSERT_ARGS_Parrot_clear_i __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_Parrot_clear_n __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_Parrot_clear_p __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_Parrot_clear_s __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
 #define ASSERT_ARGS_Parrot_pcc_constants __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(ctx)
@@ -1024,6 +1154,9 @@
 #define ASSERT_ARGS_Parrot_pcc_get_continuation __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(ctx)
+#define ASSERT_ARGS_Parrot_pcc_get_FLOATVAL_reg __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx)
 #define ASSERT_ARGS_Parrot_pcc_get_handlers __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(ctx)
@@ -1033,6 +1166,9 @@
 #define ASSERT_ARGS_Parrot_pcc_get_int_constant __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(ctx)
+#define ASSERT_ARGS_Parrot_pcc_get_INTVAL_reg __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx)
 #define ASSERT_ARGS_Parrot_pcc_get_lex_pad __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(ctx)
@@ -1054,6 +1190,9 @@
 #define ASSERT_ARGS_Parrot_pcc_get_pmc_constant __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(ctx)
+#define ASSERT_ARGS_Parrot_pcc_get_PMC_reg __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx)
 #define ASSERT_ARGS_Parrot_pcc_get_pred_offset __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(ctx)
@@ -1061,6 +1200,15 @@
      __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(ctx)
+#define ASSERT_ARGS_Parrot_pcc_get_regs_ni __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx)
+#define ASSERT_ARGS_Parrot_pcc_get_regs_ps __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx)
+#define ASSERT_ARGS_Parrot_pcc_get_regs_used __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx)
 #define ASSERT_ARGS_Parrot_pcc_get_results __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(ctx)
@@ -1072,6 +1220,9 @@
      __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(ctx)
+#define ASSERT_ARGS_Parrot_pcc_get_STRING_reg __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx)
 #define ASSERT_ARGS_Parrot_pcc_get_sub __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(ctx)
@@ -1116,6 +1267,17 @@
 #define ASSERT_ARGS_Parrot_pcc_set_pred_offset __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(ctx)
+#define ASSERT_ARGS_Parrot_pcc_set_regs_ni __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx) \
+    || PARROT_ASSERT_ARG(bp)
+#define ASSERT_ARGS_Parrot_pcc_set_regs_ps __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx) \
+    || PARROT_ASSERT_ARG(bp_ps)
+#define ASSERT_ARGS_Parrot_pcc_set_regs_used __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(ctx)
 #define ASSERT_ARGS_Parrot_pcc_set_results __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(ctx)
@@ -1144,6 +1306,22 @@
 #define ASSERT_ARGS_Parrot_pcc_warnings_test __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(ctx)
+#define ASSERT_ARGS_Parrot_pop_context __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_Parrot_push_context __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(n_regs_used)
+#define ASSERT_ARGS_create_initial_context __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp)
+#define ASSERT_ARGS_Parrot_alloc_context __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(number_regs_used)
+#define ASSERT_ARGS_Parrot_pcc_calculate_context_size \
+     __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(number_regs_used)
+#define ASSERT_ARGS_Parrot_set_new_context __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(number_regs_used)
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 /* HEADERIZER END: src/call/context.c */
 

Modified: trunk/include/parrot/pmc_freeze.h
==============================================================================
--- trunk/include/parrot/pmc_freeze.h	Mon Sep  7 12:38:04 2009	(r41109)
+++ trunk/include/parrot/pmc_freeze.h	Mon Sep  7 13:22:34 2009	(r41110)
@@ -91,14 +91,14 @@
 PARROT_EXPORT
 PARROT_WARN_UNUSED_RESULT
 PARROT_CAN_RETURN_NULL
-PMC* Parrot_clone(PARROT_INTERP, ARGIN(PMC* pmc))
+PMC* Parrot_clone(PARROT_INTERP, ARGIN(PMC *pmc))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
 PARROT_EXPORT
 PARROT_WARN_UNUSED_RESULT
 PARROT_CAN_RETURN_NULL
-STRING* Parrot_freeze(PARROT_INTERP, ARGIN(PMC* pmc))
+STRING* Parrot_freeze(PARROT_INTERP, ARGIN(PMC *pmc))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
@@ -112,14 +112,14 @@
 PARROT_EXPORT
 PARROT_WARN_UNUSED_RESULT
 PARROT_CAN_RETURN_NULL
-PMC* Parrot_thaw(PARROT_INTERP, ARGIN(STRING* image))
+PMC* Parrot_thaw(PARROT_INTERP, ARGIN(STRING *image))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
 PARROT_EXPORT
 PARROT_WARN_UNUSED_RESULT
 PARROT_CAN_RETURN_NULL
-PMC* Parrot_thaw_constants(PARROT_INTERP, ARGIN(STRING* image))
+PMC* Parrot_thaw_constants(PARROT_INTERP, ARGIN(STRING *image))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 

Modified: trunk/src/call/context.c
==============================================================================
--- trunk/src/call/context.c	Mon Sep  7 12:38:04 2009	(r41109)
+++ trunk/src/call/context.c	Mon Sep  7 13:22:34 2009	(r41110)
@@ -19,12 +19,87 @@
 #include "parrot/parrot.h"
 #include "parrot/call.h"
 
+#include "parrot/parrot.h"
+#include "parrot/register.h"
+#include "../pmc/pmc_sub.h"
+
+
+/* set CTX_LEAK_DEBUG_FULL to 1 for enhanced context debugging.
+ * When set (1) freed contexts are "poisoned" so that any dangling
+ * references produce segfaults, and (2) contexts are not recycled
+ * so that later allocations don't suddenly restore a dangling
+ * reference to a "working" condition.
+ */
+#define CTX_LEAK_DEBUG_FULL 0
+
+
+/*
+=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
+
+*/
+
+
+#define ALIGNED_CTX_SIZE (((sizeof (Parrot_Context) + NUMVAL_SIZE - 1) \
+        / NUMVAL_SIZE) * NUMVAL_SIZE)
+
+/*
+
+=pod
+
+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.
+
+=cut
+
+*/
+
+#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)
+
 
 /* HEADERIZER HFILE: include/parrot/call.h */
 
 /* HEADERIZER BEGIN: static */
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 
+static void clear_regs(PARROT_INTERP, ARGMOD(PMC *pmcctx))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        FUNC_MODIFIES(*pmcctx);
+
+static void init_context(PARROT_INTERP,
+    ARGMOD(PMC *pmcctx),
+    ARGIN_NULLOK(PMC *pmcold))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        FUNC_MODIFIES(*pmcctx);
+
+#define ASSERT_ARGS_clear_regs __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(pmcctx)
+#define ASSERT_ARGS_init_context __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(pmcctx)
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 /* HEADERIZER END: static */
 
@@ -941,6 +1016,594 @@
 
 /*
 
+=head2 Context and Register Allocation Functions
+
+=over 4
+
+=cut
+
+*/
+
+
+/*
+
+=item C<void create_initial_context(PARROT_INTERP)>
+
+Creates the interpreter's initial context.
+
+=cut
+
+*/
+
+void
+create_initial_context(PARROT_INTERP)
+{
+    ASSERT_ARGS(create_initial_context)
+    static INTVAL   num_regs[] = {32, 32, 32, 32};
+    PMC *ignored;
+
+    /* Create some initial free_list slots. */
+
+#define INITIAL_FREE_SLOTS 8
+    /* 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<static void clear_regs(PARROT_INTERP, PMC *pmcctx)>
+
+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(PMC *pmcctx))
+{
+    ASSERT_ARGS(clear_regs)
+    UINTVAL i;
+    Parrot_Context *ctx = Parrot_pcc_get_context_struct(interp, pmcctx);
+
+    /* 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->bp_ps.regs_p[-1L - i] = PMCNULL;
+    }
+
+    for (i = 0; i < ctx->n_regs_used[REGNO_STR]; i++) {
+        ctx->bp_ps.regs_s[i] = NULL;
+    }
+
+    if (Interp_debug_TEST(interp, PARROT_REG_DEBUG_FLAG)) {
+        /* depending on -D40, set int and num to identifiable garbage values */
+        for (i = 0; i < ctx->n_regs_used[REGNO_INT]; i++) {
+            ctx->bp.regs_i[i] = -999;
+        }
+
+        for (i = 0; i < ctx->n_regs_used[REGNO_NUM]; i++) {
+            ctx->bp.regs_n[-1L - i] = -99.9;
+        }
+    }
+}
+
+
+/*
+
+=item C<static void init_context(PARROT_INTERP, PMC *pmcctx, PMC *pmcold)>
+
+Initializes a freshly allocated or recycled context.
+
+=cut
+
+*/
+
+static void
+init_context(PARROT_INTERP, ARGMOD(PMC *pmcctx), ARGIN_NULLOK(PMC *pmcold))
+{
+    ASSERT_ARGS(init_context)
+    Parrot_Context *ctx = Parrot_pcc_get_context_struct(interp, pmcctx);
+    Parrot_Context *old = Parrot_pcc_get_context_struct(interp, pmcold);
+
+    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;
+    ctx->pred_offset       = 0;
+
+    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, pmcctx);
+}
+
+
+/*
+
+=item C<PMC * 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
+PMC *
+Parrot_push_context(PARROT_INTERP, ARGIN(const INTVAL *n_regs_used))
+{
+    ASSERT_ARGS(Parrot_push_context)
+    PMC * const old = CURRENT_CONTEXT(interp);
+    PMC * const ctx = Parrot_set_new_context(interp, n_regs_used);
+
+    Parrot_pcc_set_caller_ctx(interp, ctx, old);
+
+    /* doesn't change */
+    Parrot_pcc_set_sub(interp, ctx, Parrot_pcc_get_sub(interp, old));
+
+    /* 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)
+    PMC * const ctx = CURRENT_CONTEXT(interp);
+    PMC * const old = Parrot_pcc_get_caller_ctx(interp, ctx);
+
+    /* restore old, set cached interpreter base pointers */
+    CURRENT_CONTEXT(interp) = old;
+}
+
+/*
+
+=item C<size_t Parrot_pcc_calculate_context_size(PARROT_INTERP, const UINTVAL
+*number_regs_used)>
+
+Calculate size of Context.
+
+=cut
+
+*/
+size_t
+Parrot_pcc_calculate_context_size(SHIM_INTERP, ARGIN(const UINTVAL *number_regs_used))
+{
+    ASSERT_ARGS(Parrot_pcc_calculate_context_size)
+
+    return ALIGNED_CTX_SIZE + ROUND_ALLOC_SIZE(
+            sizeof (INTVAL)   * number_regs_used[REGNO_INT] +
+            sizeof (FLOATVAL) * number_regs_used[REGNO_NUM] +
+            sizeof (STRING *) * number_regs_used[REGNO_STR] +
+            sizeof (PMC *)    * number_regs_used[REGNO_PMC]);
+}
+
+/*
+
+=item C<PMC * Parrot_alloc_context(PARROT_INTERP, const INTVAL
+*number_regs_used, PMC *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
+PMC *
+Parrot_alloc_context(PARROT_INTERP, ARGIN(const INTVAL *number_regs_used),
+    ARGIN_NULLOK(PMC *old))
+{
+    ASSERT_ARGS(Parrot_alloc_context)
+    PMC            *pmcctx;
+    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 size_t to_alloc = reg_alloc + ALIGNED_CTX_SIZE;
+
+#ifdef GC_USE_FIXED_SIZE_ALLOCATOR
+    ctx  = (Parrot_Context *)Parrot_gc_allocate_fixed_size_storage(interp, to_alloc);
+#else
+    ctx  = (Parrot_Context *)mem_sys_allocate(to_alloc);
+#endif
+
+    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];
+
+    /* 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);
+
+    pmcctx = pmc_new(interp, enum_class_Context);
+    VTABLE_set_pointer(interp, pmcctx, ctx);
+
+    init_context(interp, pmcctx, old);
+
+    return pmcctx;
+}
+
+
+/*
+
+=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
+register usage C<n_regs_used> is copied.
+
+=cut
+
+*/
+
+PARROT_CANNOT_RETURN_NULL
+PARROT_WARN_UNUSED_RESULT
+PMC *
+Parrot_set_new_context(PARROT_INTERP, ARGIN(const INTVAL *number_regs_used))
+{
+    ASSERT_ARGS(Parrot_set_new_context)
+    PMC *old = CURRENT_CONTEXT(interp);
+    PMC *ctx = Parrot_alloc_context(interp, number_regs_used, old);
+
+    CURRENT_CONTEXT(interp) = ctx;
+
+    return ctx;
+}
+
+
+/*
+
+=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)
+    UINTVAL i;
+    for (i = 0; i < Parrot_pcc_get_regs_used(interp, CURRENT_CONTEXT(interp), 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)
+    UINTVAL i;
+    for (i = 0; i < Parrot_pcc_get_regs_used(interp, CURRENT_CONTEXT(interp), 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)
+    UINTVAL i;
+    for (i = 0; i < Parrot_pcc_get_regs_used(interp, CURRENT_CONTEXT(interp), 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)
+    UINTVAL i;
+    for (i = 0; i < Parrot_pcc_get_regs_used(interp, CURRENT_CONTEXT(interp), REGNO_NUM); ++i)
+        REG_NUM(interp, i) = 0.0;
+}
+
+/*
+
+=item C<INTVAL * Parrot_pcc_get_INTVAL_reg(PARROT_INTERP, PMC *ctx, UINTVAL
+idx)>
+
+Get pointer to INTVAL register.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+PARROT_CANNOT_RETURN_NULL
+INTVAL *
+Parrot_pcc_get_INTVAL_reg(PARROT_INTERP, ARGIN(PMC *ctx), UINTVAL idx)
+{
+    ASSERT_ARGS(Parrot_pcc_get_INTVAL_reg)
+    PARROT_ASSERT(Parrot_pcc_get_regs_used(interp, ctx, REGNO_INT) > idx);
+    return &(Parrot_pcc_get_context_struct(interp, ctx)->bp.regs_i[idx]);
+}
+
+/*
+
+=item C<FLOATVAL * Parrot_pcc_get_FLOATVAL_reg(PARROT_INTERP, PMC *ctx, UINTVAL
+idx)>
+
+Get pointer to FLOATVAL register.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+PARROT_CANNOT_RETURN_NULL
+FLOATVAL *
+Parrot_pcc_get_FLOATVAL_reg(PARROT_INTERP, ARGIN(PMC *ctx), UINTVAL idx)
+{
+    ASSERT_ARGS(Parrot_pcc_get_FLOATVAL_reg)
+    PARROT_ASSERT(Parrot_pcc_get_regs_used(interp, ctx, REGNO_NUM) > idx);
+    return &(Parrot_pcc_get_context_struct(interp, ctx)->bp.regs_n[-1L - idx]);
+}
+
+/*
+
+=item C<STRING ** Parrot_pcc_get_STRING_reg(PARROT_INTERP, PMC *ctx, UINTVAL
+idx)>
+
+Get pointer to STRING register.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+PARROT_CANNOT_RETURN_NULL
+STRING **
+Parrot_pcc_get_STRING_reg(PARROT_INTERP, ARGIN(PMC *ctx), UINTVAL idx)
+{
+    ASSERT_ARGS(Parrot_pcc_get_STRING_reg)
+    PARROT_ASSERT(Parrot_pcc_get_regs_used(interp, ctx, REGNO_STR) > idx);
+    return &(Parrot_pcc_get_context_struct(interp, ctx)->bp_ps.regs_s[idx]);
+}
+
+/*
+
+=item C<PMC ** Parrot_pcc_get_PMC_reg(PARROT_INTERP, PMC *ctx, UINTVAL idx)>
+
+Get pointer to PMC register.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+PARROT_CANNOT_RETURN_NULL
+PMC **
+Parrot_pcc_get_PMC_reg(PARROT_INTERP, ARGIN(PMC *ctx), UINTVAL idx)
+{
+    ASSERT_ARGS(Parrot_pcc_get_PMC_reg)
+    PARROT_ASSERT(Parrot_pcc_get_regs_used(interp, ctx, REGNO_PMC) > idx);
+    return &(Parrot_pcc_get_context_struct(interp, ctx)->bp_ps.regs_p[-1L - idx]);
+}
+
+/*
+
+=item C<UINTVAL Parrot_pcc_get_regs_used(PARROT_INTERP, PMC *ctx, int type)>
+
+Return number of used registers of particular type.
+
+=cut
+
+*/
+PARROT_EXPORT
+UINTVAL
+Parrot_pcc_get_regs_used(PARROT_INTERP, ARGIN(PMC *ctx), int type)
+{
+    ASSERT_ARGS(Parrot_pcc_get_regs_used)
+    return Parrot_pcc_get_context_struct(interp, ctx)->n_regs_used[type];
+}
+
+/*
+
+=item C<void Parrot_pcc_set_regs_used(PARROT_INTERP, PMC *ctx, int type, INTVAL
+num)>
+
+Set number of used registers of particular type.
+
+=cut
+
+*/
+PARROT_EXPORT
+void
+Parrot_pcc_set_regs_used(PARROT_INTERP, ARGIN(PMC *ctx), int type, INTVAL num)
+{
+    ASSERT_ARGS(Parrot_pcc_set_regs_used)
+    Parrot_pcc_get_context_struct(interp, ctx)->n_regs_used[type] = num;
+}
+
+/*
+
+=item C<Regs_ni* Parrot_pcc_get_regs_ni(PARROT_INTERP, PMC *ctx)>
+
+Get pointer to FLOANFAL and INTVAL registers.
+
+=cut
+
+*/
+PARROT_EXPORT
+PARROT_CANNOT_RETURN_NULL
+Regs_ni*
+Parrot_pcc_get_regs_ni(PARROT_INTERP, ARGIN(PMC *ctx))
+{
+    ASSERT_ARGS(Parrot_pcc_get_regs_ni)
+    return &(Parrot_pcc_get_context_struct(interp, ctx)->bp);
+}
+
+/*
+
+=item C<void Parrot_pcc_set_regs_ni(PARROT_INTERP, PMC *ctx, Regs_ni *bp)>
+
+Copy Regs_ni into Context.
+
+=cut
+
+*/
+PARROT_EXPORT
+PARROT_CANNOT_RETURN_NULL
+void
+Parrot_pcc_set_regs_ni(PARROT_INTERP, ARGIN(PMC *ctx), ARGIN(Regs_ni *bp))
+{
+    ASSERT_ARGS(Parrot_pcc_set_regs_ni)
+    Parrot_pcc_get_context_struct(interp, ctx)->bp = *bp;
+}
+
+/*
+
+=item C<Regs_ps* Parrot_pcc_get_regs_ps(PARROT_INTERP, PMC *ctx)>
+
+Get pointer to PMC and STRING registers.
+
+=cut
+
+*/
+PARROT_EXPORT
+PARROT_CANNOT_RETURN_NULL
+Regs_ps*
+Parrot_pcc_get_regs_ps(PARROT_INTERP, ARGIN(PMC *ctx))
+{
+    ASSERT_ARGS(Parrot_pcc_get_regs_ps)
+    return &(Parrot_pcc_get_context_struct(interp, ctx)->bp_ps);
+}
+
+/*
+
+=item C<void Parrot_pcc_set_regs_ps(PARROT_INTERP, PMC *ctx, Regs_ps *bp_ps)>
+
+Copy Regs_ps into Context.
+
+=cut
+
+*/
+PARROT_EXPORT
+PARROT_CANNOT_RETURN_NULL
+void
+Parrot_pcc_set_regs_ps(PARROT_INTERP, ARGIN(PMC *ctx), ARGIN(Regs_ps *bp_ps))
+{
+    ASSERT_ARGS(Parrot_pcc_set_regs_ps)
+    Parrot_pcc_get_context_struct(interp, ctx)->bp_ps = *bp_ps;
+}
+
+
+/*
+
 =back
 
 */

Modified: trunk/src/gc/alloc_register.c
==============================================================================
--- trunk/src/gc/alloc_register.c	Mon Sep  7 12:38:04 2009	(r41109)
+++ trunk/src/gc/alloc_register.c	Mon Sep  7 13:22:34 2009	(r41110)
@@ -17,677 +17,8 @@
 
 */
 
-#include "parrot/parrot.h"
-#include "parrot/register.h"
-#include "../pmc/pmc_sub.h"
-
-
-/* set CTX_LEAK_DEBUG_FULL to 1 for enhanced context debugging.
- * When set (1) freed contexts are "poisoned" so that any dangling
- * references produce segfaults, and (2) contexts are not recycled
- * so that later allocations don't suddenly restore a dangling
- * reference to a "working" condition.
- */
-#define CTX_LEAK_DEBUG_FULL 0
-
-
-
 /* 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(PMC *pmcctx))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        FUNC_MODIFIES(*pmcctx);
-
-static void init_context(PARROT_INTERP,
-    ARGMOD(PMC *pmcctx),
-    ARGIN_NULLOK(PMC *pmcold))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        FUNC_MODIFIES(*pmcctx);
-
-#define ASSERT_ARGS_clear_regs __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(pmcctx)
-#define ASSERT_ARGS_init_context __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(pmcctx)
-/* 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
-
-*/
-
-
-#define ALIGNED_CTX_SIZE (((sizeof (Parrot_Context) + NUMVAL_SIZE - 1) \
-        / NUMVAL_SIZE) * NUMVAL_SIZE)
-
-/*
-
-=pod
-
-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.
-
-=cut
-
-*/
-
-#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)
-
-/*
-
-=head2 Context and Register Allocation Functions
-
-=over 4
-
-=cut
-
-*/
-
-
-/*
-
-=item C<void create_initial_context(PARROT_INTERP)>
-
-Creates the interpreter's initial context.
-
-=cut
-
-*/
-
-void
-create_initial_context(PARROT_INTERP)
-{
-    ASSERT_ARGS(create_initial_context)
-    static INTVAL   num_regs[] = {32, 32, 32, 32};
-    PMC *ignored;
-
-    /* Create some initial free_list slots. */
-
-#define INITIAL_FREE_SLOTS 8
-    /* 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<static void clear_regs(PARROT_INTERP, PMC *pmcctx)>
-
-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(PMC *pmcctx))
-{
-    ASSERT_ARGS(clear_regs)
-    UINTVAL i;
-    Parrot_Context *ctx = Parrot_pcc_get_context_struct(interp, pmcctx);
-
-    /* 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->bp_ps.regs_p[-1L - i] = PMCNULL;
-    }
-
-    for (i = 0; i < ctx->n_regs_used[REGNO_STR]; i++) {
-        ctx->bp_ps.regs_s[i] = NULL;
-    }
-
-    if (Interp_debug_TEST(interp, PARROT_REG_DEBUG_FLAG)) {
-        /* depending on -D40, set int and num to identifiable garbage values */
-        for (i = 0; i < ctx->n_regs_used[REGNO_INT]; i++) {
-            ctx->bp.regs_i[i] = -999;
-        }
-
-        for (i = 0; i < ctx->n_regs_used[REGNO_NUM]; i++) {
-            ctx->bp.regs_n[-1L - i] = -99.9;
-        }
-    }
-}
-
-
-/*
-
-=item C<static void init_context(PARROT_INTERP, PMC *pmcctx, PMC *pmcold)>
-
-Initializes a freshly allocated or recycled context.
-
-=cut
-
-*/
-
-static void
-init_context(PARROT_INTERP, ARGMOD(PMC *pmcctx), ARGIN_NULLOK(PMC *pmcold))
-{
-    ASSERT_ARGS(init_context)
-    Parrot_Context *ctx = Parrot_pcc_get_context_struct(interp, pmcctx);
-    Parrot_Context *old = Parrot_pcc_get_context_struct(interp, pmcold);
-
-    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;
-    ctx->pred_offset       = 0;
-
-    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, pmcctx);
-}
-
-
-/*
-
-=item C<PMC * 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
-PMC *
-Parrot_push_context(PARROT_INTERP, ARGIN(const INTVAL *n_regs_used))
-{
-    ASSERT_ARGS(Parrot_push_context)
-    PMC * const old = CURRENT_CONTEXT(interp);
-    PMC * const ctx = Parrot_set_new_context(interp, n_regs_used);
-
-    Parrot_pcc_set_caller_ctx(interp, ctx, old);
-
-    /* doesn't change */
-    Parrot_pcc_set_sub(interp, ctx, Parrot_pcc_get_sub(interp, old));
-
-    /* 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)
-    PMC * const ctx = CURRENT_CONTEXT(interp);
-    PMC * const old = Parrot_pcc_get_caller_ctx(interp, ctx);
-
-    /* restore old, set cached interpreter base pointers */
-    CURRENT_CONTEXT(interp) = old;
-}
-
-/*
-
-=item C<size_t Parrot_pcc_calculate_context_size(PARROT_INTERP, const UINTVAL
-*number_regs_used)>
-
-Calculate size of Context.
-
-=cut
-
-*/
-size_t
-Parrot_pcc_calculate_context_size(SHIM_INTERP, ARGIN(const UINTVAL *number_regs_used))
-{
-    ASSERT_ARGS(Parrot_pcc_calculate_context_size)
-
-    return ALIGNED_CTX_SIZE + ROUND_ALLOC_SIZE(
-            sizeof (INTVAL)   * number_regs_used[REGNO_INT] +
-            sizeof (FLOATVAL) * number_regs_used[REGNO_NUM] +
-            sizeof (STRING *) * number_regs_used[REGNO_STR] +
-            sizeof (PMC *)    * number_regs_used[REGNO_PMC]);
-}
-
-/*
-
-=item C<PMC * Parrot_alloc_context(PARROT_INTERP, const INTVAL
-*number_regs_used, PMC *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
-PMC *
-Parrot_alloc_context(PARROT_INTERP, ARGIN(const INTVAL *number_regs_used),
-    ARGIN_NULLOK(PMC *old))
-{
-    ASSERT_ARGS(Parrot_alloc_context)
-    PMC            *pmcctx;
-    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 size_t to_alloc = reg_alloc + ALIGNED_CTX_SIZE;
-
-#ifdef GC_USE_FIXED_SIZE_ALLOCATOR
-    ctx  = (Parrot_Context *)Parrot_gc_allocate_fixed_size_storage(interp, to_alloc);
-#else
-    ctx  = (Parrot_Context *)mem_sys_allocate(to_alloc);
-#endif
-
-    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];
-
-    /* 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);
-
-    pmcctx = pmc_new(interp, enum_class_Context);
-    VTABLE_set_pointer(interp, pmcctx, ctx);
-
-    init_context(interp, pmcctx, old);
-
-    return pmcctx;
-}
-
-
-/*
-
-=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
-register usage C<n_regs_used> is copied.
-
-=cut
-
-*/
-
-PARROT_CANNOT_RETURN_NULL
-PARROT_WARN_UNUSED_RESULT
-PMC *
-Parrot_set_new_context(PARROT_INTERP, ARGIN(const INTVAL *number_regs_used))
-{
-    ASSERT_ARGS(Parrot_set_new_context)
-    PMC *old = CURRENT_CONTEXT(interp);
-    PMC *ctx = Parrot_alloc_context(interp, number_regs_used, old);
-
-    CURRENT_CONTEXT(interp) = ctx;
-
-    return ctx;
-}
-
-
-/*
-
-=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)
-    UINTVAL i;
-    for (i = 0; i < Parrot_pcc_get_regs_used(interp, CURRENT_CONTEXT(interp), 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)
-    UINTVAL i;
-    for (i = 0; i < Parrot_pcc_get_regs_used(interp, CURRENT_CONTEXT(interp), 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)
-    UINTVAL i;
-    for (i = 0; i < Parrot_pcc_get_regs_used(interp, CURRENT_CONTEXT(interp), 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)
-    UINTVAL i;
-    for (i = 0; i < Parrot_pcc_get_regs_used(interp, CURRENT_CONTEXT(interp), REGNO_NUM); ++i)
-        REG_NUM(interp, i) = 0.0;
-}
-
-/*
-
-=item C<INTVAL * Parrot_pcc_get_INTVAL_reg(PARROT_INTERP, PMC *ctx, UINTVAL
-idx)>
-
-Get pointer to INTVAL register.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-PARROT_CANNOT_RETURN_NULL
-INTVAL *
-Parrot_pcc_get_INTVAL_reg(PARROT_INTERP, ARGIN(PMC *ctx), UINTVAL idx)
-{
-    ASSERT_ARGS(Parrot_pcc_get_INTVAL_reg)
-    PARROT_ASSERT(Parrot_pcc_get_regs_used(interp, ctx, REGNO_INT) > idx);
-    return &(Parrot_pcc_get_context_struct(interp, ctx)->bp.regs_i[idx]);
-}
-
-/*
-
-=item C<FLOATVAL * Parrot_pcc_get_FLOATVAL_reg(PARROT_INTERP, PMC *ctx, UINTVAL
-idx)>
-
-Get pointer to FLOATVAL register.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-PARROT_CANNOT_RETURN_NULL
-FLOATVAL *
-Parrot_pcc_get_FLOATVAL_reg(PARROT_INTERP, ARGIN(PMC *ctx), UINTVAL idx)
-{
-    ASSERT_ARGS(Parrot_pcc_get_FLOATVAL_reg)
-    PARROT_ASSERT(Parrot_pcc_get_regs_used(interp, ctx, REGNO_NUM) > idx);
-    return &(Parrot_pcc_get_context_struct(interp, ctx)->bp.regs_n[-1L - idx]);
-}
-
-/*
-
-=item C<STRING ** Parrot_pcc_get_STRING_reg(PARROT_INTERP, PMC *ctx, UINTVAL
-idx)>
-
-Get pointer to STRING register.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-PARROT_CANNOT_RETURN_NULL
-STRING **
-Parrot_pcc_get_STRING_reg(PARROT_INTERP, ARGIN(PMC *ctx), UINTVAL idx)
-{
-    ASSERT_ARGS(Parrot_pcc_get_STRING_reg)
-    PARROT_ASSERT(Parrot_pcc_get_regs_used(interp, ctx, REGNO_STR) > idx);
-    return &(Parrot_pcc_get_context_struct(interp, ctx)->bp_ps.regs_s[idx]);
-}
-
-/*
-
-=item C<PMC ** Parrot_pcc_get_PMC_reg(PARROT_INTERP, PMC *ctx, UINTVAL idx)>
-
-Get pointer to PMC register.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-PARROT_CANNOT_RETURN_NULL
-PMC **
-Parrot_pcc_get_PMC_reg(PARROT_INTERP, ARGIN(PMC *ctx), UINTVAL idx)
-{
-    ASSERT_ARGS(Parrot_pcc_get_PMC_reg)
-    PARROT_ASSERT(Parrot_pcc_get_regs_used(interp, ctx, REGNO_PMC) > idx);
-    return &(Parrot_pcc_get_context_struct(interp, ctx)->bp_ps.regs_p[-1L - idx]);
-}
-
-/*
-
-=item C<UINTVAL Parrot_pcc_get_regs_used(PARROT_INTERP, PMC *ctx, int type)>
-
-Return number of used registers of particular type.
-
-=cut
-
-*/
-PARROT_EXPORT
-UINTVAL
-Parrot_pcc_get_regs_used(PARROT_INTERP, ARGIN(PMC *ctx), int type)
-{
-    ASSERT_ARGS(Parrot_pcc_get_regs_used)
-    return Parrot_pcc_get_context_struct(interp, ctx)->n_regs_used[type];
-}
-
-/*
-
-=item C<void Parrot_pcc_set_regs_used(PARROT_INTERP, PMC *ctx, int type, INTVAL
-num)>
-
-Set number of used registers of particular type.
-
-=cut
-
-*/
-PARROT_EXPORT
-void
-Parrot_pcc_set_regs_used(PARROT_INTERP, ARGIN(PMC *ctx), int type, INTVAL num)
-{
-    ASSERT_ARGS(Parrot_pcc_set_regs_used)
-    Parrot_pcc_get_context_struct(interp, ctx)->n_regs_used[type] = num;
-}
-
-/*
-
-=item C<Regs_ni* Parrot_pcc_get_regs_ni(PARROT_INTERP, PMC *ctx)>
-
-Get pointer to FLOANFAL and INTVAL registers.
-
-=cut
-
-*/
-PARROT_EXPORT
-PARROT_CANNOT_RETURN_NULL
-Regs_ni*
-Parrot_pcc_get_regs_ni(PARROT_INTERP, ARGIN(PMC *ctx))
-{
-    ASSERT_ARGS(Parrot_pcc_get_regs_ni)
-    return &(Parrot_pcc_get_context_struct(interp, ctx)->bp);
-}
-
-/*
-
-=item C<void Parrot_pcc_set_regs_ni(PARROT_INTERP, PMC *ctx, Regs_ni *bp)>
-
-Copy Regs_ni into Context.
-
-=cut
-
-*/
-PARROT_EXPORT
-PARROT_CANNOT_RETURN_NULL
-void
-Parrot_pcc_set_regs_ni(PARROT_INTERP, ARGIN(PMC *ctx), ARGIN(Regs_ni *bp))
-{
-    ASSERT_ARGS(Parrot_pcc_set_regs_ni)
-    Parrot_pcc_get_context_struct(interp, ctx)->bp = *bp;
-}
-
-/*
-
-=item C<Regs_ps* Parrot_pcc_get_regs_ps(PARROT_INTERP, PMC *ctx)>
-
-Get pointer to PMC and STRING registers.
-
-=cut
-
-*/
-PARROT_EXPORT
-PARROT_CANNOT_RETURN_NULL
-Regs_ps*
-Parrot_pcc_get_regs_ps(PARROT_INTERP, ARGIN(PMC *ctx))
-{
-    ASSERT_ARGS(Parrot_pcc_get_regs_ps)
-    return &(Parrot_pcc_get_context_struct(interp, ctx)->bp_ps);
-}
-
-/*
-
-=item C<void Parrot_pcc_set_regs_ps(PARROT_INTERP, PMC *ctx, Regs_ps *bp_ps)>
-
-Copy Regs_ps into Context.
-
-=cut
-
-*/
-PARROT_EXPORT
-PARROT_CANNOT_RETURN_NULL
-void
-Parrot_pcc_set_regs_ps(PARROT_INTERP, ARGIN(PMC *ctx), ARGIN(Regs_ps *bp_ps))
-{
-    ASSERT_ARGS(Parrot_pcc_set_regs_ps)
-    Parrot_pcc_get_context_struct(interp, ctx)->bp_ps = *bp_ps;
-}
 /*
 
 =back


More information about the parrot-commits mailing list