summaryrefslogtreecommitdiff
path: root/finalize.c
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2018-05-18 10:58:54 +0300
committerIvan Maidanski <ivmai@mail.ru>2018-05-18 10:58:54 +0300
commit73d30d2b4f7b16473c38036a5ad409deb296ac4a (patch)
tree2a7af440e09d179a7bbad1da6b5c542fd9c900dc /finalize.c
parentf30c01500208d4c459986a32cd4e36bc2a483789 (diff)
downloadbdwgc-73d30d2b4f7b16473c38036a5ad409deb296ac4a.tar.gz
Fix missing GC_dirty calls for GC-allocated objects used internally
This change matters only in case of MANUAL_VDB mode. * finalize.c (GC_grow_table, GC_register_disappearing_link, GC_unregister_disappearing_link_inner, GC_process_togglerefs, GC_toggleref_add, GC_move_disappearing_link_inner, GC_register_finalizer_inner, ITERATE_DL_HASHTBL_END, DELETE_DL_HASHTBL_ENTRY, GC_finalize, GC_enqueue_all_finalizers): Call GC_dirty where needed. * gcj_mlc.c [GC_GCJ_SUPPORT] (GC_gcj_malloc, GC_debug_gcj_malloc, GC_gcj_malloc_ignore_off_page): Likewise. * pthread_start.c [GC_PTHREADS && !GC_WIN32_THREADS] (GC_inner_start_routine): Likewise. * pthread_support.c [GC_PTHREADS && !GC_WIN32_THREADS] (GC_new_thread, GC_delete_thread, GC_delete_gc_thread): Likewise. * specific.c [USE_CUSTOM_SPECIFIC] (GC_setspecific, GC_remove_specific_after_fork): Likewise. * typd_mlc.c (GC_make_sequence_descriptor, GC_malloc_explicitly_typed, GC_malloc_explicitly_typed_ignore_off_page, GC_calloc_explicitly_typed): Likewise. * win32_threads.c (GC_new_thread, GC_delete_gc_thread_no_free, GC_delete_thread, GC_CreateThread): Likewise. * win32_threads.c [!CYGWIN32 && !MSWINCE && !MSWIN_XBOX1] (GC_beginthreadex): Likewise. * win32_threads.c [GC_PTHREADS] (GC_pthread_create, GC_pthread_start_inner): Likewise. * include/gc_inline.h (GC_FAST_MALLOC_GRANS): Call GC_end_stubborn_change(my_fl) after GC_FAST_M_AO_STORE() call unless kind is GC_I_PTRFREE. * include/gc_inline.h (GC_CONS): Call GC_end_stubborn_change(result).
Diffstat (limited to 'finalize.c')
-rw-r--r--finalize.c40
1 files changed, 39 insertions, 1 deletions
diff --git a/finalize.c b/finalize.c
index 1fc7a2ed..c73febe0 100644
--- a/finalize.c
+++ b/finalize.c
@@ -154,12 +154,14 @@ STATIC void GC_grow_table(struct hash_chain_entry ***table,
size_t new_hash = HASH3(real_key, new_size, log_new_size);
p -> next = new_table[new_hash];
+ GC_dirty(p);
new_table[new_hash] = p;
p = next;
}
}
*log_size_ptr = log_new_size;
*table = new_table;
+ GC_dirty(new_table); /* entire object */
}
GC_API int GC_CALL GC_register_disappearing_link(void * * link)
@@ -236,7 +238,9 @@ STATIC int GC_register_disappearing_link_inner(
dl_set_next(new_dl, dl_hashtbl -> head[index]);
dl_hashtbl -> head[index] = new_dl;
dl_hashtbl -> entries++;
+ GC_dirty(dl_hashtbl->head + index);
UNLOCK();
+ GC_dirty(new_dl);
return GC_SUCCESS;
}
@@ -274,8 +278,10 @@ GC_INLINE struct disappearing_link *GC_unregister_disappearing_link_inner(
/* Remove found entry from the table. */
if (NULL == prev_dl) {
dl_hashtbl -> head[index] = dl_next(curr_dl);
+ GC_dirty(dl_hashtbl->head + index);
} else {
dl_set_next(prev_dl, dl_next(curr_dl));
+ GC_dirty(prev_dl);
}
dl_hashtbl -> entries--;
break;
@@ -317,6 +323,7 @@ GC_API int GC_CALL GC_unregister_disappearing_link(void * * link)
{
int i;
int new_size = 0;
+ GC_bool needs_barrier = FALSE;
GC_ASSERT(I_HOLD_LOCK());
for (i = 0; i < GC_toggleref_array_size; ++i) {
@@ -334,6 +341,7 @@ GC_API int GC_CALL GC_unregister_disappearing_link(void * * link)
break;
case GC_TOGGLE_REF_STRONG:
GC_toggleref_arr[new_size++].strong_ref = obj;
+ needs_barrier = TRUE;
break;
case GC_TOGGLE_REF_WEAK:
GC_toggleref_arr[new_size++].weak_ref = GC_HIDE_POINTER(obj);
@@ -348,6 +356,8 @@ GC_API int GC_CALL GC_unregister_disappearing_link(void * * link)
(GC_toggleref_array_size - new_size) * sizeof(GCToggleRef));
GC_toggleref_array_size = new_size;
}
+ if (needs_barrier)
+ GC_dirty(GC_toggleref_arr); /* entire object */
}
STATIC void GC_normal_finalize_mark_proc(ptr_t);
@@ -463,8 +473,11 @@ GC_API int GC_CALL GC_unregister_disappearing_link(void * * link)
if (!ensure_toggleref_capacity(1)) {
res = GC_NO_MEMORY;
} else {
- GC_toggleref_arr[GC_toggleref_array_size++].strong_ref =
+ GC_toggleref_arr[GC_toggleref_array_size].strong_ref =
is_strong_ref ? obj : (void *)GC_HIDE_POINTER(obj);
+ if (is_strong_ref)
+ GC_dirty(GC_toggleref_arr + GC_toggleref_array_size);
+ GC_toggleref_array_size++;
}
}
UNLOCK();
@@ -570,10 +583,13 @@ GC_API GC_await_finalize_proc GC_CALL GC_get_await_finalize_proc(void)
dl_hashtbl -> head[curr_index] = dl_next(curr_dl);
} else {
dl_set_next(prev_dl, dl_next(curr_dl));
+ GC_dirty(prev_dl);
}
curr_dl -> dl_hidden_link = new_hidden_link;
dl_set_next(curr_dl, dl_hashtbl -> head[new_index]);
dl_hashtbl -> head[new_index] = curr_dl;
+ GC_dirty(curr_dl);
+ GC_dirty(dl_hashtbl->head); /* entire object */
return GC_SUCCESS;
}
@@ -712,6 +728,7 @@ STATIC void GC_register_finalizer_inner(void * obj,
GC_fnlz_roots.fo_head[index] = fo_next(curr_fo);
} else {
fo_set_next(prev_fo, fo_next(curr_fo));
+ GC_dirty(prev_fo);
}
if (fn == 0) {
GC_fo_entries--;
@@ -725,14 +742,18 @@ STATIC void GC_register_finalizer_inner(void * obj,
curr_fo -> fo_fn = fn;
curr_fo -> fo_client_data = (ptr_t)cd;
curr_fo -> fo_mark_proc = mp;
+ GC_dirty(curr_fo);
/* Reinsert it. We deleted it first to maintain */
/* consistency in the event of a signal. */
if (prev_fo == 0) {
GC_fnlz_roots.fo_head[index] = curr_fo;
} else {
fo_set_next(prev_fo, curr_fo);
+ GC_dirty(prev_fo);
}
}
+ if (NULL == prev_fo)
+ GC_dirty(GC_fnlz_roots.fo_head + index);
UNLOCK();
# ifndef DBG_HDRS_ALL
if (EXPECT(new_fo != 0, FALSE)) {
@@ -795,7 +816,9 @@ STATIC void GC_register_finalizer_inner(void * obj,
fo_set_next(new_fo, GC_fnlz_roots.fo_head[index]);
GC_fo_entries++;
GC_fnlz_roots.fo_head[index] = new_fo;
+ GC_dirty(GC_fnlz_roots.fo_head + index);
UNLOCK();
+ GC_dirty(new_fo);
}
GC_API void GC_CALL GC_register_finalizer(void * obj,
@@ -922,6 +945,7 @@ GC_API void GC_CALL GC_register_finalizer_unreachable(void * obj,
size_t i; \
size_t dl_size = dl_hashtbl->log_size == -1 ? 0 : \
(size_t)1 << dl_hashtbl->log_size; \
+ GC_bool needs_barrier = FALSE; \
GC_ASSERT(I_HOLD_LOCK()); \
for (i = 0; i < dl_size; i++) { \
struct disappearing_link *prev_dl = NULL; \
@@ -933,6 +957,8 @@ GC_API void GC_CALL GC_register_finalizer_unreachable(void * obj,
curr_dl = dl_next(curr_dl); \
} \
} \
+ if (needs_barrier) \
+ GC_dirty(dl_hashtbl -> head); /* entire object */ \
}
#define DELETE_DL_HASHTBL_ENTRY(dl_hashtbl, curr_dl, prev_dl, next_dl) \
@@ -940,8 +966,10 @@ GC_API void GC_CALL GC_register_finalizer_unreachable(void * obj,
next_dl = dl_next(curr_dl); \
if (NULL == prev_dl) { \
dl_hashtbl -> head[i] = next_dl; \
+ needs_barrier = TRUE; \
} else { \
dl_set_next(prev_dl, next_dl); \
+ GC_dirty(prev_dl); \
} \
GC_clear_mark_bit(curr_dl); \
dl_hashtbl -> entries--; \
@@ -992,6 +1020,7 @@ GC_INNER void GC_finalize(void)
size_t i;
size_t fo_size = log_fo_table_size == -1 ? 0 :
(size_t)1 << log_fo_table_size;
+ GC_bool needs_barrier = FALSE;
GC_ASSERT(I_HOLD_LOCK());
# ifndef SMALL_CONFIG
@@ -1040,8 +1069,10 @@ GC_INNER void GC_finalize(void)
next_fo = fo_next(curr_fo);
if (NULL == prev_fo) {
GC_fnlz_roots.fo_head[i] = next_fo;
+ needs_barrier = TRUE;
} else {
fo_set_next(prev_fo, next_fo);
+ GC_dirty(prev_fo);
}
GC_fo_entries--;
if (GC_object_finalized_proc)
@@ -1049,6 +1080,7 @@ GC_INNER void GC_finalize(void)
/* Add to list of objects awaiting finalization. */
fo_set_next(curr_fo, GC_fnlz_roots.finalize_now);
+ GC_dirty(curr_fo);
SET_FINALIZE_NOW(curr_fo);
/* unhide object pointer so any future collections will */
/* see it. */
@@ -1102,6 +1134,7 @@ GC_INNER void GC_finalize(void)
SET_FINALIZE_NOW(next_fo);
} else {
fo_set_next(prev_fo, next_fo);
+ GC_dirty(prev_fo);
}
curr_fo -> fo_hidden_base =
GC_HIDE_POINTER(curr_fo -> fo_hidden_base);
@@ -1110,9 +1143,11 @@ GC_INNER void GC_finalize(void)
i = HASH2(real_ptr, log_fo_table_size);
fo_set_next(curr_fo, GC_fnlz_roots.fo_head[i]);
+ GC_dirty(curr_fo);
GC_fo_entries++;
GC_fnlz_roots.fo_head[i] = curr_fo;
curr_fo = prev_fo;
+ needs_barrier = TRUE;
}
}
prev_fo = curr_fo;
@@ -1120,6 +1155,8 @@ GC_INNER void GC_finalize(void)
}
}
}
+ if (needs_barrier)
+ GC_dirty(GC_fnlz_roots.fo_head); /* entire object */
GC_remove_dangling_disappearing_links(&GC_dl_hashtbl);
# ifndef GC_TOGGLE_REFS_NOT_NEEDED
@@ -1167,6 +1204,7 @@ GC_INNER void GC_finalize(void)
/* Add to list of objects awaiting finalization. */
fo_set_next(curr_fo, GC_fnlz_roots.finalize_now);
+ GC_dirty(curr_fo);
SET_FINALIZE_NOW(curr_fo);
/* unhide object pointer so any future collections will */