+2009-09-30 Ivan Maidanski <ivmai@mail.ru>
+
+ * allchblk.c (GC_large_alloc_warn_interval): Move declaration from
+ gc_priv.h.
+ * allchblk.c (GC_large_alloc_warn_suppressed): Move definition
+ from misc.c; define as STATIC.
+ * include/private/gc_priv.h (GC_large_alloc_warn_interval,
+ GC_large_alloc_warn_suppressed): Remove declaration.
+ * alloc.c (GC_bytes_found): Add "defined in" comment.
+ * mallocx.c (GC_bytes_found): Ditto.
+ * misc.c (GC_unmap_threshold): Ditto.
+ * os_dep.c (GC_old_allocator): Ditto.
+ * pthread_support.c (GC_markers): Ditto.
+ * thread_local_alloc.c (GC_gcjobjfreelist,
+ GC_gcj_malloc_initialized, GC_gcj_kind): Ditto.
+ * win32_threads.c (GC_markers): Ditto.
+ * alloc.c (GC_start_time): Explicitly initialize to 0 or NULL (to
+ be distinctive from a variable declaration).
+ * backgraph.c (GC_max_height, GC_deepest_obj): Ditto.
+ * blacklst.c (GC_old_normal_bl, GC_incomplete_normal_bl,
+ GC_old_stack_bl, GC_incomplete_stack_bl): Ditto.
+ * checksums.c (GC_faulted, GC_n_dirty_errors,
+ GC_n_faulted_dirty_errors, GC_n_changed_errors, GC_n_clean,
+ GC_n_dirty, GC_bytes_in_used_blocks): Ditto.
+ * dbg_mlc.c (GC_smashed): Ditto.
+ * finalize.c (GC_old_dl_entries): Ditto.
+ * gcj_mlc.c (GC_gcj_kind, GC_gcj_debug_kind, GC_gcjobjfreelist,
+ GC_gcjdebugobjfreelist): Ditto.
+ * mach_dep.c (GC_save_regs_ret_val): Ditto.
+ * mark.c (GC_n_rescuing_pages, GC_mark_stack, GC_mark_stack_limit,
+ GC_mark_stack_top): Ditto.
+ * misc.c (GC_min_sp, GC_high_water, GC_bytes_allocd_at_reset):
+ Ditto.
+ * os_dep.c (GC_data_start, GC_page_size, GC_sysinfo,
+ GC_old_segv_handler, GC_old_bus_handler,
+ GC_old_bus_handler_used_si, GC_old_segv_handler_used_si,
+ GC_proc_buf, GC_proc_fd, GC_vd_base): Ditto.
+ * pthread_stop_world.c (GC_stop_count, GC_stopping_pid): Ditto.
+ * reclaim.c (GC_leaked): Ditto.
+ * typd_mlc.c (GC_explicit_kind, GC_array_kind, GC_ext_descriptors,
+ GC_typed_mark_proc_index, GC_array_mark_proc_index,
+ GC_eobjfreelist, GC_arobjfreelist): Ditto.
+ * win32_threads.c (GC_pthread_map_cache, GC_marker_cv,
+ GC_marker_Id): Ditto.
+ * dbg_mlc.c (GC_smashed, GC_n_smashed): Define as STATIC.
+ * gcj_mlc.c (GC_gcjdebugobjfreelist): Ditto.
+ * os_dep.c (GC_vd_base): Ditto.
+ * pthread_support.c (GC_mark_threads): Ditto.
+ * reclaim.c (GC_leaked): Ditto.
+ * typd_mlc.c (GC_bm_table): Ditto.
+ * mark_rts.c (GC_save_regs_ret_val): Change declaration type to
+ that of definition; add "defined in" comment.
+ * mark_rts.c (GC_push_current_stack): Remove unnecessary cast for
+ GC_save_regs_ret_val.
+ * misc.c (GC_check_heap, GC_print_all_smashed,
+ GC_start_call_back): Remove unnecessary cast (of 0).
+ * misc.c (GC_LARGE_ALLOC_WARN_INTERVAL): New tuning macro.
+ * misc.c (GC_large_alloc_warn_interval): Initialize to
+ GC_LARGE_ALLOC_WARN_INTERVAL value.
+ * misc.c (GC_tmp): Change to "static".
+ * os_dep.c (GC_setpagesize): Reformat the code (collapse multiple
+ function definitions).
+ * os_dep.c (GC_mprotect_state): Define as static.
+ * pthread_support.c (dummy_thread_local): Prefix with "GC_".
+ * win32_threads.c (WinMain): Remove FIXME for WinCE.
+
2009-09-30 Ivan Maidanski <ivmai@mail.ru> (really Hans Boehm)
* os_dep.c (PROTECT, UNPROTECT): Use distinct ABORT messages.
unsigned GC_fail_count; /* defined in alloc.c */
+long GC_large_alloc_warn_interval; /* defined in misc.c */
+
+STATIC long GC_large_alloc_warn_suppressed = 0;
+ /* Number of warnings suppressed so far. */
+
/*
* The same, but with search restricted to nth free list.
* Flags is IGNORE_OFF_PAGE or zero.
*
*/
-
# include "private/gc_priv.h"
# include <stdio.h>
/* some more variables */
signed_word GC_bytes_found; /* Number of reclaimed bytes */
- /* after garbage collection */
+ /* after garbage collection; */
+ /* defined in reclaim.c. */
#ifdef GC_DONT_EXPAND
GC_bool GC_dont_expand = TRUE;
unsigned long GC_time_limit = GC_TIME_LIMIT;
#ifndef NO_CLOCK
-STATIC CLOCK_TYPE GC_start_time;/* Time at which we stopped world. */
+STATIC CLOCK_TYPE GC_start_time = 0;
+ /* Time at which we stopped world. */
/* used only in GC_timeout_stop_func. */
#endif
return(TRUE);
}
-
-
/*
* Perform n units of garbage collection work. A unit is intended to touch
* roughly GC_RATE pages. Every once in a while, we do more than that.
/* Add the (forward) edge from p to q to the backward graph. Both p */
/* q are pointers to the object base, i.e. pointers to an oh. */
-static void add_edge(ptr_t p, ptr_t q)
+static void add_edge(ptr_t p, ptr_t q)
{
ptr_t old_back_ptr = GET_OH_BG_PTR(q);
back_edges * be, *be_cont;
return result;
}
-STATIC word GC_max_height;
-STATIC ptr_t GC_deepest_obj;
+STATIC word GC_max_height = 0;
+STATIC ptr_t GC_deepest_obj = NULL;
-/* Compute the maximum height of every unreachable predecessor p of a */
+/* Compute the maximum height of every unreachable predecessor p of a */
/* reachable object. Arrange to save the heights of all such objects p */
/* so that they can be used in calculating the height of objects in the */
/* next GC. */
/* Pointers to individual tables. We replace one table by another by */
/* switching these pointers. */
-STATIC word * GC_old_normal_bl;
+STATIC word * GC_old_normal_bl = NULL;
/* Nonstack false references seen at last full */
/* collection. */
-STATIC word * GC_incomplete_normal_bl;
+STATIC word * GC_incomplete_normal_bl = NULL;
/* Nonstack false references seen since last */
/* full collection. */
-STATIC word * GC_old_stack_bl;
-STATIC word * GC_incomplete_stack_bl;
+STATIC word * GC_old_stack_bl = NULL;
+STATIC word * GC_incomplete_stack_bl = NULL;
-STATIC word GC_total_stack_black_listed;
+STATIC word GC_total_stack_black_listed = 0;
/* Number of bytes on stack blacklist. */
word GC_black_list_spacing = MINHINCR*HBLKSIZE; /* Initial rough guess */
/* to hide it from collector. */
} page_entry;
-page_entry GC_sums [NSUMS];
+page_entry GC_sums[NSUMS];
+
+STATIC word GC_faulted[NSUMS] = { 0 };
+ /* Record of pages on which we saw a write fault. */
-STATIC word GC_faulted[NSUMS]; /* Record of pages on which we saw a write */
- /* fault. */
STATIC size_t GC_n_faulted = 0;
void GC_record_fault(struct hblk * h)
}
# endif
-int GC_n_dirty_errors;
-int GC_n_faulted_dirty_errors;
-int GC_n_changed_errors;
-int GC_n_clean;
-int GC_n_dirty;
+int GC_n_dirty_errors = 0;
+int GC_n_faulted_dirty_errors = 0;
+int GC_n_changed_errors = 0;
+int GC_n_clean = 0;
+int GC_n_dirty = 0;
STATIC void GC_update_check_page(struct hblk *h, int index)
{
pe -> block = h + OFFSET;
}
-word GC_bytes_in_used_blocks;
+word GC_bytes_in_used_blocks = 0;
/*ARGSUSED*/
STATIC void GC_add_block(struct hblk *h, word dummy)
}
}
-
-
void GC_print_obj(ptr_t p)
{
oh * ohdr = (oh *)GC_base(p);
# endif
if (old_sz < copy_sz) copy_sz = old_sz;
if (result == 0) return(0);
- BCOPY(p, result, copy_sz);
+ BCOPY(p, result, copy_sz);
GC_debug_free(p);
return(result);
}
/* We put them here instead of in GC_arrays, since it may be useful to */
/* be able to look at them with the debugger. */
#define MAX_SMASHED 20
-ptr_t GC_smashed[MAX_SMASHED];
-unsigned GC_n_smashed = 0;
+STATIC ptr_t GC_smashed[MAX_SMASHED] = {0};
+STATIC unsigned GC_n_smashed = 0;
STATIC void GC_add_smashed(ptr_t smashed)
{
}
GC_API int GC_CALL GC_general_register_disappearing_link(void * * link,
- void * obj)
+ void * obj)
{
struct disappearing_link *curr_dl;
size_t index;
GC_normal_finalize_mark_proc(p);
}
-
-
/* Register a finalization function. See gc.h for details. */
/* The last parameter is a procedure that determines */
/* marking for finalization ordering. Any objects marked */
#endif
#ifndef SMALL_CONFIG
- STATIC word GC_old_dl_entries; /* for stats printing */
+ STATIC word GC_old_dl_entries = 0; /* for stats printing */
#endif
unsigned GC_fail_count;
GC_bool GC_gcj_malloc_initialized = FALSE;
-int GC_gcj_kind; /* Object kind for objects with descriptors */
+int GC_gcj_kind = 0; /* Object kind for objects with descriptors */
/* in "vtable". */
-int GC_gcj_debug_kind; /* The kind of objects that is always marked */
+int GC_gcj_debug_kind = 0;
+ /* The kind of objects that is always marked */
/* with a mark proc call. */
-ptr_t * GC_gcjobjfreelist;
-ptr_t * GC_gcjdebugobjfreelist;
+ptr_t * GC_gcjobjfreelist = NULL;
+STATIC ptr_t * GC_gcjdebugobjfreelist = NULL;
/*ARGSUSED*/
STATIC struct GC_ms_entry * GC_gcj_fake_mark_proc(word * addr,
/* Caller does not hold allocation lock. */
GC_API void GC_CALL GC_init_gcj_malloc(int mp_index,
- void * /* really GC_mark_proc */mp)
+ void * /* really GC_mark_proc */mp)
{
GC_bool ignore_gcj_info;
DCL_LOCK_STATE;
void * GC_core_gcj_malloc(size_t lb, void * ptr_to_struct_containing_descr)
#else
GC_API void * GC_CALL GC_gcj_malloc(size_t lb,
- void * ptr_to_struct_containing_descr)
+ void * ptr_to_struct_containing_descr)
#endif
{
ptr_t op;
* CLOCKS_PER_SEC be defined. But at least under SunOS4.1.1, it isn't.
* Also note that the combination of ANSI C and POSIX is incredibly gross
* here. The type clock_t is used by both clock() and times(). But on
- * some machines these use different notions of a clock tick, CLOCKS_PER_SEC
+ * some machines these use different notions of a clock tick, CLOCKS_PER_SEC
* seems to apply only to clock. Hence we use it here. On many machines,
* including SunOS, clock actually uses units of microseconds (which are
* not really clock ticks).
(bl)[divWORDSZ(index)] = ONES
-
/********************************************/
/* */
/* H e a p B l o c k s */
extern GC_bool GC_debugging_started; /* GC_debug_malloc has been called */
-extern long GC_large_alloc_warn_interval;
- /* Interval between unsuppressed warnings. */
-
-extern long GC_large_alloc_warn_suppressed;
- /* Number of warnings suppressed so far. */
-
/* This is used by GC_do_blocking[_inner](). */
struct blocking_data {
GC_fn_type fn;
# if defined(SPARC) || defined(IA64)
/* Value returned from register flushing routine; either sp (SPARC) */
- /* or ar.bsp (IA64) */
- ptr_t GC_save_regs_ret_val;
+ /* or ar.bsp (IA64). */
+ ptr_t GC_save_regs_ret_val = NULL;
# endif
/* Routine to mark from registers that are preserved by the C compiler. */
#if defined(THREADS)
-signed_word GC_bytes_found; /* Protected by GC lock. */
+signed_word GC_bytes_found; /* protected by GC lock; defined in reclaim.c */
#ifdef PARALLEL_MARK
volatile signed_word GC_bytes_allocd_tmp = 0;
* need to be marked from.
*/
-STATIC word GC_n_rescuing_pages;/* Number of dirty pages we marked from */
+STATIC word GC_n_rescuing_pages = 0;
+ /* Number of dirty pages we marked from */
/* excludes ptrfree pages, etc. */
-mse * GC_mark_stack;
+mse * GC_mark_stack = NULL;
-mse * GC_mark_stack_limit;
+mse * GC_mark_stack_limit = NULL;
size_t GC_mark_stack_size = 0;
#ifdef PARALLEL_MARK
- mse * volatile GC_mark_stack_top;
+ mse * volatile GC_mark_stack_top = NULL;
/* Updated only with mark lock held, but read asynchronously. */
volatile AO_t GC_first_nonempty;
/* Lowest entry on mark stack */
/* Updated only by initiating */
/* thread. */
#else
- mse * GC_mark_stack_top;
+ mse * GC_mark_stack_top = NULL;
#endif
static struct hblk * scan_ptr;
# endif
-
-
-
word GC_root_size = 0;
GC_API void GC_CALL GC_add_roots(void *b, void *e)
}
# ifdef IA64
- word GC_save_regs_ret_val;
+ ptr_t GC_save_regs_ret_val; /* defined in mach_dep.c. */
/* Previously set to backing store pointer. */
# endif
/* Note that the backing store grows up, so we can't use */
/* GC_push_all_stack_partially_eager. */
{
- ptr_t bsp = (ptr_t) GC_save_regs_ret_val;
+ ptr_t bsp = GC_save_regs_ret_val;
ptr_t cold_gc_bs_pointer = bsp - 2048;
if (GC_all_interior_pointers &&
cold_gc_bs_pointer > BACKING_STORE_BASE) {
# endif /* !THREADS */
}
-void (*GC_push_typed_structures) (void) = NULL;
+void (*GC_push_typed_structures) (void) = 0;
/* Push GC internal roots. These are normally */
/* included in the static data segment, and */
GC_bool GC_debugging_started = FALSE;
/* defined here so we don't have to load debug_malloc.o */
-void (*GC_check_heap) (void) = (void (*) (void))0;
-void (*GC_print_all_smashed) (void) = (void (*) (void))0;
+void (*GC_check_heap) (void) = 0;
+void (*GC_print_all_smashed) (void) = 0;
-void (*GC_start_call_back) (void) = (void (*) (void))0;
+void (*GC_start_call_back) (void) = 0;
ptr_t GC_stackbottom = 0;
GC_bool GC_force_unmap_on_gcollect = FALSE;
#endif
-long GC_large_alloc_warn_interval = 5;
+#ifndef GC_LARGE_ALLOC_WARN_INTERVAL
+# define GC_LARGE_ALLOC_WARN_INTERVAL 5
+#endif
+long GC_large_alloc_warn_interval = GC_LARGE_ALLOC_WARN_INTERVAL;
/* Interval between unsuppressed warnings. */
-long GC_large_alloc_warn_suppressed = 0;
- /* Number of warnings suppressed so far. */
-
/*ARGSUSED*/
STATIC void * GC_CALLBACK GC_default_oom_fn(size_t bytes_requested)
{
# define SMALL_CLEAR_SIZE 256 /* Clear this much every time. */
# else
STATIC word GC_stack_last_cleared = 0; /* GC_no when we last did this */
- STATIC ptr_t GC_min_sp; /* Coolest stack pointer value from which */
- /* we've already cleared the stack. */
- STATIC ptr_t GC_high_water;
+ STATIC ptr_t GC_min_sp = NULL;
+ /* Coolest stack pointer value from which */
+ /* we've already cleared the stack. */
+ STATIC ptr_t GC_high_water = NULL;
/* "hottest" stack pointer value we have seen */
/* recently. Degrades over time. */
- STATIC word GC_bytes_allocd_at_reset;
+ STATIC word GC_bytes_allocd_at_reset = 0;
# define DEGRADE_RATE 50
# endif
#endif
#ifdef USE_MUNMAP
- int GC_unmap_threshold;
+ int GC_unmap_threshold; /* defined in allchblk.c */
#endif
#ifdef LINT
STATIC FILE * GC_stdout = NULL;
STATIC FILE * GC_stderr = NULL;
STATIC FILE * GC_log = NULL;
-STATIC int GC_tmp; /* Should really be local ... */
+static int GC_tmp; /* Should really be local ... */
STATIC void GC_set_files(void)
{
# endif /* LINUX */
extern int _end[];
- ptr_t GC_data_start;
+ ptr_t GC_data_start = NULL;
ptr_t GC_find_limit(ptr_t, GC_bool);
# endif /* ECOS */
#if (defined(NETBSD) || defined(OPENBSD)) && defined(__ELF__)
- ptr_t GC_data_start;
+ ptr_t GC_data_start = NULL;
ptr_t GC_find_limit(ptr_t, GC_bool);
extern char **environ;
# endif /* OS/2 */
/* Find the page size */
-word GC_page_size;
+word GC_page_size = 0;
# if defined(MSWIN32) || defined(MSWINCE)
- void GC_setpagesize(void)
- {
- GetSystemInfo(&GC_sysinfo);
- GC_page_size = GC_sysinfo.dwPageSize;
- }
+ void GC_setpagesize(void)
+ {
+ GetSystemInfo(&GC_sysinfo);
+ GC_page_size = GC_sysinfo.dwPageSize;
+ }
# else
-# if defined(MPROTECT_VDB) || defined(PROC_VDB) || defined(USE_MMAP)
- void GC_setpagesize(void)
- {
- GC_page_size = GETPAGESIZE();
- }
-# else
+ void GC_setpagesize(void)
+ {
+# if defined(MPROTECT_VDB) || defined(PROC_VDB) || defined(USE_MMAP)
+ GC_page_size = GETPAGESIZE();
+# else
/* It's acceptable to fake it. */
- void GC_setpagesize(void)
- {
- GC_page_size = HBLKSIZE;
- }
-# endif
+ GC_page_size = HBLKSIZE;
+# endif
+ }
# endif
# if defined(MSWIN32) || defined(MSWINCE) || defined(CYGWIN32)
}
# endif
- if (bytes & (GC_page_size -1)) ABORT("Bad GET_MEM arg");
+ if (bytes & (GC_page_size - 1)) ABORT("Bad GET_MEM arg");
result = mmap(last_addr, bytes, PROT_READ | PROT_WRITE | OPT_PROT_EXEC,
GC_MMAP_FLAGS | OPT_MAP_ANON, zero_fd, 0/* offset */);
if (result == MAP_FAILED) return(0);
# if defined(MSWIN32) || defined(MSWINCE)
-SYSTEM_INFO GC_sysinfo;
+SYSTEM_INFO GC_sysinfo = {0};
# endif
# ifdef MSWIN32
return(PCR_ERes_okay);
}
-struct PCR_MM_ProcsRep * GC_old_allocator;
+struct PCR_MM_ProcsRep * GC_old_allocator; /* defined in pcr_interface.c */
void GC_default_push_other_roots(void)
{
#endif /* THREADS */
/*
- * Routines for accessing dirty bits on virtual pages.
+ * Routines for accessing dirty bits on virtual pages.
* There are six ways to maintain this information:
* DEFAULT_VDB: A simple dummy implementation that treats every page
* as possibly dirty. This makes incremental collection
#endif
#ifndef DARWIN
-STATIC SIG_HNDLR_PTR GC_old_segv_handler;
+STATIC SIG_HNDLR_PTR GC_old_segv_handler = 0;
/* Also old MSWIN32 ACCESS_VIOLATION filter */
#if !defined(MSWIN32) && !defined(MSWINCE)
-STATIC SIG_HNDLR_PTR GC_old_bus_handler;
-STATIC GC_bool GC_old_bus_handler_used_si;
-STATIC GC_bool GC_old_segv_handler_used_si;
+STATIC SIG_HNDLR_PTR GC_old_bus_handler = 0;
+STATIC GC_bool GC_old_bus_handler_used_si = FALSE;
+STATIC GC_bool GC_old_segv_handler_used_si = FALSE;
#endif
#endif /* !DARWIN */
#define INITIAL_BUF_SZ 16384
STATIC word GC_proc_buf_size = INITIAL_BUF_SZ;
-STATIC char *GC_proc_buf;
+STATIC char *GC_proc_buf = NULL;
-STATIC int GC_proc_fd;
+STATIC int GC_proc_fd = 0;
void GC_dirty_init(void)
{
# define NPAGES (32*1024) /* 128 MB */
-PCR_VD_DB GC_grungy_bits[NPAGES];
+PCR_VD_DB GC_grungy_bits[NPAGES];
-ptr_t GC_vd_base; /* Address corresponding to GC_grungy_bits[0] */
+STATIC ptr_t GC_vd_base = NULL;
+ /* Address corresponding to GC_grungy_bits[0] */
/* HBLKSIZE aligned. */
void GC_dirty_init(void)
} GC_mprotect_state_t;
/* FIXME: 1 and 2 seem to be safe to use in the msgh_id field,
- but it isn't documented. Use the source and see if they
+ but it isn't documented. Use the source and see if they
should be ok. */
#define ID_STOP 1
#define ID_RESUME 2
#if defined(THREADS)
-GC_mprotect_state_t GC_mprotect_state;
+static GC_mprotect_state_t GC_mprotect_state;
/* The following should ONLY be called when the world is stopped */
static void GC_mprotect_thread_notify(mach_msg_id_t id)
#endif /* NEED_CALLINFO */
-
-
#if defined(LINUX) && defined(__ELF__) && !defined(SMALL_CONFIG)
/* Dump /proc/self/maps to GC_stderr, to enable looking up names for
static sigset_t suspend_handler_mask;
-volatile AO_t GC_stop_count;
+volatile AO_t GC_stop_count = 0;
/* Incremented at the beginning of GC_stop_world. */
volatile AO_t GC_world_is_stopped = FALSE;
/* debug that, we save the ids of the stopping thread. */
#if DEBUG_THREADS
pthread_t GC_stopping_thread;
-int GC_stopping_pid;
+int GC_stopping_pid = 0;
#endif
/* We hold the allocation lock. Suspend all threads that might */
# endif
}
-void GC_stop_init(void) {
+void GC_stop_init(void)
+{
struct sigaction act;
if (sem_init(&GC_suspend_ack_sem, 0, 0) != 0)
# include <sys/dg_sys_info.h>
# include <sys/_int_psem.h>
/* sem_t is an uint in DG/UX */
- typedef unsigned int sem_t;
+ typedef unsigned int sem_t;
#endif /* GC_DGUX386_THREADS */
/* Undefine macros used to redirect pthread primitives. */
}
}
-long GC_markers; /* Number of mark threads we would */
- /* like to have. Includes the */
- /* initiating thread. */
+long GC_markers; /* Number of mark threads we would like to */
+ /* have. Includes the initiating thread. */
+ /* Defined in mark.c. */
-pthread_t GC_mark_threads[MAX_MARKERS];
+STATIC pthread_t GC_mark_threads[MAX_MARKERS];
#define PTHREAD_CREATE REAL_FUNC(pthread_create)
#endif /* GC_NETBSD_THREADS */
# if defined(GC_LINUX_THREADS) && defined(INCLUDE_LINUX_THREAD_DESCR)
-__thread int dummy_thread_local;
+__thread int GC_dummy_thread_local;
# endif
/* We hold the allocation lock. */
/* locals for the main thread, except for those allocated */
/* in response to dlopen calls. */
{
- ptr_t thread_local_addr = (ptr_t)(&dummy_thread_local);
+ ptr_t thread_local_addr = (ptr_t)(&GC_dummy_thread_local);
ptr_t main_thread_start, main_thread_end;
if (!GC_enclosing_mapping(thread_local_addr, &main_thread_start,
&main_thread_end)) {
/* cycle, since the routine for printing objects needs to run outside */
/* the collector, e.g. without the allocation lock. */
#define MAX_LEAKED 40
-ptr_t GC_leaked[MAX_LEAKED];
+STATIC ptr_t GC_leaked[MAX_LEAKED] = { NULL };
STATIC unsigned GC_n_leaked = 0;
GC_bool GC_have_errors = FALSE;
}
#ifdef GC_GCJ_SUPPORT
- ptr_t * GC_gcjobjfreelist;
+ ptr_t * GC_gcjobjfreelist; /* defined in gcj_mlc.c. */
#endif
/* We hold the allocator lock. */
#include "include/gc_gcj.h"
#ifdef GC_ASSERTIONS
- GC_bool GC_gcj_malloc_initialized;
+ GC_bool GC_gcj_malloc_initialized; /* defined in gcj_mlc.c. */
#endif
-int GC_gcj_kind;
+int GC_gcj_kind; /* defined in gcj_mlc.c. */
/* Gcj-style allocation without locks is extremely tricky. The */
/* fundamental issue is that we may end up marking a free list, which */
/* Unlike the other thread local allocation calls, we assume that the */
/* collector has been explicitly initialized. */
GC_API void * GC_CALL GC_gcj_malloc(size_t bytes,
- void * ptr_to_struct_containing_descr)
+ void * ptr_to_struct_containing_descr)
{
if (GC_EXPECT(GC_incremental, 0)) {
return GC_core_gcj_malloc(bytes, ptr_to_struct_containing_descr);
STATIC GC_bool GC_explicit_typing_initialized = FALSE;
-STATIC int GC_explicit_kind;
+STATIC int GC_explicit_kind = 0;
/* Object kind for objects with indirect */
/* (possibly extended) descriptors. */
-STATIC int GC_array_kind;
+STATIC int GC_array_kind = 0;
/* Object kind for objects with complex */
/* descriptors and GC_array_mark_proc. */
} complex_descriptor;
#define TAG ld.ld_tag
-STATIC ext_descr * GC_ext_descriptors; /* Points to array of extended */
+STATIC ext_descr * GC_ext_descriptors = NULL;
+ /* Points to array of extended */
/* descriptors. */
STATIC size_t GC_ed_size = 0; /* Current size of above arrays. */
STATIC size_t GC_avail_descr = 0; /* Next available slot. */
-STATIC int GC_typed_mark_proc_index; /* Indices of my mark */
-STATIC int GC_array_mark_proc_index; /* procedures. */
+STATIC int GC_typed_mark_proc_index = 0; /* Indices of my mark */
+STATIC int GC_array_mark_proc_index = 0; /* procedures. */
static void GC_push_typed_structures_proc (void)
{
}
/* Table of bitmap descriptors for n word long all pointer objects. */
-GC_descr GC_bm_table[WORDSZ/2];
+STATIC GC_descr GC_bm_table[WORDSZ/2];
/* Return a descriptor for the concatenation of 2 nwords long objects, */
/* each of which is described by descriptor. */
#ifdef UNDEFINED
complex_descriptor * GC_make_complex_array_descriptor(word nelements,
- complex_descriptor *descr)
+ complex_descriptor *descr)
{
struct ComplexArrayDescriptor * result =
(struct ComplexArrayDescriptor *)
}
#endif
-STATIC ptr_t * GC_eobjfreelist;
+STATIC ptr_t * GC_eobjfreelist = NULL;
-STATIC ptr_t * GC_arobjfreelist;
+STATIC ptr_t * GC_arobjfreelist = NULL;
STATIC mse * GC_typed_mark_proc(word * addr, mse * mark_stack_ptr,
mse * mark_stack_limit, word env);
}
GC_API void * GC_CALL GC_malloc_explicitly_typed_ignore_off_page(size_t lb,
- GC_descr d)
+ GC_descr d)
{
ptr_t op;
ptr_t * opp;
}
GC_API void * GC_CALL GC_calloc_explicitly_typed(size_t n, size_t lb,
- GC_descr d)
+ GC_descr d)
{
ptr_t op;
ptr_t * opp;
/* GC_do_blocking() to temporarily back allow calling any GC function */
/* and/or manipulating pointers to the garbage collected heap. */
GC_API void * GC_CALL GC_call_with_gc_active(GC_fn_type fn,
- void * client_data)
+ void * client_data)
{
struct GC_activation_frame_s frame;
GC_thread me;
/* A quick-and-dirty cache of the mapping between pthread_t */
/* and win32 thread id. */
# define PTHREAD_MAP_SIZE 512
- DWORD GC_pthread_map_cache[PTHREAD_MAP_SIZE];
+ DWORD GC_pthread_map_cache[PTHREAD_MAP_SIZE] = {0};
# define HASH(pthread_id) ((NUMERIC_THREAD_ID(pthread_id) >> 5) % \
PTHREAD_MAP_SIZE)
/* It appears pthread_t is really a pointer type ... */
# define MAX_MARKERS 16
# endif
- long GC_markers; /* Number of mark threads we would */
- /* like to have. Includes the */
- /* initiating thread. */
+ long GC_markers; /* Number of mark threads we would like to */
+ /* have. Includes the initiating thread. */
+ /* Defined in mark.c. */
static ptr_t marker_sp[MAX_MARKERS - 1]; /* The cold end of the stack */
/* for markers. */
# else /* ! GC_PTHREADS_PARAMARK */
# ifdef DONT_USE_SIGNALANDWAIT
- STATIC HANDLE GC_marker_cv[MAX_MARKERS - 1];
+ STATIC HANDLE GC_marker_cv[MAX_MARKERS - 1] = {0};
/* Events with manual reset (one for each */
/* mark helper). */
- STATIC DWORD GC_marker_Id[MAX_MARKERS - 1];
+ STATIC DWORD GC_marker_Id[MAX_MARKERS - 1] = {0};
/* This table is used for mapping helper */
/* threads ID to mark helper index (linear */
/* search is used since the mapping contains */
/* a signal loosing between checking for a particular condition */
/* and calling WaitForSingleObject. So, we use PulseEvent() and */
/* NT SignalObjectAndWait() (which atomically sets mutex event to */
- /* signaled state and starts waiting on condvar). A special */
+ /* signaled state and starts waiting on condvar). A special */
/* case here is GC_mark_mutex_waitcnt == 1 (i.e. nobody waits for */
/* mark lock at this moment) - we don't change it (otherwise we */
/* may loose a signal sent between decrementing */
}
# ifdef MSWINCE
- /* FIXME: Is this really obligatory on WinCE? */
GC_deinit();
DeleteCriticalSection(&GC_allocate_ml);
# endif