aboutsummaryrefslogtreecommitdiff
path: root/boehm-gc
diff options
context:
space:
mode:
authordnovillo <dnovillo@138bc75d-0d04-0410-961f-82ee72b054a4>2003-04-09 19:29:57 +0000
committerdnovillo <dnovillo@138bc75d-0d04-0410-961f-82ee72b054a4>2003-04-09 19:29:57 +0000
commit25ffd9a9fccd6d9cced804647029c43a07adf62d (patch)
treee9a619ee14c1364e56f9f37ea65f70cb157d4827 /boehm-gc
parentc1aa10e4910892be16f3c9cb1f35f63965677f50 (diff)
Mainline merge as of 2003-04-06. Additional fixes for bugs
exposed by the merge: gcc/ChangeLog.tree-ssa: * gimplify.c (simplify_expr): Handle VECTOR_CST nodes. * tree-cfg.c (make_blocks): Ignore empty statement containers. Create a basic block before processing containers that only have empty statements. (make_loop_expr_blocks): Use the container instead of the statement when setting NEXT_BLOCK_LINK. (make_cond_expr_blocks): Likewise. (make_switch_expr_blocks): Likewise. (make_bind_expr_blocks): Likewise. (successor_block): If the last statement of the block is the empty statement, use its container to get NEXT_BLOCK_LINK. (stmt_starts_bb_p): Return false if the statement is NULL. * tree-pretty-print.c (dump_generic_node): Handle VECTOR_CST nodes. * tree-simple.c (is_simple_const): Accept VECTOR_CST as constants. * objc/objc-lang.c (LANG_HOOKS_TREE_INLINING_TREE_CHAIN_MATTERS_P): Define. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/tree-ssa-20020619-branch@65404 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'boehm-gc')
-rw-r--r--boehm-gc/ChangeLog39
-rw-r--r--boehm-gc/alloc.c5
-rwxr-xr-xboehm-gc/configure43
-rw-r--r--boehm-gc/configure.in6
-rw-r--r--boehm-gc/dyn_load.c68
-rw-r--r--boehm-gc/include/private/gc_locks.h21
-rw-r--r--boehm-gc/include/private/gc_priv.h13
-rw-r--r--boehm-gc/include/private/gcconfig.h13
-rw-r--r--boehm-gc/mark_rts.c40
-rw-r--r--boehm-gc/misc.c10
10 files changed, 185 insertions, 73 deletions
diff --git a/boehm-gc/ChangeLog b/boehm-gc/ChangeLog
index 64ff38f169c..fc5cbe746a9 100644
--- a/boehm-gc/ChangeLog
+++ b/boehm-gc/ChangeLog
@@ -1,3 +1,42 @@
+2003-03-22 Richard Henderson <rth@redhat.com>
+
+ * include/private/gc_locks.h [IA64]: Include ia64intrin.h.
+ (GC_test_and_set): Use __sync_lock_test_and_set.
+ (GC_clear): Use volatile assignment.
+ (GC_compare_and_exchange): Use __sync_bool_compare_and_swap.
+ (GC_memory_write_barrier): Use __sync_synchronize.
+
+2003-03-12 Andreas Schwab <schwab@suse.de>
+
+ * configure.in: Avoid trailing /. in toolexeclibdir.
+ * configure: Rebuilt.
+
+2003-03-04 Hans Boehm <Hans.Boehm@hp.com>
+ * include/private/gcconfig.h (GC_data_start): declare when needed.
+ * include/private/gc_priv.h: Include gcconfig.h after ptr_t
+ declaration.
+ * dyn_load.c (GC_register_dynamic_libraries_dl_iterate_phdr,
+ GC_register_dynlib_callback): Register main data for static
+ executable if dl_iterate_phdr() didn't.
+ * misc.c (GC_init_inner): Call GC_init_linux_data_start() even
+ if we don't expect to register main static data.
+
+2003-03-03 Hans Boehm <Hans.Boehm@hp.com>
+ * mark_rts.c (GC_cond_register_dynamic_libraries): add.
+ (GC_push_roots): explicitly mark free list headers, register
+ dynamic libraries only if !REGISTER_LIBRARIES_EARLY.
+ * alloc.c (GC_stopped_mark): Conditionally call
+ GC_cond_register_dynamic_libraries().
+ (GC_collect_a_little_inner, GC_try_to_collect_inner): Check GC_dont_gc.
+ * dyn_load.c (GC_register_main_static_data): define.
+ (GC_register_dyn_libraries (Linux /proc, Linux ELF versions)):
+ no longer skip main data.
+ * misc.c (GC_REGISTER_MAIN_STATIC_DATA): define.
+ (GC_init_inner): Make main data registration conditional.
+ * include/private/gc_priv.h (GC_register_main_static_data): declare.
+ * include/private/gcconfig.h (REGISTER_LIBRARIES_EARLY): define
+ for LINUX.
+
2003-02-20 Alexandre Oliva <aoliva@redhat.com>
* configure.in: Propagate ORIGINAL_LD_FOR_MULTILIBS to
diff --git a/boehm-gc/alloc.c b/boehm-gc/alloc.c
index 8a413b275f8..f2e5af05720 100644
--- a/boehm-gc/alloc.c
+++ b/boehm-gc/alloc.c
@@ -306,6 +306,7 @@ void GC_maybe_gc()
GC_bool GC_try_to_collect_inner(stop_func)
GC_stop_func stop_func;
{
+ if (GC_dont_gc) return FALSE;
if (GC_incremental && GC_collection_in_progress()) {
# ifdef CONDPRINT
if (GC_print_stats) {
@@ -386,6 +387,7 @@ int n;
{
register int i;
+ if (GC_dont_gc) return;
if (GC_incremental && GC_collection_in_progress()) {
for (i = GC_deficit; i < GC_RATE*n; i++) {
if (GC_mark_some((ptr_t)0)) {
@@ -446,6 +448,9 @@ GC_stop_func stop_func;
CLOCK_TYPE start_time, current_time;
# endif
+# if defined(REGISTER_LIBRARIES_EARLY)
+ GC_cond_register_dynamic_libraries();
+# endif
STOP_WORLD();
# ifdef PRINTTIMES
GET_TIME(start_time);
diff --git a/boehm-gc/configure b/boehm-gc/configure
index f9bb29090e1..d8f00631534 100755
--- a/boehm-gc/configure
+++ b/boehm-gc/configure
@@ -3091,7 +3091,11 @@ else
toolexecdir='$(libdir)/gcc-lib/$(target_alias)'
toolexeclibdir='$(libdir)'
fi
-toolexeclibdir=$toolexeclibdir/`$CC -print-multi-os-directory`
+multi_os_directory=`$CC -print-multi-os-directory`
+case $multi_os_directory in
+ .) ;; # Avoid trailing /.
+ *) toolexeclibdir=$toolexeclibdir/$multi_os_directory ;;
+esac
@@ -3167,34 +3171,15 @@ trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
# Transform confdefs.h into DEFS.
# Protect against shell expansion while executing Makefile rules.
# Protect against Makefile macro expansion.
-#
-# If the first sed substitution is executed (which looks for macros that
-# take arguments), then we branch to the quote section. Otherwise,
-# look for a macro that doesn't take arguments.
-cat >confdef2opt.sed <<\_ACEOF
-t clear
-: clear
-s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\),-D\1=\2,g
-t quote
-s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\),-D\1=\2,g
-t quote
-d
-: quote
-s,[ `~#$^&*(){}\\|;'"<>?],\\&,g
-s,\[,\\&,g
-s,\],\\&,g
-s,\$,$$,g
-p
-_ACEOF
-# We use echo to avoid assuming a particular line-breaking character.
-# The extra dot is to prevent the shell from consuming trailing
-# line-breaks from the sub-command output. A line-break within
-# single-quotes doesn't work because, if this script is created in a
-# platform that uses two characters for line-breaks (e.g., DOS), tr
-# would break.
-ac_LF_and_DOT=`echo; echo .`
-DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'`
-rm -f confdef2opt.sed
+cat > conftest.defs <<\EOF
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
+s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g
+s%\[%\\&%g
+s%\]%\\&%g
+s%\$%$$%g
+EOF
+DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '`
+rm -f conftest.defs
# Without the "./", some shells look in PATH for config.status.
diff --git a/boehm-gc/configure.in b/boehm-gc/configure.in
index 029a8048c9d..9da20406414 100644
--- a/boehm-gc/configure.in
+++ b/boehm-gc/configure.in
@@ -275,7 +275,11 @@ else
toolexecdir='$(libdir)/gcc-lib/$(target_alias)'
toolexeclibdir='$(libdir)'
fi
-toolexeclibdir=$toolexeclibdir/`$CC -print-multi-os-directory`
+multi_os_directory=`$CC -print-multi-os-directory`
+case $multi_os_directory in
+ .) ;; # Avoid trailing /.
+ *) toolexeclibdir=$toolexeclibdir/$multi_os_directory ;;
+esac
AC_SUBST(toolexecdir)
AC_SUBST(toolexeclibdir)
diff --git a/boehm-gc/dyn_load.c b/boehm-gc/dyn_load.c
index d3ef572be68..71ad5fb1d78 100644
--- a/boehm-gc/dyn_load.c
+++ b/boehm-gc/dyn_load.c
@@ -355,10 +355,6 @@ void GC_register_dynamic_libraries()
/* Stack mapping; discard */
continue;
}
- if (start <= datastart && end > datastart && maj_dev != 0) {
- /* Main data segment; discard */
- continue;
- }
# ifdef THREADS
if (GC_segment_is_thread_stack(start, end)) continue;
# endif
@@ -384,6 +380,13 @@ void GC_register_dynamic_libraries()
}
}
+/* We now take care of the main data segment ourselves: */
+GC_bool GC_register_main_static_data()
+{
+ return FALSE;
+}
+
+# define HAVE_REGISTER_MAIN_STATIC_DATA
//
// parse_map_entry parses an entry from /proc/self/maps so we can
// locate all writable data segments that belong to shared libraries.
@@ -469,13 +472,6 @@ static int GC_register_dynlib_callback(info, size, ptr)
+ sizeof (info->dlpi_phnum))
return -1;
- /* Skip the first object - it is the main program. */
- if (*(int *)ptr == 0)
- {
- *(int *)ptr = 1;
- return 0;
- }
-
p = info->dlpi_phdr;
for( i = 0; i < (int)(info->dlpi_phnum); ((i++),(p++)) ) {
switch( p->p_type ) {
@@ -491,6 +487,7 @@ static int GC_register_dynlib_callback(info, size, ptr)
}
}
+ * (int *)ptr = 1; /* Signal that we were called */
return 0;
}
@@ -500,16 +497,31 @@ static int GC_register_dynlib_callback(info, size, ptr)
GC_bool GC_register_dynamic_libraries_dl_iterate_phdr()
{
- int tmp = 0;
-
if (dl_iterate_phdr) {
- dl_iterate_phdr(GC_register_dynlib_callback, &tmp);
+ int did_something = 0;
+ dl_iterate_phdr(GC_register_dynlib_callback, &did_something);
+ if (!did_something) {
+ /* dl_iterate_phdr may forget the static data segment in */
+ /* statically linked executables. */
+ GC_add_roots_inner(DATASTART, (char *)(DATAEND), TRUE);
+# if defined(DATASTART2)
+ GC_add_roots_inner(DATASTART2, (char *)(DATAEND2), TRUE);
+# endif
+ }
return TRUE;
} else {
return FALSE;
}
}
+/* Do we need to separately register the main static data segment? */
+GC_bool GC_register_main_static_data()
+{
+ return (dl_iterate_phdr == 0);
+}
+
+#define HAVE_REGISTER_MAIN_STATIC_DATA
+
# else /* !LINUX || version(glibc) < 2.2.4 */
/* Dynamic loading code for Linux running ELF. Somewhat tested on
@@ -775,10 +787,23 @@ void GC_register_dynamic_libraries()
}
# endif
-# ifndef MSWINCE
+# ifdef MSWINCE
+ /* Do we need to separately register the main static data segment? */
+ GC_bool GC_register_main_static_data()
+ {
+ return FALSE;
+ }
+# else /* win32 */
extern GC_bool GC_no_win32_dlls;
-# endif
+
+ GC_bool GC_register_main_static_data()
+ {
+ return GC_no_win32_dlls;
+ }
+# endif /* win32 */
+# define HAVE_REGISTER_MAIN_STATIC_DATA
+
void GC_register_dynamic_libraries()
{
MEMORY_BASIC_INFORMATION buf;
@@ -1079,4 +1104,15 @@ void GC_register_dynamic_libraries(){}
int GC_no_dynamic_loading;
#endif /* !PCR */
+
#endif /* !DYNAMIC_LOADING */
+
+#ifndef HAVE_REGISTER_MAIN_STATIC_DATA
+
+/* Do we need to separately register the main static data segment? */
+GC_bool GC_register_main_static_data()
+{
+ return TRUE;
+}
+#endif /* HAVE_REGISTER_MAIN_STATIC_DATA */
+
diff --git a/boehm-gc/include/private/gc_locks.h b/boehm-gc/include/private/gc_locks.h
index 33101f8c2d0..9b91ada917a 100644
--- a/boehm-gc/include/private/gc_locks.h
+++ b/boehm-gc/include/private/gc_locks.h
@@ -100,17 +100,13 @@
# define GC_TEST_AND_SET_DEFINED
# endif
# if defined(IA64)
+# include <ia64intrin.h>
inline static int GC_test_and_set(volatile unsigned int *addr) {
- long oldval, n = 1;
- __asm__ __volatile__("xchg4 %0=%1,%2"
- : "=r"(oldval), "=m"(*addr)
- : "r"(n), "1"(*addr) : "memory");
- return oldval;
+ return __sync_lock_test_and_set(addr, 1);
}
# define GC_TEST_AND_SET_DEFINED
- /* Should this handle post-increment addressing?? */
inline static void GC_clear(volatile unsigned int *addr) {
- __asm__ __volatile__("st4.rel %0=r0" : "=m" (*addr) : : "memory");
+ *addr = 0;
}
# define GC_CLEAR_DEFINED
# endif
@@ -326,20 +322,17 @@
# if defined(IA64)
# if !defined(GENERIC_COMPARE_AND_SWAP)
inline static GC_bool GC_compare_and_exchange(volatile GC_word *addr,
- GC_word old, GC_word new_val)
+ GC_word old,
+ GC_word new_val)
{
- unsigned long oldval;
- __asm__ __volatile__("mov ar.ccv=%4 ;; cmpxchg8.rel %0=%1,%2,ar.ccv"
- : "=r"(oldval), "=m"(*addr)
- : "r"(new_val), "1"(*addr), "r"(old) : "memory");
- return (oldval == old);
+ return __sync_bool_compare_and_swap (addr, old, new_val);
}
# endif /* !GENERIC_COMPARE_AND_SWAP */
# if 0
/* Shouldn't be needed; we use volatile stores instead. */
inline static void GC_memory_write_barrier()
{
- __asm__ __volatile__("mf" : : : "memory");
+ __sync_synchronize ();
}
# endif /* 0 */
# endif /* IA64 */
diff --git a/boehm-gc/include/private/gc_priv.h b/boehm-gc/include/private/gc_priv.h
index 5465c78b6e4..b09c4840945 100644
--- a/boehm-gc/include/private/gc_priv.h
+++ b/boehm-gc/include/private/gc_priv.h
@@ -44,10 +44,6 @@
# include "../gc_mark.h"
# endif
-# ifndef GCCONFIG_H
-# include "gcconfig.h"
-# endif
-
typedef GC_word word;
typedef GC_signed_word signed_word;
@@ -60,6 +56,10 @@ typedef char * ptr_t; /* A generic pointer to which we can add */
/* Preferably identical to caddr_t, if it */
/* exists. */
+# ifndef GCCONFIG_H
+# include "gcconfig.h"
+# endif
+
# ifndef HEADERS_H
# include "gc_hdrs.h"
# endif
@@ -1462,6 +1462,11 @@ GC_bool GC_is_tmp_root GC_PROTO((ptr_t p));
# endif
void GC_register_dynamic_libraries GC_PROTO((void));
/* Add dynamic library data sections to the root set. */
+
+GC_bool GC_register_main_static_data GC_PROTO((void));
+ /* We need to register the main data segment. Returns */
+ /* TRUE unless this is done implicitly as part of */
+ /* dynamic library registration. */
/* Machine dependent startup routines */
ptr_t GC_get_stack_base GC_PROTO((void)); /* Cold end of stack */
diff --git a/boehm-gc/include/private/gcconfig.h b/boehm-gc/include/private/gcconfig.h
index f71bb9813ed..51d9de0186c 100644
--- a/boehm-gc/include/private/gcconfig.h
+++ b/boehm-gc/include/private/gcconfig.h
@@ -1801,6 +1801,19 @@
# define CACHE_LINE_SIZE 32 /* Wild guess */
# endif
+# ifdef LINUX
+# define REGISTER_LIBRARIES_EARLY
+ /* We sometimes use dl_iterate_phdr, which may acquire an internal */
+ /* lock. This isn't safe after the world has stopped. So we must */
+ /* call GC_register_dynamic_libraries before stopping the world. */
+ /* For performance reasons, this may be beneficial on other */
+ /* platforms as well, though it should be avoided in win32. */
+# endif /* LINUX */
+
+# if defined(SEARCH_FOR_DATA_START) && defined(GC_PRIVATE_H)
+ extern ptr_t GC_data_start;
+# endif
+
# ifndef CLEAR_DOUBLE
# define CLEAR_DOUBLE(x) \
((word*)x)[0] = 0; \
diff --git a/boehm-gc/mark_rts.c b/boehm-gc/mark_rts.c
index 628cba289ac..f663dcd55c3 100644
--- a/boehm-gc/mark_rts.c
+++ b/boehm-gc/mark_rts.c
@@ -506,6 +506,17 @@ void GC_push_gc_structures GC_PROTO((void))
void GC_mark_thread_local_free_lists();
#endif
+void GC_cond_register_dynamic_libraries()
+{
+# if (defined(DYNAMIC_LOADING) || defined(MSWIN32) || defined(MSWINCE) \
+ || defined(PCR)) && !defined(SRC_M3)
+ GC_remove_tmp_roots();
+ if (!GC_no_dls) GC_register_dynamic_libraries();
+# else
+ GC_no_dls = TRUE;
+# endif
+}
+
/*
* Call the mark routines (GC_tl_push for a single pointer, GC_push_conditional
* on groups of pointers) on every top level accessible pointer.
@@ -519,19 +530,20 @@ void GC_push_roots(all, cold_gc_frame)
GC_bool all;
ptr_t cold_gc_frame;
{
- register int i;
+ int i;
+ int kind;
/*
* Next push static data. This must happen early on, since it's
* not robust against mark stack overflow.
*/
- /* Reregister dynamic libraries, in case one got added. */
-# if (defined(DYNAMIC_LOADING) || defined(MSWIN32) || defined(MSWINCE) \
- || defined(PCR)) && !defined(SRC_M3)
- GC_remove_tmp_roots();
- if (!GC_no_dls) GC_register_dynamic_libraries();
-# else
- GC_no_dls = TRUE;
+ /* Reregister dynamic libraries, in case one got added. */
+ /* There is some argument for doing this as late as possible, */
+ /* especially on win32, where it can change asynchronously. */
+ /* In those cases, we do it here. But on other platforms, it's */
+ /* not safe with the world stopped, so we do it earlier. */
+# if !defined(REGISTER_LIBRARIES_EARLY)
+ GC_cond_register_dynamic_libraries();
# endif
/* Mark everything in static data areas */
@@ -541,6 +553,18 @@ ptr_t cold_gc_frame;
GC_static_roots[i].r_end, all);
}
+ /* Mark all free list header blocks, if those were allocated from */
+ /* the garbage collected heap. This makes sure they don't */
+ /* disappear if we are not marking from static data. It also */
+ /* saves us the trouble of scanning them, and possibly that of */
+ /* marking the freelists. */
+ for (kind = 0; kind < GC_n_kinds; kind++) {
+ GC_PTR base = GC_base(GC_obj_kinds[kind].ok_freelist);
+ if (0 != base) {
+ GC_set_mark_bit(base);
+ }
+ }
+
/* Mark from GC internal roots if those might otherwise have */
/* been excluded. */
if (GC_no_dls || roots_were_cleared) {
diff --git a/boehm-gc/misc.c b/boehm-gc/misc.c
index f6079732fbf..8f83ff3ab53 100644
--- a/boehm-gc/misc.c
+++ b/boehm-gc/misc.c
@@ -75,6 +75,14 @@
#undef STACKBASE
#endif
+/* Dont unnecessarily call GC_register_main_static_data() in case */
+/* dyn_load.c isn't linked in. */
+#ifdef DYNAMIC_LOADING
+# define GC_REGISTER_MAIN_STATIC_DATA() GC_register_main_static_data()
+#else
+# define GC_REGISTER_MAIN_STATIC_DATA() TRUE
+#endif
+
GC_FAR struct _GC_arrays GC_arrays /* = { 0 } */;
@@ -619,7 +627,7 @@ void GC_init_inner()
/* Add initial guess of root sets. Do this first, since sbrk(0) */
/* might be used. */
- GC_register_data_segments();
+ if (GC_REGISTER_MAIN_STATIC_DATA()) GC_register_data_segments();
GC_init_headers();
GC_bl_init();
GC_mark_init();