[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