void GC_push_finalizer_structures(void) { GC_push_all((ptr_t)(&dl_head), (ptr_t)(&dl_head) + sizeof(word)); GC_push_all((ptr_t)(&fo_head), (ptr_t)(&fo_head) + sizeof(word)); GC_push_all((ptr_t)(&GC_finalize_now), (ptr_t)(&GC_finalize_now) + sizeof(word)); }
/* * A version of GC_push_all that treats all interior pointers as valid * and scans part of the area immediately, to make sure that saved * register values are not lost. * Cold_gc_frame delimits the stack section that must be scanned * eagerly. A zero value indicates that no eager scanning is needed. * We don't need to worry about the MANUAL_VDB case here, since this * is only called in the single-threaded case. We assume that we * cannot collect between an assignment and the corresponding * GC_dirty() call. */ STATIC void GC_push_all_stack_partially_eager(ptr_t bottom, ptr_t top, ptr_t cold_gc_frame) { #ifndef NEED_FIXUP_POINTER if (GC_all_interior_pointers) { /* Push the hot end of the stack eagerly, so that register values */ /* saved inside GC frames are marked before they disappear. */ /* The rest of the marking can be deferred until later. */ if (0 == cold_gc_frame) { GC_push_all_stack(bottom, top); return; } GC_ASSERT((word)bottom <= (word)cold_gc_frame && (word)cold_gc_frame <= (word)top); # ifdef STACK_GROWS_DOWN GC_push_all(cold_gc_frame - sizeof(ptr_t), top); GC_push_all_eager(bottom, cold_gc_frame); # else /* STACK_GROWS_UP */ GC_push_all(bottom, cold_gc_frame + sizeof(ptr_t)); GC_push_all_eager(cold_gc_frame, top); # endif /* STACK_GROWS_UP */ } else #endif /* else */ { GC_push_all_eager(bottom, top); } # ifdef TRACE_BUF GC_add_trace_entry("GC_push_all_stack", (word)bottom, (word)top); # endif }
void GC_push_thread_structures(void) { GC_ASSERT(I_HOLD_LOCK()); if (GC_win32_dll_threads) { /* Unlike the other threads implementations, the thread table here */ /* contains no pointers to the collectable heap. Thus we have */ /* no private structures we need to preserve. */ # ifdef GC_PTHREADS { int i; /* pthreads may keep a pointer in the thread exit value */ LONG my_max = GC_get_max_thread_index(); for (i = 0; i <= my_max; i++) if (dll_thread_table[i].in_use) GC_push_all((ptr_t)&(dll_thread_table[i].status), (ptr_t)(&(dll_thread_table[i].status)+1)); } # endif } else { GC_push_all((ptr_t)(GC_threads), (ptr_t)(GC_threads)+sizeof(GC_threads)); } # if defined(THREAD_LOCAL_ALLOC) GC_push_all((ptr_t)(&GC_thread_key), (ptr_t)(&GC_thread_key)+sizeof(&GC_thread_key)); /* Just in case we ever use our own TLS implementation. */ # endif }
void GC_push_thread_structures(void) { GC_ASSERT(I_HOLD_LOCK()); GC_push_all((ptr_t)(GC_threads), (ptr_t)(GC_threads)+sizeof(GC_threads)); # if defined(THREAD_LOCAL_ALLOC) GC_push_all((ptr_t)(&GC_thread_key), (ptr_t)(&GC_thread_key)+sizeof(&GC_thread_key)); # endif }
GC_INNER void 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); # ifndef GC_LONG_REFS_NOT_NEEDED GC_ASSERT((word)&GC_ll_hashtbl.head % sizeof(word) == 0); GC_push_all((ptr_t)(&GC_ll_hashtbl.head), (ptr_t)(&GC_ll_hashtbl.head) + sizeof(word)); # endif GC_push_all((ptr_t)(&GC_dl_hashtbl.head), (ptr_t)(&GC_dl_hashtbl.head) + sizeof(word)); GC_push_all((ptr_t)(&GC_fo_head), (ptr_t)(&GC_fo_head) + sizeof(word)); GC_push_all((ptr_t)(&GC_finalize_now), (ptr_t)(&GC_finalize_now) + sizeof(word)); }