From 09b7dbabbffe538c6f911e8038a772b69f72867f Mon Sep 17 00:00:00 2001 From: Martin Karlgren <marty@roxen.com> Date: Thu, 4 Jun 2015 22:59:17 +0200 Subject: [PATCH] count_memory: avoid visiting refs at all in negative lookahead mode. --- src/array.c | 5 +++-- src/constants.c | 2 +- src/gc.c | 4 ++++ src/gc.h | 10 ++++++++++ src/mapping.c | 7 ++++--- src/multiset.c | 7 ++++--- src/object.c | 44 +++++++++++++++++++++++--------------------- src/pike_types.c | 2 +- src/program.c | 2 +- src/stralloc.c | 2 +- 10 files changed, 52 insertions(+), 33 deletions(-) diff --git a/src/array.c b/src/array.c index ac765f289b..a0c89e02e5 100644 --- a/src/array.c +++ b/src/array.c @@ -2743,7 +2743,7 @@ void check_all_arrays(void) PMOD_EXPORT void visit_array (struct array *a, int action, void *extra) { visit_enter(a, T_ARRAY, extra); - switch (action) { + switch (action & VISIT_MODE_MASK) { #ifdef PIKE_DEBUG default: Pike_fatal ("Unknown visit action %d.\n", action); @@ -2757,7 +2757,8 @@ PMOD_EXPORT void visit_array (struct array *a, int action, void *extra) break; } - if (a->type_field & + if (!(action & VISIT_NO_REFS) && + a->type_field & (action & VISIT_COMPLEX_ONLY ? BIT_COMPLEX : BIT_REF_TYPES)) { size_t e, s = a->size; int ref_type = a->flags & ARRAY_WEAK_FLAG ? REF_TYPE_WEAK : REF_TYPE_NORMAL; diff --git a/src/constants.c b/src/constants.c index d09ed922df..70da823244 100644 --- a/src/constants.c +++ b/src/constants.c @@ -197,7 +197,7 @@ PMOD_EXPORT void quick_add_efun(const char *name, ptrdiff_t name_length, PMOD_EXPORT void visit_callable (struct callable *c, int action, void *extra) { visit_enter(c, T_STRUCT_CALLABLE, extra); - switch (action) { + switch (action & VISIT_MODE_MASK) { #ifdef PIKE_DEBUG default: Pike_fatal ("Unknown visit action %d.\n", action); diff --git a/src/gc.c b/src/gc.c index c1db83d65d..40103f8102 100644 --- a/src/gc.c +++ b/src/gc.c @@ -5750,6 +5750,10 @@ void f_count_memory (INT32 args) if (mc_ref_from->flags & MC_FLAG_INTERNAL) { action = VISIT_COUNT_BYTES; /* Memory count this. */ MC_DEBUG_MSG (NULL, "enter with byte counting"); + if (mc_lookahead < 0) { + MC_DEBUG_MSG (NULL, "VISIT_NO_REFS mode"); + action |= VISIT_NO_REFS; + } mc_ref_from->visit_fn (mc_ref_from->thing, action, mc_ref_from->extra); count_visits++; diff --git a/src/gc.h b/src/gc.h index 70baabfd74..2e3ef562b1 100644 --- a/src/gc.h +++ b/src/gc.h @@ -683,6 +683,16 @@ PMOD_EXPORT extern visit_leave_cb *visit_leave; * mc_counted_bytes, then visit the refs. Never combined with * VISIT_COMPLEX_ONLY. */ +#define VISIT_MODE_MASK 0x0F +/* Bitmask for visit mode selection. The rest is flags. */ + +#define VISIT_NO_REFS 0x10 +/* Don't visit any refs. Typically set when lookahead is negative as + an optimization. */ + +#define VISIT_FLAGS_MASK 0xF0 +/* Bitmask for visit flags. */ + /* Map between type and visit function for the standard ref types. */ PMOD_EXPORT extern visit_thing_fn *const visit_fn_from_type[MAX_TYPE + 1]; PMOD_EXPORT TYPE_T type_from_visit_fn (visit_thing_fn *fn); diff --git a/src/mapping.c b/src/mapping.c index 5126ba9c39..f8b1dcb40b 100644 --- a/src/mapping.c +++ b/src/mapping.c @@ -2528,7 +2528,7 @@ static void visit_mapping_data (struct mapping_data *md, int action, void *extra) { visit_enter(md, T_MAPPING_DATA, extra); - switch (action) { + switch (action & VISIT_MODE_MASK) { #ifdef PIKE_DEBUG default: Pike_fatal ("Unknown visit action %d.\n", action); @@ -2541,7 +2541,8 @@ static void visit_mapping_data (struct mapping_data *md, int action, break; } - if ((md->ind_types | md->val_types) & + if (!(action & VISIT_NO_REFS) && + (md->ind_types | md->val_types) & (action & VISIT_COMPLEX_ONLY ? BIT_COMPLEX : BIT_REF_TYPES)) { int ind_ref_type = md->flags & MAPPING_WEAK_INDICES ? REF_TYPE_WEAK : REF_TYPE_NORMAL; @@ -2560,7 +2561,7 @@ static void visit_mapping_data (struct mapping_data *md, int action, PMOD_EXPORT void visit_mapping (struct mapping *m, int action, void *extra) { visit_enter(m, T_MAPPING, extra); - switch (action) { + switch (action & VISIT_MODE_MASK) { #ifdef PIKE_DEBUG default: Pike_fatal ("Unknown visit action %d.\n", action); diff --git a/src/multiset.c b/src/multiset.c index 5ac958851f..02a5c8a345 100644 --- a/src/multiset.c +++ b/src/multiset.c @@ -3472,7 +3472,7 @@ static void visit_multiset_data (struct multiset_data *msd, int action, void *extra) { visit_enter(msd, T_MULTISET_DATA, extra); - switch (action) { + switch (action & VISIT_MODE_MASK) { #ifdef PIKE_DEBUG default: Pike_fatal ("Unknown visit action %d.\n", action); @@ -3487,7 +3487,8 @@ static void visit_multiset_data (struct multiset_data *msd, int action, break; } - if (msd->root && + if (!(action & VISIT_NO_REFS) && + msd->root && ((msd->ind_types | msd->val_types) & (action & VISIT_COMPLEX_ONLY ? BIT_COMPLEX : BIT_REF_TYPES))) { int ind_ref_type = @@ -3515,7 +3516,7 @@ static void visit_multiset_data (struct multiset_data *msd, int action, PMOD_EXPORT void visit_multiset (struct multiset *l, int action, void *extra) { visit_enter(l, T_MULTISET, extra); - switch (action) { + switch (action & VISIT_MODE_MASK) { #ifdef PIKE_DEBUG default: Pike_fatal ("Unknown visit action %d.\n", action); diff --git a/src/object.c b/src/object.c index 0c486cfb75..98e9f6ce33 100644 --- a/src/object.c +++ b/src/object.c @@ -2105,7 +2105,7 @@ PMOD_EXPORT void visit_object (struct object *o, int action, void *extra) if (o->next == o) return; /* Fake object used by compiler */ visit_enter(o, T_OBJECT, extra); - switch (action) { + switch (action & VISIT_MODE_MASK) { #ifdef PIKE_DEBUG default: Pike_fatal ("Unknown visit action %d.\n", action); @@ -2133,31 +2133,32 @@ PMOD_EXPORT void visit_object (struct object *o, int action, void *extra) for (e = p->num_inherits - 1; e >= 0; e--) { struct program *inh_prog = inh[e].prog; - unsigned INT16 *inh_prog_var_idxs = inh_prog->variable_index; - struct identifier *inh_prog_ids = inh_prog->identifiers; - char *inh_storage = storage + inh[e].storage_offset; - - int q, num_vars = (int) inh_prog->num_variable_index; - - for (q = 0; q < num_vars; q++) { - int d = inh_prog_var_idxs[q]; - struct identifier *id = inh_prog_ids + d; - int id_flags = id->identifier_flags; - int rtt = id->run_time_type; - void *var; - union anything *u; + if (!(action & VISIT_NO_REFS)) { + unsigned INT16 *inh_prog_var_idxs = inh_prog->variable_index; + struct identifier *inh_prog_ids = inh_prog->identifiers; + char *inh_storage = storage + inh[e].storage_offset; + + int q, num_vars = (int) inh_prog->num_variable_index; - if (IDENTIFIER_IS_ALIAS (id_flags)) - continue; + for (q = 0; q < num_vars; q++) { + int d = inh_prog_var_idxs[q]; + struct identifier *id = inh_prog_ids + d; + int id_flags = id->identifier_flags; + int rtt = id->run_time_type; + void *var; + union anything *u; - var = inh_storage + id->func.offset; - u = (union anything *) var; + if (IDENTIFIER_IS_ALIAS (id_flags)) + continue; + + var = inh_storage + id->func.offset; + u = (union anything *) var; #ifdef DEBUG_MALLOC - if (REFCOUNTED_TYPE(rtt)) - debug_malloc_touch (u->ptr); + if (REFCOUNTED_TYPE(rtt)) + debug_malloc_touch (u->ptr); #endif - switch (rtt) { + switch (rtt) { case T_MIXED: { struct svalue *s = (struct svalue *) var; dmalloc_touch_svalue (s); @@ -2209,6 +2210,7 @@ PMOD_EXPORT void visit_object (struct object *o, int action, void *extra) default: Pike_fatal ("Invalid runtime type %d.\n", rtt); #endif + } } } diff --git a/src/pike_types.c b/src/pike_types.c index ed6fad4e19..6185092f7e 100644 --- a/src/pike_types.c +++ b/src/pike_types.c @@ -8956,7 +8956,7 @@ PMOD_EXPORT void *find_type(struct pike_type *t, PMOD_EXPORT void visit_type (struct pike_type *t, int action, void *extra) { visit_enter(t, PIKE_T_TYPE, extra); - switch (action) { + switch (action & VISIT_MODE_MASK) { #ifdef PIKE_DEBUG default: Pike_fatal ("Unknown visit action %d.\n", action); diff --git a/src/program.c b/src/program.c index 5a82931949..6c57a87661 100644 --- a/src/program.c +++ b/src/program.c @@ -11042,7 +11042,7 @@ void cleanup_program(void) PMOD_EXPORT void visit_program (struct program *p, int action, void *extra) { visit_enter(p, T_PROGRAM, extra); - switch (action) { + switch (action & VISIT_MODE_MASK) { #ifdef PIKE_DEBUG default: Pike_fatal ("Unknown visit action %d.\n", action); diff --git a/src/stralloc.c b/src/stralloc.c index db28194f1c..f22bd94e9b 100644 --- a/src/stralloc.c +++ b/src/stralloc.c @@ -2242,7 +2242,7 @@ void count_memory_in_strings(size_t *num, size_t *size) PMOD_EXPORT void visit_string (struct pike_string *s, int action, void *extra) { visit_enter(s, T_STRING, extra); - switch (action) { + switch (action & VISIT_MODE_MASK) { #ifdef PIKE_DEBUG default: Pike_fatal ("Unknown visit action %d.\n", action); -- GitLab