summaryrefslogtreecommitdiff
path: root/mark_rts.c
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2011-07-26 12:51:28 +0200
committerIvan Maidanski <ivmai@mail.ru>2011-07-26 12:51:28 +0200
commitacf2e57f2091522924a0064b318642253e2b2bac (patch)
tree81d1d9fe63ae4d7b109b494d171ac33bc361c803 /mark_rts.c
parent7fd4efa1d0dbab63e6d9bddd1d72fa4aafc8ad52 (diff)
gc4.8 tarball importgc4_8
Diffstat (limited to 'mark_rts.c')
-rw-r--r--mark_rts.c124
1 files changed, 111 insertions, 13 deletions
diff --git a/mark_rts.c b/mark_rts.c
index 376746f..c5883fa 100644
--- a/mark_rts.c
+++ b/mark_rts.c
@@ -11,19 +11,23 @@
* provided the above notices are retained, and a notice that the code was
* modified is included with the above copyright notice.
*/
-/* Boehm, May 19, 1994 1:58 pm PDT */
+/* Boehm, October 9, 1995 1:06 pm PDT */
# include <stdio.h>
# include "gc_priv.h"
-# ifdef PCR
-# define MAX_ROOT_SETS 1024
+# ifdef LARGE_CONFIG
+# define MAX_ROOT_SETS 4096
# else
-# ifdef MSWIN32
+# ifdef PCR
+# define MAX_ROOT_SETS 1024
+# else
+# ifdef MSWIN32
# define MAX_ROOT_SETS 512
/* Under NT, we add only written pages, which can result */
/* in many small root sets. */
-# else
+# else
# define MAX_ROOT_SETS 64
+# endif
# endif
# endif
@@ -37,6 +41,8 @@ struct roots {
# ifndef MSWIN32
struct roots * r_next;
# endif
+ bool r_tmp;
+ /* Delete before registering new dynamic libraries */
};
static struct roots static_roots[MAX_ROOT_SETS];
@@ -45,6 +51,54 @@ static int n_root_sets = 0;
/* static_roots[0..n_root_sets) contains the valid root sets. */
+# if !defined(NO_DEBUGGING)
+/* For debugging: */
+void GC_print_static_roots()
+{
+ register int i;
+ size_t total = 0;
+
+ for (i = 0; i < n_root_sets; i++) {
+ GC_printf2("From 0x%lx to 0x%lx ",
+ (unsigned long) static_roots[i].r_start,
+ (unsigned long) static_roots[i].r_end);
+ if (static_roots[i].r_tmp) {
+ GC_printf0(" (temporary)\n");
+ } else {
+ GC_printf0("\n");
+ }
+ total += static_roots[i].r_end - static_roots[i].r_start;
+ }
+ GC_printf1("Total size: %ld\n", (unsigned long) total);
+ if (GC_root_size != total) {
+ GC_printf1("GC_root_size incorrect: %ld!!\n",
+ (unsigned long) GC_root_size);
+ }
+}
+# endif /* NO_DEBUGGING */
+
+/* Primarily for debugging support: */
+/* Is the address p in one of the registered static */
+/* root sections? */
+bool GC_is_static_root(p)
+ptr_t p;
+{
+ static int last_root_set = 0;
+ register int i;
+
+
+ if (p >= static_roots[last_root_set].r_start
+ && p < static_roots[last_root_set].r_end) return(TRUE);
+ for (i = 0; i < n_root_sets; i++) {
+ if (p >= static_roots[i].r_start
+ && p < static_roots[i].r_end) {
+ last_root_set = i;
+ return(TRUE);
+ }
+ }
+ return(FALSE);
+}
+
#ifndef MSWIN32
# define LOG_RT_SIZE 6
# define RT_SIZE (1 << LOG_RT_SIZE) /* Power of 2, may be != MAX_ROOT_SETS */
@@ -112,7 +166,7 @@ char * b; char * e;
DISABLE_SIGNALS();
LOCK();
- GC_add_roots_inner(b, e);
+ GC_add_roots_inner(b, e, FALSE);
UNLOCK();
ENABLE_SIGNALS();
}
@@ -122,8 +176,11 @@ char * b; char * e;
/* is a moderately fast noop, and hence benign. We do not handle */
/* different but overlapping intervals efficiently. (We do handle */
/* them correctly.) */
-void GC_add_roots_inner(b, e)
+/* Tmp specifies that the interval may be deleted before */
+/* reregistering dynamic libraries. */
+void GC_add_roots_inner(b, e, tmp)
char * b; char * e;
+bool tmp;
{
struct roots * old;
@@ -136,8 +193,8 @@ char * b; char * e;
} else if ((ptr_t)b >= beginGC_arrays) {
b = (char *)endGC_arrays;
} else {
- GC_add_roots_inner(b, (char *)beginGC_arrays);
- GC_add_roots_inner((char *)endGC_arrays, e);
+ GC_add_roots_inner(b, (char *)beginGC_arrays, tmp);
+ GC_add_roots_inner((char *)endGC_arrays, e, tmp);
return;
}
}
@@ -156,10 +213,13 @@ char * b; char * e;
if ((ptr_t)b <= old -> r_end && (ptr_t)e >= old -> r_start) {
if ((ptr_t)b < old -> r_start) {
old -> r_start = (ptr_t)b;
+ GC_root_size += (old -> r_start - (ptr_t)b);
}
if ((ptr_t)e > old -> r_end) {
old -> r_end = (ptr_t)e;
+ GC_root_size += ((ptr_t)e - old -> r_end);
}
+ old -> r_tmp &= tmp;
break;
}
}
@@ -174,14 +234,18 @@ char * b; char * e;
if ((ptr_t)b <= old -> r_end && (ptr_t)e >= old -> r_start) {
if ((ptr_t)b < old -> r_start) {
old -> r_start = (ptr_t)b;
+ GC_root_size += (old -> r_start - (ptr_t)b);
}
if ((ptr_t)e > old -> r_end) {
old -> r_end = (ptr_t)e;
+ GC_root_size += ((ptr_t)e - old -> r_end);
}
+ old -> r_tmp &= other -> r_tmp;
/* Delete this entry. */
+ GC_root_size -= (other -> r_end - other -> r_start);
other -> r_start = static_roots[n_root_sets-1].r_start;
other -> r_end = static_roots[n_root_sets-1].r_end;
- n_root_sets--;
+ n_root_sets--;
}
}
return;
@@ -202,6 +266,7 @@ char * b; char * e;
}
static_roots[n_root_sets].r_start = (ptr_t)b;
static_roots[n_root_sets].r_end = (ptr_t)e;
+ static_roots[n_root_sets].r_tmp = tmp;
# ifndef MSWIN32
static_roots[n_root_sets].r_next = 0;
# endif
@@ -210,7 +275,7 @@ char * b; char * e;
n_root_sets++;
}
-void GC_clear_roots()
+void GC_clear_roots GC_PROTO((void))
{
DCL_LOCK_STATE;
@@ -218,18 +283,50 @@ void GC_clear_roots()
LOCK();
n_root_sets = 0;
GC_root_size = 0;
+# ifndef MSWIN32
+ {
+ register int i;
+
+ for (i = 0; i < RT_SIZE; i++) root_index[i] = 0;
+ }
+# endif
UNLOCK();
ENABLE_SIGNALS();
}
-# ifndef THREADS
+/* Internal use only; lock held. */
+void GC_remove_tmp_roots()
+{
+ register int i;
+
+ for (i = 0; i < n_root_sets; ) {
+ if (static_roots[i].r_tmp) {
+ GC_root_size -= (static_roots[i].r_end - static_roots[i].r_start);
+ static_roots[i].r_start = static_roots[n_root_sets-1].r_start;
+ static_roots[i].r_end = static_roots[n_root_sets-1].r_end;
+ static_roots[i].r_tmp = static_roots[n_root_sets-1].r_tmp;
+ n_root_sets--;
+ } else {
+ i++;
+ }
+ }
+# ifndef MSWIN32
+ {
+ register int i;
+
+ for (i = 0; i < RT_SIZE; i++) root_index[i] = 0;
+ for (i = 0; i < n_root_sets; i++) add_roots_to_index(static_roots + i);
+ }
+# endif
+
+}
+
ptr_t GC_approx_sp()
{
word dummy;
return((ptr_t)(&dummy));
}
-# endif
/*
* Call the mark routines (GC_tl_push for a single pointer, GC_push_conditional
@@ -255,6 +352,7 @@ bool all;
/* Reregister dynamic libraries, in case one got added. */
# if (defined(DYNAMIC_LOADING) || defined(MSWIN32) || defined(PCR)) \
&& !defined(SRC_M3)
+ GC_remove_tmp_roots();
GC_register_dynamic_libraries();
# endif
/* Mark everything in static data areas */