summaryrefslogtreecommitdiff
path: root/finalize.c
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2015-08-19 10:23:36 +0300
committerIvan Maidanski <ivmai@mail.ru>2015-08-26 11:47:48 +0300
commit8320da593dcc8fa9e99e63bc9c6d4857fc4367ae (patch)
tree7d7f8652a4cf091bd8927e153a76d128d72f04b1 /finalize.c
parent9676e68e4086948002a00faccfe2b5b6b164f011 (diff)
downloadbdwgc-8320da593dcc8fa9e99e63bc9c6d4857fc4367ae.tar.gz
Mark fo_head, finalize_now with a single GC_push_all call
(code refactoring) * finalize.c (GC_fnlz_roots): New static variable. * finalize.c (GC_fo_head, GC_finalize_now): Move into GC_fnlz_roots (remove "GC_" prefix for field names). * finalize.c (GC_push_finalizer_structures): Replace GC_ASSERT and GC_PUSH_ALL_SYM for GC_fo_head, GC_finalize_now with a single GC_ASSERT and GC_PUSH_ALL_SYM for GC_fnlz_roots. * finalize.c (GC_register_finalizer_inner, GC_register_finalizer_unreachable, GC_finalize, GC_should_invoke_finalizers, GC_invoke_finalizers, GC_notify_or_invoke_finalizers): Replace access to GC_fo_head, GC_finalize_now with access to the corresponding field of GC_fnlz_roots.
Diffstat (limited to 'finalize.c')
-rw-r--r--finalize.c103
1 files changed, 52 insertions, 51 deletions
diff --git a/finalize.c b/finalize.c
index beb0d613..dc5022ba 100644
--- a/finalize.c
+++ b/finalize.c
@@ -55,7 +55,7 @@ STATIC struct dl_hashtbl_s GC_dl_hashtbl = {
STATIC struct dl_hashtbl_s GC_ll_hashtbl = { NULL, -1, 0 };
#endif
-STATIC struct finalizable_object {
+struct finalizable_object {
struct hash_chain_entry prolog;
# define fo_hidden_base prolog.hidden_key
/* Pointer to object base. */
@@ -67,25 +67,26 @@ STATIC struct finalizable_object {
ptr_t fo_client_data;
word fo_object_size; /* In bytes. */
finalization_mark_proc fo_mark_proc; /* Mark-through procedure */
-} **GC_fo_head = 0;
-
-STATIC struct finalizable_object * GC_finalize_now = 0;
- /* List of objects that should be finalized now. */
+};
static signed_word log_fo_table_size = -1;
+STATIC struct {
+ struct finalizable_object **fo_head;
+ /* List of objects that should be finalized now: */
+ struct finalizable_object *finalize_now;
+} GC_fnlz_roots = { NULL, NULL };
+
GC_API void GC_CALL GC_push_finalizer_structures(void)
{
GC_ASSERT((word)&GC_dl_hashtbl.head % sizeof(word) == 0);
- GC_ASSERT((word)&GC_fo_head % sizeof(word) == 0);
- GC_ASSERT((word)&GC_finalize_now % sizeof(word) == 0);
+ GC_ASSERT((word)&GC_fnlz_roots % sizeof(word) == 0);
# ifndef GC_LONG_REFS_NOT_NEEDED
GC_ASSERT((word)&GC_ll_hashtbl.head % sizeof(word) == 0);
GC_PUSH_ALL_SYM(GC_ll_hashtbl.head);
# endif
GC_PUSH_ALL_SYM(GC_dl_hashtbl.head);
- GC_PUSH_ALL_SYM(GC_fo_head);
- GC_PUSH_ALL_SYM(GC_finalize_now);
+ GC_PUSH_ALL_SYM(GC_fnlz_roots);
}
/* Double the size of a hash table. *size_ptr is the log of its current */
@@ -466,7 +467,7 @@ STATIC void GC_register_finalizer_inner(void * obj,
LOCK();
if (log_fo_table_size == -1
|| GC_fo_entries > ((word)1 << log_fo_table_size)) {
- GC_grow_table((struct hash_chain_entry ***)&GC_fo_head,
+ GC_grow_table((struct hash_chain_entry ***)&GC_fnlz_roots.fo_head,
&log_fo_table_size);
GC_COND_LOG_PRINTF("Grew fo table to %u entries\n",
1 << (unsigned)log_fo_table_size);
@@ -476,7 +477,7 @@ STATIC void GC_register_finalizer_inner(void * obj,
for (;;) {
index = HASH2(base, log_fo_table_size);
prev_fo = 0;
- curr_fo = GC_fo_head[index];
+ curr_fo = GC_fnlz_roots.fo_head[index];
while (curr_fo != 0) {
GC_ASSERT(GC_size(curr_fo) >= sizeof(struct finalizable_object));
if (curr_fo -> fo_hidden_base == GC_HIDE_POINTER(base)) {
@@ -487,7 +488,7 @@ STATIC void GC_register_finalizer_inner(void * obj,
if (ofn) *ofn = curr_fo -> fo_fn;
/* Delete the structure for base. */
if (prev_fo == 0) {
- GC_fo_head[index] = fo_next(curr_fo);
+ GC_fnlz_roots.fo_head[index] = fo_next(curr_fo);
} else {
fo_set_next(prev_fo, fo_next(curr_fo));
}
@@ -506,7 +507,7 @@ STATIC void GC_register_finalizer_inner(void * obj,
/* Reinsert it. We deleted it first to maintain */
/* consistency in the event of a signal. */
if (prev_fo == 0) {
- GC_fo_head[index] = curr_fo;
+ GC_fnlz_roots.fo_head[index] = curr_fo;
} else {
fo_set_next(prev_fo, curr_fo);
}
@@ -566,9 +567,9 @@ STATIC void GC_register_finalizer_inner(void * obj,
new_fo -> fo_client_data = (ptr_t)cd;
new_fo -> fo_object_size = hhdr -> hb_sz;
new_fo -> fo_mark_proc = mp;
- fo_set_next(new_fo, GC_fo_head[index]);
+ fo_set_next(new_fo, GC_fnlz_roots.fo_head[index]);
GC_fo_entries++;
- GC_fo_head[index] = new_fo;
+ GC_fnlz_roots.fo_head[index] = new_fo;
UNLOCK();
}
@@ -644,8 +645,8 @@ GC_API void GC_CALL GC_register_finalizer_unreachable(void * obj,
# endif
GC_printf("Finalizers:\n");
for (i = 0; i < fo_size; i++) {
- for (curr_fo = GC_fo_head[i]; curr_fo != 0;
- curr_fo = fo_next(curr_fo)) {
+ for (curr_fo = GC_fnlz_roots.fo_head[i];
+ curr_fo != NULL; curr_fo = fo_next(curr_fo)) {
real_ptr = GC_REVEAL_POINTER(curr_fo -> fo_hidden_base);
GC_printf("Finalizable object: %p\n", real_ptr);
}
@@ -775,8 +776,8 @@ GC_INNER void GC_finalize(void)
/* from finalizable objects. */
GC_ASSERT(GC_mark_state == MS_NONE);
for (i = 0; i < fo_size; i++) {
- for (curr_fo = GC_fo_head[i]; curr_fo != 0;
- curr_fo = fo_next(curr_fo)) {
+ for (curr_fo = GC_fnlz_roots.fo_head[i];
+ curr_fo != NULL; curr_fo = fo_next(curr_fo)) {
GC_ASSERT(GC_size(curr_fo) >= sizeof(struct finalizable_object));
real_ptr = GC_REVEAL_POINTER(curr_fo -> fo_hidden_base);
if (!GC_is_marked(real_ptr)) {
@@ -792,7 +793,7 @@ GC_INNER void GC_finalize(void)
/* unreachable. */
GC_bytes_finalized = 0;
for (i = 0; i < fo_size; i++) {
- curr_fo = GC_fo_head[i];
+ curr_fo = GC_fnlz_roots.fo_head[i];
prev_fo = 0;
while (curr_fo != 0) {
real_ptr = GC_REVEAL_POINTER(curr_fo -> fo_hidden_base);
@@ -802,8 +803,8 @@ GC_INNER void GC_finalize(void)
}
/* Delete from hash table */
next_fo = fo_next(curr_fo);
- if (prev_fo == 0) {
- GC_fo_head[i] = next_fo;
+ if (NULL == prev_fo) {
+ GC_fnlz_roots.fo_head[i] = next_fo;
} else {
fo_set_next(prev_fo, next_fo);
}
@@ -812,8 +813,8 @@ GC_INNER void GC_finalize(void)
GC_object_finalized_proc(real_ptr);
/* Add to list of objects awaiting finalization. */
- fo_set_next(curr_fo, GC_finalize_now);
- GC_finalize_now = curr_fo;
+ fo_set_next(curr_fo, GC_fnlz_roots.finalize_now);
+ GC_fnlz_roots.finalize_now = curr_fo;
/* unhide object pointer so any future collections will */
/* see it. */
curr_fo -> fo_hidden_base =
@@ -833,8 +834,8 @@ GC_INNER void GC_finalize(void)
if (GC_java_finalization) {
/* make sure we mark everything reachable from objects finalized
using the no_order mark_proc */
- for (curr_fo = GC_finalize_now;
- curr_fo != NULL; curr_fo = fo_next(curr_fo)) {
+ for (curr_fo = GC_fnlz_roots.finalize_now;
+ curr_fo != NULL; curr_fo = fo_next(curr_fo)) {
real_ptr = (ptr_t)curr_fo -> fo_hidden_base;
if (!GC_is_marked(real_ptr)) {
if (curr_fo -> fo_mark_proc == GC_null_finalize_mark_proc) {
@@ -849,29 +850,29 @@ GC_INNER void GC_finalize(void)
/* now revive finalize-when-unreachable objects reachable from
other finalizable objects */
if (need_unreachable_finalization) {
- curr_fo = GC_finalize_now;
- prev_fo = 0;
- while (curr_fo != 0) {
+ curr_fo = GC_fnlz_roots.finalize_now;
+ prev_fo = NULL;
+ while (curr_fo != NULL) {
next_fo = fo_next(curr_fo);
if (curr_fo -> fo_mark_proc == GC_unreachable_finalize_mark_proc) {
real_ptr = (ptr_t)curr_fo -> fo_hidden_base;
if (!GC_is_marked(real_ptr)) {
GC_set_mark_bit(real_ptr);
} else {
- if (prev_fo == 0)
- GC_finalize_now = next_fo;
- else
+ if (NULL == prev_fo) {
+ GC_fnlz_roots.finalize_now = next_fo;
+ } else {
fo_set_next(prev_fo, next_fo);
-
+ }
curr_fo -> fo_hidden_base =
GC_HIDE_POINTER(curr_fo -> fo_hidden_base);
GC_bytes_finalized -=
curr_fo->fo_object_size + sizeof(struct finalizable_object);
i = HASH2(real_ptr, log_fo_table_size);
- fo_set_next (curr_fo, GC_fo_head[i]);
+ fo_set_next(curr_fo, GC_fnlz_roots.fo_head[i]);
GC_fo_entries++;
- GC_fo_head[i] = curr_fo;
+ GC_fnlz_roots.fo_head[i] = curr_fo;
curr_fo = prev_fo;
}
}
@@ -911,9 +912,9 @@ GC_INNER void GC_finalize(void)
fo_size = log_fo_table_size == -1 ? 0 : 1 << log_fo_table_size;
GC_bytes_finalized = 0;
for (i = 0; i < fo_size; i++) {
- curr_fo = GC_fo_head[i];
- prev_fo = 0;
- while (curr_fo != 0) {
+ curr_fo = GC_fnlz_roots.fo_head[i];
+ prev_fo = NULL;
+ while (curr_fo != NULL) {
real_ptr = GC_REVEAL_POINTER(curr_fo -> fo_hidden_base);
GC_MARK_FO(real_ptr, GC_normal_finalize_mark_proc);
GC_set_mark_bit(real_ptr);
@@ -921,15 +922,15 @@ GC_INNER void GC_finalize(void)
/* Delete from hash table */
next_fo = fo_next(curr_fo);
if (prev_fo == 0) {
- GC_fo_head[i] = next_fo;
+ GC_fnlz_roots.fo_head[i] = next_fo;
} else {
- fo_set_next(prev_fo, next_fo);
+ fo_set_next(prev_fo, next_fo);
}
GC_fo_entries--;
/* Add to list of objects awaiting finalization. */
- fo_set_next(curr_fo, GC_finalize_now);
- GC_finalize_now = curr_fo;
+ fo_set_next(curr_fo, GC_fnlz_roots.finalize_now);
+ GC_fnlz_roots.finalize_now = curr_fo;
/* unhide object pointer so any future collections will */
/* see it. */
@@ -981,7 +982,7 @@ GC_INNER void GC_finalize(void)
/* getting into that safe state is expensive.) */
GC_API int GC_CALL GC_should_invoke_finalizers(void)
{
- return GC_finalize_now != 0;
+ return GC_fnlz_roots.finalize_now != NULL;
}
/* Invoke finalizers for all objects that are ready to be finalized. */
@@ -993,7 +994,7 @@ GC_API int GC_CALL GC_invoke_finalizers(void)
word bytes_freed_before = 0; /* initialized to prevent warning. */
DCL_LOCK_STATE;
- while (GC_finalize_now != 0) {
+ while (GC_fnlz_roots.finalize_now != NULL) {
# ifdef THREADS
LOCK();
# endif
@@ -1001,13 +1002,13 @@ GC_API int GC_CALL GC_invoke_finalizers(void)
bytes_freed_before = GC_bytes_freed;
/* Don't do this outside, since we need the lock. */
}
- curr_fo = GC_finalize_now;
+ curr_fo = GC_fnlz_roots.finalize_now;
# ifdef THREADS
- if (curr_fo != 0) GC_finalize_now = fo_next(curr_fo);
+ if (curr_fo != 0) GC_fnlz_roots.finalize_now = fo_next(curr_fo);
UNLOCK();
if (curr_fo == 0) break;
# else
- GC_finalize_now = fo_next(curr_fo);
+ GC_fnlz_roots.finalize_now = fo_next(curr_fo);
# endif
fo_set_next(curr_fo, 0);
(*(curr_fo -> fo_fn))((ptr_t)(curr_fo -> fo_hidden_base),
@@ -1043,7 +1044,7 @@ GC_INNER void GC_notify_or_invoke_finalizers(void)
# if defined(THREADS) && !defined(KEEP_BACK_PTRS) \
&& !defined(MAKE_BACK_GRAPH)
/* Quick check (while unlocked) for an empty finalization queue. */
- if (GC_finalize_now == 0) return;
+ if (NULL == GC_fnlz_roots.finalize_now) return;
# endif
LOCK();
@@ -1075,7 +1076,7 @@ GC_INNER void GC_notify_or_invoke_finalizers(void)
# endif
}
# endif
- if (GC_finalize_now == 0) {
+ if (NULL == GC_fnlz_roots.finalize_now) {
UNLOCK();
return;
}
@@ -1088,7 +1089,7 @@ GC_INNER void GC_notify_or_invoke_finalizers(void)
(void) GC_invoke_finalizers();
*pnested = 0; /* Reset since no more finalizers. */
# ifndef THREADS
- GC_ASSERT(GC_finalize_now == 0);
+ GC_ASSERT(NULL == GC_fnlz_roots.finalize_now);
# endif /* Otherwise GC can run concurrently and add more */
}
return;
@@ -1123,7 +1124,7 @@ GC_INNER void GC_notify_or_invoke_finalizers(void)
(unsigned long)IF_LONG_REFS_PRESENT_ELSE(
GC_ll_hashtbl.entries, 0));
- for (fo = GC_finalize_now; 0 != fo; fo = fo_next(fo))
+ for (fo = GC_fnlz_roots.finalize_now; fo != NULL; fo = fo_next(fo))
++ready;
GC_log_printf("%lu finalization-ready objects;"
" %ld/%ld short/long links cleared\n",