Skip to content

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also .

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also .
...
Checking mergeability… Don’t worry, you can still create the pull request.
  • 6 commits
  • 6 files changed
  • 0 commit comments
  • 1 contributor
Commits on Sep 26, 2011
@Whiteknight Whiteknight Add in the naive basics of GC anchoring for precise GC fc619a6
@Whiteknight Whiteknight Add in a header flag for whether we turn on the precise GC or not. a2f669b
@Whiteknight Whiteknight Add in support for anchoring strings. Parrot builds and runs fine in …
…GC_USE_PRECISE modes 0 and 1
117bd2e
@Whiteknight Whiteknight In GC_USE_PRECISE==1, print out some debug messages in trace_system_a…
…reas when we find an unanchored PMC or STRING. We can use that output to help narrow down occurances.
add0f24
@Whiteknight Whiteknight Add in a new macro which I think looks prettier. Several fixes. Conve…
…rt two functions in namespace.c to use the new system, even if they aren't good, representative functions to have converted.
4e40dc3
Commits on Dec 06, 2011
@Whiteknight Whiteknight Merge from master, fix conflicts 1501575
Showing with 188 additions and 30 deletions.
  1. +106 −0 include/parrot/gc_api.h
  2. +1 −0 include/parrot/interpreter.h
  3. +29 −0 src/gc/mark_sweep.c
  4. +13 −2 src/gc/system.c
  5. +2 −0 src/interp/inter_create.c
  6. +37 −28 src/namespace.c
