+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;
}
#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();
#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 */
#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)
{
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) {
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)
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;
}
}