diff options
author | Ivan Maidanski <ivmai@mail.ru> | 2018-05-18 10:58:54 +0300 |
---|---|---|
committer | Ivan Maidanski <ivmai@mail.ru> | 2018-05-18 10:58:54 +0300 |
commit | 73d30d2b4f7b16473c38036a5ad409deb296ac4a (patch) | |
tree | 2a7af440e09d179a7bbad1da6b5c542fd9c900dc /finalize.c | |
parent | f30c01500208d4c459986a32cd4e36bc2a483789 (diff) | |
download | bdwgc-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.c | 40 |
1 files changed, 39 insertions, 1 deletions
@@ -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 */ |