From c3c703da44460e0e4a8a51e6b88ce2da0a470282 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net> Date: Wed, 4 Dec 1996 16:47:58 -0800 Subject: [PATCH] fixed a small memory leak and added _memory_usage Rev: bin/test_pike.pike:1.3 Rev: src/ChangeLog:1.32 Rev: src/array.c:1.4 Rev: src/array.h:1.2 Rev: src/builtin_functions.c:1.16 Rev: src/builtin_functions.h:1.3 Rev: src/callback.c:1.4 Rev: src/callback.h:1.3 Rev: src/constants.c:1.4 Rev: src/constants.h:1.2 Rev: src/language.yacc:1.15 Rev: src/las.c:1.10 Rev: src/las.h:1.3 Rev: src/mapping.c:1.8 Rev: src/mapping.h:1.2 Rev: src/modules/call_out/call_out.c:1.4 Rev: src/modules/pipe/pipe.c:1.7 Rev: src/multiset.c:1.2 Rev: src/multiset.h:1.2 Rev: src/object.c:1.6 Rev: src/object.h:1.4 Rev: src/program.c:1.11 Rev: src/program.h:1.4 Rev: src/stralloc.c:1.8 Rev: src/stralloc.h:1.4 --- bin/test_pike.pike | 272 +++++++++++++++++++------------- src/ChangeLog | 5 + src/array.c | 14 ++ src/array.h | 4 + src/builtin_functions.c | 79 +++++++++- src/builtin_functions.h | 4 + src/callback.c | 100 ++++++++++-- src/callback.h | 3 +- src/constants.c | 23 +++ src/constants.h | 2 + src/language.yacc | 3 +- src/las.c | 57 +++++-- src/las.h | 1 + src/mapping.c | 23 ++- src/mapping.h | 2 + src/modules/call_out/call_out.c | 19 ++- src/modules/pipe/pipe.c | 3 +- src/multiset.c | 13 ++ src/multiset.h | 1 + src/object.c | 19 ++- src/object.h | 1 + src/program.c | 16 +- src/program.h | 1 + src/stralloc.c | 22 +++ src/stralloc.h | 1 + 25 files changed, 536 insertions(+), 152 deletions(-) diff --git a/bin/test_pike.pike b/bin/test_pike.pike index 258390f97c..8110b5c518 100755 --- a/bin/test_pike.pike +++ b/bin/test_pike.pike @@ -12,7 +12,8 @@ int main(int argc, string *argv) int e, verbose, successes, errors, t, check; string *tests; program testprogram; - int start, fail; + int start, fail, mem; + int loop=1; for(e=1;e<argc;e++) { @@ -49,6 +50,12 @@ int main(int argc, string *argv) fail+=arg; break; + + case "-l": + case "--loop": + loop+=arg; + break; + case "-t": case "--trace": t+=arg; @@ -59,6 +66,13 @@ int main(int argc, string *argv) check++; break; + + case "-m": + case "--mem": + case "--memory": + mem++; + break; + default: if(tests) { @@ -81,147 +95,179 @@ int main(int argc, string *argv) } tests=tests[0..sizeof(tests)-2]; - for(e=start;e<sizeof(tests);e++) - { - string test,condition; - int type; - object o; - mixed a,b; - - if(check) _verify_internals(); - test=tests[e]; - if(sscanf(test,"COND %s\n%s",condition,test)==2) - { - if(!clone(compile_string("mixed c() { return "+condition+"; }","Cond "+(e+1)))->c()) - { - if(verbose) - perror("Not doing test "+(e+1)+"\n"); - successes++; - continue; - } - } - - sscanf(test,"%s\n%s",type,test); - sscanf(type,"%*s expected result: %s",type); - - if(verbose) - { - perror("Doing test "+(e+1)+"\n"); - if(verbose>1) - perror(test+"\n"); - } - - if(check > 1) _verify_internals(); + while(loop--) + { + successes=errors=0; - switch(type) + for(e=start;e<sizeof(tests);e++) { - case "COMPILE_ERROR": - master()->set_inhibit_compile_errors(1); - if(catch(compile_string(test,"Test "+(e+1)))) + string test,condition; + int type; + object o; + mixed a,b; + + if(check) _verify_internals(); + + test=tests[e]; + if(sscanf(test,"COND %s\n%s",condition,test)==2) { - successes++; - }else{ - perror("Test "+(e+1)+" failed.\n"); - perror(test+"\n"); - errors++; + if(!clone(compile_string("mixed c() { return "+condition+"; }","Cond "+(e+1)))->c()) + { + if(verbose) + perror("Not doing test "+(e+1)+"\n"); + successes++; + continue; + } } - master()->set_inhibit_compile_errors(0); - break; - - case "EVAL_ERROR": - master()->set_inhibit_compile_errors(1); - if(catch(clone(compile_string(test,"Test "+(e+1)))->a())) + + sscanf(test,"%s\n%s",type,test); + sscanf(type,"%*s expected result: %s",type); + + if(verbose) { - successes++; - }else{ - perror("Test "+(e+1)+" failed.\n"); - perror(test+"\n"); - errors++; + perror("Doing test "+(e+1)+"\n"); + if(verbose>1) + perror(test+"\n"); } - master()->set_inhibit_compile_errors(0); - break; - - default: - o=clone(compile_string(test,"Test "+(e+1))); - - if(check > 1) _verify_internals(); - - a=b=0; - if(t) trace(t); - if(functionp(o->a)) a=o->a(); - if(functionp(o->b)) b=o->b(); - if(t) trace(0); - + if(check > 1) _verify_internals(); - + switch(type) { - case "FALSE": - a=!a; - - case "TRUE": - if(!a) + case "COMPILE_ERROR": + master()->set_inhibit_compile_errors(1); + if(catch(compile_string(test,"Test "+(e+1)))) { + successes++; + }else{ perror("Test "+(e+1)+" failed.\n"); perror(test+"\n"); errors++; - }else{ - successes++; } + master()->set_inhibit_compile_errors(0); break; - - case "RUN": - successes++; - break; - - case "EQ": - if(a!=b) + + case "EVAL_ERROR": + master()->set_inhibit_compile_errors(1); + if(catch(clone(compile_string(test,"Test "+(e+1)))->a())) { + successes++; + }else{ perror("Test "+(e+1)+" failed.\n"); perror(test+"\n"); - perror(sprintf("o->a(): %O\n",a)); - perror(sprintf("o->b(): %O\n",b)); errors++; - }else{ - successes++; } + master()->set_inhibit_compile_errors(0); break; - - case "EQUAL": - if(!equal(a,b)) + + default: + o=clone(compile_string(test,"Test "+(e+1))); + + if(check > 1) _verify_internals(); + + a=b=0; + if(t) trace(t); + if(functionp(o->a)) a=o->a(); + if(functionp(o->b)) b=o->b(); + if(t) trace(0); + + if(check > 1) _verify_internals(); + + switch(type) { - perror("Test "+(e+1)+" failed.\n"); - perror(test+"\n"); - perror(sprintf("o->a(): %O\n",a)); - perror(sprintf("o->b(): %O\n",b)); - errors++; - }else{ + case "FALSE": + a=!a; + + case "TRUE": + if(!a) + { + perror("Test "+(e+1)+" failed.\n"); + perror(test+"\n"); + errors++; + }else{ + successes++; + } + break; + + case "RUN": successes++; + break; + + case "EQ": + if(a!=b) + { + perror("Test "+(e+1)+" failed.\n"); + perror(test+"\n"); + perror(sprintf("o->a(): %O\n",a)); + perror(sprintf("o->b(): %O\n",b)); + errors++; + }else{ + successes++; + } + break; + + case "EQUAL": + if(!equal(a,b)) + { + perror("Test "+(e+1)+" failed.\n"); + perror(test+"\n"); + perror(sprintf("o->a(): %O\n",a)); + perror(sprintf("o->b(): %O\n",b)); + errors++; + }else{ + successes++; + } + break; + + default: + perror(sprintf("Unknown test type (%O).\n",type)); + errors++; } - break; - - default: - perror(sprintf("Unknown test type (%O).\n",type)); - errors++; } + + if(check > 2) _verify_internals(); + + if(fail && errors) + exit(1); + + a=b=0; } - - if(check > 2) _verify_internals(); - - if(fail && errors) - exit(1); - } - - if(errors + successes != sizeof(tests)) - { - perror("Errors + Successes != number of tests!\n"); - errors++; + + if(errors + successes != sizeof(tests)) + { + perror("Errors + Successes != number of tests!\n"); + errors++; + } + + if(errors || verbose) + { + perror("Failed tests: "+errors+".\n"); + } + } - - if(errors || verbose) + if(mem) { - perror("Failed tests: "+errors+".\n"); + int total; + tests=0; + gc(); + mapping tmp=_memory_usage(); + write(sprintf("%-10s: %6s %10s\n","Category","num","bytes")); + foreach(sort(indices(tmp)),string foo) + { + if(sscanf(foo,"%s_bytes",foo)) + { + write(sprintf("%-10s: %6d %10d\n", + foo+"s", + tmp["num_"+foo+"s"], + tmp[foo+"_bytes"])); + total+=tmp[foo+"_bytes"]; + } + } + write(sprintf("%-10s: %6s %10d\n", + "Total", + "", + total)); } return errors; diff --git a/src/ChangeLog b/src/ChangeLog index 009401d3ca..01da6eea9f 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,8 @@ +Wed Dec 4 16:33:53 1996 Fredrik Hubinette <hubbe@cytocin.hubbe.net> + + * callback.c: fixed a memory leak and added more debug + * new efun: _memory_usage + Wed Dec 4 05:01:00 1996 Niels M�ller <nisse@skuld.infovav.se> * modules/ssleay/ssleay.c (init_context): Increment reference count. diff --git a/src/array.c b/src/array.c index cd6973e35f..7cdcc0ed46 100644 --- a/src/array.c +++ b/src/array.c @@ -1534,3 +1534,17 @@ void zap_all_arrays() a=next; } while (a != & empty_array); } + +void count_memory_in_arrays(INT32 *num_, INT32 *size_) +{ + INT32 num=0, size=0; + struct array *m; + for(m=empty_array.next;m!=&empty_array;m=m->next) + { + num++; + size+=sizeof(struct array)+ + sizeof(struct svalue) * (m->malloced_size - 1); + } + *num_=num; + *size_=size; +} diff --git a/src/array.h b/src/array.h index 8e31a29fd3..9300beb256 100644 --- a/src/array.h +++ b/src/array.h @@ -128,6 +128,10 @@ void gc_mark_array_as_referenced(struct array *a); void gc_check_all_arrays(); void gc_mark_all_arrays(); void gc_free_all_unreferenced_arrays(); +void debug_dump_type_field(TYPE_FIELD t); +void debug_dump_array(struct array *a); +void zap_all_arrays(); +void count_memory_in_arrays(INT32 *num_, INT32 *size_); /* Prototypes end here */ diff --git a/src/builtin_functions.c b/src/builtin_functions.c index 6b1615cd6e..4533f770d3 100644 --- a/src/builtin_functions.c +++ b/src/builtin_functions.c @@ -4,7 +4,7 @@ ||| See the files COPYING and DISCLAIMER for more information. \*/ #include "global.h" -RCSID("$Id: builtin_functions.c,v 1.15 1996/12/03 21:41:15 hubbe Exp $"); +RCSID("$Id: builtin_functions.c,v 1.16 1996/12/05 00:47:11 hubbe Exp $"); #include "interpret.h" #include "svalue.h" #include "macros.h" @@ -1433,6 +1433,82 @@ void f_glob(INT32 args) } } +static struct callback_list memory_usage_callback; + +struct callback *add_memory_usage_callback(callback_func call, + void *arg, + callback_func free_func) +{ + return add_to_callback(&memory_usage_callback, call, arg, free_func); +} + + +void f__memory_usage(INT32 args) +{ + INT32 num,size; + struct svalue *ss; + pop_n_elems(args); + ss=sp; + + count_memory_in_mappings(&num, &size); + push_text("num_mappings"); + push_int(num); + push_text("mapping_bytes"); + push_int(size); + + count_memory_in_strings(&num, &size); + push_text("num_strings"); + push_int(num); + push_text("string_bytes"); + push_int(size); + + count_memory_in_arrays(&num, &size); + push_text("num_arrays"); + push_int(num); + push_text("array_bytes"); + push_int(size); + + count_memory_in_programs(&num,&size); + push_text("num_programs"); + push_int(num); + push_text("program_bytes"); + push_int(size); + + count_memory_in_multisets(&num, &size); + push_text("num_multisets"); + push_int(num); + push_text("multiset_bytes"); + push_int(size); + + count_memory_in_objects(&num, &size); + push_text("num_objects"); + push_int(num); + push_text("object_bytees"); + push_int(size); + + count_memory_in_callbacks(&num, &size); + push_text("num_callbacks"); + push_int(num); + push_text("callback_bytes"); + push_int(size); + + count_memory_in_constants(&num, &size); + push_text("num_constants"); + push_int(num); + push_text("constant_bytes"); + push_int(size); + + count_memory_in_callables(&num, &size); + push_text("num_callables"); + push_int(num); + push_text("callable_bytes"); + push_int(size); + + call_callback(&memory_usage_callback, (void *)0); + + f_aggregate_mapping(sp-ss); +} + void init_builtin_efuns() { init_operators(); @@ -1501,6 +1577,7 @@ void init_builtin_efuns() #ifdef DEBUG add_efun("_verify_internals",f__verify_internals,"function(:void)",OPT_SIDE_EFFECT|OPT_EXTERNAL_DEPEND); #endif + add_efun("_memory_usage",f__memory_usage,"function(:mapping(string:int))",OPT_EXTERNAL_DEPEND); #ifdef GC2 add_efun("gc",f_gc,"function(:int)",OPT_SIDE_EFFECT); diff --git a/src/builtin_functions.h b/src/builtin_functions.h index d9ac9d8273..eb2b465b0d 100644 --- a/src/builtin_functions.h +++ b/src/builtin_functions.h @@ -70,6 +70,10 @@ void f_column(INT32 args); void f__verify_internals(INT32 args); void f_localtime(INT32 args); void f_glob(INT32 args); +struct callback *add_memory_usage_callback(callback_func call, + void *arg, + callback_func free_func); +void f__memory_usage(INT32 args); void init_builtin_efuns(); /* Prototypes end here */ diff --git a/src/callback.c b/src/callback.c index ff150380d4..6294d8d742 100644 --- a/src/callback.c +++ b/src/callback.c @@ -34,23 +34,66 @@ static struct callback *first_callback =0; static struct callback *free_callbacks =0; #ifdef DEBUG +extern int d_flag; + static void check_callback_chain(struct callback_list *lst) { - int len=0; + int e,len=0; + struct callback_block *tmp; struct callback *foo; - for(foo=lst->callbacks;foo;foo=foo->next) + if(d_flag) { - if((len & 1024)==1023) + for(foo=lst->callbacks;foo;foo=foo->next) { - int len2=0; - struct callback *tmp; - for(tmp=foo->next;tmp && len2<=len;tmp=tmp->next) + if((len & 1024)==1023) { - if(tmp==foo) - fatal("Callback list is cyclic!!!\n"); + int len2=0; + struct callback *tmp; + for(tmp=foo->next;tmp && len2<=len;tmp=tmp->next) + { + if(tmp==foo) + fatal("Callback list is cyclic!!!\n"); + } } + len++; } - len++; + + for(tmp=callback_chunks;tmp;tmp=tmp->next) + { + for(e=0;e<CALLBACK_CHUNK;e++) + { + int d; + struct callback_block *tmp2; + + if(tmp->callbacks[e].free_func == (callback_func)remove_callback) + { + for(foo=free_callbacks;foo;foo=foo->next) + if(foo==tmp->callbacks+e) + break; + + if(!foo) + fatal("Lost track of a struct callback!\n"); + } + + if(tmp->callbacks[e].next) + { + d=CALLBACK_CHUNK; + for(tmp2=callback_chunks;tmp2;tmp2=tmp2->next) + { + for(d=0;d<CALLBACK_CHUNK;d++) + { + if(tmp2->callbacks+d == tmp->callbacks[e].next) + break; + + if(d < CALLBACK_CHUNK) break; + } + } + + if(d == CALLBACK_CHUNK) + fatal("Callback next pointer pointing to Z'ha'dum\n"); + } + } + } } } #else @@ -61,7 +104,7 @@ static void check_callback_chain(struct callback_list *lst) static struct callback *get_free_callback() { struct callback *tmp; - if(!(tmp=free_callbacks)) + if(!free_callbacks) { int e; struct callback_block *tmp2; @@ -69,12 +112,14 @@ static struct callback *get_free_callback() tmp2->next=callback_chunks; callback_chunks=tmp2; - for(e=0;e<(int)sizeof(CALLBACK_CHUNK);e++) + for(e=0;e<CALLBACK_CHUNK;e++) { - tmp2->callbacks[e].next=tmp; - tmp=tmp2->callbacks+e; + tmp2->callbacks[e].next=free_callbacks; + tmp2->callbacks[e].free_func=(callback_func)remove_callback; + free_callbacks=tmp2->callbacks+e; } } + tmp=free_callbacks; free_callbacks=tmp->next; return tmp; } @@ -103,9 +148,15 @@ void call_callback(struct callback_list *lst, void *arg) if(!l->call) { + if(l->free_func) + l->free_func(l, l->arg, 0); + *ptr=l->next; l->next=free_callbacks; free_callbacks=l; +#ifdef DEBUG + l->free_func=(callback_func)remove_callback; +#endif }else{ ptr=& l->next; } @@ -123,6 +174,7 @@ struct callback *add_to_callback(struct callback_list *lst, l=get_free_callback(); l->call=call; l->arg=arg; + l->free_func=free_func; l->next=lst->callbacks; lst->callbacks=l; @@ -138,6 +190,7 @@ struct callback *add_to_callback(struct callback_list *lst, void *remove_callback(struct callback *l) { l->call=0; + l->free_func=0; return l->arg; } @@ -149,11 +202,14 @@ void free_callback(struct callback_list *lst) ptr=& lst->callbacks; while(l=*ptr) { - if(l->arg && l->free_func) + if(l->free_func) l->free_func(l, l->arg, 0); *ptr=l->next; l->next=free_callbacks; free_callbacks=l; +#ifdef DEBUG + l->free_func=(callback_func)remove_callback; +#endif } } @@ -167,3 +223,19 @@ void cleanup_callbacks() } free_callbacks=0; } + + +void count_memory_in_callbacks(INT32 *num_, INT32 *size_) +{ + INT32 num=0, size=0; + struct callback_block *tmp; + struct callback *tmp2; + for(tmp=callback_chunks;tmp;tmp=tmp->next) + { + num+=CALLBACK_CHUNK; + size+=sizeof(struct callback_block); + } + for(tmp2=free_callbacks;tmp2;tmp2=tmp2->next) num--; + *num_=num; + *size_=size; +} diff --git a/src/callback.h b/src/callback.h index 104847cf2d..43bd077232 100644 --- a/src/callback.h +++ b/src/callback.h @@ -27,8 +27,9 @@ struct callback *add_to_callback(struct callback_list *lst, void *arg, callback_func free_func); void *remove_callback(struct callback *l); -void free_callback(struct callback_list *ptr); +void free_callback(struct callback_list *lst); void cleanup_callbacks(); +void count_memory_in_callbacks(INT32 *num_, INT32 *size_); /* Prototypes end here */ #endif diff --git a/src/constants.c b/src/constants.c index 8f329c6738..77fead603b 100644 --- a/src/constants.c +++ b/src/constants.c @@ -13,6 +13,7 @@ #include "interpret.h" static struct hash_table *efun_hash = 0; +static INT32 num_callable=0; struct efun *lookup_efun(struct pike_string *name) { @@ -63,6 +64,7 @@ struct callable *make_callable(c_fun fun, { struct callable *f; f=ALLOC_STRUCT(callable); + num_callable++; f->refs=1; f->function=fun; f->name=make_shared_string(name); @@ -78,6 +80,7 @@ void really_free_callable(struct callable *fun) free_string(fun->type); free_string(fun->name); free((char *)fun); + num_callable--; } void add_efun2(char *name, @@ -138,3 +141,23 @@ void cleanup_added_efuns() } } + +void count_memory_in_constants(INT32 *num_, INT32 *size_) +{ + INT32 size=0, num=0; + if(efun_hash) + { + size+=sizeof(struct hash_table) + + efun_hash->mask*sizeof(struct hash_entry)+ + efun_hash->entries*sizeof(struct efun); + } + *num_=num; + *size_=size; +} + +void count_memory_in_callables(INT32 *num_, INT32 *size_) +{ + *num_=num_callable; + *size_=num_callable*sizeof(struct callable); +} + diff --git a/src/constants.h b/src/constants.h index 83a9c56ae9..b6e274c7f4 100644 --- a/src/constants.h +++ b/src/constants.h @@ -50,6 +50,8 @@ void add_efun2(char *name, void add_efun(char *name, c_fun fun, char *type, INT16 flags); void push_all_efuns_on_stack(); void cleanup_added_efuns(); +void count_memory_in_constants(INT32 *num_, INT32 *size_); +void count_memory_in_callables(INT32 *num_, INT32 *size_); /* Prototypes end here */ #endif diff --git a/src/language.yacc b/src/language.yacc index 002786ca0b..bda3aafb97 100644 --- a/src/language.yacc +++ b/src/language.yacc @@ -156,7 +156,7 @@ /* This is the grammar definition of Pike. */ #include "global.h" -RCSID("$Id: language.yacc,v 1.14 1996/12/04 00:27:10 hubbe Exp $"); +RCSID("$Id: language.yacc,v 1.15 1996/12/05 00:47:14 hubbe Exp $"); #ifdef HAVE_MEMORY_H #include <memory.h> #endif @@ -1295,6 +1295,7 @@ void yyerror(char *str) if (num_parse_error > 5) return; num_parse_error++; + cumulative_parse_error++; if ( get_master() ) { diff --git a/src/las.c b/src/las.c index 2cf80c8f4d..d68ecec038 100644 --- a/src/las.c +++ b/src/las.c @@ -4,7 +4,7 @@ ||| See the files COPYING and DISCLAIMER for more information. \*/ #include "global.h" -RCSID("$Id: las.c,v 1.9 1996/12/04 00:27:11 hubbe Exp $"); +RCSID("$Id: las.c,v 1.10 1996/12/05 00:47:14 hubbe Exp $"); #include "language.h" #include "interpret.h" @@ -36,6 +36,7 @@ static void optimize(node *n); dynamic_buffer areas[NUM_AREAS]; node *init_node = 0; int num_parse_error; +int cumulative_parse_error=0; extern char *get_type_name(int); #define MAX_GLOBAL 256 @@ -139,28 +140,51 @@ void free_all_nodes() { node *tmp; struct node_chunk *tmp2; -#ifdef DEBUG int e=0; - for(tmp2=node_chunks;tmp2;tmp2=tmp2->next) e+=NODES; - for(tmp=free_nodes;tmp;tmp=CAR(tmp)) e--; - if(e) + + + if(cumulative_parse_error) { - int e2=e; - for(tmp2=node_chunks;tmp2;tmp2=tmp2->next) + + for(tmp2=node_chunks;tmp2;tmp2=tmp2->next) e+=NODES; + for(tmp=free_nodes;tmp;tmp=CAR(tmp)) e--; + if(e) { - for(e=0;e<NODES;e++) + int e2=e; + for(tmp2=node_chunks;tmp2;tmp2=tmp2->next) { - for(tmp=free_nodes;tmp;tmp=CAR(tmp)) - if(tmp==tmp2->nodes+e) - break; - - if(!tmp) - fprintf(stderr,"Free node at %p.\n",(tmp2->nodes+e)); + for(e=0;e<NODES;e++) + { + for(tmp=free_nodes;tmp;tmp=CAR(tmp)) + if(tmp==tmp2->nodes+e) + break; + + if(!tmp) + { + tmp=tmp2->nodes+e; +#ifdef DEBUG + if(!cumulative_parse_error) + { + fprintf(stderr,"Free node at %p.\n",tmp); + } + else +#endif + { + /* Free the node and be happy */ + /* Make sure we don't free any nodes twice */ + if(car_is_node(tmp)) CAR(tmp)=0; + if(cdr_is_node(tmp)) CDR(tmp)=0; + free_node(tmp); + } + } + } } +#ifdef DEBUG + if(!cumulative_parse_error) + fatal("Failed to free %d nodes when compiling!\n",e2); +#endif } - fatal("Failed to free %d nodes when compiling!\n",e2); } -#endif while(node_chunks) { tmp2=node_chunks; @@ -168,6 +192,7 @@ void free_all_nodes() free((char *)tmp2); } free_nodes=0; + cumulative_parse_error=0; } } diff --git a/src/las.h b/src/las.h index 736754f4a0..6d97e60d7b 100644 --- a/src/las.h +++ b/src/las.h @@ -58,6 +58,7 @@ typedef struct node_s node; extern struct locals *local_variables; extern node *init_node; extern int num_parse_error; +extern int cumulative_parse_error; #define OPT_OPTIMIZED 0x1 /* has been processed by optimize(), * only used in node_info diff --git a/src/mapping.c b/src/mapping.c index 7b792a6a9f..38ef53c929 100644 --- a/src/mapping.c +++ b/src/mapping.c @@ -4,7 +4,7 @@ ||| See the files COPYING and DISCLAIMER for more information. \*/ #include "global.h" -RCSID("$Id: mapping.c,v 1.7 1996/11/14 01:36:29 hubbe Exp $"); +RCSID("$Id: mapping.c,v 1.8 1996/12/05 00:47:15 hubbe Exp $"); #include "main.h" #include "types.h" #include "object.h" @@ -20,7 +20,6 @@ RCSID("$Id: mapping.c,v 1.7 1996/11/14 01:36:29 hubbe Exp $"); #include "las.h" #include "gc.h" - #define AVG_LINK_LENGTH 4 #define MIN_LINK_LENGTH 1 #define MAP_SLOTS(X) ((X)+((X)>>4)+8) @@ -1048,3 +1047,23 @@ void zap_all_mappings() free_mapping(m); } } + +void count_memory_in_mappings(INT32 *num_, INT32 *size_) +{ + INT32 num=0, size=0; + struct mapping *m; + for(m=first_mapping;m;m=m->next) + { + struct keypair *k; + num++; + size+=sizeof(struct mapping)+ + sizeof(struct keypair *) * m->hashsize+ + sizeof(struct keypair) * m->size; + + for(k=m->free_list;k;k=k->next) + size+=sizeof(struct keypair); + } + + *num_=num; + *size_=size; +} diff --git a/src/mapping.h b/src/mapping.h index 55f1d04597..12d0a296ba 100644 --- a/src/mapping.h +++ b/src/mapping.h @@ -65,5 +65,7 @@ void gc_mark_mapping_as_referenced(struct mapping *m); void gc_check_all_mappings(); void gc_mark_all_mappings(); void gc_free_all_unreferenced_mappings(); +void zap_all_mappings(); +void count_memory_in_mappings(INT32 *num_, INT32 *size_); /* Prototypes end here */ #endif diff --git a/src/modules/call_out/call_out.c b/src/modules/call_out/call_out.c index f46dda09bc..3a45ede2e8 100644 --- a/src/modules/call_out/call_out.c +++ b/src/modules/call_out/call_out.c @@ -4,7 +4,7 @@ ||| See the files COPYING and DISCLAIMER for more information. \*/ #include "global.h" -RCSID("$Id: call_out.c,v 1.3 1996/11/14 01:36:33 hubbe Exp $"); +RCSID("$Id: call_out.c,v 1.4 1996/12/05 00:47:43 hubbe Exp $"); #include "array.h" #include "dynamic_buffer.h" #include "object.h" @@ -16,6 +16,8 @@ RCSID("$Id: call_out.c,v 1.3 1996/11/14 01:36:33 hubbe Exp $"); #include "backend.h" #include "time_stuff.h" #include "constants.h" +#include "stralloc.h" +#include "builtin_functions.h" #include "callback.h" @@ -166,7 +168,19 @@ static struct array * new_call_out(int num_arg,struct svalue *argp) return new->args; } +static void count_memory_in_call_outs(struct callback *foo, + void *bar, + void *gazonk) +{ + push_text("num_call_outs"); + push_int(num_pending_calls); + push_text("call_out_memory"); + push_int(call_buffer_size * sizeof(call_out **)+ + num_pending_calls * sizeof(call_out)); +} + static struct callback *call_out_backend_callback=0; +static struct callback *mem_callback=0; void do_call_outs(struct callback *ignored, void *ignored_too, void *arg); void f_call_out(INT32 args) @@ -193,6 +207,9 @@ void f_call_out(INT32 args) */ if(!call_out_backend_callback) call_out_backend_callback=add_backend_callback(do_call_outs,0,0); + + if(!mem_callback) + mem_callback=add_memory_usage_callback(count_memory_in_call_outs,0,0); } void do_call_outs(struct callback *ignored, void *ignored_too, void *arg) diff --git a/src/modules/pipe/pipe.c b/src/modules/pipe/pipe.c index e6ceed60bf..2d7c631568 100644 --- a/src/modules/pipe/pipe.c +++ b/src/modules/pipe/pipe.c @@ -20,7 +20,7 @@ #include <fcntl.h> #include "global.h" -RCSID("$Id: pipe.c,v 1.6 1996/11/14 01:36:35 hubbe Exp $"); +RCSID("$Id: pipe.c,v 1.7 1996/12/05 00:47:58 hubbe Exp $"); #include "stralloc.h" #include "types.h" @@ -1108,6 +1108,7 @@ void init_pipe_programs() pipe_program->refs++; + /* Why is this here?? /Hubbe */ port_setup_program(); offset_output_close_callback=find_identifier("_output_close_callback", diff --git a/src/multiset.c b/src/multiset.c index eda1ac0f63..ae6c32c87f 100644 --- a/src/multiset.c +++ b/src/multiset.c @@ -305,3 +305,16 @@ void gc_free_all_unreferenced_multisets() } #endif /* GC2 */ + +void count_memory_in_multisets(INT32 *num_, INT32 *size_) +{ + struct multiset *m; + INT32 size=0, num=0; + for(m=first_multiset;m;m=m->next) + { + num++; + size+=sizeof(struct multiset); + } + *num_=num; + *size_=size; +} diff --git a/src/multiset.h b/src/multiset.h index 538b71431a..1b83a92598 100644 --- a/src/multiset.h +++ b/src/multiset.h @@ -43,6 +43,7 @@ void gc_mark_multiset_as_referenced(struct multiset *l); void gc_check_all_multisets(); void gc_mark_all_multisets(); void gc_free_all_unreferenced_multisets(); +void count_memory_in_multisets(INT32 *num_, INT32 *size_); /* Prototypes end here */ #endif diff --git a/src/object.c b/src/object.c index e0ca94a113..7702305abe 100644 --- a/src/object.c +++ b/src/object.c @@ -4,7 +4,7 @@ ||| See the files COPYING and DISCLAIMER for more information. \*/ #include "global.h" -RCSID("$Id: object.c,v 1.5 1996/11/14 01:36:29 hubbe Exp $"); +RCSID("$Id: object.c,v 1.6 1996/12/05 00:47:17 hubbe Exp $"); #include "object.h" #include "dynamic_buffer.h" #include "interpret.h" @@ -808,3 +808,20 @@ void gc_free_all_unreferenced_objects() #endif /* GC2 */ +void count_memory_in_objects(INT32 *num_, INT32 *size_) +{ + INT32 num=0, size=0; + struct object *o; + for(o=first_object;o;o=o->next) + { + num++; + if(o->prog) + { + size+=sizeof(struct object); + }else{ + size+=sizeof(struct object)-1+o->prog->storage_needed; + } + } + *num_=num; + *size_=size; +} diff --git a/src/object.h b/src/object.h index 9abde9f91c..b7ff6fb774 100644 --- a/src/object.h +++ b/src/object.h @@ -67,6 +67,7 @@ void gc_mark_object_as_referenced(struct object *o); void gc_check_all_objects(); void gc_mark_all_objects(); void gc_free_all_unreferenced_objects(); +void count_memory_in_objects(INT32 *num_, INT32 *size_); /* Prototypes end here */ #endif /* OBJECT_H */ diff --git a/src/program.c b/src/program.c index 9f34f7aadf..5d58844d27 100644 --- a/src/program.c +++ b/src/program.c @@ -4,7 +4,7 @@ ||| See the files COPYING and DISCLAIMER for more information. \*/ #include "global.h" -RCSID("$Id: program.c,v 1.10 1996/12/04 00:27:12 hubbe Exp $"); +RCSID("$Id: program.c,v 1.11 1996/12/05 00:47:18 hubbe Exp $"); #include "program.h" #include "object.h" #include "dynamic_buffer.h" @@ -1452,3 +1452,17 @@ void gc_free_all_unreferenced_programs() } #endif /* GC2 */ + + +void count_memory_in_programs(INT32 *num_, INT32 *size_) +{ + INT32 size=0, num=0; + struct program *p; + for(p=first_program;p;p=p->next) + { + num++; + size+=p->total_size; + } + *num_=num; + *size_=size; +} diff --git a/src/program.h b/src/program.h index e327cb1906..5849c82c5a 100644 --- a/src/program.h +++ b/src/program.h @@ -223,6 +223,7 @@ void gc_mark_program_as_referenced(struct program *p); void gc_check_all_programs(); void gc_mark_all_programs(); void gc_free_all_unreferenced_programs(); +void count_memory_in_programs(INT32 *num_, INT32 *size_); /* Prototypes end here */ diff --git a/src/stralloc.c b/src/stralloc.c index 5be92fab38..4d8d4c0c82 100644 --- a/src/stralloc.c +++ b/src/stralloc.c @@ -526,3 +526,25 @@ void cleanup_shared_string_table() } free((char *)base_table); } + +void count_memory_in_strings(INT32 *num, INT32 *size) +{ + unsigned INT32 e, num_=0, size_=0; + if(!base_table) return; + size_+=htable_size * sizeof(struct pike_string *); + for(e=0;e<htable_size;e++) + { + struct pike_string *p; + for(p=base_table[e];p;p=p->next) + { + num_++; + size_+=sizeof(struct pike_string)+p->len; + } + } +#ifdef DEBUG + if(num_strings != num_) + fatal("Num strings is wrong!.\n"); +#endif + num[0]=num_; + size[0]=size_; +} diff --git a/src/stralloc.h b/src/stralloc.h index a0201a1b55..6b3575679b 100644 --- a/src/stralloc.h +++ b/src/stralloc.h @@ -56,6 +56,7 @@ struct pike_string *string_replace(struct pike_string *str, struct pike_string *to); void init_shared_string_table(); void cleanup_shared_string_table(); +void count_memory_in_strings(INT32 *num, INT32 *size); /* Prototypes end here */ #endif /* STRALLOC_H */ -- GitLab