From 72b081ac549ee98c4559fcb409d39cc7df994d7b Mon Sep 17 00:00:00 2001 From: Per Hedbor <ph@opera.com> Date: Tue, 11 Jun 2013 11:00:35 +0200 Subject: [PATCH] Optimize destruct somewhat. Avoid keeping track of if destroy() has been called for objects that lack destroy(). --- src/object.c | 40 ++++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/src/object.c b/src/object.c index d8ab53080d..91ee24c0cc 100644 --- a/src/object.c +++ b/src/object.c @@ -327,7 +327,7 @@ void call_pike_initializers(struct object *o, int args) if(fun!=-1) { apply_low(o,fun,0); - pop_stack(); + Pike_sp--; } STACK_LEVEL_CHECK(args); fun=FIND_LFUN(p, LFUN_CREATE); @@ -794,13 +794,17 @@ static void call_destroy(struct object *o, enum object_destruct_reason reason) #endif } +static int object_has_destroy( struct object *o ) +{ + return QUICK_FIND_LFUN( o->prog, LFUN_DESTROY ) != -1; +} PMOD_EXPORT void destruct_object (struct object *o, enum object_destruct_reason reason) { int e; struct program *p; struct pike_frame *pike_frame=0; - int frame_pushed = 0; + int frame_pushed = 0, destroy_called = 0; #ifdef PIKE_DEBUG ONERROR uwp; @@ -827,26 +831,29 @@ PMOD_EXPORT void destruct_object (struct object *o, enum object_destruct_reason else fputs(", is destructed\n", stderr); } #endif + if( !(p = o->prog) ) + return; add_ref( o ); - call_destroy(o, reason); - - /* destructed in destroy() */ - if(!(p=o->prog)) + if( object_has_destroy( o ) ) { - free_object(o); + call_destroy(o, reason); + destroy_called = 1; + /* destructed in destroy() */ + if(!(p=o->prog)) + { + free_object(o); #ifdef PIKE_DEBUG - UNSET_ONERROR(uwp); + UNSET_ONERROR(uwp); #endif - return; + return; + } + get_destroy_called_mark(o)->p=p; } - get_destroy_called_mark(o)->p=p; - debug_malloc_touch(o); debug_malloc_touch(o->storage); debug_malloc_touch(p); o->prog=0; - #ifdef GC_VERBOSE if (Pike_in_gc > GC_PASS_PREPARE) fprintf(stderr, "| Zapping references in %p with %d refs.\n", o, o->refs); @@ -858,7 +865,7 @@ PMOD_EXPORT void destruct_object (struct object *o, enum object_destruct_reason int q; struct program *prog = p->inherits[e].prog; char *storage = o->storage+p->inherits[e].storage_offset; - + if(prog->event_handler) { if( !frame_pushed ) @@ -935,8 +942,8 @@ PMOD_EXPORT void destruct_object (struct object *o, enum object_destruct_reason free_object( o ); free_program(p); - - remove_destroy_called_mark(o); + if( destroy_called ) + remove_destroy_called_mark(o); #ifdef PIKE_DEBUG UNSET_ONERROR(uwp); @@ -1127,6 +1134,7 @@ static void assign_svalue_from_ptr_no_free(struct svalue *to, assign_svalue_no_free(to, s); break; } + case T_OBJ_INDEX: { SET_SVAL(*to, T_FUNCTION, DO_NOT_WARN(func.offset), object, o); @@ -1153,7 +1161,7 @@ static void assign_svalue_from_ptr_no_free(struct svalue *to, } break; } - + case T_MIXED: case PIKE_T_NO_REF_MIXED: { -- GitLab