e576bb | 2002-10-11 | Martin Nilsson | | |
eb4aba | 2007-05-26 | Martin Stjernholm | | || $Id: gc.c,v 1.285 2007/05/26 18:35:29 mast Exp $
|
e576bb | 2002-10-11 | Martin Nilsson | | */
|
aedfb1 | 2002-10-09 | Martin Nilsson | |
|
693018 | 1996-02-25 | Fredrik Hübinette (Hubbe) | | #include "global.h"
|
a29e02 | 1996-10-15 | Fredrik Hübinette (Hubbe) | | struct callback *gc_evaluator_callback=0;
|
c94c37 | 1996-03-28 | Fredrik Hübinette (Hubbe) | | #include "array.h"
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | #include "multiset.h"
|
c94c37 | 1996-03-28 | Fredrik Hübinette (Hubbe) | | #include "mapping.h"
#include "object.h"
#include "program.h"
|
4a578f | 1997-01-27 | Fredrik Hübinette (Hubbe) | | #include "stralloc.h"
|
9c6f7d | 1997-04-15 | Fredrik Hübinette (Hubbe) | | #include "stuff.h"
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | #include "pike_error.h"
|
9aa6fa | 1997-05-19 | Fredrik Hübinette (Hubbe) | | #include "pike_memory.h"
|
1a1168 | 1997-10-06 | Fredrik Hübinette (Hubbe) | | #include "pike_macros.h"
|
51adb8 | 2003-01-12 | Martin Stjernholm | | #include "pike_rusage.h"
|
1ca3ba | 1997-10-13 | Fredrik Hübinette (Hubbe) | | #include "pike_types.h"
|
dc296b | 1997-10-21 | Fredrik Hübinette (Hubbe) | | #include "time_stuff.h"
|
2eeba9 | 1999-03-17 | Fredrik Hübinette (Hubbe) | | #include "constants.h"
|
1637c4 | 2000-02-01 | Fredrik Hübinette (Hubbe) | | #include "interpret.h"
|
132f0d | 2000-08-13 | Henrik Grubbström (Grubba) | | #include "bignum.h"
|
cd9aec | 2003-02-09 | Martin Stjernholm | | #include "pike_threadlib.h"
|
c94c37 | 1996-03-28 | Fredrik Hübinette (Hubbe) | |
|
693018 | 1996-02-25 | Fredrik Hübinette (Hubbe) | | #include "gc.h"
#include "main.h"
|
dc296b | 1997-10-21 | Fredrik Hübinette (Hubbe) | | #include <math.h>
|
693018 | 1996-02-25 | Fredrik Hübinette (Hubbe) | |
|
374109 | 1999-09-25 | Henrik Grubbström (Grubba) | | #include "block_alloc.h"
|
51adb8 | 2003-01-12 | Martin Stjernholm | | int gc_enabled = 1;
|
51955c | 2003-01-11 | Martin Stjernholm | |
|
51adb8 | 2003-01-12 | Martin Stjernholm | |
double gc_garbage_ratio_low = 0.2;
double gc_time_ratio = 0.05;
double gc_garbage_ratio_high = 0.5;
|
51955c | 2003-01-11 | Martin Stjernholm | |
|
51adb8 | 2003-01-12 | Martin Stjernholm | |
double gc_average_slowness = 0.9;
|
51955c | 2003-01-11 | Martin Stjernholm | |
|
5b1275 | 2007-05-23 | Martin Stjernholm | | |
e2d9e6 | 2000-06-10 | Martin Stjernholm | | *
* o If an object A references B single way, then A is destructed
* before B.
* o If A and B are in a cycle, and there is a reference somewhere
* from B to A that is weaker than any reference from A to B, then
|
e7634f | 2007-05-13 | Martin Stjernholm | | * the cycle is resolved by disregarding the weaker reference, and
* A is therefore destructed before B.
* o If a cycle is resolved through disregarding a weaker reference
* according to the preceding rule, and there is another cycle
* without weak references which also gets resolved through
* disregarding the same reference, then the other cycle won't be
* resolved by disregarding some other reference.
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | * o Weak references are considered weaker than normal ones, and both
* are considered weaker than strong references.
* o Strong references are used in special cases like parent object
* references. There can never be a cycle consisting only of strong
* references. (This means the gc will never destruct a parent
|
22aa2f | 2000-09-04 | Martin Stjernholm | | * object before all children have been destructed.)
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | *
* The gc tries to detect and warn about cases where there are live
* objects with no well defined order between them. There are cases
* that are missed by this detection, though.
*
* Things that aren't live objects but are referenced from them are
* still intact during this destruct pass, so it's entirely possible
|
22aa2f | 2000-09-04 | Martin Stjernholm | | * to save them by adding external references to them. However, it's
* not possible for live objects to save themselves or other live
* objects; all live objects that didn't have external references at
* the start of the gc pass will be destructed regardless of added
* references.
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | *
|
10c4a4 | 2000-08-17 | Martin Stjernholm | | * Things that have only weak external references at the start of the
* gc pass will be freed. That's done before the live object destruct
* pass. Internal weak references are however still intact.
|
79566d | 2004-03-15 | Martin Stjernholm | | *
* Note: Keep the doc for lfun::destroy up-to-date with the above.
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | */
|
d9dd81 | 2000-06-12 | Martin Stjernholm | |
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | |
|
45d87e | 2000-07-18 | Martin Stjernholm | |
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | #if defined(GC_VERBOSE) && !defined(PIKE_DEBUG)
#undef GC_VERBOSE
#endif
#ifdef GC_VERBOSE
#define GC_VERBOSE_DO(X) X
#else
#define GC_VERBOSE_DO(X)
#endif
|
693018 | 1996-02-25 | Fredrik Hübinette (Hubbe) | |
|
5272b2 | 2004-09-22 | Martin Stjernholm | | int num_objects = 2;
|
88ef97 | 2004-03-19 | Martin Stjernholm | | ALLOC_COUNT_TYPE num_allocs =0;
ALLOC_COUNT_TYPE alloc_threshold = GC_MIN_ALLOC_THRESHOLD;
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT int Pike_in_gc = 0;
|
9a6d00 | 2001-06-26 | Fredrik Hübinette (Hubbe) | | int gc_generation = 0;
|
0d9f93 | 2003-01-14 | Martin Stjernholm | | time_t last_gc;
|
50d97a | 2003-02-01 | Martin Stjernholm | | int gc_trace = 0, gc_debug = 0;
|
57cfbd | 2004-03-15 | Martin Stjernholm | | #ifdef DO_PIKE_CLEANUP
int gc_destruct_everything = 0;
#endif
|
e7634f | 2007-05-13 | Martin Stjernholm | | size_t gc_ext_weak_refs;
|
4452c1 | 2000-02-02 | Fredrik Hübinette (Hubbe) | |
|
e7634f | 2007-05-13 | Martin Stjernholm | | static double objects_alloced = 0.0;
static double objects_freed = 0.0;
static double gc_time = 0.0, non_gc_time = 0.0;
static cpu_time_t last_gc_end_time = 0;
#if CPU_TIME_IS_THREAD_LOCAL == PIKE_NO
cpu_time_t auto_gc_time = 0;
#endif
|
1bad5c | 2005-04-14 | Martin Stjernholm | |
|
e7634f | 2007-05-13 | Martin Stjernholm | | struct link_frame
|
1bad5c | 2005-04-14 | Martin Stjernholm | | {
|
e7634f | 2007-05-13 | Martin Stjernholm | | void *data;
struct link_frame *prev;
gc_cycle_check_cb *checkfn;
int weak;
|
1bad5c | 2005-04-14 | Martin Stjernholm | | };
|
e7634f | 2007-05-13 | Martin Stjernholm | | struct gc_rec_frame
|
1bad5c | 2005-04-14 | Martin Stjernholm | | {
|
e7634f | 2007-05-13 | Martin Stjernholm | | void *data;
int rf_flags;
struct gc_rec_frame *prev;
struct gc_rec_frame *next;
struct gc_rec_frame *cycle_id;
struct gc_rec_frame *cycle_piece;
union {
struct link_frame *link_top;
struct gc_rec_frame *last_cycle_piece;
} u;
|
1bad5c | 2005-04-14 | Martin Stjernholm | | };
|
e7634f | 2007-05-13 | Martin Stjernholm | |
#define GC_PREV_WEAK 0x01
#define GC_PREV_STRONG 0x02
#define GC_PREV_BROKEN 0x04
#define GC_MARK_LIVE 0x08
#define GC_ON_KILL_LIST 0x10
#ifdef PIKE_DEBUG
#define GC_ON_CYCLE_PIECE_LIST 0x20
#define GC_FRAME_FREED 0x40
#define GC_FOLLOWED_NONSTRONG 0x80
#endif
static struct gc_rec_frame sentinel_frame = {
(void *) (ptrdiff_t) -1,
0,
(struct gc_rec_frame *) (ptrdiff_t) -1,
(struct gc_rec_frame *) (ptrdiff_t) -1,
&sentinel_frame,
(struct gc_rec_frame *) (ptrdiff_t) -1,
{(struct link_frame *) (ptrdiff_t) -1}
|
1bad5c | 2005-04-14 | Martin Stjernholm | | };
|
e7634f | 2007-05-13 | Martin Stjernholm | | static struct gc_rec_frame *stack_top = &sentinel_frame;
static struct gc_rec_frame *kill_list = &sentinel_frame;
|
1bad5c | 2005-04-14 | Martin Stjernholm | |
|
e7634f | 2007-05-13 | Martin Stjernholm | |
struct free_extra_frame
|
45d87e | 2000-07-18 | Martin Stjernholm | | {
void *data;
|
e7634f | 2007-05-13 | Martin Stjernholm | | struct free_extra_frame *next;
|
1bad5c | 2005-04-14 | Martin Stjernholm | | int type;
};
|
e7634f | 2007-05-13 | Martin Stjernholm | | static struct free_extra_frame *free_extra_list = NULL;
|
1bad5c | 2005-04-14 | Martin Stjernholm | |
|
e7634f | 2007-05-13 | Martin Stjernholm | | #ifdef PIKE_DEBUG
static unsigned delayed_freed, weak_freed, checked, marked, cycle_checked, live_ref;
static unsigned mark_live, frame_rot, link_search;
static unsigned gc_extra_refs = 0;
static unsigned tot_cycle_checked = 0, tot_mark_live = 0, tot_frame_rot = 0;
static unsigned gc_rec_frame_seq_max;
#endif
static unsigned rec_frames, link_frames, free_extra_frames;
static unsigned max_rec_frames, max_link_frames;
static unsigned tot_max_rec_frames = 0, tot_max_link_frames = 0, tot_max_free_extra_frames = 0;
#undef INIT_BLOCK
#define INIT_BLOCK(f) do { \
if (++rec_frames > max_rec_frames) \
max_rec_frames = rec_frames; \
} while (0)
#undef EXIT_BLOCK
#define EXIT_BLOCK(f) do { \
DO_IF_DEBUG ({ \
if (f->rf_flags & GC_FRAME_FREED) \
gc_fatal (f->data, 0, "Freeing gc_rec_frame twice.\n"); \
f->rf_flags |= GC_FRAME_FREED; \
f->u.link_top = (struct link_frame *) (ptrdiff_t) -1; \
f->prev = f->next = f->cycle_id = f->cycle_piece = \
(struct gc_rec_frame *) (ptrdiff_t) -1; \
}); \
rec_frames--; \
} while (0)
BLOCK_ALLOC_FILL_PAGES (gc_rec_frame, 2)
struct ba_mixed_frame
|
1bad5c | 2005-04-14 | Martin Stjernholm | | {
|
45d87e | 2000-07-18 | Martin Stjernholm | | union {
|
e7634f | 2007-05-13 | Martin Stjernholm | | struct link_frame link;
struct free_extra_frame free_extra;
struct ba_mixed_frame *next;
|
45d87e | 2000-07-18 | Martin Stjernholm | | } u;
};
#undef BLOCK_ALLOC_NEXT
|
1bad5c | 2005-04-14 | Martin Stjernholm | | #define BLOCK_ALLOC_NEXT u.next
|
e7634f | 2007-05-13 | Martin Stjernholm | | #undef INIT_BLOCK
#define INIT_BLOCK(f)
#undef EXIT_BLOCK
#define EXIT_BLOCK(f)
|
45d87e | 2000-07-18 | Martin Stjernholm | |
|
e7634f | 2007-05-13 | Martin Stjernholm | | BLOCK_ALLOC_FILL_PAGES (ba_mixed_frame, 2)
|
1bad5c | 2005-04-14 | Martin Stjernholm | |
|
e7634f | 2007-05-13 | Martin Stjernholm | | static INLINE struct link_frame *alloc_link_frame()
|
1bad5c | 2005-04-14 | Martin Stjernholm | | {
|
e7634f | 2007-05-13 | Martin Stjernholm | | struct ba_mixed_frame *f = alloc_ba_mixed_frame();
if (++link_frames > max_link_frames)
max_link_frames = link_frames;
return (struct link_frame *) f;
|
1bad5c | 2005-04-14 | Martin Stjernholm | | }
|
e7634f | 2007-05-13 | Martin Stjernholm | | static INLINE struct free_extra_frame *alloc_free_extra_frame()
|
1bad5c | 2005-04-14 | Martin Stjernholm | | {
|
e7634f | 2007-05-13 | Martin Stjernholm | | struct ba_mixed_frame *f = alloc_ba_mixed_frame();
free_extra_frames++;
return (struct free_extra_frame *) f;
|
1bad5c | 2005-04-14 | Martin Stjernholm | | }
|
e7634f | 2007-05-13 | Martin Stjernholm | | static INLINE void really_free_link_frame (struct link_frame *f)
|
1bad5c | 2005-04-14 | Martin Stjernholm | | {
|
e7634f | 2007-05-13 | Martin Stjernholm | | link_frames--;
really_free_ba_mixed_frame ((struct ba_mixed_frame *) f);
|
1bad5c | 2005-04-14 | Martin Stjernholm | | }
|
e7634f | 2007-05-13 | Martin Stjernholm | | static INLINE void really_free_free_extra_frame (struct free_extra_frame *f)
|
1bad5c | 2005-04-14 | Martin Stjernholm | | {
|
e7634f | 2007-05-13 | Martin Stjernholm | | free_extra_frames--;
really_free_ba_mixed_frame ((struct ba_mixed_frame *) f);
|
1bad5c | 2005-04-14 | Martin Stjernholm | | }
|
51adb8 | 2003-01-12 | Martin Stjernholm | |
static double last_garbage_ratio = 0.0;
static enum {
GARBAGE_RATIO_LOW, GARBAGE_RATIO_HIGH
} last_garbage_strategy = GARBAGE_RATIO_LOW;
|
693018 | 1996-02-25 | Fredrik Hübinette (Hubbe) | |
|
4a578f | 1997-01-27 | Fredrik Hübinette (Hubbe) | | struct callback_list gc_callbacks;
|
030541 | 2003-09-29 | Martin Stjernholm | |
|
424d9c | 1999-05-02 | Fredrik Hübinette (Hubbe) | | struct callback *debug_add_gc_callback(callback_func call,
|
e7634f | 2007-05-13 | Martin Stjernholm | | void *arg,
callback_func free_func)
|
4a578f | 1997-01-27 | Fredrik Hübinette (Hubbe) | | {
return add_to_callback(&gc_callbacks, call, arg, free_func);
}
|
1e9121 | 2001-07-05 | Martin Stjernholm | | static void init_gc(void);
|
e7634f | 2007-05-13 | Martin Stjernholm | | static void gc_cycle_pop();
|
45d87e | 2000-07-18 | Martin Stjernholm | |
#undef BLOCK_ALLOC_NEXT
#define BLOCK_ALLOC_NEXT next
|
c94c37 | 1996-03-28 | Fredrik Hübinette (Hubbe) | |
|
424d9c | 1999-05-02 | Fredrik Hübinette (Hubbe) | | #undef INIT_BLOCK
|
71f3a2 | 1998-11-22 | Fredrik Hübinette (Hubbe) | | #ifdef PIKE_DEBUG
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | #define INIT_BLOCK(X) \
(X)->flags=(X)->refs=(X)->weak_refs=(X)->xrefs=0; \
|
081629 | 2000-07-03 | Martin Stjernholm | | (X)->saved_refs=-1; \
|
45d87e | 2000-07-18 | Martin Stjernholm | | (X)->frame = 0;
|
424d9c | 1999-05-02 | Fredrik Hübinette (Hubbe) | | #else
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | #define INIT_BLOCK(X) \
|
45d87e | 2000-07-18 | Martin Stjernholm | | (X)->flags=(X)->refs=(X)->weak_refs=0; \
(X)->frame = 0;
|
05c7cd | 1997-07-19 | Fredrik Hübinette (Hubbe) | | #endif
|
c94c37 | 1996-03-28 | Fredrik Hübinette (Hubbe) | |
|
22aa2f | 2000-09-04 | Martin Stjernholm | | #undef get_marker
#define get_marker debug_get_marker
#undef find_marker
#define find_marker debug_find_marker
|
3aab37 | 2002-11-24 | Martin Stjernholm | | PTR_HASH_ALLOC_FIXED_FILL_PAGES(marker,2)
|
c94c37 | 1996-03-28 | Fredrik Hübinette (Hubbe) | |
|
11a5af | 2006-08-06 | Martin Stjernholm | | #undef get_marker
#define get_marker(X) ((struct marker *) debug_malloc_pass(debug_get_marker(X)))
#undef find_marker
#define find_marker(X) ((struct marker *) debug_malloc_pass(debug_find_marker(X)))
PMOD_EXPORT struct marker *pmod_get_marker (void *p)
{
return debug_get_marker (p);
}
PMOD_EXPORT struct marker *pmod_find_marker (void *p)
{
return debug_find_marker (p);
}
|
e1a35e | 2003-09-08 | Martin Stjernholm | | #if defined (PIKE_DEBUG) || defined (GC_MARK_DEBUG)
void *gc_found_in = NULL;
int gc_found_in_type = PIKE_T_UNKNOWN;
const char *gc_found_place = NULL;
#endif
|
3b6567 | 2004-05-23 | Martin Nilsson | | #ifdef DO_PIKE_CLEANUP
int gc_keep_markers = 0;
|
a5a334 | 2006-07-05 | Martin Stjernholm | | PMOD_EXPORT int gc_external_refs_zapped = 0;
|
3b6567 | 2004-05-23 | Martin Nilsson | | #endif
|
e7634f | 2007-05-13 | Martin Stjernholm | | #if defined (PIKE_DEBUG) || defined (GC_CYCLE_DEBUG)
static void describe_rec_frame (struct gc_rec_frame *f)
{
fprintf (stderr, "data=%p rf_flags=0x%02x prev=%p next=%p "
"cycle_id=%p cycle_piece=%p link_top/last_cycle_piece=%p",
f->data, f->rf_flags, f->prev, f->next,
f->cycle_id, f->cycle_piece, f->u.link_top);
}
#endif
|
71f3a2 | 1998-11-22 | Fredrik Hübinette (Hubbe) | | #ifdef PIKE_DEBUG
|
1ca3ba | 1997-10-13 | Fredrik Hübinette (Hubbe) | |
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | int gc_in_cycle_check = 0;
|
8e6d5c | 2001-07-02 | Martin Stjernholm | |
|
1e9121 | 2001-07-05 | Martin Stjernholm | | static int gc_is_watching = 0;
|
e1a35e | 2003-09-08 | Martin Stjernholm | | int attempt_to_identify(void *something, void **inblock)
|
1ca3ba | 1997-10-13 | Fredrik Hübinette (Hubbe) | | {
|
60c15a | 2003-08-20 | Martin Stjernholm | | size_t i;
|
1ca3ba | 1997-10-13 | Fredrik Hübinette (Hubbe) | | struct array *a;
struct object *o;
struct program *p;
|
62971d | 1998-01-19 | Fredrik Hübinette (Hubbe) | | struct mapping *m;
struct multiset *mu;
|
60c15a | 2003-08-20 | Martin Stjernholm | | struct pike_type *t;
struct callable *c;
|
1ca3ba | 1997-10-13 | Fredrik Hübinette (Hubbe) | |
|
b35129 | 2001-08-20 | Martin Stjernholm | | if (inblock) *inblock = 0;
|
cd451f | 2004-03-15 | Martin Stjernholm | | for (a = first_array; a; a = a->next) {
|
1ca3ba | 1997-10-13 | Fredrik Hübinette (Hubbe) | | if(a==(struct array *)something) return T_ARRAY;
|
cd451f | 2004-03-15 | Martin Stjernholm | | }
|
1ca3ba | 1997-10-13 | Fredrik Hübinette (Hubbe) | |
|
b35129 | 2001-08-20 | Martin Stjernholm | | for(o=first_object;o;o=o->next) {
|
1ca3ba | 1997-10-13 | Fredrik Hübinette (Hubbe) | | if(o==(struct object *)something)
return T_OBJECT;
|
b35129 | 2001-08-20 | Martin Stjernholm | | if (o->storage && o->prog &&
(char *) something >= o->storage &&
(char *) something < o->storage + o->prog->storage_needed) {
if (inblock) *inblock = (void *) o;
return T_STORAGE;
}
}
|
1ca3ba | 1997-10-13 | Fredrik Hübinette (Hubbe) | |
|
55530f | 2000-09-30 | Martin Stjernholm | | for(p=first_program;p;p=p->next)
|
1ca3ba | 1997-10-13 | Fredrik Hübinette (Hubbe) | | if(p==(struct program *)something)
return T_PROGRAM;
|
55530f | 2000-09-30 | Martin Stjernholm | | for(m=first_mapping;m;m=m->next)
|
62971d | 1998-01-19 | Fredrik Hübinette (Hubbe) | | if(m==(struct mapping *)something)
return T_MAPPING;
|
22aa2f | 2000-09-04 | Martin Stjernholm | | else if (m->data == (struct mapping_data *) something)
return T_MAPPING_DATA;
|
62971d | 1998-01-19 | Fredrik Hübinette (Hubbe) | |
|
55530f | 2000-09-30 | Martin Stjernholm | | for(mu=first_multiset;mu;mu=mu->next)
|
62971d | 1998-01-19 | Fredrik Hübinette (Hubbe) | | if(mu==(struct multiset *)something)
return T_MULTISET;
|
5b15bb | 2001-12-10 | Martin Stjernholm | | else if (mu->msd == (struct multiset_data *) something)
return T_MULTISET_DATA;
|
62971d | 1998-01-19 | Fredrik Hübinette (Hubbe) | |
if(safe_debug_findstring((struct pike_string *)something))
return T_STRING;
|
4fab5f | 2004-04-18 | Martin Stjernholm | | if (pike_type_hash)
for (i = 0; i < pike_type_hash_size; i++)
for (t = pike_type_hash[i]; t; t = t->next)
if (t == (struct pike_type *) something)
return T_TYPE;
|
60c15a | 2003-08-20 | Martin Stjernholm | |
for (c = first_callable; c; c = c->next)
if (c == (struct callable *) something)
return T_STRUCT_CALLABLE;
|
04966d | 2000-10-03 | Fredrik Hübinette (Hubbe) | | return PIKE_T_UNKNOWN;
|
1ca3ba | 1997-10-13 | Fredrik Hübinette (Hubbe) | | }
|
20513c | 2000-04-12 | Fredrik Hübinette (Hubbe) | | void *check_for =0;
|
f6d017 | 1997-10-15 | Fredrik Hübinette (Hubbe) | | void *gc_svalue_location=0;
|
884c12 | 2004-03-15 | Martin Stjernholm | | static size_t found_ref_count;
|
06ae27 | 2000-04-19 | Martin Stjernholm | | char *fatal_after_gc=0;
|
ad2bdb | 2000-04-12 | Fredrik Hübinette (Hubbe) | |
|
a4033e | 2000-04-14 | Fredrik Hübinette (Hubbe) | | #define DESCRIBE_MEM 1
#define DESCRIBE_SHORT 4
#define DESCRIBE_NO_DMALLOC 8
|
ad2bdb | 2000-04-12 | Fredrik Hübinette (Hubbe) | |
|
a4033e | 2000-04-14 | Fredrik Hübinette (Hubbe) | |
void describe_location(void *real_memblock,
|
b35129 | 2001-08-20 | Martin Stjernholm | | int type,
|
a4033e | 2000-04-14 | Fredrik Hübinette (Hubbe) | | void *location,
int indent,
int depth,
int flags)
|
356810 | 1997-10-16 | Fredrik Hübinette (Hubbe) | | {
|
1e4e5f | 2000-04-07 | Fredrik Hübinette (Hubbe) | | struct program *p;
|
b35129 | 2001-08-20 | Martin Stjernholm | | void *memblock=0, *descblock, *inblock;
|
469411 | 1997-11-07 | Fredrik Hübinette (Hubbe) | | if(!location) return;
|
1e4e5f | 2000-04-07 | Fredrik Hübinette (Hubbe) | |
|
62971d | 1998-01-19 | Fredrik Hübinette (Hubbe) | |
|
b35129 | 2001-08-20 | Martin Stjernholm | | if(type!=-1 && real_memblock != (void *) -1) memblock=real_memblock;
|
a4033e | 2000-04-14 | Fredrik Hübinette (Hubbe) | |
|
20513c | 2000-04-12 | Fredrik Hübinette (Hubbe) | | #ifdef DEBUG_MALLOC
if(memblock == 0 || type == -1)
{
extern void *dmalloc_find_memblock_base(void *);
memblock=dmalloc_find_memblock_base(location);
}
#endif
|
04966d | 2000-10-03 | Fredrik Hübinette (Hubbe) | | if(type==PIKE_T_UNKNOWN)
|
b35129 | 2001-08-20 | Martin Stjernholm | | type=attempt_to_identify(memblock, &inblock);
|
20513c | 2000-04-12 | Fredrik Hübinette (Hubbe) | |
if(memblock)
|
e1be4f | 2001-07-01 | Martin Stjernholm | | fprintf(stderr,"%*s-> from %s %p offset %"PRINTPTRDIFFT"d\n",
|
a4033e | 2000-04-14 | Fredrik Hübinette (Hubbe) | | indent,"",
|
20513c | 2000-04-12 | Fredrik Hübinette (Hubbe) | | get_name_of_type(type),
memblock,
|
e1be4f | 2001-07-01 | Martin Stjernholm | | (char *)location - (char *)memblock);
|
20513c | 2000-04-12 | Fredrik Hübinette (Hubbe) | | else
|
d9d6f0 | 2001-06-30 | Martin Stjernholm | | fprintf(stderr,"%*s-> at location %p%s\n",
|
a4033e | 2000-04-14 | Fredrik Hübinette (Hubbe) | | indent,"",
|
d9d6f0 | 2001-06-30 | Martin Stjernholm | | location,
real_memblock == (void *) -1 ? "" : " in unknown memblock (mmaped?)");
|
20513c | 2000-04-12 | Fredrik Hübinette (Hubbe) | |
|
a4033e | 2000-04-14 | Fredrik Hübinette (Hubbe) | | again:
|
d9d6f0 | 2001-06-30 | Martin Stjernholm | | descblock = memblock;
|
62971d | 1998-01-19 | Fredrik Hübinette (Hubbe) | | switch(type)
|
356810 | 1997-10-16 | Fredrik Hübinette (Hubbe) | | {
|
04966d | 2000-10-03 | Fredrik Hübinette (Hubbe) | | case PIKE_T_UNKNOWN:
|
1e4e5f | 2000-04-07 | Fredrik Hübinette (Hubbe) | | for(p=first_program;p;p=p->next)
{
if(memblock == (void *)p->program)
{
|
a4033e | 2000-04-14 | Fredrik Hübinette (Hubbe) | | fprintf(stderr,"%*s **In memory block for program at %p\n",
indent,"",
p);
|
1e4e5f | 2000-04-07 | Fredrik Hübinette (Hubbe) | | memblock=p;
type=T_PROGRAM;
|
a4033e | 2000-04-14 | Fredrik Hübinette (Hubbe) | | goto again;
|
1e4e5f | 2000-04-07 | Fredrik Hübinette (Hubbe) | | }
}
break;
|
0b6944 | 1998-01-19 | Fredrik Hübinette (Hubbe) | | case T_PROGRAM:
{
|
9c815b | 2000-08-10 | Henrik Grubbström (Grubba) | | ptrdiff_t e;
|
0b6944 | 1998-01-19 | Fredrik Hübinette (Hubbe) | | char *ptr=(char *)location;
|
a4033e | 2000-04-14 | Fredrik Hübinette (Hubbe) | | p=(struct program *)memblock;
|
0b6944 | 1998-01-19 | Fredrik Hübinette (Hubbe) | |
|
1e4e5f | 2000-04-07 | Fredrik Hübinette (Hubbe) | | if(location == (void *)&p->prev)
|
a4033e | 2000-04-14 | Fredrik Hübinette (Hubbe) | | fprintf(stderr,"%*s **In p->prev\n",indent,"");
|
1e4e5f | 2000-04-07 | Fredrik Hübinette (Hubbe) | |
if(location == (void *)&p->next)
|
a4033e | 2000-04-14 | Fredrik Hübinette (Hubbe) | | fprintf(stderr,"%*s **In p->next\n",indent,"");
|
1e4e5f | 2000-04-07 | Fredrik Hübinette (Hubbe) | |
|
f3c715 | 2001-04-14 | Fredrik Hübinette (Hubbe) | | if(location == (void *)&p->parent)
fprintf(stderr,"%*s **In p->parent\n",indent,"");
|
a4033e | 2000-04-14 | Fredrik Hübinette (Hubbe) | | if(p->inherits &&
ptr >= (char *)p->inherits &&
|
f00c36 | 2000-08-10 | Henrik Grubbström (Grubba) | | ptr < (char*)(p->inherits+p->num_inherits))
|
1e4e5f | 2000-04-07 | Fredrik Hübinette (Hubbe) | | {
|
f00c36 | 2000-08-10 | Henrik Grubbström (Grubba) | | e=((char *)ptr - (char *)(p->inherits)) / sizeof(struct inherit);
|
e1be4f | 2001-07-01 | Martin Stjernholm | | fprintf(stderr,"%*s **In p->inherits[%"PRINTPTRDIFFT"d] (%s)\n",indent,"",
e, p->inherits[e].name ? p->inherits[e].name->str : "no name");
|
dfe8f3 | 2000-04-26 | Fredrik Hübinette (Hubbe) | | break;
|
1e4e5f | 2000-04-07 | Fredrik Hübinette (Hubbe) | | }
|
a4033e | 2000-04-14 | Fredrik Hübinette (Hubbe) | | if(p->constants &&
ptr >= (char *)p->constants &&
|
f00c36 | 2000-08-10 | Henrik Grubbström (Grubba) | | ptr < (char*)(p->constants+p->num_constants))
|
1e4e5f | 2000-04-07 | Fredrik Hübinette (Hubbe) | | {
|
f00c36 | 2000-08-10 | Henrik Grubbström (Grubba) | | e = ((char *)ptr - (char *)(p->constants)) /
|
9c815b | 2000-08-10 | Henrik Grubbström (Grubba) | | sizeof(struct program_constant);
|
4ea54f | 2004-05-29 | Henrik Grubbström (Grubba) | | #if 0
|
e1be4f | 2001-07-01 | Martin Stjernholm | | fprintf(stderr,"%*s **In p->constants[%"PRINTPTRDIFFT"d] (%s)\n",indent,"",
e, p->constants[e].name ? p->constants[e].name->str : "no name");
|
4ea54f | 2004-05-29 | Henrik Grubbström (Grubba) | | #else /* !0 */
|
2ac3f5 | 2005-04-06 | Henrik Grubbström (Grubba) | | fprintf(stderr,"%*s **In p->constants[%"PRINTPTRDIFFT"d] "
|
2d76f2 | 2005-05-20 | Martin Stjernholm | | "(%"PRINTPTRDIFFT"d)\n",indent,"",
|
4ea54f | 2004-05-29 | Henrik Grubbström (Grubba) | | e, p->constants[e].offset);
#endif /* 0 */
|
dfe8f3 | 2000-04-26 | Fredrik Hübinette (Hubbe) | | break;
|
1e4e5f | 2000-04-07 | Fredrik Hübinette (Hubbe) | | }
|
0b6944 | 1998-01-19 | Fredrik Hübinette (Hubbe) | |
|
a4033e | 2000-04-14 | Fredrik Hübinette (Hubbe) | | if(p->identifiers &&
ptr >= (char *)p->identifiers &&
|
f00c36 | 2000-08-10 | Henrik Grubbström (Grubba) | | ptr < (char*)(p->identifiers+p->num_identifiers))
|
1e4e5f | 2000-04-07 | Fredrik Hübinette (Hubbe) | | {
|
f00c36 | 2000-08-10 | Henrik Grubbström (Grubba) | | e = ((char *)ptr - (char *)(p->identifiers)) /
|
9c815b | 2000-08-10 | Henrik Grubbström (Grubba) | | sizeof(struct identifier);
|
074d0a | 2001-02-27 | Fredrik Hübinette (Hubbe) | |
|
e1be4f | 2001-07-01 | Martin Stjernholm | | fprintf(stderr,"%*s **In p->identifiers[%"PRINTPTRDIFFT"d] (%s)\n",indent,"",
e, p->identifiers[e].name ?
|
074d0a | 2001-02-27 | Fredrik Hübinette (Hubbe) | | (strlen(p->identifiers[e].name->str)<100 ? p->identifiers[e].name->str : "Name too long or already freed.." )
: "no name");
|
dfe8f3 | 2000-04-26 | Fredrik Hübinette (Hubbe) | | break;
|
1e4e5f | 2000-04-07 | Fredrik Hübinette (Hubbe) | | }
|
7e877a | 2003-04-02 | Martin Stjernholm | | #define FOO(NUMTYPE,TYPE,ARGTYPE,NAME) \
|
a4033e | 2000-04-14 | Fredrik Hübinette (Hubbe) | | if(location == (void *)&p->NAME) fprintf(stderr,"%*s **In p->" #NAME "\n",indent,""); \
|
1e4e5f | 2000-04-07 | Fredrik Hübinette (Hubbe) | | if(ptr >= (char *)p->NAME && ptr<(char*)(p->NAME+p->PIKE_CONCAT(num_,NAME))) \
|
e1be4f | 2001-07-01 | Martin Stjernholm | | fprintf(stderr,"%*s **In p->" #NAME "[%"PRINTPTRDIFFT"d]\n",indent,"", \
|
7e877a | 2003-04-02 | Martin Stjernholm | | ((char *)ptr - (char *)(p->NAME)) / sizeof(TYPE));
|
1e4e5f | 2000-04-07 | Fredrik Hübinette (Hubbe) | | #include "program_areas.h"
|
0b6944 | 1998-01-19 | Fredrik Hübinette (Hubbe) | |
|
dfe8f3 | 2000-04-26 | Fredrik Hübinette (Hubbe) | | break;
|
0b6944 | 1998-01-19 | Fredrik Hübinette (Hubbe) | | }
|
b35129 | 2001-08-20 | Martin Stjernholm | |
|
62971d | 1998-01-19 | Fredrik Hübinette (Hubbe) | | case T_OBJECT:
|
356810 | 1997-10-16 | Fredrik Hübinette (Hubbe) | | {
|
62971d | 1998-01-19 | Fredrik Hübinette (Hubbe) | | struct object *o=(struct object *)memblock;
|
1e4e5f | 2000-04-07 | Fredrik Hübinette (Hubbe) | | struct program *p;
|
f3c715 | 2001-04-14 | Fredrik Hübinette (Hubbe) | | if(o->prog && o->prog->flags & PROGRAM_USES_PARENT)
{
if(location == (void *)&PARENT_INFO(o)->parent)
fprintf(stderr,"%*s **In o->parent\n",indent,"");
}
|
a4033e | 2000-04-14 | Fredrik Hübinette (Hubbe) | | if(location == (void *)&o->prog) fprintf(stderr,"%*s **In o->prog\n",indent,"");
if(location == (void *)&o->next) fprintf(stderr,"%*s **In o->next\n",indent,"");
if(location == (void *)&o->prev) fprintf(stderr,"%*s **In o->prev\n",indent,"");
|
1e4e5f | 2000-04-07 | Fredrik Hübinette (Hubbe) | |
p=o->prog;
if(!o->prog)
{
p=id_to_program(o->program_id);
if(p)
|
a4033e | 2000-04-14 | Fredrik Hübinette (Hubbe) | | fprintf(stderr,"%*s **(We are lucky, found program for destructed object)\n",indent,"");
|
1e4e5f | 2000-04-07 | Fredrik Hübinette (Hubbe) | | }
if(p)
|
356810 | 1997-10-16 | Fredrik Hübinette (Hubbe) | | {
|
62971d | 1998-01-19 | Fredrik Hübinette (Hubbe) | | INT32 e,d;
|
1e4e5f | 2000-04-07 | Fredrik Hübinette (Hubbe) | | for(e=0;e<(INT32)p->num_inherits;e++)
|
356810 | 1997-10-16 | Fredrik Hübinette (Hubbe) | | {
|
1e4e5f | 2000-04-07 | Fredrik Hübinette (Hubbe) | | struct inherit tmp=p->inherits[e];
|
62971d | 1998-01-19 | Fredrik Hübinette (Hubbe) | | char *base=o->storage + tmp.storage_offset;
for(d=0;d<(INT32)tmp.prog->num_identifiers;d++)
|
356810 | 1997-10-16 | Fredrik Hübinette (Hubbe) | | {
|
62971d | 1998-01-19 | Fredrik Hübinette (Hubbe) | | struct identifier *id=tmp.prog->identifiers+d;
if(!IDENTIFIER_IS_VARIABLE(id->identifier_flags)) continue;
if(location == (void *)(base + id->func.offset))
{
|
a4033e | 2000-04-14 | Fredrik Hübinette (Hubbe) | | fprintf(stderr,"%*s **In variable %s\n",indent,"",id->name->str);
|
62971d | 1998-01-19 | Fredrik Hübinette (Hubbe) | | }
|
356810 | 1997-10-16 | Fredrik Hübinette (Hubbe) | | }
|
1e4e5f | 2000-04-07 | Fredrik Hübinette (Hubbe) | |
if((char *)location >= base && (char *)location <= base +
( tmp.prog->storage_needed - tmp.prog->inherits[0].storage_offset ))
{
|
a4033e | 2000-04-14 | Fredrik Hübinette (Hubbe) | | fprintf(stderr,"%*s **In storage for inherit %d",indent,"",e);
|
030541 | 2003-09-29 | Martin Stjernholm | | if(tmp.name && !tmp.name->size_shift)
|
1e4e5f | 2000-04-07 | Fredrik Hübinette (Hubbe) | | fprintf(stderr," (%s)",tmp.name->str);
fprintf(stderr,"\n");
}
|
356810 | 1997-10-16 | Fredrik Hübinette (Hubbe) | | }
}
|
dfe8f3 | 2000-04-26 | Fredrik Hübinette (Hubbe) | | break;
|
356810 | 1997-10-16 | Fredrik Hübinette (Hubbe) | | }
|
b35129 | 2001-08-20 | Martin Stjernholm | | case T_STORAGE:
fprintf(stderr, "%*s **In storage of object\n", indent, "");
break;
|
5b15bb | 2001-12-10 | Martin Stjernholm | | case T_MULTISET:
descblock = ((struct multiset *) memblock)->msd;
case T_MULTISET_DATA: {
struct multiset_data *msd = (struct multiset_data *) descblock;
union msnode *node = low_multiset_first (msd);
struct svalue ind;
int indval = msd->flags & MULTISET_INDVAL;
for (; node; node = low_multiset_next (node)) {
if (&node->i.ind == (struct svalue *) location) {
fprintf (stderr, "%*s **In index ", indent, "");
print_svalue (stderr, low_use_multiset_index (node, ind));
fputc ('\n', stderr);
break;
}
else if (indval && &node->iv.val == (struct svalue *) location) {
fprintf(stderr, "%*s **In value with index ", indent, "");
print_svalue(stderr, low_use_multiset_index (node, ind));
fputc('\n', stderr);
break;
}
}
break;
}
|
62971d | 1998-01-19 | Fredrik Hübinette (Hubbe) | | case T_ARRAY:
{
|
d9d6f0 | 2001-06-30 | Martin Stjernholm | | struct array *a=(struct array *)descblock;
|
62971d | 1998-01-19 | Fredrik Hübinette (Hubbe) | | struct svalue *s=(struct svalue *)location;
|
d5dcf3 | 2001-09-10 | Fredrik Hübinette (Hubbe) | |
if(location == (void *)&a->next)
fprintf(stderr,"%*s **In a->next\n",indent,"");
if(location == (void *)&a->prev)
fprintf(stderr,"%*s **In a->prev\n",indent,"");
if( s-ITEM(a) > 0)
fprintf(stderr,"%*s **In index number %"PRINTPTRDIFFT"d\n",indent,"",
s-ITEM(a));
|
dfe8f3 | 2000-04-26 | Fredrik Hübinette (Hubbe) | | break;
|
62971d | 1998-01-19 | Fredrik Hübinette (Hubbe) | | }
|
d9d6f0 | 2001-06-30 | Martin Stjernholm | |
case T_MAPPING:
descblock = ((struct mapping *) memblock)->data;
case T_MAPPING_DATA: {
INT32 e;
struct keypair *k;
NEW_MAPPING_LOOP((struct mapping_data *) descblock)
if (&k->ind == (struct svalue *) location) {
fprintf(stderr, "%*s **In index ", indent, "");
print_svalue(stderr, &k->ind);
fputc('\n', stderr);
break;
}
else if (&k->val == (struct svalue *) location) {
fprintf(stderr, "%*s **In value with index ", indent, "");
print_svalue(stderr, &k->ind);
fputc('\n', stderr);
break;
}
break;
}
|
f2bfde | 2003-09-24 | Martin Stjernholm | |
case T_PIKE_FRAME: {
struct pike_frame *f = (struct pike_frame *) descblock;
if (f->locals) {
ptrdiff_t pos = (struct svalue *) location - f->locals;
if (pos >= 0) {
if (pos < f->num_args)
fprintf (stderr, "%*s **In argument %"PRINTPTRDIFFT"d\n",
indent, "", pos);
else
fprintf (stderr, "%*s **At position %"PRINTPTRDIFFT"d among locals\n",
indent, "", pos - f->num_args);
|
79566d | 2004-03-15 | Martin Stjernholm | |
flags |= DESCRIBE_SHORT;
|
f2bfde | 2003-09-24 | Martin Stjernholm | | }
}
break;
}
|
356810 | 1997-10-16 | Fredrik Hübinette (Hubbe) | | }
|
dfe8f3 | 2000-04-26 | Fredrik Hübinette (Hubbe) | |
|
d9d6f0 | 2001-06-30 | Martin Stjernholm | | if(memblock && depth>0)
|
c905ff | 2003-09-24 | Martin Stjernholm | | describe_something(memblock,type,indent+2,depth-1,flags,inblock);
|
d9d6f0 | 2001-06-30 | Martin Stjernholm | |
|
57a436 | 2000-04-27 | Fredrik Hübinette (Hubbe) | | #ifdef DEBUG_MALLOC
|
dc4d8c | 2000-08-11 | Henrik Grubbström (Grubba) | |
|
e743b7 | 2001-08-31 | Martin Stjernholm | |
if (memblock)
dmalloc_describe_location(memblock, (char *) location - (char *) memblock, indent);
|
57a436 | 2000-04-27 | Fredrik Hübinette (Hubbe) | | #endif
|
356810 | 1997-10-16 | Fredrik Hübinette (Hubbe) | | }
|
e7634f | 2007-05-13 | Martin Stjernholm | | static void describe_link_frame (struct link_frame *f)
|
45d87e | 2000-07-18 | Martin Stjernholm | | {
|
e7634f | 2007-05-13 | Martin Stjernholm | | fprintf (stderr, "data=%p prev=%p checkfn=%p weak=%d",
f->data, f->prev, f->checkfn, f->weak);
|
45d87e | 2000-07-18 | Martin Stjernholm | | }
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | static void describe_marker(struct marker *m)
{
|
45d87e | 2000-07-18 | Martin Stjernholm | | if (m) {
|
e7634f | 2007-05-13 | Martin Stjernholm | | fprintf(stderr, "marker at %p: flags=0x%05lx refs=%d weak=%d "
"xrefs=%d saved=%d frame=%p",
|
1e9121 | 2001-07-05 | Martin Stjernholm | | m, (long) m->flags, m->refs, m->weak_refs,
|
45d87e | 2000-07-18 | Martin Stjernholm | | m->xrefs, m->saved_refs, m->frame);
if (m->frame) {
fputs(" [", stderr);
|
e7634f | 2007-05-13 | Martin Stjernholm | | describe_rec_frame (m->frame);
|
45d87e | 2000-07-18 | Martin Stjernholm | | putc(']', stderr);
}
putc('\n', stderr);
}
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | else
fprintf(stderr, "no marker\n");
}
|
50d97a | 2003-02-01 | Martin Stjernholm | | #endif /* PIKE_DEBUG */
|
eb4aba | 2007-05-26 | Martin Stjernholm | | static void debug_gc_fatal_va (void *a, int flags,
const char *fmt, va_list args)
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | {
|
1e0b96 | 2003-05-12 | Martin Nilsson | | #ifdef PIKE_DEBUG
|
56252f | 2001-06-28 | Fredrik Hübinette (Hubbe) | | struct marker *m;
|
1e0b96 | 2003-05-12 | Martin Nilsson | | #endif
|
1d938c | 2001-04-18 | Martin Stjernholm | | int orig_gc_pass = Pike_in_gc;
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | |
fprintf(stderr, "**");
(void) VFPRINTF(stderr, fmt, args);
|
50d97a | 2003-02-01 | Martin Stjernholm | | #ifdef PIKE_DEBUG
|
8ed8dc | 2001-07-01 | Martin Stjernholm | | if (a) {
|
028537 | 2006-02-28 | Martin Stjernholm | | |
8ed8dc | 2001-07-01 | Martin Stjernholm | | * checks in describe(). */
Pike_in_gc = 0;
describe(a);
|
56252f | 2001-06-28 | Fredrik Hübinette (Hubbe) | |
|
8ed8dc | 2001-07-01 | Martin Stjernholm | | if (flags & 1) locate_references(a);
|
56252f | 2001-06-28 | Fredrik Hübinette (Hubbe) | |
|
8ed8dc | 2001-07-01 | Martin Stjernholm | | m=find_marker(a);
if(m)
{
fprintf(stderr,"** Describing marker for this thing.\n");
describe(m);
}else{
fprintf(stderr,"** No marker found for this thing.\n");
}
Pike_in_gc = orig_gc_pass;
|
56252f | 2001-06-28 | Fredrik Hübinette (Hubbe) | | }
|
8ed8dc | 2001-07-01 | Martin Stjernholm | |
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | if (flags & 2)
fatal_after_gc = "Fatal in garbage collector.\n";
else
|
50d97a | 2003-02-01 | Martin Stjernholm | | #endif
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | debug_fatal("Fatal in garbage collector.\n");
}
|
eb4aba | 2007-05-26 | Martin Stjernholm | | void debug_gc_fatal (void *a, int flags, const char *fmt, ...)
{
va_list args;
va_start (args, fmt);
debug_gc_fatal_va (a, flags, fmt, args);
va_end (args);
}
static void dloc_gc_fatal (const char *file, int line,
void *a, int flags, const char *fmt, ...)
{
va_list args;
fprintf (stderr, "%s:%d: GC fatal:\n", file, line);
va_start (args, fmt);
debug_gc_fatal_va (a, flags, fmt, args);
va_end (args);
}
|
50d97a | 2003-02-01 | Martin Stjernholm | | #ifdef PIKE_DEBUG
|
081629 | 2000-07-03 | Martin Stjernholm | | static void gdb_gc_stop_here(void *a, int weak)
|
b8a6e7 | 1996-09-25 | Fredrik Hübinette (Hubbe) | | {
|
884c12 | 2004-03-15 | Martin Stjernholm | | found_ref_count++;
|
1a12e8 | 2000-09-30 | Martin Stjernholm | | fprintf(stderr,"***One %sref found%s. ",
|
081629 | 2000-07-03 | Martin Stjernholm | | weak ? "weak " : "",
|
e1a35e | 2003-09-08 | Martin Stjernholm | | gc_found_place ? gc_found_place : "");
if (gc_found_in) {
|
5d01dd | 2001-07-11 | Martin Stjernholm | | if (gc_svalue_location)
|
79566d | 2004-03-15 | Martin Stjernholm | | describe_location(gc_found_in , gc_found_in_type, gc_svalue_location,0,1,
DESCRIBE_SHORT);
|
5d01dd | 2001-07-11 | Martin Stjernholm | | else {
fputc('\n', stderr);
|
79566d | 2004-03-15 | Martin Stjernholm | | describe_something(gc_found_in, gc_found_in_type, 0, 0, DESCRIBE_SHORT, 0);
|
5d01dd | 2001-07-11 | Martin Stjernholm | | }
|
d9d6f0 | 2001-06-30 | Martin Stjernholm | | }
|
a7078c | 2001-09-06 | Martin Stjernholm | | else
fputc('\n', stderr);
|
20513c | 2000-04-12 | Fredrik Hübinette (Hubbe) | | fprintf(stderr,"----------end------------\n");
|
b8a6e7 | 1996-09-25 | Fredrik Hübinette (Hubbe) | | }
|
f6d017 | 1997-10-15 | Fredrik Hübinette (Hubbe) | |
|
a4033e | 2000-04-14 | Fredrik Hübinette (Hubbe) | | void low_describe_something(void *a,
int t,
int indent,
int depth,
|
b35129 | 2001-08-20 | Martin Stjernholm | | int flags,
void *inblock)
|
f6d017 | 1997-10-15 | Fredrik Hübinette (Hubbe) | | {
struct program *p=(struct program *)a;
|
081629 | 2000-07-03 | Martin Stjernholm | | struct marker *m;
|
f6d017 | 1997-10-15 | Fredrik Hübinette (Hubbe) | |
|
a4033e | 2000-04-14 | Fredrik Hübinette (Hubbe) | | if(depth<0) return;
|
c0df09 | 2001-06-29 | Martin Stjernholm | | if (marker_hash_table && (m = find_marker(a))) {
|
081629 | 2000-07-03 | Martin Stjernholm | | fprintf(stderr,"%*s**Got gc ",indent,"");
describe_marker(m);
}
|
b35129 | 2001-08-20 | Martin Stjernholm | | again:
|
f6d017 | 1997-10-15 | Fredrik Hübinette (Hubbe) | | switch(t)
{
|
b35129 | 2001-08-20 | Martin Stjernholm | | case T_STORAGE:
if (!inblock) attempt_to_identify (a, &a);
t = T_OBJECT;
goto again;
|
2eeba9 | 1999-03-17 | Fredrik Hübinette (Hubbe) | | case T_FUNCTION:
|
b35129 | 2001-08-20 | Martin Stjernholm | | if(attempt_to_identify(a, 0) != T_OBJECT)
|
2eeba9 | 1999-03-17 | Fredrik Hübinette (Hubbe) | | {
|
a4033e | 2000-04-14 | Fredrik Hübinette (Hubbe) | | fprintf(stderr,"%*s**Builtin function!\n",indent,"");
|
2eeba9 | 1999-03-17 | Fredrik Hübinette (Hubbe) | | break;
}
|
b35129 | 2001-08-20 | Martin Stjernholm | |
|
2eeba9 | 1999-03-17 | Fredrik Hübinette (Hubbe) | |
|
f6d017 | 1997-10-15 | Fredrik Hübinette (Hubbe) | | case T_OBJECT:
p=((struct object *)a)->prog;
|
f3c715 | 2001-04-14 | Fredrik Hübinette (Hubbe) | | if(p && (p->flags & PROGRAM_USES_PARENT))
{
fprintf(stderr,"%*s**Parent identifier: %d\n",indent,"",PARENT_INFO( ((struct object *)a) )->parent_identifier);
}
|
c8eea5 | 2003-08-02 | Martin Stjernholm | | fprintf(stderr,"%*s**Program id: %d\n",indent,"",((struct object *)a)->program_id);
|
1e4e5f | 2000-04-07 | Fredrik Hübinette (Hubbe) | |
|
7bf623 | 2000-04-23 | Martin Stjernholm | | if (((struct object *)a)->next == ((struct object *)a))
fprintf(stderr, "%*s**The object is fake.\n",indent,"");
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | {
struct object *o;
for (o = first_object; o && o != (struct object *) a; o = o->next) {}
if (!o)
fprintf(stderr,"%*s**The object is not on the object link list.\n",indent,"");
for (o = objects_to_destruct; o && o != (struct object *) a; o = o->next) {}
if (o)
fprintf(stderr,"%*s**The object is on objects_to_destruct.\n",indent,"");
}
|
7bf623 | 2000-04-23 | Martin Stjernholm | | if(!p)
{
p=id_to_program(((struct object *)a)->program_id);
|
8e5a40 | 2004-03-16 | Martin Stjernholm | | if(p)
fprintf(stderr,"%*s**The object is destructed but program found from id.\n",
indent,"");
else
fprintf(stderr,"%*s**The object is destructed and program not found from id.\n",
indent,"");
|
7bf623 | 2000-04-23 | Martin Stjernholm | | }
|
5a484d | 2003-09-09 | Martin Stjernholm | |
|
3eed60 | 2004-04-18 | Martin Stjernholm | | if (((struct object *) a)->refs > 0 && p) {
|
5a484d | 2003-09-09 | Martin Stjernholm | | size_t inh_idx, var_idx, var_count = 0;
fprintf (stderr, "%*s**Object variables:\n", indent, "");
for (inh_idx = 0; inh_idx < p->num_inherits; inh_idx++) {
struct inherit *inh = p->inherits + inh_idx;
struct program *p2 = inh->prog;
if (inh->inherit_level) {
if (inh->name) {
fprintf (stderr, "%*s**%*s=== In inherit ",
indent, "", inh->inherit_level + 1, "");
|
f18937 | 2004-04-03 | Martin Stjernholm | | print_short_svalue (stderr, (union anything *) &inh->name, T_STRING);
|
5a484d | 2003-09-09 | Martin Stjernholm | | fprintf (stderr, ", program %d:\n", inh->prog->id);
}
else
fprintf (stderr, "%*s**%*s=== In nameless inherit, program %d:\n",
indent, "", inh->inherit_level + 1, "", inh->prog->id);
}
for (var_idx = 0; var_idx < p2->num_variable_index; var_idx++) {
struct identifier *id = p2->identifiers + p2->variable_index[var_idx];
void *ptr;
fprintf (stderr, "%*s**%*srtt: %-8s name: ",
indent, "", inh->inherit_level + 1, "",
get_name_of_type (id->run_time_type));
|
99cee9 | 2004-04-03 | Martin Stjernholm | | if (id->name->size_shift)
|
f18937 | 2004-04-03 | Martin Stjernholm | | print_short_svalue (stderr, (union anything *) &id->name, T_STRING);
|
5a484d | 2003-09-09 | Martin Stjernholm | | else
fprintf (stderr, "%-20s", id->name->str);
fprintf (stderr, " off: %4"PRINTPTRDIFFT"d value: ",
inh->storage_offset + id->func.offset);
ptr = PIKE_OBJ_STORAGE ((struct object *) a) +
inh->storage_offset + id->func.offset;
if (id->run_time_type == T_MIXED)
|
99cee9 | 2004-04-03 | Martin Stjernholm | | print_svalue_compact (stderr, (struct svalue *) ptr);
|
5a484d | 2003-09-09 | Martin Stjernholm | | else
|
99cee9 | 2004-04-03 | Martin Stjernholm | | print_short_svalue_compact (stderr, (union anything *) ptr,
id->run_time_type);
|
5a484d | 2003-09-09 | Martin Stjernholm | |
fputc ('\n', stderr);
var_count++;
}
}
if (!var_count)
fprintf (stderr, "%*s** (none)\n", indent, "");
|
60c15a | 2003-08-20 | Martin Stjernholm | | fprintf(stderr,"%*s**Describing program %p of object:\n",indent,"", p);
|
505e3e | 2000-09-30 | Martin Stjernholm | | #ifdef DEBUG_MALLOC
|
2ac3f5 | 2005-04-06 | Henrik Grubbström (Grubba) | | if ((INT32)(ptrdiff_t) p == 0x55555555)
|
728b23 | 2000-09-30 | Martin Stjernholm | | fprintf(stderr, "%*s**Zapped program pointer.\n", indent, "");
|
505e3e | 2000-09-30 | Martin Stjernholm | | else
#endif
|
c905ff | 2003-09-24 | Martin Stjernholm | | low_describe_something(p, T_PROGRAM, indent, depth,
|
22415d | 2003-09-24 | Martin Stjernholm | | depth ? flags : flags | DESCRIBE_SHORT, 0);
|
7bf623 | 2000-04-23 | Martin Stjernholm | |
|
5a484d | 2003-09-09 | Martin Stjernholm | | if((p->flags & PROGRAM_USES_PARENT) &&
LOW_PARENT_INFO(((struct object *)a),p)->parent)
{
if (depth) {
fprintf(stderr,"%*s**Describing parent of object:\n",indent,"");
describe_something( PARENT_INFO((struct object *)a)->parent, T_OBJECT,
indent+2, depth-1,
|
22415d | 2003-09-24 | Martin Stjernholm | | (flags | DESCRIBE_SHORT) & ~DESCRIBE_MEM,
|
5a484d | 2003-09-09 | Martin Stjernholm | | 0);
}
else
fprintf (stderr, "%*s**Object got a parent.\n", indent, "");
}else{
fprintf(stderr,"%*s**There is no parent (any longer?)\n",indent,"");
}
|
8fb1e1 | 1998-04-05 | Fredrik Hübinette (Hubbe) | | }
|
7bf623 | 2000-04-23 | Martin Stjernholm | | break;
|
22aa2f | 2000-09-04 | Martin Stjernholm | |
|
f6d017 | 1997-10-15 | Fredrik Hübinette (Hubbe) | | case T_PROGRAM:
|
356810 | 1997-10-16 | Fredrik Hübinette (Hubbe) | | {
|
376e47 | 2001-09-10 | Fredrik Hübinette (Hubbe) | | char *tmp;
|
b13ee6 | 2001-06-30 | Martin Stjernholm | | INT32 line;
|
5a484d | 2003-09-09 | Martin Stjernholm | | ptrdiff_t id_idx, id_count = 0;
struct inherit *inh = p->inherits, *next_inh = p->inherits + 1;
ptrdiff_t inh_id_end = p->num_identifier_references;
|
356810 | 1997-10-16 | Fredrik Hübinette (Hubbe) | |
|
a6c6a1 | 2003-08-02 | Martin Stjernholm | | fprintf(stderr,"%*s**Program id: %ld, flags: %x, parent id: %d\n",
indent,"", (long)(p->id), p->flags,
p->parent ? p->parent->id : -1);
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | |
|
05590d | 1998-04-23 | Fredrik Hübinette (Hubbe) | | if(p->flags & PROGRAM_HAS_C_METHODS)
|
f6d017 | 1997-10-15 | Fredrik Hübinette (Hubbe) | | {
|
a4033e | 2000-04-14 | Fredrik Hübinette (Hubbe) | | fprintf(stderr,"%*s**The program was written in C.\n",indent,"");
|
f6d017 | 1997-10-15 | Fredrik Hübinette (Hubbe) | | }
|
50edc8 | 2001-07-13 | Henrik Grubbström (Grubba) | |
|
e0cbd3 | 2003-03-29 | Martin Stjernholm | | tmp = low_get_program_line_plain(p, &line, 1);
if (tmp) {
|
50edc8 | 2001-07-13 | Henrik Grubbström (Grubba) | | fprintf(stderr,"%*s**Location: %s:%ld\n",
|
376e47 | 2001-09-10 | Fredrik Hübinette (Hubbe) | | indent, "", tmp, (long)line);
|
e0cbd3 | 2003-03-29 | Martin Stjernholm | | free (tmp);
|
2eeba9 | 1999-03-17 | Fredrik Hübinette (Hubbe) | | }
|
3eed60 | 2004-04-18 | Martin Stjernholm | | if (!(flags & DESCRIBE_SHORT) && p->refs > 0) {
|
c905ff | 2003-09-24 | Martin Stjernholm | | fprintf (stderr, "%*s**Identifiers:\n", indent, "");
|
5a484d | 2003-09-09 | Martin Stjernholm | |
|
c905ff | 2003-09-24 | Martin Stjernholm | | for (id_idx = 0; id_idx < p->num_identifier_references; id_idx++) {
struct reference *id_ref = p->identifier_references + id_idx;
struct inherit *id_inh;
struct identifier *id;
const char *type;
char prot[100], descr[120];
while (next_inh < p->inherits + p->num_inherits &&
id_idx == next_inh->identifier_level) {
inh = next_inh++;
inh_id_end = inh->identifier_level + inh->prog->num_identifier_references;
if (inh->name) {
fprintf (stderr, "%*s**%*s=== In inherit ",
indent, "", inh->inherit_level + 1, "");
|
f18937 | 2004-04-03 | Martin Stjernholm | | print_short_svalue (stderr, (union anything *) &inh->name, T_STRING);
|
c905ff | 2003-09-24 | Martin Stjernholm | | fprintf (stderr, ", program %d:\n", inh->prog->id);
}
else
fprintf (stderr, "%*s**%*s=== In nameless inherit, program %d:\n",
indent, "", inh->inherit_level + 1, "", inh->prog->id);
|
5a484d | 2003-09-09 | Martin Stjernholm | | }
|
c905ff | 2003-09-24 | Martin Stjernholm | |
while (id_idx == inh_id_end) {
int cur_lvl = inh->inherit_level;
if (inh->name) {
fprintf (stderr, "%*s**%*s=== End of inherit ",
indent, "", inh->inherit_level + 1, "");
|
f18937 | 2004-04-03 | Martin Stjernholm | | print_short_svalue (stderr, (union anything *) &inh->name, T_STRING);
|
c905ff | 2003-09-24 | Martin Stjernholm | | fputc ('\n', stderr);
}
else
fprintf (stderr, "%*s**%*s=== End of nameless inherit\n",
indent, "", inh->inherit_level + 1, "");
while (inh > p->inherits) {
if ((--inh)->inherit_level < cur_lvl) break;
}
inh_id_end = inh->identifier_level + inh->prog->num_identifier_references;
|
5a484d | 2003-09-09 | Martin Stjernholm | | }
|
c905ff | 2003-09-24 | Martin Stjernholm | | if (id_ref->id_flags & ID_HIDDEN ||
(id_ref->id_flags & (ID_INHERITED|ID_PRIVATE)) ==
(ID_INHERITED|ID_PRIVATE)) continue;
|
5a484d | 2003-09-09 | Martin Stjernholm | |
|
c905ff | 2003-09-24 | Martin Stjernholm | | id_inh = INHERIT_FROM_PTR (p, id_ref);
id = id_inh->prog->identifiers + id_ref->identifier_offset;
|
5a484d | 2003-09-09 | Martin Stjernholm | |
|
c905ff | 2003-09-24 | Martin Stjernholm | | if (IDENTIFIER_IS_PIKE_FUNCTION (id->identifier_flags)) type = "fun";
else if (IDENTIFIER_IS_FUNCTION (id->identifier_flags)) type = "cfun";
else if (IDENTIFIER_IS_CONSTANT (id->identifier_flags)) type = "const";
else if (IDENTIFIER_IS_ALIAS (id->identifier_flags)) type = "alias";
else if (IDENTIFIER_IS_VARIABLE (id->identifier_flags)) type = "var";
else type = "???";
|
5a484d | 2003-09-09 | Martin Stjernholm | |
|
c905ff | 2003-09-24 | Martin Stjernholm | | prot[0] = prot[1] = 0;
if (id_ref->id_flags & ID_PRIVATE) {
strcat (prot, ",pri");
if (!(id_ref->id_flags & ID_STATIC)) strcat (prot, ",!sta");
}
else
if (id_ref->id_flags & ID_STATIC) strcat (prot, ",sta");
if (id_ref->id_flags & ID_NOMASK) strcat (prot, ",nom");
if (id_ref->id_flags & ID_PUBLIC) strcat (prot, ",pub");
if (id_ref->id_flags & ID_PROTECTED) strcat (prot, ",pro");
if (id_ref->id_flags & ID_INLINE) strcat (prot, ",inl");
if (id_ref->id_flags & ID_OPTIONAL) strcat (prot, ",opt");
if (id_ref->id_flags & ID_EXTERN) strcat (prot, ",ext");
if (id_ref->id_flags & ID_VARIANT) strcat (prot, ",var");
if (id_ref->id_flags & ID_ALIAS) strcat (prot, ",ali");
sprintf (descr, "%s: %s", type, prot + 1);
fprintf (stderr, "%*s**%*s%-18s name: ",
indent, "", id_inh->inherit_level + 1, "", descr);
|
99cee9 | 2004-04-03 | Martin Stjernholm | | if (id->name->size_shift)
|
f18937 | 2004-04-03 | Martin Stjernholm | | print_short_svalue (stderr, (union anything *) &id->name, T_STRING);
|
c905ff | 2003-09-24 | Martin Stjernholm | | else
fprintf (stderr, "%-20s", id->name->str);
if (id->identifier_flags & IDENTIFIER_C_FUNCTION)
fprintf (stderr, " addr: %p", id->func.c_fun);
else if (IDENTIFIER_IS_VARIABLE (id->identifier_flags))
fprintf (stderr, " rtt: %s off: %"PRINTPTRDIFFT"d",
get_name_of_type (id->run_time_type), id->func.offset);
else if (IDENTIFIER_IS_PIKE_FUNCTION (id->identifier_flags))
fprintf (stderr, " pc: %"PRINTPTRDIFFT"d", id->func.offset);
else if (IDENTIFIER_IS_CONSTANT (id->identifier_flags)) {
fputs (" value: ", stderr);
print_svalue_compact (stderr, &id_inh->prog->constants[id->func.offset].sval);
}
fputc ('\n', stderr);
id_count++;
|
5a484d | 2003-09-09 | Martin Stjernholm | | }
|
c905ff | 2003-09-24 | Martin Stjernholm | | if (!id_count)
fprintf (stderr, "%*s** (none)\n", indent, "");
|
f6d017 | 1997-10-15 | Fredrik Hübinette (Hubbe) | | }
|
a4033e | 2000-04-14 | Fredrik Hübinette (Hubbe) | |
if(flags & DESCRIBE_MEM)
{
|
7e877a | 2003-04-02 | Martin Stjernholm | | #define FOO(NUMTYPE,TYPE,ARGTYPE,NAME) \
|
17c762 | 2001-08-20 | Martin Stjernholm | | fprintf(stderr, "%*s* " #NAME " %p[%"PRINTSIZET"u]\n", \
|
2d76f2 | 2005-05-20 | Martin Stjernholm | | indent, "", p->NAME, (size_t)p->PIKE_CONCAT(num_,NAME));
|
1e4e5f | 2000-04-07 | Fredrik Hübinette (Hubbe) | | #include "program_areas.h"
|
a4033e | 2000-04-14 | Fredrik Hübinette (Hubbe) | | }
|
2eeba9 | 1999-03-17 | Fredrik Hübinette (Hubbe) | |
|
f6d017 | 1997-10-15 | Fredrik Hübinette (Hubbe) | | break;
|
356810 | 1997-10-16 | Fredrik Hübinette (Hubbe) | | }
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | |
|
5b15bb | 2001-12-10 | Martin Stjernholm | | case T_MULTISET_DATA: {
|
308d27 | 2003-08-26 | Martin Stjernholm | | int found = 0;
|
5b15bb | 2001-12-10 | Martin Stjernholm | | struct multiset *l;
for (l = first_multiset; l; l = l->next) {
if (l->msd == (struct multiset_data *) a) {
|
308d27 | 2003-08-26 | Martin Stjernholm | | fprintf(stderr, "%*s**Describing multiset %p for this data block:\n",
indent, "", l);
|
5b15bb | 2001-12-10 | Martin Stjernholm | | debug_dump_multiset(l);
|
308d27 | 2003-08-26 | Martin Stjernholm | | found = 1;
|
5b15bb | 2001-12-10 | Martin Stjernholm | | }
}
|
308d27 | 2003-08-26 | Martin Stjernholm | | if (!found)
fprintf (stderr, "%*s**Didn't find multiset for this data block!\n", indent, "");
|
5b15bb | 2001-12-10 | Martin Stjernholm | | break;
}
case T_MULTISET:
|
3eed60 | 2004-04-18 | Martin Stjernholm | | if (((struct multiset *) a)->refs > 0)
debug_dump_multiset((struct multiset *) a);
|
5b15bb | 2001-12-10 | Martin Stjernholm | | break;
|
f6d017 | 1997-10-15 | Fredrik Hübinette (Hubbe) | | case T_ARRAY:
|
3eed60 | 2004-04-18 | Martin Stjernholm | | if (((struct array *) a)->refs > 0)
debug_dump_array((struct array *)a);
|
f6d017 | 1997-10-15 | Fredrik Hübinette (Hubbe) | | break;
|
62971d | 1998-01-19 | Fredrik Hübinette (Hubbe) | |
|
9a6d00 | 2001-06-26 | Fredrik Hübinette (Hubbe) | | case T_MAPPING_DATA:
{
|
308d27 | 2003-08-26 | Martin Stjernholm | | int found = 0;
|
9a6d00 | 2001-06-26 | Fredrik Hübinette (Hubbe) | | struct mapping *m;
for(m=first_mapping;m;m=m->next)
{
if(m->data == (struct mapping_data *)a)
{
|
ffb390 | 2001-06-26 | Fredrik Hübinette (Hubbe) | | fprintf(stderr,"%*s**Describing mapping for this data block:\n",indent,"");
|
9a6d00 | 2001-06-26 | Fredrik Hübinette (Hubbe) | | debug_dump_mapping((struct mapping *)m);
|
308d27 | 2003-08-26 | Martin Stjernholm | | found = 1;
|
9a6d00 | 2001-06-26 | Fredrik Hübinette (Hubbe) | | }
}
|
308d27 | 2003-08-26 | Martin Stjernholm | | if (!found)
fprintf (stderr, "%*s**Didn't find mapping for this data block!\n", indent, "");
|
9a6d00 | 2001-06-26 | Fredrik Hübinette (Hubbe) | | break;
}
|
61e9a0 | 1998-01-25 | Fredrik Hübinette (Hubbe) | | case T_MAPPING:
|
3eed60 | 2004-04-18 | Martin Stjernholm | | if (((struct mapping *) a)->refs > 0)
debug_dump_mapping((struct mapping *)a);
|
61e9a0 | 1998-01-25 | Fredrik Hübinette (Hubbe) | | break;
|
62971d | 1998-01-19 | Fredrik Hübinette (Hubbe) | | case T_STRING:
{
struct pike_string *s=(struct pike_string *)a;
|
2ac3f5 | 2005-04-06 | Henrik Grubbström (Grubba) | | fprintf(stderr,"%*s**size_shift: %d, "
"len: %"PRINTPTRDIFFT"d, "
"hash: %"PRINTSIZET"x\n",
indent,"", s->size_shift, s->len, s->hval);
|
3eed60 | 2004-04-18 | Martin Stjernholm | | if (!s->size_shift && s->refs > 0) {
|
308d27 | 2003-08-26 | Martin Stjernholm | | if(s->len>77)
{
fprintf(stderr,"%*s** \"%60s\"...\n",indent,"",s->str);
}else{
fprintf(stderr,"%*s** \"%s\"\n",indent,"",s->str);
}
|
62971d | 1998-01-19 | Fredrik Hübinette (Hubbe) | | }
break;
}
|
b35129 | 2001-08-20 | Martin Stjernholm | |
|
38da52 | 2007-03-31 | Henrik Grubbström (Grubba) | | case PIKE_T_TYPE:
{
fprintf(stderr, "%*s**type: ", indent, "");
simple_describe_type((struct pike_type *)a);
fprintf(stderr, "\n");
break;
}
|
b35129 | 2001-08-20 | Martin Stjernholm | | case T_PIKE_FRAME: {
struct pike_frame *f = (struct pike_frame *) a;
do {
|
3eed60 | 2004-04-18 | Martin Stjernholm | | if (f->refs <= 0) break;
|
b35129 | 2001-08-20 | Martin Stjernholm | | if (f->current_object) {
|
17c762 | 2001-08-20 | Martin Stjernholm | | struct program *p = f->current_object->prog;
if (p) {
struct identifier *id = ID_FROM_INT(p, f->fun);
INT32 line;
struct pike_string *file;
if (IDENTIFIER_IS_PIKE_FUNCTION(id->identifier_flags) &&
|
4d0475 | 2003-08-20 | Henrik Grubbström (Grubba) | | id->func.offset >= 0 &&
|
17c762 | 2001-08-20 | Martin Stjernholm | | (file = get_line(p->program + id->func.offset, p, &line))) {
fprintf(stderr, "%*s**Function %s at %s:%ld\n",
indent, "", id->name->str, file->str, (long) line);
free_string(file);
}
else
fprintf(stderr, "%*s**Function %s at unknown location.\n",
indent, "", id->name->str);
}
|
79566d | 2004-03-15 | Martin Stjernholm | | if (!(flags & DESCRIBE_SHORT)) {
fprintf(stderr, "%*s**Describing the current object:\n", indent, "");
describe_something(f->current_object, T_OBJECT, indent+2, depth, flags, 0);
}
|
b35129 | 2001-08-20 | Martin Stjernholm | | }
|
17c762 | 2001-08-20 | Martin Stjernholm | | else
fprintf(stderr, "%*s**No current object.\n", indent, "");
|
b35129 | 2001-08-20 | Martin Stjernholm | | if ((f = f->scope))
fprintf(stderr, "%*s**Moving on to outer scope frame %p:\n", indent, "", f);
} while (f);
break;
}
default:
fprintf(stderr, "%*s**Cannot describe block of unknown type %d\n",
indent, "", t);
|
f6d017 | 1997-10-15 | Fredrik Hübinette (Hubbe) | | }
|
25479a | 2000-03-07 | Fredrik Hübinette (Hubbe) | | }
|
b35129 | 2001-08-20 | Martin Stjernholm | | void describe_something(void *a, int t, int indent, int depth, int flags,
void *inblock)
|
25479a | 2000-03-07 | Fredrik Hübinette (Hubbe) | | {
|
111fdd | 2000-04-17 | Fredrik Hübinette (Hubbe) | | int tmp;
|
25479a | 2000-03-07 | Fredrik Hübinette (Hubbe) | | struct program *p=(struct program *)a;
|
f18937 | 2004-04-03 | Martin Stjernholm | | if(!a) {
fprintf (stderr, "%*s**NULL pointer\n", indent, "");
return;
}
|
25479a | 2000-03-07 | Fredrik Hübinette (Hubbe) | |
if(t==-1)
{
|
a4033e | 2000-04-14 | Fredrik Hübinette (Hubbe) | | fprintf(stderr,"%*s**Location description: %s\n",indent,"",(char *)a);
|
25479a | 2000-03-07 | Fredrik Hübinette (Hubbe) | | return;
}
|
111fdd | 2000-04-17 | Fredrik Hübinette (Hubbe) | |
tmp=d_flag;
d_flag=0;
|
384545 | 2000-03-08 | Henrik Grubbström (Grubba) | | #ifdef DEBUG_MALLOC
|
2ac3f5 | 2005-04-06 | Henrik Grubbström (Grubba) | | if (((INT32)(ptrdiff_t)a) == 0x55555555) {
|
43c778 | 2003-03-30 | Martin Stjernholm | | fprintf(stderr,"%*s**Block: %p Type: %s Zapped pointer\n",indent,"",a,
|
384545 | 2000-03-08 | Henrik Grubbström (Grubba) | | get_name_of_type(t));
} else
#endif /* DEBUG_MALLOC */
|
728b23 | 2000-09-30 | Martin Stjernholm | | if (((ptrdiff_t)a) & 3) {
|
43c778 | 2003-03-30 | Martin Stjernholm | | fprintf(stderr,"%*s**Block: %p Type: %s Misaligned address\n",indent,"",a,
|
728b23 | 2000-09-30 | Martin Stjernholm | | get_name_of_type(t));
} else {
|
43c778 | 2003-03-30 | Martin Stjernholm | | fprintf(stderr,"%*s**Block: %p Type: %s Refs: %d\n",indent,"",a,
|
728b23 | 2000-09-30 | Martin Stjernholm | | get_name_of_type(t),
*(INT32 *)a);
|
25479a | 2000-03-07 | Fredrik Hübinette (Hubbe) | |
|
e0cbd3 | 2003-03-29 | Martin Stjernholm | | low_describe_something(a,t,indent,depth,flags,inblock);
|
25479a | 2000-03-07 | Fredrik Hübinette (Hubbe) | | #ifdef DEBUG_MALLOC
|
728b23 | 2000-09-30 | Martin Stjernholm | | if(!(flags & DESCRIBE_NO_DMALLOC))
debug_malloc_dump_references(a,indent+2,depth-1,flags);
|
25479a | 2000-03-07 | Fredrik Hübinette (Hubbe) | | #endif
|
728b23 | 2000-09-30 | Martin Stjernholm | | }
|
87c7f9 | 2000-04-19 | Martin Stjernholm | |
|
a4033e | 2000-04-14 | Fredrik Hübinette (Hubbe) | | fprintf(stderr,"%*s*******************\n",indent,"");
|
111fdd | 2000-04-17 | Fredrik Hübinette (Hubbe) | | d_flag=tmp;
|
8fb1e1 | 1998-04-05 | Fredrik Hübinette (Hubbe) | | }
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void describe(void *x)
|
8fb1e1 | 1998-04-05 | Fredrik Hübinette (Hubbe) | | {
|
b35129 | 2001-08-20 | Martin Stjernholm | | void *inblock;
int type = attempt_to_identify(x, &inblock);
|
5a484d | 2003-09-09 | Martin Stjernholm | | describe_something(x, type, 0, 0, 0, inblock);
|
f6d017 | 1997-10-15 | Fredrik Hübinette (Hubbe) | | }
|
c72a4e | 1998-12-15 | Fredrik Hübinette (Hubbe) | | void debug_describe_svalue(struct svalue *s)
{
fprintf(stderr,"Svalue at %p is:\n",s);
switch(s->type)
{
case T_INT:
|
f98013 | 2004-03-21 | Martin Nilsson | | fprintf(stderr," %"PRINTPIKEINT"d (subtype %d)\n",s->u.integer,
s->subtype);
|
c72a4e | 1998-12-15 | Fredrik Hübinette (Hubbe) | | break;
case T_FLOAT:
|
27ec27 | 2003-09-10 | Martin Stjernholm | | fprintf(stderr," %"PRINTPIKEFLOAT"f\n",s->u.float_number);
|
c72a4e | 1998-12-15 | Fredrik Hübinette (Hubbe) | | break;
|
2eeba9 | 1999-03-17 | Fredrik Hübinette (Hubbe) | |
case T_FUNCTION:
if(s->subtype == FUNCTION_BUILTIN)
{
fprintf(stderr," Builtin function: %s\n",s->u.efun->name->str);
}else{
if(!s->u.object->prog)
{
|
1e4e5f | 2000-04-07 | Fredrik Hübinette (Hubbe) | | struct program *p=id_to_program(s->u.object->program_id);
if(p)
{
|
8e5a40 | 2004-03-16 | Martin Stjernholm | | fprintf(stderr," Function in destructed object: %s\n",
ID_FROM_INT(p,s->subtype)->name->str);
|
1e4e5f | 2000-04-07 | Fredrik Hübinette (Hubbe) | | }else{
fprintf(stderr," Function in destructed object.\n");
}
|
2eeba9 | 1999-03-17 | Fredrik Hübinette (Hubbe) | | }else{
|
8e5a40 | 2004-03-16 | Martin Stjernholm | | fprintf(stderr," Function name: %s\n",
ID_FROM_INT(s->u.object->prog,s->subtype)->name->str);
|
2eeba9 | 1999-03-17 | Fredrik Hübinette (Hubbe) | | }
}
|
c72a4e | 1998-12-15 | Fredrik Hübinette (Hubbe) | | }
|
22415d | 2003-09-24 | Martin Stjernholm | | describe_something(s->u.refs,s->type,0,1,0,0);
|
c72a4e | 1998-12-15 | Fredrik Hübinette (Hubbe) | | }
|
1e9121 | 2001-07-05 | Martin Stjernholm | | void gc_watch(void *a)
{
struct marker *m;
init_gc();
m = get_marker(a);
if (!(m->flags & GC_WATCHED)) {
m->flags |= GC_WATCHED;
fprintf(stderr, "## Watching thing %p.\n", a);
gc_is_watching++;
}
else
fprintf(stderr, "## Already watching thing %p.\n", a);
}
|
8e5a40 | 2004-03-16 | Martin Stjernholm | | static void gc_watched_found (struct marker *m, const char *found_in)
{
fprintf(stderr, "## Watched thing %p with %d refs found in "
"%s in pass %d.\n", m->data, *(INT32 *) m->data, found_in, Pike_in_gc);
describe_marker (m);
}
|
50d97a | 2003-02-01 | Martin Stjernholm | | #endif /* PIKE_DEBUG */
|
e1a35e | 2003-09-08 | Martin Stjernholm | | #ifndef GC_MARK_DEBUG
struct pike_queue gc_mark_queue;
#else /* !GC_MARK_DEBUG */
struct gc_queue_entry
{
queue_call call;
void *data;
int in_type;
void *in;
const char *place;
};
#define GC_QUEUE_ENTRIES 8191
struct gc_queue_block
{
struct gc_queue_block *next;
int used;
struct gc_queue_entry entries[GC_QUEUE_ENTRIES];
};
struct gc_queue_block *gc_mark_first = NULL, *gc_mark_last = NULL;
void gc_mark_run_queue()
{
struct gc_queue_block *b;
while((b=gc_mark_first))
{
int e;
for(e=0;e<b->used;e++)
{
debug_malloc_touch(b->entries[e].data);
b->entries[e].call(b->entries[e].data);
}
gc_mark_first=b->next;
free((char *)b);
}
gc_mark_last=0;
}
void gc_mark_discard_queue()
{
struct gc_queue_block *b = gc_mark_first;
while (b)
{
struct gc_queue_block *next = b->next;
free((char *) b);
b = next;
}
gc_mark_first = gc_mark_last = 0;
}
void gc_mark_enqueue (queue_call call, void *data)
{
struct gc_queue_block *b;
#ifdef PIKE_DEBUG
if (gc_found_in_type == PIKE_T_UNKNOWN || !gc_found_in)
gc_fatal (data, 0, "gc_mark_enqueue() called outside GC_ENTER.\n");
{
struct marker *m;
if (gc_is_watching && (m = find_marker(data)) && m->flags & GC_WATCHED) {
|
8e5a40 | 2004-03-16 | Martin Stjernholm | | gc_watched_found (m, "gc_mark_enqueue()");
|
e1a35e | 2003-09-08 | Martin Stjernholm | | }
}
#endif
b=gc_mark_last;
if(!b || b->used >= GC_QUEUE_ENTRIES)
{
b = (struct gc_queue_block *) malloc (sizeof (struct gc_queue_block));
if (!b) fatal ("Out of memory in gc.\n");
b->used=0;
b->next=0;
if(gc_mark_first)
gc_mark_last->next=b;
else
gc_mark_first=b;
gc_mark_last=b;
}
b->entries[b->used].call=call;
b->entries[b->used].data=debug_malloc_pass(data);
b->entries[b->used].in_type = gc_found_in_type;
b->entries[b->used].in = debug_malloc_pass (gc_found_in);
b->entries[b->used].place = gc_found_place;
b->used++;
}
#endif /* GC_MARK_DEBUG */
|
7bf623 | 2000-04-23 | Martin Stjernholm | | void debug_gc_touch(void *a)
{
struct marker *m;
|
1e9121 | 2001-07-05 | Martin Stjernholm | |
|
50d97a | 2003-02-01 | Martin Stjernholm | | #ifdef PIKE_DEBUG
|
1e9121 | 2001-07-05 | Martin Stjernholm | | if (gc_is_watching && (m = find_marker(a)) && m->flags & GC_WATCHED) {
|
8e5a40 | 2004-03-16 | Martin Stjernholm | | gc_watched_found (m, "gc_touch()");
|
1e9121 | 2001-07-05 | Martin Stjernholm | | }
|
50d97a | 2003-02-01 | Martin Stjernholm | | #endif
|
1e9121 | 2001-07-05 | Martin Stjernholm | |
|
5aad93 | 2002-08-15 | Marcus Comstedt | | if (!a) Pike_fatal("Got null pointer.\n");
|
22aa2f | 2000-09-04 | Martin Stjernholm | |
switch (Pike_in_gc) {
case GC_PASS_PRETOUCH:
|
c0df09 | 2001-06-29 | Martin Stjernholm | | m = find_marker(a);
|
03cc2c | 2005-04-06 | Henrik Grubbström (Grubba) | | if (
#ifdef DO_PIKE_CLEANUP
!gc_keep_markers &&
#endif
m && !(m->flags & (GC_PRETOUCHED
|
50d97a | 2003-02-01 | Martin Stjernholm | | #ifdef PIKE_DEBUG
|GC_WATCHED
#endif
)))
|
22aa2f | 2000-09-04 | Martin Stjernholm | | gc_fatal(a, 1, "Thing got an existing but untouched marker.\n");
|
b13ee6 | 2001-06-30 | Martin Stjernholm | | m = get_marker(a);
m->flags |= GC_PRETOUCHED;
|
50d97a | 2003-02-01 | Martin Stjernholm | | #ifdef PIKE_DEBUG
|
b13ee6 | 2001-06-30 | Martin Stjernholm | | m->saved_refs = *(INT32 *) a;
|
50d97a | 2003-02-01 | Martin Stjernholm | | #endif
|
22aa2f | 2000-09-04 | Martin Stjernholm | | break;
|
a3574b | 2007-05-13 | Martin Stjernholm | | case GC_PASS_POSTTOUCH: {
|
1e0b96 | 2003-05-12 | Martin Nilsson | | #ifdef PIKE_DEBUG
|
b13ee6 | 2001-06-30 | Martin Stjernholm | | int extra_ref;
|
1e0b96 | 2003-05-12 | Martin Nilsson | | #endif
|
c0df09 | 2001-06-29 | Martin Stjernholm | | m = find_marker(a);
|
22aa2f | 2000-09-04 | Martin Stjernholm | | if (!m)
gc_fatal(a, 1, "Found a thing without marker.\n");
else if (!(m->flags & GC_PRETOUCHED))
gc_fatal(a, 1, "Thing got an existing but untouched marker.\n");
|
e7634f | 2007-05-13 | Martin Stjernholm | | if (gc_destruct_everything && (m->flags & GC_MARKED))
gc_fatal (a, 1, "Thing got marked in gc_destruct_everything mode.\n");
|
50d97a | 2003-02-01 | Martin Stjernholm | | #ifdef PIKE_DEBUG
|
b13ee6 | 2001-06-30 | Martin Stjernholm | | extra_ref = (m->flags & GC_GOT_EXTRA_REF) == GC_GOT_EXTRA_REF;
if (m->saved_refs + extra_ref < *(INT32 *) a)
if (m->flags & GC_WEAK_FREED)
gc_fatal(a, 1, "Something failed to remove weak reference(s) to thing, "
"or it has gotten more references since gc start.\n");
else
gc_fatal(a, 1, "Thing has gotten more references since gc start.\n");
|
50d97a | 2003-02-01 | Martin Stjernholm | | else
if (m->weak_refs > m->saved_refs)
gc_fatal(a, 0, "A thing got more weak references than references.\n");
#endif
|
a3574b | 2007-05-13 | Martin Stjernholm | | m->flags |= GC_POSTTOUCHED;
|
22aa2f | 2000-09-04 | Martin Stjernholm | | break;
|
b13ee6 | 2001-06-30 | Martin Stjernholm | | }
|
22aa2f | 2000-09-04 | Martin Stjernholm | |
default:
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("debug_gc_touch() used in invalid gc pass.\n");
|
7bf623 | 2000-04-23 | Martin Stjernholm | | }
}
|
50d97a | 2003-02-01 | Martin Stjernholm | | #ifdef PIKE_DEBUG
|
081629 | 2000-07-03 | Martin Stjernholm | | static INLINE struct marker *gc_check_debug(void *a, int weak)
|
c94c37 | 1996-03-28 | Fredrik Hübinette (Hubbe) | | {
|
7bf623 | 2000-04-23 | Martin Stjernholm | | struct marker *m;
|
87c7f9 | 2000-04-19 | Martin Stjernholm | |
|
5aad93 | 2002-08-15 | Marcus Comstedt | | if (!a) Pike_fatal("Got null pointer.\n");
|
d9d6f0 | 2001-06-30 | Martin Stjernholm | | if(Pike_in_gc == GC_PASS_LOCATE)
|
b8a6e7 | 1996-09-25 | Fredrik Hübinette (Hubbe) | | {
if(check_for == a)
{
|
081629 | 2000-07-03 | Martin Stjernholm | | gdb_gc_stop_here(a, weak);
|
b8a6e7 | 1996-09-25 | Fredrik Hübinette (Hubbe) | | }
|
4a578f | 1997-01-27 | Fredrik Hübinette (Hubbe) | | return 0;
|
b8a6e7 | 1996-09-25 | Fredrik Hübinette (Hubbe) | | }
|
e942a7 | 2000-04-15 | Fredrik Hübinette (Hubbe) | |
|
03c660 | 2003-06-05 | Martin Stjernholm | | #if 0
fprintf (stderr, "Ref: %s %p -> %p%s\n",
|
e1a35e | 2003-09-08 | Martin Stjernholm | | get_name_of_type (gc_found_in_type), gc_found_in, a,
gc_found_place ? gc_found_place : "");
|
03c660 | 2003-06-05 | Martin Stjernholm | | #endif
|
7bf623 | 2000-04-23 | Martin Stjernholm | | if (Pike_in_gc != GC_PASS_CHECK)
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("gc check attempted in invalid pass.\n");
|
7bf623 | 2000-04-23 | Martin Stjernholm | |
m = get_marker(a);
|
87c7f9 | 2000-04-19 | Martin Stjernholm | |
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | if (!*(INT32 *)a)
gc_fatal(a, 1, "GC check on thing without refs.\n");
|
b13ee6 | 2001-06-30 | Martin Stjernholm | | if (m->saved_refs == -1) m->saved_refs = *(INT32 *)a;
else if (m->saved_refs != *(INT32 *)a)
|
081629 | 2000-07-03 | Martin Stjernholm | | gc_fatal(a, 1, "Refs changed in gc check pass.\n");
|
ff322e | 2000-06-10 | Martin Stjernholm | | if (m->refs + m->xrefs >= *(INT32 *) a)
|
9fa128 | 2004-04-04 | Martin Stjernholm | | gc_fatal(a, 1, "Thing is getting more internal refs than refs "
"(a pointer has probably been checked more than once).\n");
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | checked++;
return m;
}
#endif /* PIKE_DEBUG */
|
fa8c69 | 2000-11-30 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT INT32 real_gc_check(void *a)
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | {
struct marker *m;
|
081629 | 2000-07-03 | Martin Stjernholm | | INT32 ret;
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | #ifdef PIKE_DEBUG
|
e1a35e | 2003-09-08 | Martin Stjernholm | | if (gc_found_in_type == PIKE_T_UNKNOWN || !gc_found_in)
gc_fatal (a, 0, "gc_check() called outside GC_ENTER.\n");
|
1e9121 | 2001-07-05 | Martin Stjernholm | | if (gc_is_watching && (m = find_marker(a)) && m->flags & GC_WATCHED) {
|
8e5a40 | 2004-03-16 | Martin Stjernholm | | gc_watched_found (m, "gc_check()");
|
1e9121 | 2001-07-05 | Martin Stjernholm | | }
|
081629 | 2000-07-03 | Martin Stjernholm | | if (!(m = gc_check_debug(a, 0))) return 0;
|
220000 | 2000-04-23 | Martin Stjernholm | | #else
m = get_marker(a);
|
b8a6e7 | 1996-09-25 | Fredrik Hübinette (Hubbe) | | #endif
|
081629 | 2000-07-03 | Martin Stjernholm | |
|
aad99b | 2001-03-28 | Fredrik Hübinette (Hubbe) | | ret=m->refs;
add_ref(m);
|
b13ee6 | 2001-06-30 | Martin Stjernholm | | if (m->refs == *(INT32 *) a)
|
081629 | 2000-07-03 | Martin Stjernholm | | m->flags |= GC_NOT_REFERENCED;
return ret;
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | }
|
e942a7 | 2000-04-15 | Fredrik Hübinette (Hubbe) | |
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | INT32 real_gc_check_weak(void *a)
{
struct marker *m;
|
081629 | 2000-07-03 | Martin Stjernholm | | INT32 ret;
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | #ifdef PIKE_DEBUG
|
e1a35e | 2003-09-08 | Martin Stjernholm | | if (gc_found_in_type == PIKE_T_UNKNOWN || !gc_found_in)
gc_fatal (a, 0, "gc_check_weak() called outside GC_ENTER.\n");
|
1e9121 | 2001-07-05 | Martin Stjernholm | | if (gc_is_watching && (m = find_marker(a)) && m->flags & GC_WATCHED) {
|
8e5a40 | 2004-03-16 | Martin Stjernholm | | gc_watched_found (m, "gc_check_weak()");
|
1e9121 | 2001-07-05 | Martin Stjernholm | | }
|
081629 | 2000-07-03 | Martin Stjernholm | | if (!(m = gc_check_debug(a, 1))) return 0;
|
10c4a4 | 2000-08-17 | Martin Stjernholm | | if (m->weak_refs < 0)
|
932633 | 2000-06-12 | Martin Stjernholm | | gc_fatal(a, 1, "Thing has already reached threshold for weak free.\n");
|
081629 | 2000-07-03 | Martin Stjernholm | | if (m->weak_refs >= *(INT32 *) a)
gc_fatal(a, 1, "Thing has gotten more weak refs than refs.\n");
|
932633 | 2000-06-12 | Martin Stjernholm | | if (m->weak_refs > m->refs + 1)
gc_fatal(a, 1, "Thing has gotten more weak refs than internal refs.\n");
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | #else
m = get_marker(a);
|
ff322e | 2000-06-10 | Martin Stjernholm | | #endif
|
081629 | 2000-07-03 | Martin Stjernholm | |
m->weak_refs++;
|
6d30f5 | 2000-07-11 | Martin Stjernholm | | gc_ext_weak_refs++;
|
b13ee6 | 2001-06-30 | Martin Stjernholm | | if (m->weak_refs == *(INT32 *) a)
|
081629 | 2000-07-03 | Martin Stjernholm | | m->weak_refs = -1;
|
aad99b | 2001-03-28 | Fredrik Hübinette (Hubbe) | | ret=m->refs;
add_ref(m);
|
b13ee6 | 2001-06-30 | Martin Stjernholm | | if (m->refs == *(INT32 *) a)
|
081629 | 2000-07-03 | Martin Stjernholm | | m->flags |= GC_NOT_REFERENCED;
return ret;
|
c94c37 | 1996-03-28 | Fredrik Hübinette (Hubbe) | | }
|
a12b8c | 2003-03-30 | Martin Stjernholm | | static void cleanup_markers (void)
{
#ifdef DO_PIKE_CLEANUP
size_t e=0;
|
4fab5f | 2004-04-18 | Martin Stjernholm | |
if (gc_keep_markers) {
for(e=0;e<marker_hash_table_size;e++) {
struct marker *m;
for (m = marker_hash_table[e]; m; m = m->next) {
|
31a868 | 2004-09-27 | Martin Stjernholm | | #ifdef PIKE_DEBUG
|
4fab5f | 2004-04-18 | Martin Stjernholm | | m->flags &= GC_CLEANUP_FREED;
|
31a868 | 2004-09-27 | Martin Stjernholm | | m->xrefs = 0;
|
4fab5f | 2004-04-18 | Martin Stjernholm | | m->saved_refs = -1;
|
31a868 | 2004-09-27 | Martin Stjernholm | | #else
m->flags = 0;
#endif
m->refs = m->weak_refs = 0;
|
4fab5f | 2004-04-18 | Martin Stjernholm | | m->frame = 0;
}
}
return;
}
|
a12b8c | 2003-03-30 | Martin Stjernholm | | for(e=0;e<marker_hash_table_size;e++)
while(marker_hash_table[e])
remove_marker(marker_hash_table[e]->data);
#endif
exit_marker_hash();
}
|
b51e6d | 1998-02-18 | Fredrik Hübinette (Hubbe) | | static void init_gc(void)
{
|
1e9121 | 2001-07-05 | Martin Stjernholm | | #ifdef PIKE_DEBUG
if (!gc_is_watching) {
|
31a868 | 2004-09-27 | Martin Stjernholm | | #endif
#if defined (PIKE_DEBUG) || defined (DO_PIKE_CLEANUP)
|
a12b8c | 2003-03-30 | Martin Stjernholm | |
if (marker_hash_table) cleanup_markers();
|
4fab5f | 2004-04-18 | Martin Stjernholm | | if (!marker_hash_table)
|
31a868 | 2004-09-27 | Martin Stjernholm | | #endif
|
0429a3 | 2004-09-28 | Martin Stjernholm | | low_init_marker_hash(num_objects);
|
1e9121 | 2001-07-05 | Martin Stjernholm | | #ifdef PIKE_DEBUG
}
#endif
|
b51e6d | 1998-02-18 | Fredrik Hübinette (Hubbe) | | }
|
4fab5f | 2004-04-18 | Martin Stjernholm | | void exit_gc(void)
|
b51e6d | 1998-02-18 | Fredrik Hübinette (Hubbe) | | {
|
f3fa82 | 2004-01-13 | Henrik Grubbström (Grubba) | | if (gc_evaluator_callback) {
remove_callback(gc_evaluator_callback);
gc_evaluator_callback = NULL;
}
|
a12b8c | 2003-03-30 | Martin Stjernholm | | if (!gc_keep_markers)
cleanup_markers();
|
e7634f | 2007-05-13 | Martin Stjernholm | | free_all_gc_rec_frame_blocks();
free_all_ba_mixed_frame_blocks();
|
a12b8c | 2003-03-30 | Martin Stjernholm | |
|
1e9121 | 2001-07-05 | Martin Stjernholm | | #ifdef PIKE_DEBUG
if (gc_is_watching) {
fprintf(stderr, "## Exiting gc and resetting watches for %d things.\n",
gc_is_watching);
gc_is_watching = 0;
}
|
45d87e | 2000-07-18 | Martin Stjernholm | | #endif
|
b51e6d | 1998-02-18 | Fredrik Hübinette (Hubbe) | | }
|
31a868 | 2004-09-27 | Martin Stjernholm | | #ifdef PIKE_DEBUG
|
a5a334 | 2006-07-05 | Martin Stjernholm | | PMOD_EXPORT void gc_check_zapped (void *a, TYPE_T type, const char *file, int line)
|
3b6567 | 2004-05-23 | Martin Nilsson | | {
struct marker *m = find_marker (a);
if (m && (m->flags & GC_CLEANUP_FREED))
fprintf (stderr, "Free of leaked %s %p from %s:%d, %d refs remaining\n",
get_name_of_type (type), a, file, line, *(INT32 *)a - 1);
}
#endif
|
71f3a2 | 1998-11-22 | Fredrik Hübinette (Hubbe) | | #ifdef PIKE_DEBUG
|
030541 | 2003-09-29 | Martin Stjernholm | |
static void mark_externals (void)
{
struct mapping *constants;
if (master_object)
gc_mark_external (master_object, " as master_object");
if ((constants = get_builtin_constants()))
gc_mark_external (constants, " as global constants mapping");
}
|
b51e6d | 1998-02-18 | Fredrik Hübinette (Hubbe) | | void locate_references(void *a)
{
|
7bf623 | 2000-04-23 | Martin Stjernholm | | int tmp, orig_in_gc = Pike_in_gc;
|
9fa128 | 2004-04-04 | Martin Stjernholm | | const char *orig_gc_found_place = gc_found_place;
|
ffb390 | 2001-06-26 | Fredrik Hübinette (Hubbe) | | int i=0;
if(!marker_blocks)
{
i=1;
|
b51e6d | 1998-02-18 | Fredrik Hübinette (Hubbe) | | init_gc();
|
ffb390 | 2001-06-26 | Fredrik Hübinette (Hubbe) | | }
|
7bf623 | 2000-04-23 | Martin Stjernholm | | Pike_in_gc = GC_PASS_LOCATE;
|
9fa128 | 2004-04-04 | Martin Stjernholm | | gc_found_place = NULL;
|
7bf623 | 2000-04-23 | Martin Stjernholm | |
tmp=d_flag;
d_flag=0;
|
06ae27 | 2000-04-19 | Martin Stjernholm | |
|
8c4cbb | 2001-12-16 | Martin Stjernholm | | fprintf(stderr,"**Looking for references to %p:\n", a);
|
b51e6d | 1998-02-18 | Fredrik Hübinette (Hubbe) | |
check_for=a;
|
884c12 | 2004-03-15 | Martin Stjernholm | | found_ref_count = 0;
|
25d21c | 1998-02-24 | Per Hedbor | |
|
04bbb7 | 2003-09-24 | Martin Stjernholm | | GC_ENTER (NULL, PIKE_T_UNKNOWN) {
|
030541 | 2003-09-29 | Martin Stjernholm | | mark_externals();
call_callback(& gc_callbacks, NULL);
|
04bbb7 | 2003-09-24 | Martin Stjernholm | | gc_check_all_arrays();
gc_check_all_multisets();
gc_check_all_mappings();
gc_check_all_programs();
gc_check_all_objects();
|
fec15e | 2007-04-25 | Martin Stjernholm | | #if defined (PIKE_DEBUG) || defined (DO_PIKE_CLEANUP)
debug_gc_check_all_types();
#endif
|
04bbb7 | 2003-09-24 | Martin Stjernholm | | } GC_LEAVE;
|
20513c | 2000-04-12 | Fredrik Hübinette (Hubbe) | |
#ifdef DEBUG_MALLOC
{
extern void dmalloc_find_references_to(void *);
#if 0
fprintf(stderr,"**DMALLOC Looking for references:\n");
dmalloc_find_references_to(a);
#endif
}
#endif
|
884c12 | 2004-03-15 | Martin Stjernholm | | fprintf(stderr,"**Done looking for references to %p, "
"found %"PRINTSIZET"d refs.\n", a, found_ref_count);
|
8c4cbb | 2001-12-16 | Martin Stjernholm | |
|
7bf623 | 2000-04-23 | Martin Stjernholm | | Pike_in_gc = orig_in_gc;
|
9fa128 | 2004-04-04 | Martin Stjernholm | | gc_found_place = orig_gc_found_place;
|
ffb390 | 2001-06-26 | Fredrik Hübinette (Hubbe) | | if(i) exit_gc();
|
7bf623 | 2000-04-23 | Martin Stjernholm | | d_flag=tmp;
|
b51e6d | 1998-02-18 | Fredrik Hübinette (Hubbe) | | }
|
1637c4 | 2000-02-01 | Fredrik Hübinette (Hubbe) | |
|
c2be51 | 2001-03-21 | Fredrik Hübinette (Hubbe) | | void debug_gc_add_extra_ref(void *a)
|
c94c37 | 1996-03-28 | Fredrik Hübinette (Hubbe) | | {
|
c0df09 | 2001-06-29 | Martin Stjernholm | | struct marker *m;
|
1e9121 | 2001-07-05 | Martin Stjernholm | | if (gc_is_watching && (m = find_marker(a)) && m->flags & GC_WATCHED) {
|
8e5a40 | 2004-03-16 | Martin Stjernholm | | gc_watched_found (m, "gc_add_extra_ref()");
|
1e9121 | 2001-07-05 | Martin Stjernholm | | }
|
c0df09 | 2001-06-29 | Martin Stjernholm | | if (gc_debug) {
m = find_marker(a);
if ((!m || !(m->flags & GC_PRETOUCHED)) &&
!safe_debug_findstring((struct pike_string *) a))
gc_fatal(a, 0, "Doing gc_add_extra_ref() on invalid object.\n");
if (!m) m = get_marker(a);
}
else m = get_marker(a);
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | if (m->flags & GC_GOT_EXTRA_REF)
gc_fatal(a, 0, "Thing already got an extra gc ref.\n");
m->flags |= GC_GOT_EXTRA_REF;
gc_extra_refs++;
|
9a6d00 | 2001-06-26 | Fredrik Hübinette (Hubbe) | | add_ref( (struct ref_dummy *)a);
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | }
|
1637c4 | 2000-02-01 | Fredrik Hübinette (Hubbe) | |
|
c2be51 | 2001-03-21 | Fredrik Hübinette (Hubbe) | | void debug_gc_free_extra_ref(void *a)
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | {
|
c0df09 | 2001-06-29 | Martin Stjernholm | | struct marker *m;
|
1e9121 | 2001-07-05 | Martin Stjernholm | | if (gc_is_watching && (m = find_marker(a)) && m->flags & GC_WATCHED) {
|
8e5a40 | 2004-03-16 | Martin Stjernholm | | gc_watched_found (m, "gc_free_extra_ref()");
|
1e9121 | 2001-07-05 | Martin Stjernholm | | }
|
c0df09 | 2001-06-29 | Martin Stjernholm | | if (gc_debug) {
m = find_marker(a);
if ((!m || !(m->flags & GC_PRETOUCHED)) &&
!safe_debug_findstring((struct pike_string *) a))
gc_fatal(a, 0, "Doing gc_add_extra_ref() on invalid object.\n");
if (!m) m = get_marker(a);
}
else m = get_marker(a);
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | if (!(m->flags & GC_GOT_EXTRA_REF))
gc_fatal(a, 0, "Thing haven't got an extra gc ref.\n");
m->flags &= ~GC_GOT_EXTRA_REF;
gc_extra_refs--;
}
|
c2be51 | 2001-03-21 | Fredrik Hübinette (Hubbe) | |
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | int debug_gc_is_referenced(void *a)
{
struct marker *m;
|
1e9121 | 2001-07-05 | Martin Stjernholm | |
if (gc_is_watching && (m = find_marker(a)) && m->flags & GC_WATCHED) {
|
8e5a40 | 2004-03-16 | Martin Stjernholm | | gc_watched_found (m, "gc_is_referenced()");
|
1e9121 | 2001-07-05 | Martin Stjernholm | | }
|
5aad93 | 2002-08-15 | Marcus Comstedt | | if (!a) Pike_fatal("Got null pointer.\n");
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | if (Pike_in_gc != GC_PASS_MARK)
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("gc_is_referenced() called in invalid gc pass.\n");
|
142241 | 1997-10-13 | Fredrik Hübinette (Hubbe) | |
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | if (gc_debug) {
m = find_marker(a);
|
22aa2f | 2000-09-04 | Martin Stjernholm | | if ((!m || !(m->flags & GC_PRETOUCHED)) &&
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | !safe_debug_findstring((struct pike_string *) a))
gc_fatal(a, 0, "Doing gc_is_referenced() on invalid object.\n");
if (!m) m = get_marker(a);
|
b8a6e7 | 1996-09-25 | Fredrik Hübinette (Hubbe) | | }
|
7e697c | 2000-09-14 | Martin Stjernholm | | else m = get_marker(a);
|
1637c4 | 2000-02-01 | Fredrik Hübinette (Hubbe) | |
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | if (m->flags & GC_IS_REFERENCED)
gc_fatal(a, 0, "gc_is_referenced() called twice for thing.\n");
m->flags |= GC_IS_REFERENCED;
|
081629 | 2000-07-03 | Martin Stjernholm | |
return !(m->flags & GC_NOT_REFERENCED);
|
c94c37 | 1996-03-28 | Fredrik Hübinette (Hubbe) | | }
|
e1a35e | 2003-09-08 | Martin Stjernholm | | int gc_mark_external (void *a, const char *place)
|
05c7cd | 1997-07-19 | Fredrik Hübinette (Hubbe) | | {
struct marker *m;
|
1e9121 | 2001-07-05 | Martin Stjernholm | |
if (gc_is_watching && (m = find_marker(a)) && m->flags & GC_WATCHED) {
|
8e5a40 | 2004-03-16 | Martin Stjernholm | | gc_watched_found (m, "gc_mark_external()");
|
1e9121 | 2001-07-05 | Martin Stjernholm | | }
|
5aad93 | 2002-08-15 | Marcus Comstedt | | if (!a) Pike_fatal("Got null pointer.\n");
|
7506fe | 2000-04-19 | Martin Stjernholm | |
|
d9d6f0 | 2001-06-30 | Martin Stjernholm | | if(Pike_in_gc == GC_PASS_LOCATE)
|
05c7cd | 1997-07-19 | Fredrik Hübinette (Hubbe) | | {
|
e1a35e | 2003-09-08 | Martin Stjernholm | | if(a==check_for) {
const char *orig_gc_found_place = gc_found_place;
gc_found_place = place;
|
081629 | 2000-07-03 | Martin Stjernholm | | gdb_gc_stop_here(a, 0);
|
e1a35e | 2003-09-08 | Martin Stjernholm | | gc_found_place = orig_gc_found_place;
|
05c7cd | 1997-07-19 | Fredrik Hübinette (Hubbe) | | }
return 0;
}
|
d9d6f0 | 2001-06-30 | Martin Stjernholm | |
if (Pike_in_gc != GC_PASS_CHECK)
|
e1a35e | 2003-09-08 | Martin Stjernholm | | Pike_fatal("gc_mark_external() called in invalid gc pass.\n");
|
d9d6f0 | 2001-06-30 | Martin Stjernholm | |
|
a12b8c | 2003-03-30 | Martin Stjernholm | | #ifdef DEBUG_MALLOC
if (gc_external_refs_zapped) {
fprintf (stderr, "One external ref to %p found%s.\n",
|
e1a35e | 2003-09-08 | Martin Stjernholm | | a, place ? place : "");
|
4c6e55 | 2003-09-08 | Martin Stjernholm | | if (gc_found_in) describe (gc_found_in);
|
a12b8c | 2003-03-30 | Martin Stjernholm | | return 0;
}
#endif
|
424d9c | 1999-05-02 | Fredrik Hübinette (Hubbe) | | m=get_marker(a);
|
05c7cd | 1997-07-19 | Fredrik Hübinette (Hubbe) | | m->xrefs++;
m->flags|=GC_XREFERENCED;
|
081629 | 2000-07-03 | Martin Stjernholm | | if(Pike_in_gc == GC_PASS_CHECK &&
(m->refs + m->xrefs > *(INT32 *)a ||
(m->saved_refs != -1 && m->saved_refs != *(INT32 *)a)))
|
ff322e | 2000-06-10 | Martin Stjernholm | | gc_fatal(a, 1, "Ref counts are wrong.\n");
|
05c7cd | 1997-07-19 | Fredrik Hübinette (Hubbe) | | return 0;
}
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | |
|
eb4aba | 2007-05-26 | Martin Stjernholm | | #define LOW_CHECK_REC_FRAME(f, file, line) do { \
if (f->rf_flags & GC_FRAME_FREED) \
dloc_gc_fatal (file, line, f->data, 0, \
"Accessing freed gc_stack_frame %p.\n", f); \
if (f->cycle_id->rf_flags & GC_FRAME_FREED) { \
fprintf (stderr, "Cycle id frame is freed. It is: "); \
describe_rec_frame (f->cycle_id); \
fputc ('\n', stderr); \
dloc_gc_fatal (file, line, f->data, 0, "Cycle id frame is freed.\n"); \
} \
} while (0)
static void check_rec_stack_frame (struct gc_rec_frame *f,
const char *file, int line)
{
LOW_CHECK_REC_FRAME (f, file, line);
if (f->rf_flags & (GC_ON_CYCLE_PIECE_LIST|GC_ON_KILL_LIST))
dloc_gc_fatal (file, line, f->data, 0, "Frame is not on the rec stack.\n");
if (!f->prev)
dloc_gc_fatal (file, line, f->data, 0,
"Prev pointer not set for rec stack frame.\n");
if (f->prev->next != f)
dloc_gc_fatal (file, line, f->data, 0,
"Rec stack pointers are inconsistent.\n");
if (f->cycle_id &&
f->cycle_id->rf_flags & (GC_ON_CYCLE_PIECE_LIST|GC_ON_KILL_LIST))
dloc_gc_fatal (file, line, f->data, 0,
"Cycle id frame not on the rec stack.\n");
if (f->cycle_piece &&
(!f->cycle_piece->u.last_cycle_piece ||
f->cycle_piece->u.last_cycle_piece->cycle_piece))
dloc_gc_fatal (file, line, f->data, 0,
"Bogus last_cycle_piece %p is %p in %p.\n",
f->cycle_piece->u.last_cycle_piece,
f->cycle_piece->u.last_cycle_piece ?
f->cycle_piece->u.last_cycle_piece->cycle_piece : NULL,
f->cycle_piece);
if ((f->rf_flags & GC_PREV_STRONG) &&
(f->rf_flags & (GC_PREV_WEAK|GC_PREV_BROKEN)))
dloc_gc_fatal (file, line, f->data, 0,
"GC_PREV_STRONG set together with "
"GC_PREV_WEAK or GC_PREV_BROKEN.\n");
}
#define CHECK_REC_STACK_FRAME(f) \
do check_rec_stack_frame ((f), __FILE__, __LINE__); while (0)
static void check_cycle_piece_frame (struct gc_rec_frame *f,
const char *file, int line)
{
LOW_CHECK_REC_FRAME (f, file, line);
if ((f->rf_flags & (GC_ON_CYCLE_PIECE_LIST|GC_ON_KILL_LIST)) !=
GC_ON_CYCLE_PIECE_LIST)
dloc_gc_fatal (file, line, f->data, 0,
"Frame is not on a cycle piece list.\n");
if (f->prev)
dloc_gc_fatal (file, line, f->data, 0,
"Prev pointer set for frame on cycle piece list.\n");
}
#define CHECK_CYCLE_PIECE_FRAME(f) \
do check_cycle_piece_frame ((f), __FILE__, __LINE__); while (0)
static void check_kill_list_frame (struct gc_rec_frame *f,
const char *file, int line)
{
LOW_CHECK_REC_FRAME (f, file, line);
if ((f->rf_flags & (GC_ON_CYCLE_PIECE_LIST|GC_ON_KILL_LIST)) !=
GC_ON_KILL_LIST)
dloc_gc_fatal (file, line, f->data, 0, "Frame is not on kill list.\n");
if (f->prev)
dloc_gc_fatal (file, line, f->data, 0,
"Prev pointer set for frame on kill list.\n");
}
#define CHECK_KILL_LIST_FRAME(f) \
do check_kill_list_frame ((f), __FILE__, __LINE__); while (0)
#else /* !PIKE_DEBUG */
#define CHECK_REC_STACK_FRAME(f) do {} while (0)
#define CHECK_CYCLE_PIECE_FRAME(f) do {} while (0)
#define CHECK_KILL_LIST_FRAME(f) do {} while (0)
#endif /* !PIKE_DEBUG */
|
63709a | 2000-07-18 | Martin Stjernholm | |
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | int gc_do_weak_free(void *a)
{
struct marker *m;
|
63709a | 2000-07-18 | Martin Stjernholm | | #ifdef PIKE_DEBUG
|
1e9121 | 2001-07-05 | Martin Stjernholm | | if (gc_is_watching && (m = find_marker(a)) && m->flags & GC_WATCHED) {
|
8e5a40 | 2004-03-16 | Martin Stjernholm | | gc_watched_found (m, "gc_do_weak_free()");
|
1e9121 | 2001-07-05 | Martin Stjernholm | | }
|
5aad93 | 2002-08-15 | Marcus Comstedt | | if (!a) Pike_fatal("Got null pointer.\n");
|
22aa2f | 2000-09-04 | Martin Stjernholm | | if (Pike_in_gc != GC_PASS_MARK && Pike_in_gc != GC_PASS_ZAP_WEAK)
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("gc_do_weak_free() called in invalid gc pass.\n");
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | if (gc_debug) {
if (!(m = find_marker(a)))
gc_fatal(a, 0, "gc_do_weak_free() got unknown object.\n");
}
|
ff322e | 2000-06-10 | Martin Stjernholm | | else m = get_marker(a);
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | debug_malloc_touch(a);
if (m->weak_refs > m->refs)
gc_fatal(a, 0, "More weak references than internal references.\n");
|
63709a | 2000-07-18 | Martin Stjernholm | | #else
m = get_marker(a);
#endif
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | |
|
45d87e | 2000-07-18 | Martin Stjernholm | | if (Pike_in_gc != GC_PASS_ZAP_WEAK) {
|
2b8dde | 2000-09-15 | Martin Stjernholm | | if (m->weak_refs < 0)
goto should_free;
|
6d30f5 | 2000-07-11 | Martin Stjernholm | | }
else
if (!(m->flags & GC_MARKED)) {
|
63709a | 2000-07-18 | Martin Stjernholm | | #ifdef PIKE_DEBUG
|
6d30f5 | 2000-07-11 | Martin Stjernholm | | if (m->weak_refs <= 0)
gc_fatal(a, 0, "Too many weak refs cleared to thing with external "
"weak refs.\n");
|
63709a | 2000-07-18 | Martin Stjernholm | | #endif
|
6d30f5 | 2000-07-11 | Martin Stjernholm | | m->weak_refs--;
|
2b8dde | 2000-09-15 | Martin Stjernholm | | goto should_free;
|
6d30f5 | 2000-07-11 | Martin Stjernholm | | }
return 0;
|
2b8dde | 2000-09-15 | Martin Stjernholm | |
should_free:
gc_ext_weak_refs--;
#ifdef PIKE_DEBUG
|
1a12e8 | 2000-09-30 | Martin Stjernholm | | m->saved_refs--;
|
2b8dde | 2000-09-15 | Martin Stjernholm | | m->flags |= GC_WEAK_FREED;
#endif
if (*(INT32 *) a == 1) {
gc_add_extra_ref(a);
m->flags |= GC_GOT_DEAD_REF;
|
d9d6f0 | 2001-06-30 | Martin Stjernholm | | #ifdef PIKE_DEBUG
delayed_freed++;
#endif
|
2b8dde | 2000-09-15 | Martin Stjernholm | | }
return 1;
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | }
|
05c7cd | 1997-07-19 | Fredrik Hübinette (Hubbe) | |
|
b35129 | 2001-08-20 | Martin Stjernholm | | void gc_delayed_free(void *a, int type)
|
49bf8a | 2000-12-14 | Martin Stjernholm | | {
struct marker *m;
#ifdef PIKE_DEBUG
|
1e9121 | 2001-07-05 | Martin Stjernholm | | if (gc_is_watching && (m = find_marker(a)) && m->flags & GC_WATCHED) {
|
8e5a40 | 2004-03-16 | Martin Stjernholm | | gc_watched_found (m, "gc_delayed_free()");
|
1e9121 | 2001-07-05 | Martin Stjernholm | | }
|
49bf8a | 2000-12-14 | Martin Stjernholm | | if (Pike_in_gc != GC_PASS_MARK && Pike_in_gc != GC_PASS_CYCLE &&
Pike_in_gc != GC_PASS_ZAP_WEAK)
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("gc_delayed_free() called in invalid gc pass.\n");
|
49bf8a | 2000-12-14 | Martin Stjernholm | | if (gc_debug) {
if (!(m = find_marker(a)))
gc_fatal(a, 0, "gc_delayed_free() got unknown object (missed by pretouch pass).\n");
}
else m = get_marker(a);
if (*(INT32 *) a != 1)
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("gc_delayed_free() called for thing that haven't got a single ref.\n");
|
49bf8a | 2000-12-14 | Martin Stjernholm | | debug_malloc_touch(a);
|
d9d6f0 | 2001-06-30 | Martin Stjernholm | | delayed_freed++;
|
49bf8a | 2000-12-14 | Martin Stjernholm | | #else
m = get_marker(a);
#endif
|
fcb322 | 2001-07-05 | Martin Stjernholm | | if (m->flags & GC_MARKED) {
|
e7634f | 2007-05-13 | Martin Stjernholm | | struct free_extra_frame *l = alloc_free_extra_frame();
|
fcb322 | 2001-07-05 | Martin Stjernholm | | l->data = a;
|
1bad5c | 2005-04-14 | Martin Stjernholm | | l->type = type;
|
e7634f | 2007-05-13 | Martin Stjernholm | | l->next = free_extra_list;
|
fcb322 | 2001-07-05 | Martin Stjernholm | | free_extra_list = l;
}
|
49bf8a | 2000-12-14 | Martin Stjernholm | | gc_add_extra_ref(a);
m->flags |= GC_GOT_DEAD_REF;
}
|
c94c37 | 1996-03-28 | Fredrik Hübinette (Hubbe) | | int gc_mark(void *a)
{
|
28d6b7 | 2006-03-10 | Martin Stjernholm | | struct marker *m;
#ifdef PIKE_DEBUG
if (Pike_in_gc == GC_PASS_ZAP_WEAK && !find_marker (a))
gc_fatal (a, 0, "gc_mark() called for for thing without marker "
"in zap weak pass.\n");
#endif
m = get_marker (a);
|
c94c37 | 1996-03-28 | Fredrik Hübinette (Hubbe) | |
|
87c7f9 | 2000-04-19 | Martin Stjernholm | | #ifdef PIKE_DEBUG
|
1e9121 | 2001-07-05 | Martin Stjernholm | | if (gc_is_watching && m && m->flags & GC_WATCHED) {
|
8e5a40 | 2004-03-16 | Martin Stjernholm | | gc_watched_found (m, "gc_mark()");
|
1e9121 | 2001-07-05 | Martin Stjernholm | | }
|
5aad93 | 2002-08-15 | Marcus Comstedt | | if (!a) Pike_fatal("Got null pointer.\n");
|
45d87e | 2000-07-18 | Martin Stjernholm | | if (Pike_in_gc != GC_PASS_MARK && Pike_in_gc != GC_PASS_ZAP_WEAK)
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("gc mark attempted in invalid pass.\n");
|
081629 | 2000-07-03 | Martin Stjernholm | | if (!*(INT32 *) a)
gc_fatal(a, 0, "Marked a thing without refs.\n");
|
10c4a4 | 2000-08-17 | Martin Stjernholm | | if (m->weak_refs < 0)
|
6d30f5 | 2000-07-11 | Martin Stjernholm | | gc_fatal(a, 0, "Marking thing scheduled for weak free.\n");
|
87c7f9 | 2000-04-19 | Martin Stjernholm | | #endif
|
1a12e8 | 2000-09-30 | Martin Stjernholm | | if (Pike_in_gc == GC_PASS_ZAP_WEAK) {
|
45d87e | 2000-07-18 | Martin Stjernholm | |
|
1a12e8 | 2000-09-30 | Martin Stjernholm | | #ifdef PIKE_DEBUG
if (!(m->flags & GC_MARKED))
gc_fatal(a, 0, "gc_mark() called for thing in zap weak pass "
"that wasn't marked before.\n");
#endif
|
28d6b7 | 2006-03-10 | Martin Stjernholm | | if (m->flags & GC_FREE_VISITED) {
debug_malloc_touch (a);
|
6d30f5 | 2000-07-11 | Martin Stjernholm | | return 0;
|
28d6b7 | 2006-03-10 | Martin Stjernholm | | }
|
6d30f5 | 2000-07-11 | Martin Stjernholm | | else {
|
28d6b7 | 2006-03-10 | Martin Stjernholm | | debug_malloc_touch (a);
|
6d30f5 | 2000-07-11 | Martin Stjernholm | | m->flags |= GC_FREE_VISITED;
return 1;
}
|
1a12e8 | 2000-09-30 | Martin Stjernholm | | }
|
6d30f5 | 2000-07-11 | Martin Stjernholm | |
else if (m->flags & GC_MARKED) {
|
28d6b7 | 2006-03-10 | Martin Stjernholm | | debug_malloc_touch (a);
|
6d30f5 | 2000-07-11 | Martin Stjernholm | | #ifdef PIKE_DEBUG
if (m->weak_refs != 0)
gc_fatal(a, 0, "weak_refs changed in marker already visited by gc_mark().\n");
#endif
|
c94c37 | 1996-03-28 | Fredrik Hübinette (Hubbe) | | return 0;
|
6d30f5 | 2000-07-11 | Martin Stjernholm | | }
else {
|
28d6b7 | 2006-03-10 | Martin Stjernholm | | debug_malloc_touch (a);
|
6d30f5 | 2000-07-11 | Martin Stjernholm | | if (m->weak_refs) {
gc_ext_weak_refs -= m->weak_refs;
m->weak_refs = 0;
}
|
081629 | 2000-07-03 | Martin Stjernholm | | m->flags = (m->flags & ~GC_NOT_REFERENCED) | GC_MARKED;
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | DO_IF_DEBUG(marked++);
|
c94c37 | 1996-03-28 | Fredrik Hübinette (Hubbe) | | return 1;
}
}
|
8eaec8 | 2006-02-18 | Martin Stjernholm | | void gc_move_marker (void *old, void *new)
{
|
28d6b7 | 2006-03-10 | Martin Stjernholm | | struct marker *m = find_marker (old);
|
8eaec8 | 2006-02-18 | Martin Stjernholm | |
#ifdef PIKE_DEBUG
|
28d6b7 | 2006-03-10 | Martin Stjernholm | | if (!Pike_in_gc || Pike_in_gc >= GC_PASS_FREE)
Pike_fatal ("gc move mark attempted in invalid pass.\n");
if (!old) Pike_fatal ("Got null pointer in old.\n");
if (!new) Pike_fatal ("Got null pointer in new.\n");
|
8eaec8 | 2006-02-18 | Martin Stjernholm | | if (!m) Pike_fatal ("Have no marker for old block %p.\n", old);
if (find_marker (new))
Pike_fatal ("New block %p already got a marker.\n", new);
#endif
|
0569d1 | 2006-02-25 | Martin Stjernholm | | move_marker (m, debug_malloc_pass (new));
|
8eaec8 | 2006-02-18 | Martin Stjernholm | | }
|
1e0c4f | 2007-05-13 | Martin Stjernholm | | int gc_object_is_live (struct object *o)
{
extern void compat_event_handler(int e);
struct program *p = o->prog;
if (!p) return 0;
if (FIND_LFUN (p, LFUN_DESTROY) != -1) return 1;
if (!p->event_handler) return 0;
if (p->event_handler != compat_event_handler)
return 1;
return !!((void (**) (struct object *)) p->program)[PROG_EVENT_EXIT];
}
|
fa8c69 | 2000-11-30 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void gc_cycle_enqueue(gc_cycle_check_cb *checkfn, void *data, int weak)
|
45d87e | 2000-07-18 | Martin Stjernholm | | {
|
e7634f | 2007-05-13 | Martin Stjernholm | | struct link_frame *l = alloc_link_frame();
|
1a12e8 | 2000-09-30 | Martin Stjernholm | | #ifdef PIKE_DEBUG
|
1e9121 | 2001-07-05 | Martin Stjernholm | | {
struct marker *m;
if (gc_is_watching && (m = find_marker(data)) && m->flags & GC_WATCHED) {
|
8e5a40 | 2004-03-16 | Martin Stjernholm | | gc_watched_found (m, "gc_cycle_enqueue()");
|
1e9121 | 2001-07-05 | Martin Stjernholm | | }
}
|
1a12e8 | 2000-09-30 | Martin Stjernholm | | if (Pike_in_gc != GC_PASS_CYCLE)
gc_fatal(data, 0, "Use of the gc frame stack outside the cycle check pass.\n");
|
e7634f | 2007-05-13 | Martin Stjernholm | | if (stack_top == &sentinel_frame)
gc_fatal (data, 0, "No thing on rec stack to follow links from.\n");
|
45d87e | 2000-07-18 | Martin Stjernholm | | #endif
l->data = data;
|
1bad5c | 2005-04-14 | Martin Stjernholm | | l->checkfn = checkfn;
l->weak = weak;
|
e7634f | 2007-05-13 | Martin Stjernholm | | l->prev = stack_top->u.link_top;
|
45d87e | 2000-07-18 | Martin Stjernholm | | #ifdef GC_STACK_DEBUG
|
e7634f | 2007-05-13 | Martin Stjernholm | | fprintf (stderr, "push link %p [%p in %p]: ", l, stack_top->u.link_top, stack_top);
describe_link_frame (l);
|
45d87e | 2000-07-18 | Martin Stjernholm | | fputc('\n', stderr);
#endif
|
e7634f | 2007-05-13 | Martin Stjernholm | | stack_top->u.link_top = l;
|
45d87e | 2000-07-18 | Martin Stjernholm | | }
|
e7634f | 2007-05-13 | Martin Stjernholm | | static struct gc_rec_frame *gc_cycle_enqueue_rec (void *data)
|
45d87e | 2000-07-18 | Martin Stjernholm | | {
|
e7634f | 2007-05-13 | Martin Stjernholm | | struct gc_rec_frame *r = alloc_gc_rec_frame();
|
1a12e8 | 2000-09-30 | Martin Stjernholm | | #ifdef PIKE_DEBUG
if (Pike_in_gc != GC_PASS_CYCLE)
gc_fatal(data, 0, "Use of the gc frame stack outside the cycle check pass.\n");
|
e7634f | 2007-05-13 | Martin Stjernholm | | r->next = (struct gc_rec_frame *) (ptrdiff_t) -1;
|
1a12e8 | 2000-09-30 | Martin Stjernholm | | #endif
|
e7634f | 2007-05-13 | Martin Stjernholm | | r->data = data;
r->u.link_top = NULL;
r->prev = stack_top;
r->cycle_id = r;
r->cycle_piece = NULL;
|
45d87e | 2000-07-18 | Martin Stjernholm | | #ifdef GC_STACK_DEBUG
|
e7634f | 2007-05-13 | Martin Stjernholm | | fprintf (stderr, "push rec %p [%p]: ", r, stack_top);
describe_rec_frame (r);
|
45d87e | 2000-07-18 | Martin Stjernholm | | fputc('\n', stderr);
#endif
|
e7634f | 2007-05-13 | Martin Stjernholm | | stack_top->next = r;
stack_top = r;
return r;
|
45d87e | 2000-07-18 | Martin Stjernholm | | }
void gc_cycle_run_queue()
{
|
1a12e8 | 2000-09-30 | Martin Stjernholm | | #ifdef PIKE_DEBUG
if (Pike_in_gc != GC_PASS_CYCLE)
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Use of the gc frame stack outside the cycle check pass.\n");
|
1a12e8 | 2000-09-30 | Martin Stjernholm | | #endif
|
cde9da | 2005-04-15 | Martin Stjernholm | |
|
e7634f | 2007-05-13 | Martin Stjernholm | | while (stack_top != &sentinel_frame) {
while (stack_top->u.link_top) {
struct link_frame l = *stack_top->u.link_top;
|
45d87e | 2000-07-18 | Martin Stjernholm | | #ifdef GC_STACK_DEBUG
|
e7634f | 2007-05-13 | Martin Stjernholm | | fprintf (stderr, "pop link %p [%p in %p]: ",
stack_top->u.link_top, l.prev, stack_top);
describe_link_frame (stack_top->u.link_top);
fputc ('\n', stderr);
#endif
really_free_link_frame (stack_top->u.link_top);
stack_top->u.link_top = l.prev;
l.checkfn (l.data, l.weak);
|
cde9da | 2005-04-15 | Martin Stjernholm | | }
|
e7634f | 2007-05-13 | Martin Stjernholm | | #ifdef GC_STACK_DEBUG
fprintf (stderr, "pop rec %p [%p]: ", stack_top, stack_top->prev);
describe_rec_frame (stack_top);
fputc ('\n', stderr);
|
45d87e | 2000-07-18 | Martin Stjernholm | | #endif
|
e7634f | 2007-05-13 | Martin Stjernholm | | CHECK_REC_STACK_FRAME (stack_top);
#ifdef PIKE_DEBUG
{
struct gc_rec_frame *old_stack_top = stack_top;
gc_cycle_pop();
if (stack_top == old_stack_top)
fatal ("gc_cycle_pop didn't pop the stack.\n");
|
45d87e | 2000-07-18 | Martin Stjernholm | | }
|
e7634f | 2007-05-13 | Martin Stjernholm | | #else
gc_cycle_pop();
#endif
|
45d87e | 2000-07-18 | Martin Stjernholm | | }
}
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | #ifdef GC_CYCLE_DEBUG
static int gc_cycle_indent = 0;
|
e7634f | 2007-05-13 | Martin Stjernholm | | #define CYCLE_DEBUG_MSG(REC, TXT) do { \
struct gc_rec_frame *r_ = (REC); \
fprintf (stderr, "%*s%-35s %p [%p] ", gc_cycle_indent, "", \
(TXT), r_ ? r_->data : NULL, stack_top->data); \
if (r_) describe_rec_frame (r_); \
putc ('\n', stderr); \
} while (0)
|
996f87 | 2000-06-12 | Martin Stjernholm | | #else
|
e7634f | 2007-05-13 | Martin Stjernholm | | #define CYCLE_DEBUG_MSG(REC, TXT) do {} while (0)
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | #endif
|
e7634f | 2007-05-13 | Martin Stjernholm | | static struct gc_rec_frame *rotate_rec_stack (struct gc_rec_frame *beg,
struct gc_rec_frame *pos)
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | {
|
e7634f | 2007-05-13 | Martin Stjernholm | | CYCLE_DEBUG_MSG (beg, "> rotate_rec_stack, requested beg");
|
0db2c0 | 2003-02-14 | Martin Stjernholm | |
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | #ifdef PIKE_DEBUG
|
1a12e8 | 2000-09-30 | Martin Stjernholm | | if (Pike_in_gc != GC_PASS_CYCLE)
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Use of the gc frame stack outside the cycle check pass.\n");
|
e7634f | 2007-05-13 | Martin Stjernholm | | CHECK_REC_STACK_FRAME (beg);
CHECK_REC_STACK_FRAME (pos);
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | if (beg == pos)
|
e7634f | 2007-05-13 | Martin Stjernholm | | gc_fatal (beg->data, 0, "Cycle already broken at requested position.\n");
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | #endif
|
45d87e | 2000-07-18 | Martin Stjernholm | | #ifdef GC_STACK_DEBUG
fprintf(stderr,"Stack before:\n");
|
e7634f | 2007-05-13 | Martin Stjernholm | | {
struct gc_rec_frame *l;
for (l = stack_top; l != &sentinel_frame; l = l->prev) {
fprintf (stderr, " %p%s ", l,
l == beg ? " (beg)" : l == pos ? " (pos)" : "");
describe_rec_frame (l);
fputc ('\n', stderr);
}
|
45d87e | 2000-07-18 | Martin Stjernholm | | }
#endif
|
0db2c0 | 2003-02-14 | Martin Stjernholm | |
|
e7634f | 2007-05-13 | Martin Stjernholm | | for (; beg->rf_flags & GC_PREV_STRONG; beg = beg->prev)
CYCLE_DEBUG_MSG (beg, "> rotate_rec_stack, skipping strong");
#ifdef PIKE_DEBUG
if (beg == &sentinel_frame) fatal ("Strong ref chain ended up off stack.\n");
#endif
CYCLE_DEBUG_MSG (beg, "> rotate_rec_stack, actual beg");
|
46d4e7 | 2000-06-12 | Martin Stjernholm | |
|
45d87e | 2000-07-18 | Martin Stjernholm | | {
|
e7634f | 2007-05-13 | Martin Stjernholm | | struct gc_rec_frame *new_stack_top = pos->prev;
|
996f87 | 2000-06-12 | Martin Stjernholm | |
|
1bad5c | 2005-04-14 | Martin Stjernholm | | beg->prev->next = pos;
pos->prev = beg->prev;
|
e7634f | 2007-05-13 | Martin Stjernholm | |
stack_top->next = beg;
beg->prev = stack_top;
stack_top = new_stack_top;
#ifdef PIKE_DEBUG
stack_top->next = (struct gc_rec_frame *) (ptrdiff_t) -1;
#endif
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | }
|
af72c5 | 2000-07-02 | Martin Stjernholm | |
|
e7634f | 2007-05-13 | Martin Stjernholm | | #ifdef PIKE_DEBUG
frame_rot++;
#endif
pos->rf_flags |= GC_PREV_BROKEN;
|
45d87e | 2000-07-18 | Martin Stjernholm | | #ifdef GC_STACK_DEBUG
fprintf(stderr,"Stack after:\n");
|
e7634f | 2007-05-13 | Martin Stjernholm | | {
struct gc_rec_frame *l;
for (l = stack_top; l != &sentinel_frame; l = l->prev) {
fprintf (stderr, " %p%s ", l,
l == beg ? " (beg)" : l == pos ? " (pos)" : "");
describe_rec_frame (l);
fputc ('\n', stderr);
}
|
45d87e | 2000-07-18 | Martin Stjernholm | | }
#endif
|
e7634f | 2007-05-13 | Martin Stjernholm | |
return beg;
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | }
|
e7634f | 2007-05-13 | Martin Stjernholm | | int gc_cycle_push(void *data, struct marker *m, int weak)
|
c94c37 | 1996-03-28 | Fredrik Hübinette (Hubbe) | | {
|
e7634f | 2007-05-13 | Martin Stjernholm | | struct marker *pm;
|
45d87e | 2000-07-18 | Martin Stjernholm | |
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | #ifdef PIKE_DEBUG
|
1e9121 | 2001-07-05 | Martin Stjernholm | | if (gc_is_watching && m && m->flags & GC_WATCHED) {
|
8e5a40 | 2004-03-16 | Martin Stjernholm | | gc_watched_found (m, "gc_cycle_push()");
|
1e9121 | 2001-07-05 | Martin Stjernholm | | }
|
9a6d00 | 2001-06-26 | Fredrik Hübinette (Hubbe) | |
|
e7634f | 2007-05-13 | Martin Stjernholm | | debug_malloc_touch (data);
|
9a6d00 | 2001-06-26 | Fredrik Hübinette (Hubbe) | |
|
e7634f | 2007-05-13 | Martin Stjernholm | | if (!data) Pike_fatal ("Got null pointer.\n");
if (m->data != data) Pike_fatal ("Got wrong marker.\n");
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | if (Pike_in_gc != GC_PASS_CYCLE)
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("GC cycle push attempted in invalid pass.\n");
|
22aa2f | 2000-09-04 | Martin Stjernholm | | if (gc_debug && !(m->flags & GC_PRETOUCHED))
|
e7634f | 2007-05-13 | Martin Stjernholm | | gc_fatal (data, 0, "gc_cycle_push() called for untouched thing.\n");
|
57cfbd | 2004-03-15 | Martin Stjernholm | | if (!gc_destruct_everything) {
if ((!(m->flags & GC_NOT_REFERENCED) || m->flags & GC_MARKED) &&
|
e7634f | 2007-05-13 | Martin Stjernholm | | *(INT32 *) data)
gc_fatal (data, 1, "Got a referenced marker to gc_cycle_push.\n");
|
57cfbd | 2004-03-15 | Martin Stjernholm | | if (m->flags & GC_XREFERENCED)
|
e7634f | 2007-05-13 | Martin Stjernholm | | gc_fatal (data, 1, "Doing cycle check in externally referenced thing "
"missed in mark pass.\n");
|
57cfbd | 2004-03-15 | Martin Stjernholm | | }
|
e7634f | 2007-05-13 | Martin Stjernholm | | if (weak && stack_top == &sentinel_frame)
gc_fatal (data, 1, "weak is %d when stack is empty.\n", weak);
|
0db2c0 | 2003-02-14 | Martin Stjernholm | | if (gc_debug > 1) {
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | struct array *a;
struct object *o;
struct program *p;
struct mapping *m;
struct multiset *l;
|
cd451f | 2004-03-15 | Martin Stjernholm | | for(a = gc_internal_array; a; a = a->next)
|
e7634f | 2007-05-13 | Martin Stjernholm | | if(a == (struct array *) data) goto on_gc_internal_lists;
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | for(o = gc_internal_object; o; o = o->next)
|
e7634f | 2007-05-13 | Martin Stjernholm | | if(o == (struct object *) data) goto on_gc_internal_lists;
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | for(p = gc_internal_program; p; p = p->next)
|
e7634f | 2007-05-13 | Martin Stjernholm | | if(p == (struct program *) data) goto on_gc_internal_lists;
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | for(m = gc_internal_mapping; m; m = m->next)
|
e7634f | 2007-05-13 | Martin Stjernholm | | if(m == (struct mapping *) data) goto on_gc_internal_lists;
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | for(l = gc_internal_multiset; l; l = l->next)
|
e7634f | 2007-05-13 | Martin Stjernholm | | if(l == (struct multiset *) data) goto on_gc_internal_lists;
gc_fatal (data, 0, "gc_cycle_check() called for thing not on gc_internal lists.\n");
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | on_gc_internal_lists:
|
1f3b78 | 2000-06-16 | Fredrik Hübinette (Hubbe) | | ;
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | }
#endif
|
11649a | 2000-04-14 | Henrik Grubbström (Grubba) | |
|
e7634f | 2007-05-13 | Martin Stjernholm | | if (stack_top->rf_flags & GC_MARK_LIVE) {
if (m->flags & GC_CYCLE_CHECKED && !(m->flags & GC_LIVE)) {
CYCLE_DEBUG_MSG (m->frame, "gc_cycle_push, mark live");
goto mark_live;
}
CYCLE_DEBUG_MSG (m->frame, "gc_cycle_push, no mark live");
return 0;
}
if (stack_top == &sentinel_frame)
pm = NULL;
else {
pm = find_marker (stack_top->data);
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | #ifdef PIKE_DEBUG
|
e7634f | 2007-05-13 | Martin Stjernholm | | if (!pm)
gc_fatal (stack_top->data, 0, "No marker for thing on top of the stack.\n");
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | #endif
|
e7634f | 2007-05-13 | Martin Stjernholm | | }
|
1637c4 | 2000-02-01 | Fredrik Hübinette (Hubbe) | |
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | #ifdef PIKE_DEBUG
|
e7634f | 2007-05-13 | Martin Stjernholm | | if (weak < 0 && stack_top->rf_flags & GC_FOLLOWED_NONSTRONG)
gc_fatal (data, 0, "Followed strong link too late.\n");
if (weak >= 0) stack_top->rf_flags |= GC_FOLLOWED_NONSTRONG;
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | #endif
|
e7634f | 2007-05-13 | Martin Stjernholm | |
if (m->frame) {
struct gc_rec_frame *cycle_frame = m->frame;
if (cycle_frame->rf_flags & GC_ON_KILL_LIST)
CYCLE_DEBUG_MSG (cycle_frame, "gc_cycle_push, ref to kill list");
else if (cycle_frame == stack_top)
CYCLE_DEBUG_MSG (cycle_frame, "gc_cycle_push, self-ref");
else if (weak > 0)
CYCLE_DEBUG_MSG (cycle_frame, "gc_cycle_push, weak cyclic ref");
|
e1be4f | 2001-07-01 | Martin Stjernholm | |
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | else {
|
e7634f | 2007-05-13 | Martin Stjernholm | | struct gc_rec_frame *weakly_refd = NULL;
struct gc_rec_frame *brokenly_refd = NULL;
struct gc_rec_frame *nonstrongly_refd = NULL;
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | #ifdef PIKE_DEBUG
|
e7634f | 2007-05-13 | Martin Stjernholm | | if (stack_top == &sentinel_frame)
gc_fatal (data, 0, "Cyclic ref involves dummy sentinel frame.\n");
CHECK_REC_STACK_FRAME (stack_top);
|
8ed8dc | 2001-07-01 | Martin Stjernholm | | #endif
|
cde9da | 2005-04-15 | Martin Stjernholm | |
|
e7634f | 2007-05-13 | Martin Stjernholm | | CYCLE_DEBUG_MSG (cycle_frame, "gc_cycle_push, cyclic ref");
|
cde9da | 2005-04-15 | Martin Stjernholm | |
|
e7634f | 2007-05-13 | Martin Stjernholm | |
{
struct gc_rec_frame *r;
for (r = cycle_frame; !r->prev; r = r->cycle_id)
CHECK_CYCLE_PIECE_FRAME (r);
while (cycle_frame != r) {
struct gc_rec_frame *next = cycle_frame->cycle_id;
cycle_frame->cycle_id = r;
cycle_frame = next;
|
45d87e | 2000-07-18 | Martin Stjernholm | | }
|
e7634f | 2007-05-13 | Martin Stjernholm | | CHECK_REC_STACK_FRAME (cycle_frame);
|
8ed8dc | 2001-07-01 | Martin Stjernholm | | }
|
932633 | 2000-06-12 | Martin Stjernholm | |
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | if (!weak) {
|
e7634f | 2007-05-13 | Martin Stjernholm | | struct gc_rec_frame *r;
CYCLE_DEBUG_MSG (cycle_frame, "gc_cycle_push, search normal");
for (r = stack_top; r != cycle_frame; r = r->prev) {
CHECK_REC_STACK_FRAME (r);
|
cde9da | 2005-04-15 | Martin Stjernholm | | DO_IF_DEBUG (link_search++);
|
e7634f | 2007-05-13 | Martin Stjernholm | | if (r->rf_flags & GC_PREV_WEAK) {
CYCLE_DEBUG_MSG (r, "> gc_cycle_push, found weak");
weakly_refd = r;
break;
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | }
|
e7634f | 2007-05-13 | Martin Stjernholm | | if (!brokenly_refd && (r->rf_flags & GC_PREV_BROKEN)) {
CYCLE_DEBUG_MSG (r, "> gc_cycle_push, found broken");
brokenly_refd = r;
}
else
CYCLE_DEBUG_MSG (r, "> gc_cycle_push, search");
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | }
}
|
e7634f | 2007-05-13 | Martin Stjernholm | | else {
struct gc_rec_frame *r;
CYCLE_DEBUG_MSG (cycle_frame, "gc_cycle_push, search strong");
|
0db2c0 | 2003-02-14 | Martin Stjernholm | |
|
e7634f | 2007-05-13 | Martin Stjernholm | | for (r = stack_top; r != cycle_frame; r = r->prev) {
CHECK_REC_STACK_FRAME (r);
|
cde9da | 2005-04-15 | Martin Stjernholm | | DO_IF_DEBUG (link_search++);
|
e7634f | 2007-05-13 | Martin Stjernholm | | if (r->rf_flags & GC_PREV_WEAK) {
CYCLE_DEBUG_MSG (r, "> gc_cycle_push, found weak");
weakly_refd = r;
break;
}
if (!nonstrongly_refd && !(r->rf_flags & GC_PREV_STRONG)) {
nonstrongly_refd = r;
CYCLE_DEBUG_MSG (r, "> gc_cycle_push, found nonstrong");
}
if (!brokenly_refd && (r->rf_flags & GC_PREV_BROKEN)) {
CYCLE_DEBUG_MSG (r, "> gc_cycle_push, found broken");
brokenly_refd = r;
}
#ifdef GC_CYCLE_DEBUG
else if (r != nonstrongly_refd)
CYCLE_DEBUG_MSG (r, "> gc_cycle_push, search");
#endif
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | }
#ifdef PIKE_DEBUG
|
e7634f | 2007-05-13 | Martin Stjernholm | | if (weak && r == cycle_frame && !nonstrongly_refd) {
|
8ed8dc | 2001-07-01 | Martin Stjernholm | | fprintf(stderr, "Only strong links in cycle:\n");
|
e7634f | 2007-05-13 | Martin Stjernholm | | for (r = cycle_frame;; r = r->next) {
describe (r->data);
locate_references (r->data);
if (r == stack_top) break;
|
8ed8dc | 2001-07-01 | Martin Stjernholm | | fprintf(stderr, "========= next =========\n");
}
gc_fatal(0, 0, "Only strong links in cycle.\n");
}
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | #endif
}
|
e7634f | 2007-05-13 | Martin Stjernholm | | if (weakly_refd) {
CYCLE_DEBUG_MSG (weakly_refd, "gc_cycle_push, weak break");
rotate_rec_stack (cycle_frame, weakly_refd);
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | }
|
e7634f | 2007-05-13 | Martin Stjernholm | | else {
struct gc_rec_frame *cycle_id = cycle_frame->cycle_id;
struct gc_rec_frame *break_pos;
if (brokenly_refd) {
CYCLE_DEBUG_MSG (brokenly_refd, "gc_cycle_push, break at broken");
break_pos = brokenly_refd;
}
else if (!weak) {
CYCLE_DEBUG_MSG (cycle_frame, "gc_cycle_push, no break spot found");
break_pos = NULL;
}
else {
CYCLE_DEBUG_MSG (nonstrongly_refd, "gc_cycle_push, nonstrong break");
break_pos = nonstrongly_refd;
}
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | |
|
e7634f | 2007-05-13 | Martin Stjernholm | | if (break_pos) {
struct gc_rec_frame *rot_beg;
rot_beg = rotate_rec_stack (cycle_frame, break_pos);
cycle_frame->rf_flags =
(cycle_frame->rf_flags & ~(GC_PREV_WEAK|GC_PREV_BROKEN)) | GC_PREV_STRONG;
if (rot_beg->cycle_id != break_pos->prev->cycle_id)
cycle_id = break_pos;
|
46d4e7 | 2000-06-12 | Martin Stjernholm | | }
|
45d87e | 2000-07-18 | Martin Stjernholm | |
|
e7634f | 2007-05-13 | Martin Stjernholm | |
CHECK_REC_STACK_FRAME (cycle_id);
{
struct gc_rec_frame *r, *bottom = break_pos ? break_pos : cycle_frame;
CYCLE_DEBUG_MSG (cycle_id, "gc_cycle_push, cycle");
for (r = stack_top;; r = r->prev) {
CHECK_REC_STACK_FRAME (r);
r->cycle_id = cycle_id;
CYCLE_DEBUG_MSG (r, "> gc_cycle_push, mark cycle 1");
if (r == bottom) break;
|
45d87e | 2000-07-18 | Martin Stjernholm | | }}}}}
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | |
else
if (!(m->flags & GC_CYCLE_CHECKED)) {
|
e7634f | 2007-05-13 | Martin Stjernholm | | struct gc_rec_frame *r;
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | #ifdef PIKE_DEBUG
cycle_checked++;
|
45d87e | 2000-07-18 | Martin Stjernholm | | if (m->frame)
|
e7634f | 2007-05-13 | Martin Stjernholm | | gc_fatal (data, 0, "Marker already got a frame.\n");
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | #endif
|
e7634f | 2007-05-13 | Martin Stjernholm | | m->flags |= GC_CYCLE_CHECKED | (pm ? pm->flags & GC_LIVE : 0);
m->frame = r = gc_cycle_enqueue_rec (data);
debug_malloc_touch (data);
|
45d87e | 2000-07-18 | Martin Stjernholm | | if (weak) {
|
e7634f | 2007-05-13 | Martin Stjernholm | | if (weak > 0) r->rf_flags = GC_PREV_WEAK;
else r->rf_flags = GC_PREV_STRONG;
|
45d87e | 2000-07-18 | Martin Stjernholm | | }
|
e7634f | 2007-05-13 | Martin Stjernholm | | else
r->rf_flags = 0;
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | |
#ifdef GC_CYCLE_DEBUG
|
e7634f | 2007-05-13 | Martin Stjernholm | | if (weak > 0) CYCLE_DEBUG_MSG (r, "gc_cycle_push, recurse weak");
else if (weak < 0) CYCLE_DEBUG_MSG (r, "gc_cycle_push, recurse strong");
else CYCLE_DEBUG_MSG (r, "gc_cycle_push, recurse");
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | gc_cycle_indent += 2;
#endif
return 1;
}
|
e7634f | 2007-05-13 | Martin Stjernholm | | * must propagate GC_LIVE flags. */
if (!pm || !(pm->flags & GC_LIVE) || m->flags & GC_LIVE) {
CYCLE_DEBUG_MSG (m->frame ? m->frame : NULL, "gc_cycle_push, no recurse");
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | return 0;
}
|
e7634f | 2007-05-13 | Martin Stjernholm | |
gc_cycle_enqueue_rec (NULL)->rf_flags = GC_MARK_LIVE;
#ifdef GC_CYCLE_DEBUG
CYCLE_DEBUG_MSG (m->frame ? m->frame : NULL, "gc_cycle_push, mark live begins");
gc_cycle_indent += 2;
#endif
mark_live:
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | #ifdef PIKE_DEBUG
if (m->flags & GC_LIVE)
|
e7634f | 2007-05-13 | Martin Stjernholm | | Pike_fatal("Shouldn't mark live recurse when there's nothing to do.\n");
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | #endif
|
e7634f | 2007-05-13 | Martin Stjernholm | | m->flags |= GC_LIVE;
debug_malloc_touch (data);
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | |
if (m->flags & GC_GOT_DEAD_REF) {
|
e7634f | 2007-05-13 | Martin Stjernholm | | gc_free_extra_ref (data);
if (!sub_ref ((struct ref_dummy *) data)) {
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | #ifdef PIKE_DEBUG
|
e7634f | 2007-05-13 | Martin Stjernholm | | gc_fatal (data, 0, "Thing got zero refs after removing the dead gc ref.\n");
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | #endif
}
}
|
e7634f | 2007-05-13 | Martin Stjernholm | |
|
8e6d5c | 2001-07-02 | Martin Stjernholm | | #ifdef PIKE_DEBUG
|
e7634f | 2007-05-13 | Martin Stjernholm | | mark_live++;
|
8e6d5c | 2001-07-02 | Martin Stjernholm | | #endif
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | return 1;
}
|
e7634f | 2007-05-13 | Martin Stjernholm | | static void gc_cycle_pop()
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | {
#ifdef PIKE_DEBUG
if (Pike_in_gc != GC_PASS_CYCLE)
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("GC cycle pop attempted in invalid pass.\n");
|
e7634f | 2007-05-13 | Martin Stjernholm | | if (stack_top->u.link_top)
gc_fatal (stack_top->data, 0, "Link list not empty for popped rec frame.\n");
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | #endif
#ifdef GC_CYCLE_DEBUG
gc_cycle_indent -= 2;
#endif
|
e7634f | 2007-05-13 | Martin Stjernholm | | if (stack_top->rf_flags & GC_MARK_LIVE) {
struct gc_rec_frame *r = stack_top->prev;
CYCLE_DEBUG_MSG (stack_top, "gc_cycle_pop, mark live ends");
really_free_gc_rec_frame (stack_top);
stack_top = r;
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | }
|
e7634f | 2007-05-13 | Martin Stjernholm | | else {
struct gc_rec_frame *popped = stack_top;
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | #ifdef PIKE_DEBUG
|
e7634f | 2007-05-13 | Martin Stjernholm | | {
void *data = popped->data;
struct marker *m = find_marker (data);
if (gc_is_watching && m && m->flags & GC_WATCHED) {
gc_watched_found (m, "gc_cycle_pop()");
}
if (!(m->flags & GC_CYCLE_CHECKED))
gc_fatal (data, 0, "Marker being popped doesn't have GC_CYCLE_CHECKED.\n");
if (!gc_destruct_everything) {
if ((!(m->flags & GC_NOT_REFERENCED) || m->flags & GC_MARKED) &&
*(INT32 *) data)
gc_fatal (data, 1, "Got a referenced marker to gc_cycle_pop.\n");
if (m->flags & GC_XREFERENCED)
gc_fatal (data, 1, "Doing cycle check in externally referenced thing "
"missed in mark pass.\n");
}
if (popped->next != (struct gc_rec_frame *) (ptrdiff_t) -1)
gc_fatal (data, 0, "Popped rec frame got stuff in the next pointer.\n");
}
|
932633 | 2000-06-12 | Martin Stjernholm | | #endif
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | |
|
e7634f | 2007-05-13 | Martin Stjernholm | | stack_top = popped->prev;
#ifdef PIKE_DEBUG
if (stack_top != &sentinel_frame) CHECK_REC_STACK_FRAME (stack_top);
CHECK_REC_STACK_FRAME (popped);
#endif
|
5b1275 | 2007-05-23 | Martin Stjernholm | | popped->prev = NULL;
|
af72c5 | 2000-07-02 | Martin Stjernholm | |
|
e7634f | 2007-05-13 | Martin Stjernholm | | if (popped->cycle_id != popped) {
struct gc_rec_frame *this_list_last =
popped->cycle_piece ? popped->cycle_piece->u.last_cycle_piece : popped;
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | #ifdef PIKE_DEBUG
|
e7634f | 2007-05-13 | Martin Stjernholm | | if (this_list_last->cycle_piece)
gc_fatal (this_list_last->data, 0,
"This frame should be last on the cycle piece list.\n");
popped->rf_flags |= GC_ON_CYCLE_PIECE_LIST;
CHECK_CYCLE_PIECE_FRAME (this_list_last);
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | #endif
|
e7634f | 2007-05-13 | Martin Stjernholm | | CYCLE_DEBUG_MSG (popped, "gc_cycle_pop, keep cycle piece");
if (!stack_top->cycle_piece)
popped->u.last_cycle_piece = this_list_last;
else {
struct gc_rec_frame *up_list_first = stack_top->cycle_piece;
struct gc_rec_frame *up_list_last = up_list_first->u.last_cycle_piece;
#ifdef PIKE_DEBUG
CHECK_CYCLE_PIECE_FRAME (up_list_last);
if (up_list_last->cycle_piece)
gc_fatal (up_list_last->data, 0,
"This frame should be last on the cycle piece list.\n");
#endif
CYCLE_DEBUG_MSG (up_list_first, "> gc_cycle_pop, inserted before");
this_list_last->cycle_piece = up_list_first;
popped->u.last_cycle_piece = up_list_last;
}
stack_top->cycle_piece = popped;
popped->cycle_id = stack_top;
CHECK_CYCLE_PIECE_FRAME (popped);
CHECK_REC_STACK_FRAME (stack_top);
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | }
|
e7634f | 2007-05-13 | Martin Stjernholm | |
|
45d87e | 2000-07-18 | Martin Stjernholm | | else {
|
e7634f | 2007-05-13 | Martin Stjernholm | |
struct gc_rec_frame **kill_list_ptr = &kill_list;
struct gc_rec_frame *cycle_id = NULL;
#ifdef PIKE_DEBUG
{
struct gc_rec_frame *r;
for (r = popped->cycle_piece; r; r = r->cycle_piece)
CHECK_CYCLE_PIECE_FRAME (r);
|
2b8dde | 2000-09-15 | Martin Stjernholm | | }
|
e7634f | 2007-05-13 | Martin Stjernholm | | #endif
CYCLE_DEBUG_MSG (popped, "gc_cycle_pop, popping cycle");
do {
struct marker *m = find_marker (popped->data);
struct gc_rec_frame *next = popped->cycle_piece;
if (m->flags & GC_LIVE_OBJ) {
#ifdef PIKE_DEBUG
popped->rf_flags &= ~GC_ON_CYCLE_PIECE_LIST;
popped->cycle_piece = popped->u.last_cycle_piece =
(struct gc_rec_frame *) (ptrdiff_t) -1;
#endif
popped->next = *kill_list_ptr;
*kill_list_ptr = popped;
kill_list_ptr = &popped->next;
popped->rf_flags |= GC_ON_KILL_LIST;
if (!cycle_id) cycle_id = popped;
popped->cycle_id = cycle_id;
if (!(m->flags & GC_GOT_DEAD_REF))
gc_add_extra_ref (popped->data);
CHECK_KILL_LIST_FRAME (popped);
CYCLE_DEBUG_MSG (popped, "> gc_cycle_pop, move to kill list");
}
else {
if (!(m->flags & GC_LIVE)) {
if (!(m->flags & GC_GOT_DEAD_REF)) {
gc_add_extra_ref (popped->data);
m->flags |= GC_GOT_DEAD_REF;
}
}
|
996f87 | 2000-06-12 | Martin Stjernholm | | #ifdef PIKE_DEBUG
|
e7634f | 2007-05-13 | Martin Stjernholm | | else
if (m->flags & GC_GOT_DEAD_REF)
gc_fatal (popped->data, 0, "Didn't expect a dead extra ref.\n");
|
45d87e | 2000-07-18 | Martin Stjernholm | | #endif
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | |
|
e7634f | 2007-05-13 | Martin Stjernholm | | CYCLE_DEBUG_MSG (popped, "> gc_cycle_pop, free");
m->frame = NULL;
really_free_gc_rec_frame (popped);
}
popped = next;
} while (popped);
}
|
45d87e | 2000-07-18 | Martin Stjernholm | | }
|
cde9da | 2005-04-15 | Martin Stjernholm | |
|
e7634f | 2007-05-13 | Martin Stjernholm | | #ifdef PIKE_DEBUG
stack_top->next = (struct gc_rec_frame *) (ptrdiff_t) -1;
#endif
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | }
void do_gc_recurse_svalues(struct svalue *s, int num)
{
gc_recurse_svalues(s, num);
}
|
1637c4 | 2000-02-01 | Fredrik Hübinette (Hubbe) | |
|
b35129 | 2001-08-20 | Martin Stjernholm | | void do_gc_recurse_short_svalue(union anything *u, int type)
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | {
gc_recurse_short_svalue(u, type);
|
c94c37 | 1996-03-28 | Fredrik Hübinette (Hubbe) | | }
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | |
int gc_do_free(void *a)
{
struct marker *m;
#ifdef PIKE_DEBUG
|
1e9121 | 2001-07-05 | Martin Stjernholm | | if (gc_is_watching && (m = find_marker(a)) && m->flags & GC_WATCHED) {
|
8e5a40 | 2004-03-16 | Martin Stjernholm | | gc_watched_found (m, "gc_do_free()");
|
1e9121 | 2001-07-05 | Martin Stjernholm | | }
|
5aad93 | 2002-08-15 | Marcus Comstedt | | if (!a) Pike_fatal("Got null pointer.\n");
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | if (Pike_in_gc != GC_PASS_FREE)
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("gc free attempted in invalid pass.\n");
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | #endif
m=find_marker(debug_malloc_pass(a));
if (!m) return 0;
|
57cfbd | 2004-03-15 | Martin Stjernholm | | if (gc_destruct_everything) {
if (!(m->flags & GC_LIVE)) {
if (*(INT32 *) a == 1)
return 1;
else {
gc_free_extra_ref (a);
|
28a967 | 2004-09-30 | Martin Stjernholm | | sub_ref ((struct ref_dummy *) a);
|
57cfbd | 2004-03-15 | Martin Stjernholm | | }
}
return 0;
}
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | #ifdef PIKE_DEBUG
|
081629 | 2000-07-03 | Martin Stjernholm | | if (*(INT32 *) a > !!(m->flags & GC_GOT_EXTRA_REF)) {
|
57cfbd | 2004-03-15 | Martin Stjernholm | | if (!gc_destruct_everything &&
(!(m->flags & GC_NOT_REFERENCED) || m->flags & GC_MARKED))
|
081629 | 2000-07-03 | Martin Stjernholm | | gc_fatal(a, 0, "gc_do_free() called for referenced thing.\n");
if (gc_debug &&
|
22aa2f | 2000-09-04 | Martin Stjernholm | | (m->flags & (GC_PRETOUCHED|GC_MARKED|GC_IS_REFERENCED)) == GC_PRETOUCHED)
|
081629 | 2000-07-03 | Martin Stjernholm | | gc_fatal(a, 0, "gc_do_free() called without prior call to "
"gc_mark() or gc_is_referenced().\n");
}
|
57cfbd | 2004-03-15 | Martin Stjernholm | | if(!gc_destruct_everything &&
(m->flags & (GC_MARKED|GC_XREFERENCED)) == GC_XREFERENCED)
|
be39f5 | 2000-07-03 | Martin Stjernholm | | gc_fatal(a, 1, "Thing with external reference missed in gc mark pass.\n");
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | if ((m->flags & (GC_DO_FREE|GC_LIVE)) == GC_LIVE) live_ref++;
m->flags |= GC_DO_FREE;
|
1637c4 | 2000-02-01 | Fredrik Hübinette (Hubbe) | | #endif
|
c94c37 | 1996-03-28 | Fredrik Hübinette (Hubbe) | |
|
081629 | 2000-07-03 | Martin Stjernholm | | return !(m->flags & GC_LIVE);
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | }
|
66ac54 | 2000-09-05 | Henrik Grubbström (Grubba) | | static void free_obj_arr(void *oa)
{
struct array *obj_arr = *((struct array **)oa);
if (obj_arr) free_array(obj_arr);
free(oa);
}
|
51376d | 2002-12-07 | Henrik Grubbström (Grubba) | |
|
0ca86e | 2005-04-09 | Henrik Grubbström (Grubba) | | static void warn_bad_cycles(void)
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | {
|
66ac54 | 2000-09-05 | Henrik Grubbström (Grubba) | |
struct array **obj_arr_ = (struct array **)xalloc(sizeof(struct array *));
ONERROR tmp;
*obj_arr_ = NULL;
SET_ONERROR(tmp, free_obj_arr, obj_arr_);
|
d70a3e | 2000-07-07 | Martin Stjernholm | |
|
e7634f | 2007-05-13 | Martin Stjernholm | | #if 0
|
66ac54 | 2000-09-05 | Henrik Grubbström (Grubba) | | {
|
1bad5c | 2005-04-14 | Martin Stjernholm | | struct gc_pop_frame *p;
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | unsigned cycle = 0;
|
66ac54 | 2000-09-05 | Henrik Grubbström (Grubba) | | *obj_arr_ = allocate_array(0);
|
4be85a | 2000-07-07 | Martin Stjernholm | |
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | for (p = kill_list; p;) {
|
1bad5c | 2005-04-14 | Martin Stjernholm | | if ((cycle = p->cycle)) {
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | push_object((struct object *) p->data);
|
50ea68 | 2003-03-14 | Henrik Grubbström (Grubba) | | dmalloc_touch_svalue(Pike_sp-1);
|
9b150a | 2002-05-11 | Martin Nilsson | | *obj_arr_ = append_array(*obj_arr_, --Pike_sp);
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | }
|
1bad5c | 2005-04-14 | Martin Stjernholm | | p = p->next;
if (p ? ((unsigned)(p->cycle != cycle)) : cycle) {
|
66ac54 | 2000-09-05 | Henrik Grubbström (Grubba) | | if ((*obj_arr_)->size >= 2) {
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | push_constant_text("gc");
push_constant_text("bad_cycle");
|
66ac54 | 2000-09-05 | Henrik Grubbström (Grubba) | | push_array(*obj_arr_);
*obj_arr_ = 0;
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | SAFE_APPLY_MASTER("runtime_warning", 3);
pop_stack();
|
66ac54 | 2000-09-05 | Henrik Grubbström (Grubba) | | *obj_arr_ = allocate_array(0);
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | }
|
66ac54 | 2000-09-05 | Henrik Grubbström (Grubba) | | else *obj_arr_ = resize_array(*obj_arr_, 0);
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | }
if (!p) break;
}
}
|
e7634f | 2007-05-13 | Martin Stjernholm | | #endif
|
d70a3e | 2000-07-07 | Martin Stjernholm | |
|
66ac54 | 2000-09-05 | Henrik Grubbström (Grubba) | | CALL_AND_UNSET_ONERROR(tmp);
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | }
|
51adb8 | 2003-01-12 | Martin Stjernholm | | size_t do_gc(void *ignored, int explicit_call)
|
693018 | 1996-02-25 | Fredrik Hübinette (Hubbe) | | {
|
88ef97 | 2004-03-19 | Martin Stjernholm | | ALLOC_COUNT_TYPE start_allocs;
|
e7fc30 | 2004-03-17 | Martin Stjernholm | | size_t start_num_objs, unreferenced;
|
5ef905 | 2003-01-13 | Martin Stjernholm | | cpu_time_t gc_start_time;
|
e1be4f | 2001-07-01 | Martin Stjernholm | | ptrdiff_t objs, pre_kill_objs;
|
8e5a40 | 2004-03-16 | Martin Stjernholm | | #if defined (PIKE_DEBUG) || defined (DO_PIKE_CLEANUP)
unsigned destroy_count;
#endif
|
db62dc | 2000-04-14 | Martin Stjernholm | | #ifdef PIKE_DEBUG
|
8e5a40 | 2004-03-16 | Martin Stjernholm | | unsigned obj_count;
|
0c8b8f | 2001-05-19 | Martin Stjernholm | | ONERROR uwp;
|
db62dc | 2000-04-14 | Martin Stjernholm | | #endif
|
693018 | 1996-02-25 | Fredrik Hübinette (Hubbe) | |
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | if(Pike_in_gc) return 0;
|
51adb8 | 2003-01-12 | Martin Stjernholm | |
|
0d9f93 | 2003-01-14 | Martin Stjernholm | | if (gc_enabled <= 0 && (gc_enabled < 0 || !explicit_call)) {
|
51adb8 | 2003-01-12 | Martin Stjernholm | | num_allocs = 0;
|
bbd816 | 2003-01-15 | Martin Stjernholm | | alloc_threshold = GC_MAX_ALLOC_THRESHOLD;
|
51adb8 | 2003-01-12 | Martin Stjernholm | | if (gc_evaluator_callback) {
remove_callback (gc_evaluator_callback);
gc_evaluator_callback = NULL;
}
return 0;
}
|
738697 | 2001-06-30 | Fredrik Hübinette (Hubbe) | | #ifdef DEBUG_MALLOC
if(debug_options & GC_RESET_DMALLOC)
reset_debug_malloc();
#endif
|
7bf623 | 2000-04-23 | Martin Stjernholm | | init_gc();
|
9a6d00 | 2001-06-26 | Fredrik Hübinette (Hubbe) | | gc_generation++;
|
7bf623 | 2000-04-23 | Martin Stjernholm | | Pike_in_gc=GC_PASS_PREPARE;
|
5ef905 | 2003-01-13 | Martin Stjernholm | | gc_start_time = get_cpu_time();
|
7bf623 | 2000-04-23 | Martin Stjernholm | | gc_debug = d_flag;
|
50d97a | 2003-02-01 | Martin Stjernholm | | #ifdef PIKE_DEBUG
|
0c8b8f | 2001-05-19 | Martin Stjernholm | | SET_ONERROR(uwp, fatal_on_error, "Shouldn't get an exception inside the gc.\n");
|
1e9121 | 2001-07-05 | Martin Stjernholm | | if (gc_is_watching)
fprintf(stderr, "## Doing gc while watching for %d things.\n", gc_is_watching);
|
7bf623 | 2000-04-23 | Martin Stjernholm | | #endif
|
890e5b | 1996-11-21 | Fredrik Hübinette (Hubbe) | |
|
7f9b4c | 2000-04-19 | Martin Stjernholm | | destruct_objects_to_destruct();
|
e78abd | 1996-11-21 | Fredrik Hübinette (Hubbe) | | if(gc_evaluator_callback)
{
remove_callback(gc_evaluator_callback);
gc_evaluator_callback=0;
}
|
890e5b | 1996-11-21 | Fredrik Hübinette (Hubbe) | |
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | objs=num_objects;
|
693018 | 1996-02-25 | Fredrik Hübinette (Hubbe) | |
|
50d97a | 2003-02-01 | Martin Stjernholm | | if(GC_VERBOSE_DO(1 ||) gc_trace) {
|
e7fc30 | 2004-03-17 | Martin Stjernholm | | if (gc_destruct_everything)
fprintf (stderr, "Destructing all objects... ");
else
fprintf(stderr,"Garbage collecting... ");
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | GC_VERBOSE_DO(fprintf(stderr, "\n"));
|
6bc62b | 2000-04-14 | Martin Stjernholm | | }
|
51adb8 | 2003-01-12 | Martin Stjernholm | | #ifdef PIKE_DEBUG
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | if(num_objects < 0)
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Panic, less than zero objects!\n");
|
693018 | 1996-02-25 | Fredrik Hübinette (Hubbe) | | #endif
|
0d9f93 | 2003-01-14 | Martin Stjernholm | | last_gc=TIME(0);
|
51adb8 | 2003-01-12 | Martin Stjernholm | | start_num_objs = num_objects;
start_allocs = num_allocs;
|
51955c | 2003-01-11 | Martin Stjernholm | | num_allocs = 0;
|
4452c1 | 2000-02-02 | Fredrik Hübinette (Hubbe) | |
|
0455ff | 2003-03-30 | Martin Stjernholm | |
|
08679c | 2000-04-26 | Martin Stjernholm | |
|
7bf623 | 2000-04-23 | Martin Stjernholm | | #ifdef PIKE_DEBUG
|
d9d6f0 | 2001-06-30 | Martin Stjernholm | | delayed_freed = weak_freed = checked = marked = cycle_checked = live_ref = 0;
|
e7634f | 2007-05-13 | Martin Stjernholm | | mark_live = frame_rot = link_search = 0;
|
50d97a | 2003-02-01 | Martin Stjernholm | | #endif
|
e7634f | 2007-05-13 | Martin Stjernholm | | rec_frames = link_frames = free_extra_frames = 0;
max_rec_frames = max_link_frames = 0;
|
7bf623 | 2000-04-23 | Martin Stjernholm | | if (gc_debug) {
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | unsigned n;
|
7bf623 | 2000-04-23 | Martin Stjernholm | | Pike_in_gc = GC_PASS_PRETOUCH;
n = gc_touch_all_arrays();
n += gc_touch_all_multisets();
n += gc_touch_all_mappings();
n += gc_touch_all_programs();
n += gc_touch_all_objects();
|
50d97a | 2003-02-01 | Martin Stjernholm | | #ifdef PIKE_DEBUG
|
22aa2f | 2000-09-04 | Martin Stjernholm | | gc_touch_all_strings();
|
50d97a | 2003-02-01 | Martin Stjernholm | | #endif
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | if (n != (unsigned) num_objects)
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Object count wrong before gc; expected %d, got %d.\n", num_objects, n);
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | GC_VERBOSE_DO(fprintf(stderr, "| pretouch: %u things\n", n));
|
7bf623 | 2000-04-23 | Martin Stjernholm | | }
|
c94c37 | 1996-03-28 | Fredrik Hübinette (Hubbe) | |
|
030541 | 2003-09-29 | Martin Stjernholm | |
|
7bf623 | 2000-04-23 | Martin Stjernholm | | Pike_in_gc=GC_PASS_CHECK;
|
6d30f5 | 2000-07-11 | Martin Stjernholm | | gc_ext_weak_refs = 0;
|
030541 | 2003-09-29 | Martin Stjernholm | |
#ifdef PIKE_DEBUG
mark_externals();
#endif
call_callback(& gc_callbacks, NULL);
|
01c63f | 2003-04-28 | Martin Stjernholm | | ACCEPT_UNFINISHED_TYPE_FIELDS {
gc_check_all_arrays();
gc_check_all_multisets();
gc_check_all_mappings();
gc_check_all_programs();
gc_check_all_objects();
|
fec15e | 2007-04-25 | Martin Stjernholm | | #if defined (PIKE_DEBUG) || defined (DO_PIKE_CLEANUP)
debug_gc_check_all_types();
#endif
|
01c63f | 2003-04-28 | Martin Stjernholm | | } END_ACCEPT_UNFINISHED_TYPE_FIELDS;
|
20513c | 2000-04-12 | Fredrik Hübinette (Hubbe) | |
|
51adb8 | 2003-01-12 | Martin Stjernholm | | GC_VERBOSE_DO(fprintf(stderr, "| check: %u references in %d things, "
|
e1be4f | 2001-07-01 | Martin Stjernholm | | "counted %"PRINTSIZET"u weak refs\n",
|
51adb8 | 2003-01-12 | Martin Stjernholm | | checked, num_objects, gc_ext_weak_refs));
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | |
|
7bf623 | 2000-04-23 | Martin Stjernholm | | Pike_in_gc=GC_PASS_MARK;
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | |
|
49bf8a | 2000-12-14 | Martin Stjernholm | | |
e2d9e6 | 2000-06-10 | Martin Stjernholm | | * are considered to lack external references. The mark pass move
* externally referenced things in front of these pointers. */
|
cd451f | 2004-03-15 | Martin Stjernholm | | gc_internal_array = first_array;
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | gc_internal_multiset = first_multiset;
gc_internal_mapping = first_mapping;
gc_internal_program = first_program;
gc_internal_object = first_object;
|
57cfbd | 2004-03-15 | Martin Stjernholm | | if (gc_destruct_everything) {
GC_VERBOSE_DO(fprintf(stderr,
"| mark pass skipped - will destruct all objects\n"));
}
else {
ACCEPT_UNFINISHED_TYPE_FIELDS {
gc_mark_all_arrays();
gc_mark_run_queue();
gc_mark_all_multisets();
gc_mark_run_queue();
gc_mark_all_mappings();
gc_mark_run_queue();
gc_mark_all_programs();
gc_mark_run_queue();
gc_mark_all_objects();
gc_mark_run_queue();
#ifdef PIKE_DEBUG
if(gc_debug) gc_mark_all_strings();
|
03f098 | 2000-09-04 | Henrik Grubbström (Grubba) | | #endif /* PIKE_DEBUG */
|
57cfbd | 2004-03-15 | Martin Stjernholm | | } END_ACCEPT_UNFINISHED_TYPE_FIELDS;
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | |
|
57cfbd | 2004-03-15 | Martin Stjernholm | | GC_VERBOSE_DO(fprintf(stderr,
"| mark: %u markers referenced, %u weak references freed,\n"
"| %d things to free, "
"got %"PRINTSIZET"u tricky weak refs\n",
marked, weak_freed, delayed_freed, gc_ext_weak_refs));
}
|
c94c37 | 1996-03-28 | Fredrik Hübinette (Hubbe) | |
|
1a12e8 | 2000-09-30 | Martin Stjernholm | | {
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | #ifdef PIKE_DEBUG
|
1a12e8 | 2000-09-30 | Martin Stjernholm | | size_t orig_ext_weak_refs = gc_ext_weak_refs;
|
d9d6f0 | 2001-06-30 | Martin Stjernholm | | obj_count = delayed_freed;
|
1a12e8 | 2000-09-30 | Martin Stjernholm | | #endif
Pike_in_gc=GC_PASS_CYCLE;
gc_cycle_check_all_objects();
gc_cycle_check_all_arrays();
gc_cycle_check_all_multisets();
gc_cycle_check_all_mappings();
gc_cycle_check_all_programs();
|
08679c | 2000-04-26 | Martin Stjernholm | |
|
20513c | 2000-04-12 | Fredrik Hübinette (Hubbe) | | #ifdef PIKE_DEBUG
|
e7634f | 2007-05-13 | Martin Stjernholm | | if (stack_top != &sentinel_frame)
|
cde9da | 2005-04-15 | Martin Stjernholm | | Pike_fatal("Frame stack not empty at end of cycle check pass.\n");
|
1a12e8 | 2000-09-30 | Martin Stjernholm | | if (gc_ext_weak_refs != orig_ext_weak_refs)
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("gc_ext_weak_refs changed from %"PRINTSIZET"u "
|
e1be4f | 2001-07-01 | Martin Stjernholm | | "to %"PRINTSIZET"u in cycle check pass.\n",
orig_ext_weak_refs, gc_ext_weak_refs);
|
1a12e8 | 2000-09-30 | Martin Stjernholm | | #endif
GC_VERBOSE_DO(fprintf(stderr,
|
e7634f | 2007-05-13 | Martin Stjernholm | | "| cycle: %u internal things visited,\n"
|
d9d6f0 | 2001-06-30 | Martin Stjernholm | | "| %u weak references freed, %d more things to free,\n"
|
e7634f | 2007-05-13 | Martin Stjernholm | | "| %u mark live visits, %u frame rotations,\n"
"| %u links searched, used max %u link frames,\n"
"| %u rec frames and %u free extra frames\n",
cycle_checked, weak_freed, delayed_freed - obj_count,
mark_live, frame_rot, link_search, max_link_frames,
max_rec_frames, free_extra_frames));
#ifdef PIKE_DEBUG
if (link_frames) fatal ("Leaked %u link frames.\n", link_frames);
#endif
|
1a12e8 | 2000-09-30 | Martin Stjernholm | | }
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | |
|
b13ee6 | 2001-06-30 | Martin Stjernholm | | if (gc_ext_weak_refs) {
size_t to_free = gc_ext_weak_refs;
#ifdef PIKE_DEBUG
|
d9d6f0 | 2001-06-30 | Martin Stjernholm | | obj_count = delayed_freed;
|
b13ee6 | 2001-06-30 | Martin Stjernholm | | #endif
Pike_in_gc = GC_PASS_ZAP_WEAK;
|
3c36c5 | 2004-09-22 | Martin Stjernholm | | * occurs when something has both external weak refs and nonweak
* cyclic refs from internal things. */
|
b13ee6 | 2001-06-30 | Martin Stjernholm | | gc_zap_ext_weak_refs_in_mappings();
gc_zap_ext_weak_refs_in_arrays();
|
5b15bb | 2001-12-10 | Martin Stjernholm | | gc_zap_ext_weak_refs_in_multisets();
|
b13ee6 | 2001-06-30 | Martin Stjernholm | | gc_zap_ext_weak_refs_in_objects();
gc_zap_ext_weak_refs_in_programs();
GC_VERBOSE_DO(
fprintf(stderr,
|
e1be4f | 2001-07-01 | Martin Stjernholm | | "| zap weak: freed %"PRINTPTRDIFFT"d external weak refs, "
"%"PRINTSIZET"u internal still around,\n"
|
d9d6f0 | 2001-06-30 | Martin Stjernholm | | "| %d more things to free\n",
|
e1be4f | 2001-07-01 | Martin Stjernholm | | to_free - gc_ext_weak_refs, gc_ext_weak_refs,
delayed_freed - obj_count));
|
b13ee6 | 2001-06-30 | Martin Stjernholm | | }
|
22aa2f | 2000-09-04 | Martin Stjernholm | | if (gc_debug) {
unsigned n;
|
1e0b96 | 2003-05-12 | Martin Nilsson | | #ifdef DEBUG_MALLOC
|
22aa2f | 2000-09-04 | Martin Stjernholm | | size_t i;
struct marker *m;
|
1e0b96 | 2003-05-12 | Martin Nilsson | | #endif
|
a3574b | 2007-05-13 | Martin Stjernholm | | Pike_in_gc=GC_PASS_POSTTOUCH;
|
22aa2f | 2000-09-04 | Martin Stjernholm | | n = gc_touch_all_arrays();
n += gc_touch_all_multisets();
n += gc_touch_all_mappings();
n += gc_touch_all_programs();
n += gc_touch_all_objects();
|
50d97a | 2003-02-01 | Martin Stjernholm | | #ifdef PIKE_DEBUG
|
22aa2f | 2000-09-04 | Martin Stjernholm | | gc_touch_all_strings();
|
50d97a | 2003-02-01 | Martin Stjernholm | | #endif
|
22aa2f | 2000-09-04 | Martin Stjernholm | | if (n != (unsigned) num_objects)
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Object count wrong in gc; expected %d, got %d.\n", num_objects, n);
|
ffb390 | 2001-06-26 | Fredrik Hübinette (Hubbe) | | #if 0 /* Temporarily disabled - Hubbe */
|
50d97a | 2003-02-01 | Martin Stjernholm | | #ifdef PIKE_DEBUG
|
22aa2f | 2000-09-04 | Martin Stjernholm | | #ifdef DEBUG_MALLOC
PTR_HASH_LOOP(marker, i, m)
|
a3574b | 2007-05-13 | Martin Stjernholm | | if (!(m->flags & (GC_POSTTOUCHED|GC_WEAK_FREED)) &&
|
22aa2f | 2000-09-04 | Martin Stjernholm | | dmalloc_is_invalid_memory_block(m->data)) {
|
a3574b | 2007-05-13 | Martin Stjernholm | | fprintf(stderr, "Found a stray marker after posttouch pass: ");
|
22aa2f | 2000-09-04 | Martin Stjernholm | | describe_marker(m);
fprintf(stderr, "Describing marker location(s):\n");
debug_malloc_dump_references(m, 2, 1, 0);
fprintf(stderr, "Describing thing for marker:\n");
|
1d938c | 2001-04-18 | Martin Stjernholm | | Pike_in_gc = 0;
|
22aa2f | 2000-09-04 | Martin Stjernholm | | describe(m->data);
|
a3574b | 2007-05-13 | Martin Stjernholm | | Pike_in_gc = GC_PASS_POSTTOUCH;
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Fatal in garbage collector.\n");
|
22aa2f | 2000-09-04 | Martin Stjernholm | | }
|
ffb390 | 2001-06-26 | Fredrik Hübinette (Hubbe) | | #endif
|
50d97a | 2003-02-01 | Martin Stjernholm | | #endif
|
22aa2f | 2000-09-04 | Martin Stjernholm | | #endif
|
a3574b | 2007-05-13 | Martin Stjernholm | | GC_VERBOSE_DO(fprintf(stderr, "| posttouch\n"));
|
22aa2f | 2000-09-04 | Martin Stjernholm | | }
|
0455ff | 2003-03-30 | Martin Stjernholm | |
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | |
|
7bf623 | 2000-04-23 | Martin Stjernholm | | Pike_in_gc=GC_PASS_FREE;
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | #ifdef PIKE_DEBUG
weak_freed = 0;
obj_count = num_objects;
#endif
|
49bf8a | 2000-12-14 | Martin Stjernholm | |
|
a1b387 | 2003-01-11 | Martin Stjernholm | | unreferenced = 0;
|
cd451f | 2004-03-15 | Martin Stjernholm | | if (gc_internal_array)
|
a1b387 | 2003-01-11 | Martin Stjernholm | | unreferenced += gc_free_all_unreferenced_arrays();
if (gc_internal_multiset)
unreferenced += gc_free_all_unreferenced_multisets();
if (gc_internal_mapping)
unreferenced += gc_free_all_unreferenced_mappings();
if (gc_internal_object)
unreferenced += gc_free_all_unreferenced_objects();
|
0455ff | 2003-03-30 | Martin Stjernholm | |
if (gc_internal_program)
unreferenced += gc_free_all_unreferenced_programs();
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | |
|
e7634f | 2007-05-13 | Martin Stjernholm | | if (free_extra_frames > tot_max_free_extra_frames)
tot_max_free_extra_frames = free_extra_frames;
|
fcb322 | 2001-07-05 | Martin Stjernholm | |
while (free_extra_list) {
|
e7634f | 2007-05-13 | Martin Stjernholm | | struct free_extra_frame *next = free_extra_list->next;
|
fcb322 | 2001-07-05 | Martin Stjernholm | | union anything u;
u.refs = (INT32 *) free_extra_list->data;
|
1bad5c | 2005-04-14 | Martin Stjernholm | | gc_free_extra_ref (u.refs);
free_short_svalue (&u, free_extra_list->type);
|
e7634f | 2007-05-13 | Martin Stjernholm | | really_free_free_extra_frame (free_extra_list);
|
fcb322 | 2001-07-05 | Martin Stjernholm | | free_extra_list = next;
}
|
e7634f | 2007-05-13 | Martin Stjernholm | | #ifdef PIKE_DEBUG
if (free_extra_frames) fatal ("Leaked %u free extra frames.\n", free_extra_frames);
#endif
GC_VERBOSE_DO(fprintf(stderr, "| free: %"PRINTSIZET"u unreferenced, "
"%d really freed, %u left with live references\n",
|
a1b387 | 2003-01-11 | Martin Stjernholm | | unreferenced, obj_count - num_objects, live_ref));
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | |
|
20513c | 2000-04-12 | Fredrik Hübinette (Hubbe) | | #ifdef PIKE_DEBUG
|
49bf8a | 2000-12-14 | Martin Stjernholm | | gc_internal_array = (struct array *) (ptrdiff_t) -1;
gc_internal_multiset = (struct multiset *) (ptrdiff_t) -1;
gc_internal_mapping = (struct mapping *) (ptrdiff_t) -1;
gc_internal_program = (struct program *) (ptrdiff_t) -1;
gc_internal_object = (struct object *) (ptrdiff_t) -1;
|
5aad93 | 2002-08-15 | Marcus Comstedt | | if(fatal_after_gc) Pike_fatal("%s", fatal_after_gc);
|
20513c | 2000-04-12 | Fredrik Hübinette (Hubbe) | | #endif
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | Pike_in_gc=GC_PASS_KILL;
|
e7634f | 2007-05-13 | Martin Stjernholm | |
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | |
pre_kill_objs = num_objects;
|
e7634f | 2007-05-13 | Martin Stjernholm | | if (Pike_interpreter.evaluator_stack && !gc_destruct_everything) {
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | objs -= num_objects;
warn_bad_cycles();
objs += num_objects;
}
|
8e5a40 | 2004-03-16 | Martin Stjernholm | | #if defined (PIKE_DEBUG) || defined (DO_PIKE_CLEANUP)
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | destroy_count = 0;
#endif
|
e7634f | 2007-05-13 | Martin Stjernholm | |
|
09f288 | 2005-02-09 | Martin Stjernholm | | {
enum object_destruct_reason reason =
#ifdef DO_PIKE_CLEANUP
gc_destruct_everything ? DESTRUCT_CLEANUP :
#endif
DESTRUCT_GC;
|
e7634f | 2007-05-13 | Martin Stjernholm | |
#ifdef PIKE_DEBUG
{
struct gc_rec_frame *r;
for (r = kill_list; r != &sentinel_frame; r = r->next)
CHECK_KILL_LIST_FRAME (r);
}
#endif
while (kill_list != &sentinel_frame) {
struct gc_rec_frame *next = kill_list->next;
|
09f288 | 2005-02-09 | Martin Stjernholm | | struct object *o = (struct object *) kill_list->data;
|
e7634f | 2007-05-13 | Martin Stjernholm | |
|
09f288 | 2005-02-09 | Martin Stjernholm | | #ifdef PIKE_DEBUG
if ((get_marker(kill_list->data)->flags & (GC_LIVE|GC_LIVE_OBJ)) !=
(GC_LIVE|GC_LIVE_OBJ))
gc_fatal(o, 0, "Invalid object on kill list.\n");
if (o->prog && (o->prog->flags & PROGRAM_USES_PARENT) &&
PARENT_INFO(o)->parent &&
!PARENT_INFO(o)->parent->prog &&
get_marker(PARENT_INFO(o)->parent)->flags & GC_LIVE_OBJ)
gc_fatal(o, 0, "GC destructed parent prematurely.\n");
#endif
|
e7634f | 2007-05-13 | Martin Stjernholm | |
|
09f288 | 2005-02-09 | Martin Stjernholm | | GC_VERBOSE_DO(
fprintf(stderr, "| Killing %p with %d refs", o, o->refs);
if (o->prog) {
INT32 line;
struct pike_string *file = get_program_line (o->prog, &line);
fprintf(stderr, ", prog %s:%d\n", file->str, line);
free_string(file);
}
else fputs(", is destructed\n", stderr);
);
|
e7634f | 2007-05-13 | Martin Stjernholm | |
|
09f288 | 2005-02-09 | Martin Stjernholm | | destruct_object (o, reason);
free_object(o);
gc_free_extra_ref(o);
|
8e5a40 | 2004-03-16 | Martin Stjernholm | | #if defined (PIKE_DEBUG) || defined (DO_PIKE_CLEANUP)
|
09f288 | 2005-02-09 | Martin Stjernholm | | destroy_count++;
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | #endif
|
e7634f | 2007-05-13 | Martin Stjernholm | | really_free_gc_rec_frame (kill_list);
|
09f288 | 2005-02-09 | Martin Stjernholm | | kill_list = next;
}
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | }
|
e7634f | 2007-05-13 | Martin Stjernholm | | #ifdef PIKE_DEBUG
if (rec_frames) fatal ("Leaked %u rec frames.\n", rec_frames);
#endif
GC_VERBOSE_DO(fprintf(stderr, "| kill: %u objects killed, "
"%"PRINTSIZET"u things really freed\n",
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | destroy_count, pre_kill_objs - num_objects));
|
7bf623 | 2000-04-23 | Martin Stjernholm | | Pike_in_gc=GC_PASS_DESTRUCT;
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | |
GC_VERBOSE_DO(obj_count = num_objects);
|
7bf623 | 2000-04-23 | Martin Stjernholm | | destruct_objects_to_destruct();
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | GC_VERBOSE_DO(fprintf(stderr, "| destruct: %d things really freed\n",
obj_count - num_objects));
|
08679c | 2000-04-26 | Martin Stjernholm | |
|
50d97a | 2003-02-01 | Martin Stjernholm | | #ifdef PIKE_DEBUG
|
60c15a | 2003-08-20 | Martin Stjernholm | | if (gc_extra_refs) {
size_t e;
fprintf (stderr, "Lost track of %d extra refs to things in gc.\n"
"Searching for marker(s) with extra refs:\n", gc_extra_refs);
|
57cfbd | 2004-03-15 | Martin Stjernholm | | for (e = 0; e < marker_hash_table_size; e++) {
struct marker *s = marker_hash_table[e], *m;
for (m = s; m;) {
|
60c15a | 2003-08-20 | Martin Stjernholm | | if (m->flags & GC_GOT_EXTRA_REF) {
fprintf (stderr, "========================================\n"
"Found marker with extra ref: ");
describe_marker (m);
fprintf (stderr, "Describing the thing pointed to:\n");
describe (m->data);
}
|
57cfbd | 2004-03-15 | Martin Stjernholm | | m = m->next;
if (m == s) break;
}
}
|
60c15a | 2003-08-20 | Martin Stjernholm | | fprintf (stderr, "========================================\n"
"Done searching for marker(s) with extra refs.\n");
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Lost track of %d extra refs to things in gc.\n", gc_extra_refs);
|
60c15a | 2003-08-20 | Martin Stjernholm | | }
|
5aad93 | 2002-08-15 | Marcus Comstedt | | if(fatal_after_gc) Pike_fatal("%s", fatal_after_gc);
|
7bf623 | 2000-04-23 | Martin Stjernholm | | #endif
|
51adb8 | 2003-01-12 | Martin Stjernholm | |
{
double multiplier, new_threshold;
|
5ef905 | 2003-01-13 | Martin Stjernholm | | cpu_time_t last_non_gc_time, last_gc_time;
|
51adb8 | 2003-01-12 | Martin Stjernholm | |
|
e7fc30 | 2004-03-17 | Martin Stjernholm | | * to give the appropriate weight to this last instance. */
|
51adb8 | 2003-01-12 | Martin Stjernholm | | multiplier=pow(gc_average_slowness,
(double) start_allocs / (double) alloc_threshold);
if (gc_start_time > last_gc_end_time) {
last_non_gc_time = gc_start_time - last_gc_end_time;
non_gc_time = non_gc_time * multiplier +
last_non_gc_time * (1.0 - multiplier);
}
|
dd2506 | 2003-02-09 | Martin Stjernholm | | else last_non_gc_time = (cpu_time_t) -1;
|
bbd816 | 2003-01-15 | Martin Stjernholm | | last_gc_end_time = get_cpu_time();
|
51adb8 | 2003-01-12 | Martin Stjernholm | | if (last_gc_end_time > gc_start_time) {
last_gc_time = last_gc_end_time - gc_start_time;
gc_time = gc_time * multiplier +
last_gc_time * (1.0 - multiplier);
}
|
dd2506 | 2003-02-09 | Martin Stjernholm | | else last_gc_time = (cpu_time_t) -1;
|
51adb8 | 2003-01-12 | Martin Stjernholm | |
last_garbage_ratio = (double) unreferenced / start_num_objs;
objects_alloced = objects_alloced * multiplier +
start_allocs * (1.0 - multiplier);
objects_freed = objects_freed * multiplier +
unreferenced * (1.0 - multiplier);
|
dd2506 | 2003-02-09 | Martin Stjernholm | | if (last_non_gc_time == (cpu_time_t) -1 ||
gc_time / non_gc_time <= gc_time_ratio) {
|
51adb8 | 2003-01-12 | Martin Stjernholm | |
new_threshold = (objects_alloced+1.0) *
(gc_garbage_ratio_low * start_num_objs) / (objects_freed+1.0);
last_garbage_strategy = GARBAGE_RATIO_LOW;
}
else {
new_threshold = (objects_alloced+1.0) *
(gc_garbage_ratio_high * start_num_objs) / (objects_freed+1.0);
last_garbage_strategy = GARBAGE_RATIO_HIGH;
}
|
693018 | 1996-02-25 | Fredrik Hübinette (Hubbe) | |
|
51955c | 2003-01-11 | Martin Stjernholm | | #if 0
|
51adb8 | 2003-01-12 | Martin Stjernholm | |
if(alloc_threshold + start_allocs < new_threshold)
new_threshold = (double)(alloc_threshold + start_allocs);
|
51955c | 2003-01-11 | Martin Stjernholm | | #endif
|
6acd50 | 2000-05-01 | Fredrik Noring | |
|
51adb8 | 2003-01-12 | Martin Stjernholm | | if(new_threshold < GC_MIN_ALLOC_THRESHOLD)
|
e7fc30 | 2004-03-17 | Martin Stjernholm | | alloc_threshold = GC_MIN_ALLOC_THRESHOLD;
|
51adb8 | 2003-01-12 | Martin Stjernholm | | else if(new_threshold > GC_MAX_ALLOC_THRESHOLD)
|
e7fc30 | 2004-03-17 | Martin Stjernholm | | alloc_threshold = GC_MAX_ALLOC_THRESHOLD;
else
|
88ef97 | 2004-03-19 | Martin Stjernholm | | alloc_threshold = (ALLOC_COUNT_TYPE) new_threshold;
|
51adb8 | 2003-01-12 | Martin Stjernholm | |
|
dd2506 | 2003-02-09 | Martin Stjernholm | | if (!explicit_call && last_gc_time != (cpu_time_t) -1) {
|
9699fc | 2003-02-10 | Martin Stjernholm | | #if CPU_TIME_IS_THREAD_LOCAL == PIKE_YES
|
043131 | 2003-02-15 | Henrik Grubbström (Grubba) | | Pike_interpreter.thread_state->auto_gc_time += last_gc_time;
|
9699fc | 2003-02-10 | Martin Stjernholm | | #elif CPU_TIME_IS_THREAD_LOCAL == PIKE_NO
|
f4a995 | 2003-02-08 | Martin Stjernholm | | auto_gc_time += last_gc_time;
#endif
}
|
50d97a | 2003-02-01 | Martin Stjernholm | | if(GC_VERBOSE_DO(1 ||) gc_trace)
|
51adb8 | 2003-01-12 | Martin Stjernholm | | {
|
e7fc30 | 2004-03-17 | Martin Stjernholm | | char timestr[40];
|
dd2506 | 2003-02-09 | Martin Stjernholm | | if (last_gc_time != (cpu_time_t) -1)
|
e7fc30 | 2004-03-17 | Martin Stjernholm | | sprintf (timestr, ", %ld ms",
(long) (last_gc_time / (CPU_TIME_TICKS / 1000)));
|
51adb8 | 2003-01-12 | Martin Stjernholm | | else
|
e7fc30 | 2004-03-17 | Martin Stjernholm | | timestr[0] = 0;
#ifdef DO_PIKE_CLEANUP
if (gc_destruct_everything)
|
daf2ac | 2006-01-24 | Martin Stjernholm | | fprintf(stderr, "done (%u %s destructed)%s\n",
destroy_count, destroy_count == 1 ? "was" : "were", timestr);
|
e7fc30 | 2004-03-17 | Martin Stjernholm | | else
#endif
|
5ef905 | 2003-01-13 | Martin Stjernholm | | fprintf(stderr, "done (%"PRINTSIZET"d of %"PRINTSIZET"d "
|
daf2ac | 2006-01-24 | Martin Stjernholm | | "%s unreferenced)%s\n",
unreferenced, start_num_objs,
unreferenced == 1 ? "was" : "were",
timestr);
|
51adb8 | 2003-01-12 | Martin Stjernholm | | }
}
|
693018 | 1996-02-25 | Fredrik Hübinette (Hubbe) | |
|
71f3a2 | 1998-11-22 | Fredrik Hübinette (Hubbe) | | #ifdef PIKE_DEBUG
|
0c8b8f | 2001-05-19 | Martin Stjernholm | | UNSET_ONERROR (uwp);
|
8e6d5c | 2001-07-02 | Martin Stjernholm | | tot_cycle_checked += cycle_checked;
|
e7634f | 2007-05-13 | Martin Stjernholm | | tot_mark_live += mark_live, tot_frame_rot += frame_rot;
|
693018 | 1996-02-25 | Fredrik Hübinette (Hubbe) | | #endif
|
e7634f | 2007-05-13 | Martin Stjernholm | | if (max_rec_frames > tot_max_rec_frames)
tot_max_rec_frames = max_rec_frames;
if (max_link_frames > tot_max_link_frames)
tot_max_link_frames = max_link_frames;
|
a29e02 | 1996-10-15 | Fredrik Hübinette (Hubbe) | |
|
a3574b | 2007-05-13 | Martin Stjernholm | | Pike_in_gc=0;
exit_gc();
|
bf4577 | 1996-12-05 | Fredrik Hübinette (Hubbe) | | #ifdef ALWAYS_GC
|
890e5b | 1996-11-21 | Fredrik Hübinette (Hubbe) | | ADD_GC_CALLBACK();
#else
|
bf4577 | 1996-12-05 | Fredrik Hübinette (Hubbe) | | if(d_flag > 3) ADD_GC_CALLBACK();
|
a29e02 | 1996-10-15 | Fredrik Hübinette (Hubbe) | | #endif
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | |
|
8e5a40 | 2004-03-16 | Martin Stjernholm | | #ifdef DO_PIKE_CLEANUP
if (gc_destruct_everything)
return destroy_count;
#endif
|
a1b387 | 2003-01-11 | Martin Stjernholm | | return unreferenced;
|
693018 | 1996-02-25 | Fredrik Hübinette (Hubbe) | | }
|
323e2b | 2002-11-25 | Martin Nilsson | | |
7c0df7 | 2001-02-06 | Henrik Grubbström (Grubba) | | *!
*! Get statistics from the garbage collector.
*!
*! @returns
*! A mapping with the following content will be returned:
*! @mapping
*! @member int "num_objects"
|
5ef905 | 2003-01-13 | Martin Stjernholm | | *! Number of arrays, mappings, multisets, objects and programs.
|
7c0df7 | 2001-02-06 | Henrik Grubbström (Grubba) | | *! @member int "num_allocs"
|
5ef905 | 2003-01-13 | Martin Stjernholm | | *! Number of memory allocations since the last gc run.
|
7c0df7 | 2001-02-06 | Henrik Grubbström (Grubba) | | *! @member int "alloc_threshold"
|
5ef905 | 2003-01-13 | Martin Stjernholm | | *! Threshold for "num_allocs" when another automatic gc run is
*! scheduled.
|
51adb8 | 2003-01-12 | Martin Stjernholm | | *! @member float "projected_garbage"
*! Estimation of the current amount of garbage.
|
7c0df7 | 2001-02-06 | Henrik Grubbström (Grubba) | | *! @member int "objects_alloced"
|
5ef905 | 2003-01-13 | Martin Stjernholm | | *! Decaying average over the number of allocated objects
*! between gc runs.
|
7c0df7 | 2001-02-06 | Henrik Grubbström (Grubba) | | *! @member int "objects_freed"
|
5ef905 | 2003-01-13 | Martin Stjernholm | | *! Decaying average over the number of freed objects in each gc
*! run.
|
51adb8 | 2003-01-12 | Martin Stjernholm | | *! @member float "last_garbage_ratio"
*! Garbage ratio in the last gc run.
*! @member int "non_gc_time"
|
5ef905 | 2003-01-13 | Martin Stjernholm | | *! Decaying average over the CPU milliseconds spent outside the
*! garbage collector.
|
51adb8 | 2003-01-12 | Martin Stjernholm | | *! @member int "gc_time"
|
5ef905 | 2003-01-13 | Martin Stjernholm | | *! Decaying average over the CPU milliseconds spent inside the
*! garbage collector.
|
51adb8 | 2003-01-12 | Martin Stjernholm | | *! @member string "last_garbage_strategy"
|
5ef905 | 2003-01-13 | Martin Stjernholm | | *! The garbage accumulation goal that the gc aimed for when
*! setting "alloc_threshold" in the last run. The value is
*! either "garbage_ratio_low" or "garbage_ratio_high", which
*! corresponds to the gc parameters with the same names in
*! @[Pike.gc_parameters].
|
0d9f93 | 2003-01-14 | Martin Stjernholm | | *! @member int "last_gc"
*! Time when the garbage-collector last ran.
|
7c0df7 | 2001-02-06 | Henrik Grubbström (Grubba) | | *! @endmapping
*!
*! @seealso
|
51adb8 | 2003-01-12 | Martin Stjernholm | | *! @[gc()], @[Pike.gc_parameters()]
|
7c0df7 | 2001-02-06 | Henrik Grubbström (Grubba) | | */
|
1637c4 | 2000-02-01 | Fredrik Hübinette (Hubbe) | | void f__gc_status(INT32 args)
{
|
8e6d5c | 2001-07-02 | Martin Stjernholm | | int size = 0;
|
1637c4 | 2000-02-01 | Fredrik Hübinette (Hubbe) | | pop_n_elems(args);
push_constant_text("num_objects");
push_int(num_objects);
|
8e6d5c | 2001-07-02 | Martin Stjernholm | | size++;
|
1637c4 | 2000-02-01 | Fredrik Hübinette (Hubbe) | |
push_constant_text("num_allocs");
|
e7fc30 | 2004-03-17 | Martin Stjernholm | | push_int64(num_allocs);
|
8e6d5c | 2001-07-02 | Martin Stjernholm | | size++;
|
1637c4 | 2000-02-01 | Fredrik Hübinette (Hubbe) | |
push_constant_text("alloc_threshold");
|
905e0c | 2000-08-11 | Henrik Grubbström (Grubba) | | push_int64(alloc_threshold);
|
8e6d5c | 2001-07-02 | Martin Stjernholm | | size++;
|
1637c4 | 2000-02-01 | Fredrik Hübinette (Hubbe) | |
|
51adb8 | 2003-01-12 | Martin Stjernholm | | push_constant_text("projected_garbage");
push_float(DO_NOT_WARN((FLOAT_TYPE)(objects_freed * (double) num_allocs /
(double) alloc_threshold)));
size++;
|
1637c4 | 2000-02-01 | Fredrik Hübinette (Hubbe) | | push_constant_text("objects_alloced");
|
a5cd6a | 2001-09-24 | Henrik Grubbström (Grubba) | | push_int64(DO_NOT_WARN((INT64)objects_alloced));
|
8e6d5c | 2001-07-02 | Martin Stjernholm | | size++;
|
1637c4 | 2000-02-01 | Fredrik Hübinette (Hubbe) | |
push_constant_text("objects_freed");
|
a5cd6a | 2001-09-24 | Henrik Grubbström (Grubba) | | push_int64(DO_NOT_WARN((INT64)objects_freed));
|
8e6d5c | 2001-07-02 | Martin Stjernholm | | size++;
|
1637c4 | 2000-02-01 | Fredrik Hübinette (Hubbe) | |
|
51adb8 | 2003-01-12 | Martin Stjernholm | | push_constant_text("last_garbage_ratio");
push_float(DO_NOT_WARN((FLOAT_TYPE) last_garbage_ratio));
|
8e6d5c | 2001-07-02 | Martin Stjernholm | | size++;
|
1637c4 | 2000-02-01 | Fredrik Hübinette (Hubbe) | |
|
51adb8 | 2003-01-12 | Martin Stjernholm | | push_constant_text("non_gc_time");
push_int64(DO_NOT_WARN((INT64) non_gc_time));
size++;
push_constant_text("gc_time");
push_int64(DO_NOT_WARN((INT64) gc_time));
size++;
push_constant_text ("last_garbage_strategy");
switch (last_garbage_strategy) {
case GARBAGE_RATIO_LOW: push_constant_text ("garbage_ratio_low"); break;
case GARBAGE_RATIO_HIGH: push_constant_text ("garbage_ratio_high"); break;
#ifdef PIKE_DEBUG
default: Pike_fatal ("Unknown last_garbage_strategy %d\n", last_garbage_strategy);
#endif
}
|
8e6d5c | 2001-07-02 | Martin Stjernholm | | size++;
|
1637c4 | 2000-02-01 | Fredrik Hübinette (Hubbe) | |
|
0d9f93 | 2003-01-14 | Martin Stjernholm | | push_constant_text("last_gc");
push_int64(last_gc);
size++;
|
e7634f | 2007-05-13 | Martin Stjernholm | | #ifdef PIKE_DEBUG
push_constant_text ("max_rec_frames");
push_int64 (DO_NOT_WARN ((INT64) tot_max_rec_frames));
push_constant_text ("max_link_frames");
push_int64 (DO_NOT_WARN ((INT64) tot_max_link_frames));
push_constant_text ("max_free_extra_frames");
push_int64 (DO_NOT_WARN ((INT64) tot_max_free_extra_frames));
#endif
|
8e6d5c | 2001-07-02 | Martin Stjernholm | | f_aggregate_mapping(size * 2);
|
1637c4 | 2000-02-01 | Fredrik Hübinette (Hubbe) | | }
|
5da087 | 2000-08-22 | Henrik Grubbström (Grubba) | |
|
51adb8 | 2003-01-12 | Martin Stjernholm | | void dump_gc_info(void)
{
fprintf(stderr,"Current number of things : %d\n",num_objects);
|
88ef97 | 2004-03-19 | Martin Stjernholm | | fprintf(stderr,"Allocations since last gc : "PRINT_ALLOC_COUNT_TYPE"\n",
num_allocs);
fprintf(stderr,"Threshold for next gc : "PRINT_ALLOC_COUNT_TYPE"\n",
alloc_threshold);
|
51adb8 | 2003-01-12 | Martin Stjernholm | | fprintf(stderr,"Projected current garbage : %f\n",
objects_freed * (double) num_allocs / (double) alloc_threshold);
fprintf(stderr,"Avg allocs between gc : %f\n",objects_alloced);
fprintf(stderr,"Avg frees per gc : %f\n",objects_freed);
fprintf(stderr,"Garbage ratio in last gc : %f\n", last_garbage_ratio);
|
bbd816 | 2003-01-15 | Martin Stjernholm | | fprintf(stderr,"Avg cpu "CPU_TIME_UNIT" between gc : %f\n", non_gc_time);
fprintf(stderr,"Avg cpu "CPU_TIME_UNIT" in gc : %f\n", gc_time);
|
51adb8 | 2003-01-12 | Martin Stjernholm | | fprintf(stderr,"Avg time ratio in gc : %f\n", gc_time / non_gc_time);
fprintf(stderr,"Garbage strategy in last gc: %s\n",
last_garbage_strategy == GARBAGE_RATIO_LOW ? "garbage_ratio_low" :
last_garbage_strategy == GARBAGE_RATIO_HIGH ? "garbage_ratio_high" :
"???");
#ifdef PIKE_DEBUG
|
e7634f | 2007-05-13 | Martin Stjernholm | | fprintf(stderr,"Max used recursion frames : %u\n", tot_max_rec_frames);
fprintf(stderr,"Max used link frames : %u\n", tot_max_link_frames);
fprintf(stderr,"Max used free extra frames : %u\n", tot_max_free_extra_frames);
fprintf(stderr,"Marked live ratio : %g\n",
(double) tot_mark_live / tot_cycle_checked);
|
51adb8 | 2003-01-12 | Martin Stjernholm | | fprintf(stderr,"Frame rotation ratio : %g\n",
(double) tot_frame_rot / tot_cycle_checked);
#endif
fprintf(stderr,"in_gc : %d\n", Pike_in_gc);
}
|
5da087 | 2000-08-22 | Henrik Grubbström (Grubba) | | void cleanup_gc(void)
{
#ifdef PIKE_DEBUG
if (gc_evaluator_callback) {
remove_callback(gc_evaluator_callback);
gc_evaluator_callback = NULL;
}
#endif /* PIKE_DEBUG */
}
|