[svn:parrot] r40592 - in branches/context_pmc2: include/parrot src src/gc src/pmc
whiteknight at svn.parrot.org
whiteknight at svn.parrot.org
Sun Aug 16 12:50:26 UTC 2009
Author: whiteknight
Date: Sun Aug 16 12:50:24 2009
New Revision: 40592
URL: https://trac.parrot.org/parrot/changeset/40592
Log:
[pmc_context2] create a skeleton PMC type for Context that is only a simple wrapper around the Parrot_Context* structure
Added:
branches/context_pmc2/src/pmc/context.pmc
Modified:
branches/context_pmc2/include/parrot/interpreter.h
branches/context_pmc2/src/gc/alloc_register.c
branches/context_pmc2/src/pmc/continuation.pmc
branches/context_pmc2/src/pmc/sub.pmc
branches/context_pmc2/src/sub.c
Modified: branches/context_pmc2/include/parrot/interpreter.h
==============================================================================
--- branches/context_pmc2/include/parrot/interpreter.h Sun Aug 16 12:02:49 2009 (r40591)
+++ branches/context_pmc2/include/parrot/interpreter.h Sun Aug 16 12:50:24 2009 (r40592)
@@ -195,14 +195,14 @@
struct Parrot_Context {
/* common header with Interp_Context */
- struct Parrot_Context *caller_ctx; /* caller context */
+ PMC *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 */
+ PMC *lex_pad; /* LexPad PMC */
+ PMC *outer_ctx; /* outer context, if a closure */
/* new call scheme and introspective variables */
PMC *current_sub; /* the Sub we are executing */
@@ -221,8 +221,6 @@
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 */
@@ -250,21 +248,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) (Parrot_ctx_get_context_struct((interp)->ctx))
#define CHUNKED_CTX_MEM 0 /* no longer works, but will be reinstated
* some day; see src/register.c for details.
@@ -303,7 +287,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_pmc2/src/gc/alloc_register.c
==============================================================================
--- branches/context_pmc2/src/gc/alloc_register.c Sun Aug 16 12:02:49 2009 (r40591)
+++ branches/context_pmc2/src/gc/alloc_register.c Sun Aug 16 12:50:24 2009 (r40592)
@@ -19,6 +19,7 @@
#include "parrot/parrot.h"
#include "parrot/register.h"
+#include "../pmc/pmc_context.h"
#include "../pmc/pmc_sub.h"
@@ -146,6 +147,22 @@
/*
+=item C<Parrot_Context * Parrot_ctx_get_context_struct(PARROT_INTERP, PMC * context)>
+
+=cut
+
+*/
+
+PARROT_CAN_RETURN_NULL
+Parrot_Context *
+Parrot_ctx_get_context_struct(PARROT_INTERP, ARGIN(PMC * context))
+{
+ ASSERT_ARGS(Parrot_ctx_get_context_struct)
+ return PARROT_CONTEXT(context);
+}
+
+/*
+
=item C<void destroy_context(PARROT_INTERP)>
Frees allocated context memory.
@@ -247,103 +264,6 @@
}
-/*
-
-=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);
-}
-
/*
@@ -412,105 +332,6 @@
interp->ctx.bp_ps = old->bp_ps;
}
-
-/*
-
-=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];
-
-#if CTX_LEAK_DEBUG
- if (Interp_debug_TEST(interp, PARROT_CTX_DESTROY_DEBUG_FLAG)) {
- fprintf(stderr, "[alloc ctx %p]\n", ctx);
- }
-#endif
-
- 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
@@ -540,112 +361,6 @@
}
-/*
-
-=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.
- * To trace context handling and check for leaks,
- * (a) disable NDEBUG, (b) enable CTX_LEAK_DEBUG in interpreter.h,
- * and (c) execute "debug 0x80" in a (preferably small) test case.
- *
- */
- if (deref) {
-#if CTX_LEAK_DEBUG
- if (Interp_debug_TEST(interp, PARROT_CTX_DESTROY_DEBUG_FLAG)) {
- fprintf(stderr, "[reference to context %p released]\n", (void*)ctx);
- }
-#endif
- 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;
-
-#if CTX_LEAK_DEBUG_FULL
- /* for debugging, poison the freed context in case anything
- * tries to use it later. */
- ctx->current_results = (opcode_t *)0xbeefcafe;
- ctx->results_signature = (PMC *)0xbeefcafe;
- ctx->lex_pad = (PMC *)0xbeefcafe;
- ctx->outer_ctx = (Parrot_Context *)0xbeefcafe;
- ctx->current_cont = (PMC *)0xbeefcafe;
- ctx->current_object = (PMC *)0xbeefcafe;
- ctx->current_HLL = -1;
- ctx->handlers = (PMC *)0xbeefcafe;
- ctx->constants = (struct PackFile_Constant **)0xbeefcafe;
- ctx->current_namespace = (PMC *)0xbeefcafe;
-#endif
-
- /* 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);
-
-#if CTX_LEAK_DEBUG_FULL
- slot = 0;
-#endif
-
- PARROT_ASSERT(slot < interp->ctx_mem.n_free_slots);
- *(void **)ptr = interp->ctx_mem.free_list[slot];
- interp->ctx_mem.free_list[slot] = ptr;
- }
-}
/*
Added: branches/context_pmc2/src/pmc/context.pmc
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ branches/context_pmc2/src/pmc/context.pmc Sun Aug 16 12:50:24 2009 (r40592)
@@ -0,0 +1,331 @@
+/*
+
+=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))
+{
+ ASSERT_ARGS(init_context)
+ 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->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_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];
+
+#if CTX_LEAK_DEBUG
+ if (Interp_debug_TEST(interp, PARROT_CTX_DESTROY_DEBUG_FLAG)) {
+ fprintf(stderr, "[alloc ctx %p]\n", ctx);
+ }
+#endif
+
+ 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<void Parrot_free_context(PARROT_INTERP, Parrot_Context *ctx, int deref)>
+
+Frees the context.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+void
+Parrot_free_context(PARROT_INTERP, ARGMOD(Parrot_Context *ctx))
+{
+ ASSERT_ARGS(Parrot_free_context)
+
+ 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
+
+ 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;
+
+#if CTX_LEAK_DEBUG_FULL
+ /* for debugging, poison the freed context in case anything
+ * tries to use it later. */
+ ctx->current_results = (opcode_t *)0xbeefcafe;
+ ctx->results_signature = (PMC *)0xbeefcafe;
+ ctx->lex_pad = (PMC *)0xbeefcafe;
+ ctx->outer_ctx = (Parrot_Context *)0xbeefcafe;
+ ctx->current_cont = (PMC *)0xbeefcafe;
+ ctx->current_object = (PMC *)0xbeefcafe;
+ ctx->current_HLL = -1;
+ ctx->handlers = (PMC *)0xbeefcafe;
+ ctx->constants = (struct PackFile_Constant **)0xbeefcafe;
+ ctx->current_namespace = (PMC *)0xbeefcafe;
+#endif
+
+ /* 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);
+
+#if CTX_LEAK_DEBUG_FULL
+ slot = 0;
+#endif
+
+ PARROT_ASSERT(slot < interp->ctx_mem.n_free_slots);
+ *(void **)ptr = interp->ctx_mem.free_list[slot];
+ interp->ctx_mem.free_list[slot] = ptr;
+}
+
+pmclass Context {
+ ATTR Parrot_Context * ctx;
+
+ VTABLE void init()
+ {
+ Parrot_Context_attributes * const attrs = mem_sys_allocate_typed(Parrot_Context_attributes);
+ Parrot_Context * const ctx = mem_sys_allocate_typed(Parrot_Context);
+ init_context(INTERP, ctx);
+ attrs->ctx = ctx;
+ PMC_DATA(SELF) = attrs;
+ }
+
+ VTABLE void mark()
+ {
+ Parrot_Context * const ctx = PARROT_CONTEXT(SELF)->ctx;
+ PObj *obj;
+ int i;
+
+ obj = (PObj *)ctx->current_sub;
+ if (obj)
+ Parrot_gc_mark_PObj_alive(interp, obj);
+
+ obj = (PObj *)ctx->current_object;
+ if (obj)
+ Parrot_gc_mark_PObj_alive(interp, obj);
+
+ obj = (PObj *)ctx->current_cont;
+ if (obj && !PObj_live_TEST(obj))
+ Parrot_gc_mark_PObj_alive(interp, obj);
+
+ obj = (PObj *)ctx->caller_ctx;
+ if (obj)
+ Parrot_gc_mark_PObj_alive(interp, obj);
+
+ obj = (PObj *)ctx->outer_ctx;
+ if (obj)
+ Parrot_gc_mark_PObj_alive(interp, obj);
+
+ obj = (PObj *)ctx->current_namespace;
+ if (obj)
+ Parrot_gc_mark_PObj_alive(interp, obj);
+
+ obj = (PObj *)ctx->lex_pad;
+ if (obj)
+ Parrot_gc_mark_PObj_alive(interp, obj);
+
+ obj = (PObj *)ctx->handlers;
+ if (obj)
+ Parrot_gc_mark_PObj_alive(interp, obj);
+
+ if (!ctx->n_regs_used)
+ return;
+
+ for (i = 0; i < ctx->n_regs_used[REGNO_PMC]; ++i) {
+ obj = (PObj *)CTX_REG_PMC(ctx, i);
+ if (obj)
+ Parrot_gc_mark_PObj_alive(interp, obj);
+ }
+
+ for (i = 0; i < ctx->n_regs_used[REGNO_STR]; ++i) {
+ obj = (PObj *)CTX_REG_STR(ctx, i);
+ if (obj)
+ Parrot_gc_mark_PObj_alive(interp, obj);
+ }
+ }
+
+ VTABLE void destroy()
+ {
+ Parrot_Context_attributes * const attrs = PARROT_CONTEXT(SELF);
+ Parrot_Context * const ctx = attrs->ctx;
+ Parrot_free_context(INTERP, ctx);
+ mem_sys_free(ctx);
+ mem_sys_free(attrs);
+ }
+}
Modified: branches/context_pmc2/src/pmc/continuation.pmc
==============================================================================
--- branches/context_pmc2/src/pmc/continuation.pmc Sun Aug 16 12:02:49 2009 (r40591)
+++ branches/context_pmc2/src/pmc/continuation.pmc Sun Aug 16 12:50:24 2009 (r40592)
@@ -89,9 +89,9 @@
Parrot_cont *cc = PMC_cont(SELF);
if (cc->to_ctx)
- mark_context(INTERP, cc->to_ctx);
+ Parrot_gc_mark_PObj_alive(INTERP, (PObj *) cc->to_ctx);
if (cc->from_ctx)
- mark_context(INTERP, cc->from_ctx);
+ Parrot_gc_mark_PObj_alive(INTERP, (PObj *) cc->from_ctx);
}
/*
Modified: branches/context_pmc2/src/pmc/sub.pmc
==============================================================================
--- branches/context_pmc2/src/pmc/sub.pmc Sun Aug 16 12:02:49 2009 (r40591)
+++ branches/context_pmc2/src/pmc/sub.pmc Sun Aug 16 12:50:24 2009 (r40592)
@@ -504,9 +504,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_pmc2/src/sub.c
==============================================================================
--- branches/context_pmc2/src/sub.c Sun Aug 16 12:02:49 2009 (r40591)
+++ branches/context_pmc2/src/sub.c Sun Aug 16 12:50:24 2009 (r40592)
@@ -26,105 +26,6 @@
/* HEADERIZER HFILE: include/parrot/sub.h */
-
-/*
-
-=item C<void mark_context_start(void)>
-
-Indicate that a new round of context marking is about to take place.
-
-=cut
-
-*/
-
-static int context_gc_mark = 0;
-
-void
-mark_context_start(void)
-{
- ASSERT_ARGS(mark_context_start)
- if (++context_gc_mark == 0) context_gc_mark = 1;
-}
-
-
-/*
-
-=item C<void mark_context(PARROT_INTERP, Parrot_Context* ctx)>
-
-Marks the context C<*ctx>.
-
-=cut
-
-*/
-
-void
-mark_context(PARROT_INTERP, ARGMOD(Parrot_Context* ctx))
-{
- ASSERT_ARGS(mark_context)
- PObj *obj;
- int i;
-
- if (ctx->gc_mark == context_gc_mark)
- return;
- ctx->gc_mark = context_gc_mark;
-
- /* don't mark the context if it's actually dead */
- if (ctx->ref_count < 0) {
- /* report it, though */
- if (Interp_debug_TEST(interp, PARROT_CTX_DESTROY_DEBUG_FLAG)) {
- fprintf(stderr, "[attempt to mark dead context %p]\n",
- (void *)ctx);
- }
- return;
- }
-
- obj = (PObj *)ctx->current_sub;
- if (obj)
- Parrot_gc_mark_PObj_alive(interp, obj);
-
- obj = (PObj *)ctx->current_object;
- if (obj)
- Parrot_gc_mark_PObj_alive(interp, obj);
-
- obj = (PObj *)ctx->current_cont;
- if (obj && !PObj_live_TEST(obj))
- Parrot_gc_mark_PObj_alive(interp, obj);
-
- if (ctx->caller_ctx)
- mark_context(interp, ctx->caller_ctx);
-
- if (ctx->outer_ctx)
- mark_context(interp, ctx->outer_ctx);
-
- obj = (PObj *)ctx->current_namespace;
- if (obj)
- Parrot_gc_mark_PObj_alive(interp, obj);
-
- obj = (PObj *)ctx->lex_pad;
- if (obj)
- Parrot_gc_mark_PObj_alive(interp, obj);
-
- obj = (PObj *)ctx->handlers;
- if (obj)
- Parrot_gc_mark_PObj_alive(interp, obj);
-
-
- if (!ctx->n_regs_used)
- return;
-
- for (i = 0; i < ctx->n_regs_used[REGNO_PMC]; ++i) {
- obj = (PObj *)CTX_REG_PMC(ctx, i);
- if (obj)
- Parrot_gc_mark_PObj_alive(interp, obj);
- }
-
- for (i = 0; i < ctx->n_regs_used[REGNO_STR]; ++i) {
- obj = (PObj *)CTX_REG_STR(ctx, i);
- if (obj)
- Parrot_gc_mark_PObj_alive(interp, obj);
- }
-}
-
/*
=item C<Parrot_sub * new_sub(PARROT_INTERP)>
More information about the parrot-commits
mailing list