=================================================================== RCS file: /home/cvs/OpenXM_contrib2/asir2000/gc/misc.c,v retrieving revision 1.5 retrieving revision 1.6 diff -u -p -r1.5 -r1.6 --- OpenXM_contrib2/asir2000/gc/misc.c 2002/07/24 07:46:20 1.5 +++ OpenXM_contrib2/asir2000/gc/misc.c 2002/07/24 08:00:10 1.6 @@ -1,6 +1,7 @@ /* * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers * Copyright (c) 1991-1994 by Xerox Corporation. All rights reserved. + * Copyright (c) 1999-2001 by Hewlett-Packard Company. All rights reserved. * * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. @@ -15,6 +16,7 @@ #include +#include #ifndef _WIN32_WCE #include #endif @@ -22,7 +24,7 @@ #define I_HIDE_POINTERS /* To make GC_call_with_alloc_lock visible */ #include "private/gc_pmark.h" -#ifdef SOLARIS_THREADS +#ifdef GC_SOLARIS_THREADS # include #endif #if defined(MSWIN32) || defined(MSWINCE) @@ -41,29 +43,29 @@ /* Critical section counter is defined in the M3 runtime */ /* That's all we use. */ # else -# ifdef SOLARIS_THREADS +# ifdef GC_SOLARIS_THREADS mutex_t GC_allocate_ml; /* Implicitly initialized. */ # else -# ifdef WIN32_THREADS -# if defined(_DLL) || defined(GC_DLL) +# if defined(GC_WIN32_THREADS) +# if defined(GC_PTHREADS) + pthread_mutex_t GC_allocate_ml = PTHREAD_MUTEX_INITIALIZER; +# elif !defined(GC_NOT_DLL) && (defined(_DLL) || defined(GC_DLL)) __declspec(dllexport) CRITICAL_SECTION GC_allocate_ml; # else CRITICAL_SECTION GC_allocate_ml; # endif # else -# if defined(IRIX_THREADS) \ - || (defined(LINUX_THREADS) && defined(USE_SPIN_LOCK)) - pthread_t GC_lock_holder = NO_THREAD; -# else -# if defined(HPUX_THREADS) \ - || defined(LINUX_THREADS) && !defined(USE_SPIN_LOCK) +# if defined(GC_PTHREADS) && !defined(GC_SOLARIS_THREADS) +# if defined(USE_SPIN_LOCK) + pthread_t GC_lock_holder = NO_THREAD; +# else pthread_mutex_t GC_allocate_ml = PTHREAD_MUTEX_INITIALIZER; pthread_t GC_lock_holder = NO_THREAD; /* Used only for assertions, and to prevent */ /* recursive reentry in the system call wrapper. */ -# else +# endif +# else --> declare allocator lock here -# endif # endif # endif # endif @@ -71,6 +73,10 @@ # endif # endif +#if defined(NOSYS) || defined(ECOS) +#undef STACKBASE +#endif + GC_FAR struct _GC_arrays GC_arrays /* = { 0 } */; @@ -78,6 +84,7 @@ GC_bool GC_debugging_started = FALSE; /* defined here so we don't have to load debug_malloc.o */ void (*GC_check_heap) GC_PROTO((void)) = (void (*) GC_PROTO((void)))0; +void (*GC_print_all_smashed) GC_PROTO((void)) = (void (*) GC_PROTO((void)))0; void (*GC_start_call_back) GC_PROTO((void)) = (void (*) GC_PROTO((void)))0; @@ -95,6 +102,8 @@ GC_bool GC_quiet = 0; GC_bool GC_print_stats = 0; +GC_bool GC_print_back_height = 0; + #ifdef FIND_LEAK int GC_find_leak = 1; #else @@ -107,6 +116,12 @@ GC_bool GC_print_stats = 0; int GC_all_interior_pointers = 0; #endif +long GC_large_alloc_warn_interval = 5; + /* Interval between unsuppressed warnings. */ + +long GC_large_alloc_warn_suppressed = 0; + /* Number of warnings suppressed so far. */ + /*ARGSUSED*/ GC_PTR GC_default_oom_fn GC_PROTO((size_t bytes_requested)) { @@ -297,6 +312,8 @@ ptr_t arg; if (++random_no % 13 == 0) { limit = sp; MAKE_HOTTER(limit, BIG_CLEAR_SIZE*sizeof(word)); + limit &= ~0xf; /* Make it sufficiently aligned for assembly */ + /* implementations of GC_clear_stack_inner. */ return GC_clear_stack_inner(arg, limit); } else { BZERO(dummy, SMALL_CLEAR_SIZE*sizeof(word)); @@ -432,11 +449,25 @@ void GC_init() DCL_LOCK_STATE; DISABLE_SIGNALS(); + +#if defined(GC_WIN32_THREADS) && !defined(GC_PTHREADS) + if (!GC_is_initialized) InitializeCriticalSection(&GC_allocate_ml); +#endif /* MSWIN32 */ + LOCK(); GC_init_inner(); UNLOCK(); ENABLE_SIGNALS(); +# if defined(PARALLEL_MARK) || defined(THREAD_LOCAL_ALLOC) + /* Make sure marker threads and started and thread local */ + /* allocation is initialized, in case we didn't get */ + /* called from GC_init_parallel(); */ + { + extern void GC_init_parallel(void); + GC_init_parallel(); + } +# endif /* PARALLEL_MARK || THREAD_LOCAL_ALLOC */ } #if defined(MSWIN32) || defined(MSWINCE) @@ -461,6 +492,12 @@ int sig; } #endif +#ifdef MSWIN32 +extern GC_bool GC_no_win32_dlls; +#else +# define GC_no_win32_dlls FALSE +#endif + void GC_init_inner() { # if !defined(THREADS) && defined(GC_ASSERTIONS) @@ -472,6 +509,9 @@ void GC_init_inner() # ifdef PRINTSTATS GC_print_stats = 1; # endif +# if defined(MSWIN32) || defined(MSWINCE) + InitializeCriticalSection(&GC_write_cs); +# endif if (0 != GETENV("GC_PRINT_STATS")) { GC_print_stats = 1; } @@ -484,6 +524,36 @@ void GC_init_inner() if (0 != GETENV("GC_DONT_GC")) { GC_dont_gc = 1; } + if (0 != GETENV("GC_PRINT_BACK_HEIGHT")) { + GC_print_back_height = 1; + } + if (0 != GETENV("GC_NO_BLACKLIST_WARNING")) { + GC_large_alloc_warn_interval = LONG_MAX; + } + { + char * time_limit_string = GETENV("GC_PAUSE_TIME_TARGET"); + if (0 != time_limit_string) { + long time_limit = atol(time_limit_string); + if (time_limit < 5) { + WARN("GC_PAUSE_TIME_TARGET environment variable value too small " + "or bad syntax: Ignoring\n", 0); + } else { + GC_time_limit = time_limit; + } + } + } + { + char * interval_string = GETENV("GC_LARGE_ALLOC_WARN_INTERVAL"); + if (0 != interval_string) { + long interval = atol(interval_string); + if (interval <= 0) { + WARN("GC_LARGE_ALLOC_WARN_INTERVAL environment variable has " + "bad value: Ignoring\n", 0); + } else { + GC_large_alloc_warn_interval = interval; + } + } + } # ifdef UNIX_LIKE if (0 != GETENV("GC_LOOP_ON_ABORT")) { GC_set_and_save_fault_handler(looping_handler); @@ -493,9 +563,6 @@ void GC_init_inner() if (ALIGNMENT > GC_DS_TAGS && EXTRA_BYTES != 0) { GC_obj_kinds[NORMAL].ok_descriptor = ((word)(-ALIGNMENT) | GC_DS_LENGTH); } -# if defined(MSWIN32) || defined(MSWINCE) - InitializeCriticalSection(&GC_write_cs); -# endif GC_setpagesize(); GC_exclude_static_roots(beginGC_arrays, endGC_arrays); GC_exclude_static_roots(beginGC_obj_kinds, endGC_obj_kinds); @@ -509,20 +576,18 @@ void GC_init_inner() # if defined(SEARCH_FOR_DATA_START) GC_init_linux_data_start(); # endif -# if defined(NETBSD) && defined(__ELF__) +# if (defined(NETBSD) || defined(OPENBSD)) && defined(__ELF__) GC_init_netbsd_elf(); # endif -# if defined(IRIX_THREADS) || defined(LINUX_THREADS) \ - || defined(HPUX_THREADS) || defined(SOLARIS_THREADS) +# if defined(GC_PTHREADS) || defined(GC_SOLARIS_THREADS) GC_thr_init(); # endif -# ifdef SOLARIS_THREADS +# ifdef GC_SOLARIS_THREADS /* We need dirty bits in order to find live stack sections. */ GC_dirty_init(); # endif -# if !defined(THREADS) || defined(SOLARIS_THREADS) || defined(WIN32_THREADS) \ - || defined(IRIX_THREADS) || defined(LINUX_THREADS) \ - || defined(HPUX_THREADS) +# if !defined(THREADS) || defined(GC_PTHREADS) || defined(GC_WIN32_THREADS) \ + || defined(GC_SOLARIS_THREADS) if (GC_stackbottom == 0) { GC_stackbottom = GC_get_stack_base(); # if defined(LINUX) && defined(IA64) @@ -595,8 +660,19 @@ void GC_init_inner() PCR_IL_Unlock(); GC_pcr_install(); # endif - /* Get black list set up */ - if (!GC_dont_precollect) GC_gcollect_inner(); +# if !defined(SMALL_CONFIG) + if (!GC_no_win32_dlls && 0 != GETENV("GC_ENABLE_INCREMENTAL")) { + GC_ASSERT(!GC_incremental); + GC_setpagesize(); +# ifndef GC_SOLARIS_THREADS + GC_dirty_init(); +# endif + GC_ASSERT(GC_words_allocd == 0) + GC_incremental = TRUE; + } +# endif /* !SMALL_CONFIG */ + /* Get black list set up and/or incrmental GC started */ + if (!GC_dont_precollect || GC_incremental) GC_gcollect_inner(); GC_is_initialized = TRUE; # ifdef STUBBORN_ALLOC GC_stubborn_init(); @@ -629,20 +705,14 @@ void GC_enable_incremental GC_PROTO(()) LOCK(); if (GC_incremental) goto out; GC_setpagesize(); -# ifdef MSWIN32 - { - extern GC_bool GC_is_win32s(); - - /* VirtualProtect is not functional under win32s. */ - if (GC_is_win32s()) goto out; - } -# endif /* MSWIN32 */ -# ifndef SOLARIS_THREADS + if (GC_no_win32_dlls) goto out; +# ifndef GC_SOLARIS_THREADS GC_dirty_init(); # endif if (!GC_is_initialized) { GC_init_inner(); } + if (GC_incremental) goto out; if (GC_dont_gc) { /* Can't easily do it. */ UNLOCK(); @@ -678,7 +748,7 @@ out: } int GC_write(buf, len) - char * buf; + GC_CONST char * buf; size_t len; { BOOL tmp; @@ -728,17 +798,18 @@ int GC_tmp; /* Should really be local ... */ # endif #endif -#if !defined(MSWIN32) && !defined(MSWINCE) && !defined(OS2) && !defined(MACOS) +#if !defined(MSWIN32) && !defined(MSWINCE) && !defined(OS2) \ + && !defined(MACOS) && !defined(ECOS) && !defined(NOSYS) int GC_write(fd, buf, len) int fd; -char *buf; +GC_CONST char *buf; size_t len; { register int bytes_written = 0; register int result; while (bytes_written < len) { -# ifdef SOLARIS_THREADS +# ifdef GC_SOLARIS_THREADS result = syscall(SYS_write, fd, buf + bytes_written, len - bytes_written); # else @@ -751,6 +822,23 @@ size_t len; } #endif /* UN*X */ +#ifdef ECOS +int GC_write(fd, buf, len) +{ + _Jv_diag_write (buf, len); + return len; +} +#endif + +#ifdef NOSYS +int GC_write(fd, buf, len) +{ + /* No writing. */ + return len; +} +#endif + + #if defined(MSWIN32) || defined(MSWINCE) # define WRITE(f, buf, len) GC_write(buf, len) #else @@ -854,7 +942,7 @@ GC_CONST char * msg; /* It's arguably nicer to sleep, but that makes it harder */ /* to look at the thread if the debugger doesn't know much */ /* about threads. */ - for(;;); + for(;;) {} } # ifdef MSWIN32 DebugBreak(); @@ -864,38 +952,6 @@ GC_CONST char * msg; } #endif -#ifdef NEED_CALLINFO - -void GC_print_callers (info) -struct callinfo info[NFRAMES]; -{ - register int i; - -# if NFRAMES == 1 - GC_err_printf0("\tCaller at allocation:\n"); -# else - GC_err_printf0("\tCall chain at allocation:\n"); -# endif - for (i = 0; i < NFRAMES; i++) { - if (info[i].ci_pc == 0) break; -# if NARGS > 0 - { - int j; - - GC_err_printf0("\t\targs: "); - for (j = 0; j < NARGS; j++) { - if (j != 0) GC_err_printf0(", "); - GC_err_printf2("%d (0x%X)", ~(info[i].ci_arg[j]), - ~(info[i].ci_arg[j])); - } - GC_err_printf0("\n"); - } -# endif - GC_err_printf1("\t\t##PC##= 0x%X\n", info[i].ci_pc); - } -} - -#endif /* SAVE_CALL_CHAIN */ /* Needed by SRC_M3, gcj, and should perhaps be the official interface */ /* to GC_dont_gc. */