diff --git a/src/array.c b/src/array.c index ac765f289be3d465e5559cb0fbf072ffd365de20..a0c89e02e52907b93ab50088916a368c0b117bcb 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 d09ed922df74acb1701b4b9a081c00e8f1c6375f..70da82324457beddd5130b22e4c822dd3be8e42f 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 c1db83d65d4368b4a7fd309cf758bfbf52747396..40103f81027835c9a99e67f3563f327532c6f10a 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 70baabfd74e09007a3d8a2e68cd423f501a22684..2e3ef562b1c23b7831e27473433dbcd5129d2944 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 5126ba9c39bfb1e1d877074161dcff24874761e9..f8b1dcb40bc7dd66435104fa19869fc563a8b4e8 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 5ac958851f920f630b44c101daf32f1a9c34c6e7..02a5c8a345b5f1de1b1a0e5c6f6c149bddd4ad55 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 0c486cfb7580e607f15ad20b174a9c86223c50cc..98e9f6ce33c08855f083bf5f0e2460f30a6efa92 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 ed6fad4e1952475f4a8713641466e77258f74ce9..6185092f7e04d7378c5f06190f96e0762864bee4 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 5a829319498e96310d39e2e22aa4a7ef4d97021f..6c57a87661509adb8bc9846b8d5ba325b7e3f06f 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 db28194f1ca293ca9d845c6fc733d504a60dc077..f22bd94e9b011683e448815a0d4112a5d852eb7c 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);