summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog18
-rw-r--r--blacklst.c31
-rw-r--r--include/private/gc_priv.h1
-rw-r--r--misc.c22
-rw-r--r--obj_map.c4
5 files changed, 58 insertions, 18 deletions
diff --git a/ChangeLog b/ChangeLog
index 0024cf70..62c10424 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,23 @@
2011-03-20 Ivan Maidanski <ivmai@mail.ru>
+ * blacklst.c (GC_bl_init_no_interiors): New function (the code
+ moved from GC_bl_init).
+ * blacklst.c (GC_bl_init): Invoke GC_bl_init_no_interiors unless
+ GC_all_interior_pointers mode; remove unnecessarily parameter cast
+ for GC_scratch_alloc call.
+ * include/private/gc_priv.h (GC_bl_init): Move the function
+ declaration to misc.c file.
+ * misc.c (GC_bl_init_no_interiors): Add a prototype.
+ * misc.c (GC_set_all_interior_pointers): Allow values other than 0
+ and 1; allow altering GC_set_all_interior_pointers value even
+ after GC initialization.
+ * obj_map.c (GC_initialize_offsets): Clear GC_valid_offsets and
+ GC_modws_valid_offsets if GC_all_interior_pointers is off.
+ * misc.c (GC_init): Don't call GC_initialize_offsets() unless
+ GC_all_interior_pointers mode.
+
+2011-03-20 Ivan Maidanski <ivmai@mail.ru>
+
* alloc.c (GC_finish_collection): Remove redundant brackets;
adjust code indentation.
* blacklst.c (GC_add_to_black_list_normal): Simplify expression
diff --git a/blacklst.c b/blacklst.c
index 1fb9d00c..a6df6933 100644
--- a/blacklst.c
+++ b/blacklst.c
@@ -83,23 +83,28 @@ STATIC void GC_print_source_ptr(ptr_t p)
}
#endif
+GC_INNER void GC_bl_init_no_interiors(void)
+{
+ if (GC_incomplete_normal_bl == 0) {
+ GC_old_normal_bl = (word *)GC_scratch_alloc(sizeof(page_hash_table));
+ GC_incomplete_normal_bl = (word *)GC_scratch_alloc(
+ sizeof(page_hash_table));
+ if (GC_old_normal_bl == 0 || GC_incomplete_normal_bl == 0) {
+ GC_err_printf("Insufficient memory for black list\n");
+ EXIT();
+ }
+ GC_clear_bl(GC_old_normal_bl);
+ GC_clear_bl(GC_incomplete_normal_bl);
+ }
+}
+
GC_INNER void GC_bl_init(void)
{
if (!GC_all_interior_pointers) {
- GC_old_normal_bl = (word *)
- GC_scratch_alloc((word)(sizeof (page_hash_table)));
- GC_incomplete_normal_bl = (word *)GC_scratch_alloc
- ((word)(sizeof(page_hash_table)));
- if (GC_old_normal_bl == 0 || GC_incomplete_normal_bl == 0) {
- GC_err_printf("Insufficient memory for black list\n");
- EXIT();
- }
- GC_clear_bl(GC_old_normal_bl);
- GC_clear_bl(GC_incomplete_normal_bl);
+ GC_bl_init_no_interiors();
}
- GC_old_stack_bl = (word *)GC_scratch_alloc((word)(sizeof(page_hash_table)));
- GC_incomplete_stack_bl = (word *)GC_scratch_alloc
- ((word)(sizeof(page_hash_table)));
+ GC_old_stack_bl = (word *)GC_scratch_alloc(sizeof(page_hash_table));
+ GC_incomplete_stack_bl = (word *)GC_scratch_alloc(sizeof(page_hash_table));
if (GC_old_stack_bl == 0 || GC_incomplete_stack_bl == 0) {
GC_err_printf("Insufficient memory for black list\n");
EXIT();
diff --git a/include/private/gc_priv.h b/include/private/gc_priv.h
index c51a0b0f..816bb0f0 100644
--- a/include/private/gc_priv.h
+++ b/include/private/gc_priv.h
@@ -1539,7 +1539,6 @@ void GC_register_data_segments(void);
#endif
/* Black listing: */
-GC_INNER void GC_bl_init(void);
#ifdef PRINT_BLACK_LIST
GC_INNER void GC_add_to_black_list_normal(word p, ptr_t source);
/* Register bits as a possible future false */
diff --git a/misc.c b/misc.c
index 75b92b06..a81b11c5 100644
--- a/misc.c
+++ b/misc.c
@@ -631,6 +631,7 @@ STATIC void GC_exit_check(void)
#endif
GC_INNER void GC_initialize_offsets(void); /* defined in obj_map.c */
+GC_INNER void GC_bl_init(void); /* defined in blacklst.c */
GC_API void GC_CALL GC_init(void)
{
@@ -946,7 +947,8 @@ GC_API void GC_CALL GC_init(void)
GC_err_printf("Can't start up: not enough memory\n");
EXIT();
}
- GC_initialize_offsets();
+ if (GC_all_interior_pointers)
+ GC_initialize_offsets();
GC_register_displacement_inner(0L);
# if defined(GC_LINUX_THREADS) && defined(REDIRECT_MALLOC)
if (!GC_all_interior_pointers) {
@@ -1694,11 +1696,23 @@ GC_API int GC_CALL GC_get_find_leak(void)
return GC_find_leak;
}
+GC_INNER void GC_bl_init_no_interiors(void); /* defined in blacklst.c */
+
GC_API void GC_CALL GC_set_all_interior_pointers(int value)
{
- GC_ASSERT(!GC_is_initialized || value == GC_all_interior_pointers);
- GC_ASSERT(value == 0 || value == 1);
- GC_all_interior_pointers = value;
+ DCL_LOCK_STATE;
+
+ GC_all_interior_pointers = value ? 1 : 0;
+ if (GC_is_initialized) {
+ /* It is not recommended to change GC_all_interior_pointers value */
+ /* after GC is initialized but it seems GC could work correctly */
+ /* even after switching the mode. */
+ LOCK();
+ GC_initialize_offsets(); /* NOTE: this resets manual offsets as well */
+ if (!GC_all_interior_pointers)
+ GC_bl_init_no_interiors();
+ UNLOCK();
+ }
}
GC_API int GC_CALL GC_get_all_interior_pointers(void)
diff --git a/obj_map.c b/obj_map.c
index 8bd09930..082a0aa7 100644
--- a/obj_map.c
+++ b/obj_map.c
@@ -82,5 +82,9 @@ GC_INNER void GC_initialize_offsets(void)
if (GC_all_interior_pointers) {
for (i = 0; i < VALID_OFFSET_SZ; ++i)
GC_valid_offsets[i] = TRUE;
+ } else {
+ BZERO(GC_valid_offsets, sizeof(GC_valid_offsets));
+ for (i = 0; i < sizeof(word); ++i)
+ GC_modws_valid_offsets[i] = FALSE;
}
}