diff --git a/src/builtin_functions.c b/src/builtin_functions.c index 569454817dc28c34e90950b31ed44e1c155d00b2..5287bcd9f7f082c03bf1c44fe6029a796457c695 100644 --- a/src/builtin_functions.c +++ b/src/builtin_functions.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: builtin_functions.c,v 1.233 2000/01/29 13:42:14 mirar Exp $"); +RCSID("$Id: builtin_functions.c,v 1.234 2000/02/02 00:38:27 hubbe Exp $"); #include "interpret.h" #include "svalue.h" #include "pike_macros.h" @@ -6017,5 +6017,9 @@ void init_builtin_efuns(void) ADD_EFUN("_describe",f__describe, tFunc(tSetvar(1,tMix),tVar(1)),OPT_SIDE_EFFECT); #endif + + ADD_EFUN("_gc_status",f__gc_status, + tFunc(tNone,tMap(tString,tOr(tInt,tFloat))), + OPT_EXTERNAL_DEPEND); } diff --git a/src/gc.c b/src/gc.c index 04ccb8ac97021d6ecba252cb140440b0ca54cb60..a04d1984c37d6952e8dec17835a9463e7d6c2ebc 100644 --- a/src/gc.c +++ b/src/gc.c @@ -21,6 +21,7 @@ struct callback *gc_evaluator_callback=0; #include "pike_types.h" #include "time_stuff.h" #include "constants.h" +#include "interpret.h" #include "gc.h" #include "main.h" @@ -28,7 +29,7 @@ struct callback *gc_evaluator_callback=0; #include "block_alloc.h" -RCSID("$Id: gc.c,v 1.45 2000/02/01 06:24:40 hubbe Exp $"); +RCSID("$Id: gc.c,v 1.46 2000/02/02 00:38:27 hubbe Exp $"); /* Run garbage collect approximate every time we have * 20 percent of all arrays, objects and programs is @@ -59,19 +60,6 @@ struct callback *debug_add_gc_callback(callback_func call, return add_to_callback(&gc_callbacks, call, arg, free_func); } -#define GC_REFERENCED 1 -#define GC_XREFERENCED 2 - -struct marker -{ - INT32 refs; -#ifdef PIKE_DEBUG - INT32 xrefs; -#endif - INT32 flags; - struct marker *next; - void *data; -}; #undef INIT_BLOCK #ifdef PIKE_DEBUG @@ -442,6 +430,7 @@ static void init_gc(void) MEMSET((char *)hash,0,sizeof(struct marker **)*hashsize); markers_left_in_chunk=0; #else +/* init_marker_hash(num_objects*8); */ init_marker_hash(); #endif } @@ -505,11 +494,13 @@ void locate_references(void *a) } #endif -int gc_is_referenced(void *a) +#ifdef PIKE_DEBUG + +int debug_gc_is_referenced(void *a) { struct marker *m; m=get_marker(a); -#ifdef PIKE_DEBUG + if(m->refs + m->xrefs > *(INT32 *)a || (!(m->refs < *(INT32 *)a) && m->xrefs) ) { @@ -527,9 +518,10 @@ int gc_is_referenced(void *a) refs, xrefs); } -#endif + return m->refs < *(INT32 *)a; } +#endif #ifdef PIKE_DEBUG int gc_external_mark(void *a) @@ -570,11 +562,12 @@ int gc_mark(void *a) } } -int gc_do_free(void *a) +#ifdef PIKE_DEBUG +int debug_gc_do_free(void *a) { struct marker *m; m=get_marker(a); -#ifdef PIKE_DEBUG + if( !(m->flags & GC_REFERENCED) && m->flags & GC_XREFERENCED ) { INT32 refs=m->refs; @@ -591,9 +584,10 @@ int gc_do_free(void *a) refs, xrefs); } -#endif + return !(m->flags & GC_REFERENCED); } +#endif void do_gc(void) { @@ -699,3 +693,31 @@ void do_gc(void) } +void f__gc_status(INT32 args) +{ + pop_n_elems(args); + + push_constant_text("num_objects"); + push_int(num_objects); + + push_constant_text("num_allocs"); + push_int(num_allocs); + + push_constant_text("alloc_threshold"); + push_int(alloc_threshold); + + push_constant_text("objects_alloced"); + push_int(objects_alloced); + + push_constant_text("objects_freed"); + push_int(objects_freed); + + push_constant_text("last_gc"); + push_int(last_gc); + + push_constant_text("projected_garbage"); + push_float(objects_freed * (double) num_allocs / (double) alloc_threshold); + + f_aggregate_mapping(14); +} + diff --git a/src/gc.h b/src/gc.h index a879ae136f9d04b9c05d6a5be2b5b28ef06b88fb..988926ad759e4efa2f23f6598640f74b96a0dc12 100644 --- a/src/gc.h +++ b/src/gc.h @@ -1,5 +1,5 @@ /* - * $Id: gc.h,v 1.22 1999/05/02 08:11:42 hubbe Exp $ + * $Id: gc.h,v 1.23 2000/02/02 00:38:27 hubbe Exp $ */ #ifndef GC_H #define GC_H @@ -27,12 +27,24 @@ extern void *gc_svalue_location; #define GC_ALLOC() do{ num_objects++; num_allocs++; if(num_allocs == alloc_threshold && !gc_evaluator_callback) ADD_GC_CALLBACK(); } while(0) #endif +struct marker +{ + struct marker *next; + INT32 refs; +#ifdef PIKE_DEBUG + INT32 xrefs; +#endif + INT32 flags; + void *data; +}; + +#include "block_alloc_h.h" +PTR_HASH_ALLOC(marker,MARKER_CHUNK_SIZE) + /* Prototypes begin here */ struct callback *debug_add_gc_callback(callback_func call, void *arg, callback_func free_func); -struct marker; -struct marker_chunk; void dump_gc_info(void); TYPE_T attempt_to_identify(void *something); void describe_location(void *memblock, TYPE_T type, void *location); @@ -45,11 +57,12 @@ void describe(void *x); void debug_describe_svalue(struct svalue *s); INT32 gc_check(void *a); void locate_references(void *a); -int gc_is_referenced(void *a); +int debug_gc_is_referenced(void *a); int gc_external_mark(void *a); int gc_mark(void *a); -int gc_do_free(void *a); +int debug_gc_do_free(void *a); void do_gc(void); +void f__gc_status(INT32 args); /* Prototypes end here */ #ifdef PIKE_DEBUG @@ -66,4 +79,16 @@ void do_gc(void); #define add_gc_callback(X,Y,Z) \ dmalloc_touch(struct callback *,debug_add_gc_callback((X),(Y),(Z))) +#define GC_REFERENCED 1 +#define GC_XREFERENCED 2 + + +#ifdef PIKE_DEBUG +#define gc_is_referenced debug_gc_is_referenced +#define gc_do_free debug_gc_do_free +#else +#define gc_is_referenced(X) (get_marker(X)->refs < *(INT32 *)(X)) +#define gc_do_free(X) ( ! (get_marker(X)->flags & GC_REFERENCED ) ) +#endif + #endif