View
106 include/parrot/gc_api.h
@@ -11,6 +11,14 @@
#include "parrot/parrot.h"
+/* Flag to turn on precise GC
+ 0 = no precise GC (use only stack walking)
+ 1 = precise GC + stack walking (for debug, also print debug messages)
+ 2 = precise GC only (this is what we want)
+*/
+
+#define GC_USE_PRECISE 1
+
/*
* we need an alignment that is the same as malloc(3) have for
* allocating Buffer items like FLOATVAL (double)
@@ -119,6 +127,104 @@ typedef enum {
#define GC_strings_cb_FLAG (UINTVAL)(1 << 4) /* Invoked from String GC during mem_alloc to sweep dead strings */
/* garbage collect. */
+typedef struct __gc_anchor_storage {
+ struct __gc_anchor_storage *prev;
+ size_t num_p;
+ size_t num_s;
+} gc_anchor_storage;
+
+#if GC_USE_PRECISE != 0
+
+#define GC_STACK_FRAME(i, p, s, _code) { \
+ const size_t __num_pmc_slots = (p); \
+ const size_t __num_str_slots = (s); \
+ const size_t __slot_storage_size = ((p) * sizeof (PMC *)) + ((s) * sizeof(STRING*)); \
+ const size_t __total_storage_size = __slot_storage_size + sizeof (gc_anchor_storage); \
+ gc_anchor_storage * const __anchor_storage = (gc_anchor_storage *) \
+ Parrot_gc_allocate_fixed_size_storage((i), __total_storage_size); \
+ PMC ** const __pmc_storage_slots = (PMC **) (__anchor_storage + 1); \
+ STRING ** const __str_storage_slots = (STRING **) (__pmc_storage_slots + __num_pmc_slots); \
+ memset(__anchor_storage, 0, __total_storage_size); \
+ __anchor_storage->num_p = (p); \
+ __anchor_storage->num_s = (s); \
+ __anchor_storage->prev = (i)->gc_anchor_storage; \
+ (i)->gc_anchor_storage = __anchor_storage; \
+ { \
+ _code \
+ } \
+ { \
+ gc_anchor_storage * __current_storage = (i)->gc_anchor_storage; \
+ while (__current_storage && __current_storage != __anchor_storage) { \
+ gc_anchor_storage * const __tmp = __current_storage->prev; \
+ Parrot_gc_free_fixed_size_storage((i), __total_storage_size, __current_storage); \
+ __current_storage = __tmp; \
+ } \
+ (i)->gc_anchor_storage = __current_storage; \
+ } \
+ }
+
+#define GC_SETUP_ANCHOR_STORAGE(i, p, s) { \
+ const size_t __num_pmc_slots = (p); \
+ const size_t __num_str_slots = (s); \
+ const size_t __slot_storage_size = ((p) * sizeof (PMC *)) + ((s) * sizeof(STRING*)); \
+ const size_t __total_storage_size = __slot_storage_size + sizeof (gc_anchor_storage); \
+ gc_anchor_storage * const __anchor_storage = (gc_anchor_storage *) \
+ Parrot_gc_allocate_fixed_size_storage((i), __total_storage_size); \
+ PMC ** const __pmc_storage_slots = (PMC **) (__anchor_storage + 1); \
+ STRING ** const __str_storage_slots = (STRING **) (__pmc_storage_slots + __num_pmc_slots); \
+ memset(__anchor_storage, 0, __total_storage_size); \
+ __anchor_storage->num_p = (p); \
+ __anchor_storage->num_s = (s); \
+ __anchor_storage->prev = (i)->gc_anchor_storage; \
+ (i)->gc_anchor_storage = __anchor_storage; \
+ {
+
+#define GC_CLEANUP_ANCHOR_STORAGE(i) \
+ } \
+ { \
+ gc_anchor_storage * __current_storage = (i)->gc_anchor_storage; \
+ while (__current_storage && __current_storage != __anchor_storage) { \
+ gc_anchor_storage * const __tmp = __current_storage->prev; \
+ Parrot_gc_free_fixed_size_storage((i), __anchor_storage_size, __current_storage); \
+ __current_storage = __tmp; \
+ } \
+ (i)->gc_anchor_storage = __current_storage; \
+ } \
+ }
+
+#define GC_GET_PMC_ANCHOR(n, p) { \
+ PARROT_ASSERT(n < __num_pmc_slots); \
+ (p) = __pmc_storage_slots[(n)]; \
+ }
+
+#define GC_SET_PMC_ANCHOR(n, p) { \
+ PARROT_ASSERT(n < __num_pmc_slots); \
+ __pmc_storage_slots[(n)] = (p); \
+ }
+
+#define GC_GET_STRING_ANCHOR(n, s) { \
+ PARROT_ASSERT(n < __num_str_slots); \
+ (s) = __str_storage_slots[(n)]; \
+ }
+
+#define GC_SET_STRING_ANCHOR(n, s) { \
+ PARROT_ASSERT(n < __num_str_slots); \
+ __str_storage_slots[(n)] = (s); \
+ }
+
+#else
+
+#define GC_STACK_FRAME(i, p, s, _code)
+#define GC_SETUP_ANCHOR_STORAGE(i, n)
+#define GC_CLEANUP_ANCHOR_STORAGE(i)
+#define GC_GET_PMC_ANCHOR(n, p)
+#define GC_SET_PMC_ANCHOR(n, p)
+#define GC_GET_STRING_ANCHOR(n, s)
+#define GC_SET_STRING_ANCHOR(n, s)
+
+#endif
+
+
/* HEADERIZER BEGIN: src/gc/api.c */
/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
View
1 include/parrot/interpreter.h
@@ -251,6 +251,7 @@ struct parrot_interp_t {
Parrot_jump_buff *api_jmp_buf; /* jmp point out of Parrot */
PMC * final_exception; /* Final exception PMC */
INTVAL exit_code;
+ gc_anchor_storage * gc_anchor_storage; /* GC anchor storage structure */
};
/* typedef struct parrot_interp_t Interp; done in parrot.h so that
View
29 src/gc/mark_sweep.c
@@ -183,10 +183,13 @@ Parrot_gc_trace_root(PARROT_INTERP,
= interp->iglobals;
}
+#if GC_USE_PRECISE != 2
if (trace == GC_TRACE_FULL)
trace_system_areas(interp, mem_pools);
+#endif
+
mark_interp(interp);
/* quick check to see if we have already marked all impatient PMCs. If we
@@ -264,6 +267,32 @@ mark_interp(PARROT_INTERP)
if (interp->parent_interpreter)
mark_interp(interp->parent_interpreter);
+#if GC_USE_PRECISE != 0
+
+ {
+ gc_anchor_storage * gcas = interp->gc_anchor_storage;
+ while(gcas) {
+ const size_t num_p = gcas->num_p;
+ const size_t num_s = gcas->num_s;
+ PMC ** const ps = (PMC **)(gcas + 1);
+ STRING ** const ss = (STRING **)(ps + num_p);
+ size_t t;
+ for(t = 0 ; t < num_p; t++) {
+ PMC * const pmc = ps[t];
+ if (!PMC_IS_NULL(pmc))
+ Parrot_gc_mark_PMC_alive(interp, pmc);
+ }
+ for(t = 0 ; t < num_s; t++) {
+ STRING * const str = ss[t];
+ if (!PMC_IS_NULL(str))
+ Parrot_gc_mark_STRING_alive(interp, str);
+ }
+ gcas = gcas->prev;
+ }
+ }
+
+#endif
+
mark_code_segment(interp);
}
View
15 src/gc/system.c
@@ -485,14 +485,25 @@ trace_mem_block(PARROT_INTERP,
if ((pmc_min <= ptr)
&& (ptr < pmc_max)
&& interp->gc_sys->is_pmc_ptr(interp, (void *)ptr)) {
+#if GC_USE_PRECISE == 1
+ fprintf(stderr, "GC_USE_PRECISE: Found PMC %x at stack location %x\n", ptr, cur_var_ptr);
+#endif
Parrot_gc_mark_PMC_alive(interp, (PMC *)ptr);
}
else if ((buffer_min <= ptr) && (ptr < buffer_max)
&& interp->gc_sys->is_string_ptr(interp, (void *)ptr)) {
- if (PObj_is_string_TEST((PObj *)ptr))
+ if (PObj_is_string_TEST((PObj *)ptr)) {
+#if GC_USE_PRECISE == 1
+ fprintf(stderr, "GC_USE_PRECISE: Found STRING %x at stack location %x\n", ptr, cur_var_ptr);
+#endif
Parrot_gc_mark_STRING_alive(interp, (STRING *)ptr);
- else
+ }
+ else {
+#if GC_USE_PRECISE == 1
+ fprintf(stderr, "GC_USE_PRECISE: Found random PObj (???) %x at stack location %x\n", ptr, cur_var_ptr);
+#endif
PObj_live_SET((PObj *)ptr);
+ }
}
}
}
View
2 src/interp/inter_create.c
@@ -335,6 +335,8 @@ initialize_interpreter(PARROT_INTERP, ARGIN(Parrot_GC_Init_Args *args))
Parrot_x_on_exit(interp, Parrot_really_destroy, NULL);
#endif
+ interp->gc_anchor_storage = NULL;
+
return interp;
}
View
65 src/namespace.c
@@ -250,21 +250,25 @@ static PMC *
internal_ns_maybe_create(PARROT_INTERP, ARGIN(PMC *ns), ARGIN(STRING *key), int flags)
{
ASSERT_ARGS(internal_ns_maybe_create)
+ PMC * sub_ns;
/* TT #1220 - stop depending on typed namespace */
if (!(flags & INTERN_NS_CREAT))
return PMCNULL;
- else {
- const INTVAL type_id = Parrot_hll_get_ctx_HLL_type(interp, enum_class_NameSpace);
- /* TT #1221 - match HLL of enclosing namespace? */
- PMC * const sub_ns = Parrot_pmc_new(interp, type_id);
- if (PMC_IS_NULL(sub_ns))
- return PMCNULL;
+ GC_STACK_FRAME(interp, 1, 0, {
+ const INTVAL type_id = Parrot_hll_get_ctx_HLL_type(interp, enum_class_NameSpace);
- VTABLE_set_pmc_keyed_str(interp, ns, key, sub_ns);
- return sub_ns;
- }
+ /* TT #1221 - match HLL of enclosing namespace? */
+ sub_ns = Parrot_pmc_new(interp, type_id);
+ GC_SET_PMC_ANCHOR(0, sub_ns);
+
+ if (!PMC_IS_NULL(sub_ns))
+ VTABLE_set_pmc_keyed_str(interp, ns, key, sub_ns);
+ else
+ sub_ns = PMCNULL;
+ });
+ return sub_ns;
}
/*
@@ -318,25 +322,30 @@ static void
store_sub_in_multi(PARROT_INTERP, ARGIN(PMC *sub_pmc), ARGIN(PMC *ns))
{
ASSERT_ARGS(store_sub_in_multi)
- Parrot_Sub_attributes *sub;
- STRING *ns_entry_name;
- PMC *multisub;
-
- PMC_get_sub(interp, sub_pmc, sub);
- ns_entry_name = sub->ns_entry_name;
- multisub = VTABLE_get_pmc_keyed_str(interp, ns, ns_entry_name);
-
- /* is there an existing MultiSub PMC? or do we need to create one? */
- if (PMC_IS_NULL(multisub)) {
- multisub = Parrot_pmc_new(interp,
- Parrot_hll_get_ctx_HLL_type(interp, enum_class_MultiSub));
- /* we have to push the sub onto the MultiSub before we try to store
- it because storing requires information from the sub */
- VTABLE_push_pmc(interp, multisub, sub_pmc);
- VTABLE_set_pmc_keyed_str(interp, ns, ns_entry_name, multisub);
- }
- else
- VTABLE_push_pmc(interp, multisub, sub_pmc);
+ GC_STACK_FRAME(interp, 1, 0, {
+ Parrot_Sub_attributes *sub;
+ STRING *ns_entry_name;
+ PMC *multisub;
+
+ PMC_get_sub(interp, sub_pmc, sub);
+ ns_entry_name = sub->ns_entry_name;
+ multisub = VTABLE_get_pmc_keyed_str(interp, ns, ns_entry_name);
+ GC_SET_PMC_ANCHOR(0, multisub);
+
+ /* is there an existing MultiSub PMC? or do we need to create one? */
+ if (PMC_IS_NULL(multisub)) {
+
+ multisub = Parrot_pmc_new(interp,
+ Parrot_hll_get_ctx_HLL_type(interp, enum_class_MultiSub));
+ GC_SET_PMC_ANCHOR(0, multisub);
+ /* we have to push the sub onto the MultiSub before we try to store
+ it because storing requires information from the sub */
+ VTABLE_push_pmc(interp, multisub, sub_pmc);
+ VTABLE_set_pmc_keyed_str(interp, ns, ns_entry_name, multisub);
+ }
+ else
+ VTABLE_push_pmc(interp, multisub, sub_pmc);
+ });
}
/*

No commit comments for this range

Something went wrong with that request. Please try again.