aboutsummaryrefslogtreecommitdiff
path: root/boehm-gc/mark_rts.c
diff options
context:
space:
mode:
authorHans Boehm <Hans_Boehm@hp.com>2003-03-03 19:34:11 +0000
committerHans Boehm <hboehm@gcc.gnu.org>2003-03-03 19:34:11 +0000
commitebcc6a7ec08a1e7cc2cf1d2a06daebbb904bde25 (patch)
tree0e084fa019f219c6affbd96447044ea359920119 /boehm-gc/mark_rts.c
parentb22b239e5a587d473731560ea5d05cba42bdd4a7 (diff)
downloadgcc-ebcc6a7ec08a1e7cc2cf1d2a06daebbb904bde25.zip
gcc-ebcc6a7ec08a1e7cc2cf1d2a06daebbb904bde25.tar.gz
gcc-ebcc6a7ec08a1e7cc2cf1d2a06daebbb904bde25.tar.bz2
mark_rts.c (GC_cond_register_dynamic_libraries): add.
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. From-SVN: r63727
Diffstat (limited to 'boehm-gc/mark_rts.c')
-rw-r--r--boehm-gc/mark_rts.c40
1 files changed, 32 insertions, 8 deletions
diff --git a/boehm-gc/mark_rts.c b/boehm-gc/mark_rts.c
index 628cba2..f663dcd 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) {