📄 gc_priv.h
字号:
word GC_words_allocd; /* Number of words allocated during this collection cycle */ ptr_t GC_objfreelist[MAXOBJSZ+1]; /* free list for NORMAL objects */# define beginGC_objfreelist ((ptr_t)(&GC_objfreelist))# define endGC_objfreelist (beginGC_objfreelist + sizeof(GC_objfreelist)) ptr_t GC_aobjfreelist[MAXOBJSZ+1]; /* free list for atomic (PTRFREE) objs */# define beginGC_aobjfreelist ((ptr_t)(&GC_aobjfreelist))# define endGC_aobjfreelist (beginGC_aobjfreelist + sizeof(GC_aobjfreelist))#endif/* Predefined kinds: */# define PTRFREE 0# define NORMAL 1# define UNCOLLECTABLE 2# ifdef ATOMIC_UNCOLLECTABLE# define AUNCOLLECTABLE 3# define STUBBORN 4# define IS_UNCOLLECTABLE(k) (((k) & ~1) == UNCOLLECTABLE)# else# define STUBBORN 3# define IS_UNCOLLECTABLE(k) ((k) == UNCOLLECTABLE)# endifextern int GC_n_kinds;GC_API word GC_fo_entries;extern word GC_n_heap_sects; /* Number of separately added heap */ /* sections. */extern word GC_page_size;# if defined(MSWIN32) || defined(MSWINCE) struct _SYSTEM_INFO; extern struct _SYSTEM_INFO GC_sysinfo; extern word GC_n_heap_bases; /* See GC_heap_bases. */# endifextern word GC_total_stack_black_listed; /* Number of bytes on stack blacklist. */extern word GC_black_list_spacing; /* Average number of bytes between blacklisted */ /* blocks. Approximate. */ /* Counts only blocks that are */ /* "stack-blacklisted", i.e. that are */ /* problematic in the interior of an object. */extern map_entry_type * GC_invalid_map; /* Pointer to the nowhere valid hblk map */ /* Blocks pointing to this map are free. */extern struct hblk * GC_hblkfreelist[]; /* List of completely empty heap blocks */ /* Linked through hb_next field of */ /* header structure associated with */ /* block. */extern GC_bool GC_objects_are_marked; /* There are marked objects in */ /* the heap. */#ifndef SMALL_CONFIG extern GC_bool GC_incremental; /* Using incremental/generational collection. */# define TRUE_INCREMENTAL \ (GC_incremental && GC_time_limit != GC_TIME_UNLIMITED) /* True incremental, not just generational, mode */#else# define GC_incremental FALSE /* Hopefully allow optimizer to remove some code. */# define TRUE_INCREMENTAL FALSE#endifextern GC_bool GC_dirty_maintained; /* Dirty bits are being maintained, */ /* either for incremental collection, */ /* or to limit the root set. */extern word GC_root_size; /* Total size of registered root sections */extern GC_bool GC_debugging_started; /* GC_debug_malloc has been called. */ extern long GC_large_alloc_warn_interval; /* Interval between unsuppressed warnings. */extern long GC_large_alloc_warn_suppressed; /* Number of warnings suppressed so far. */#ifdef THREADS extern GC_bool GC_world_stopped;#endif/* Operations */# ifndef abs# define abs(x) ((x) < 0? (-(x)) : (x))# endif/* Marks are in a reserved area in *//* each heap block. Each word has one mark bit associated *//* with it. Only those corresponding to the beginning of an *//* object are used. *//* Set mark bit correctly, even if mark bits may be concurrently *//* accessed. */#ifdef PARALLEL_MARK# define OR_WORD(addr, bits) \ { word old; \ do { \ old = *((volatile word *)addr); \ } while (!GC_compare_and_exchange((addr), old, old | (bits))); \ }# define OR_WORD_EXIT_IF_SET(addr, bits, exit_label) \ { word old; \ word my_bits = (bits); \ do { \ old = *((volatile word *)addr); \ if (old & my_bits) goto exit_label; \ } while (!GC_compare_and_exchange((addr), old, old | my_bits)); \ }#else# define OR_WORD(addr, bits) *(addr) |= (bits)# define OR_WORD_EXIT_IF_SET(addr, bits, exit_label) \ { \ word old = *(addr); \ word my_bits = (bits); \ if (old & my_bits) goto exit_label; \ *(addr) = (old | my_bits); \ }#endif/* Mark bit operations *//* * Retrieve, set, clear the mark bit corresponding * to the nth word in a given heap block. * * (Recall that bit n corresponds to object beginning at word n * relative to the beginning of the block, including unused words) */#ifdef USE_MARK_BYTES# define mark_bit_from_hdr(hhdr,n) ((hhdr)->hb_marks[(n) >> 1])# define set_mark_bit_from_hdr(hhdr,n) ((hhdr)->hb_marks[(n)>>1]) = 1# define clear_mark_bit_from_hdr(hhdr,n) ((hhdr)->hb_marks[(n)>>1]) = 0#else /* !USE_MARK_BYTES */# define mark_bit_from_hdr(hhdr,n) (((hhdr)->hb_marks[divWORDSZ(n)] \ >> (modWORDSZ(n))) & (word)1)# define set_mark_bit_from_hdr(hhdr,n) \ OR_WORD((hhdr)->hb_marks+divWORDSZ(n), \ (word)1 << modWORDSZ(n))# define clear_mark_bit_from_hdr(hhdr,n) (hhdr)->hb_marks[divWORDSZ(n)] \ &= ~((word)1 << modWORDSZ(n))#endif /* !USE_MARK_BYTES *//* Important internal collector routines */ptr_t GC_approx_sp GC_PROTO((void)); GC_bool GC_should_collect GC_PROTO((void)); void GC_apply_to_all_blocks GC_PROTO(( \ void (*fn) GC_PROTO((struct hblk *h, word client_data)), \ word client_data)); /* Invoke fn(hbp, client_data) for each */ /* allocated heap block. */struct hblk * GC_next_used_block GC_PROTO((struct hblk * h)); /* Return first in-use block >= h */struct hblk * GC_prev_block GC_PROTO((struct hblk * h)); /* Return last block <= h. Returned block */ /* is managed by GC, but may or may not be in */ /* use. */void GC_mark_init GC_PROTO((void));void GC_clear_marks GC_PROTO((void)); /* Clear mark bits for all heap objects. */void GC_invalidate_mark_state GC_PROTO((void)); /* Tell the marker that marked */ /* objects may point to unmarked */ /* ones, and roots may point to */ /* unmarked objects. */ /* Reset mark stack. */GC_bool GC_mark_stack_empty GC_PROTO((void));GC_bool GC_mark_some GC_PROTO((ptr_t cold_gc_frame)); /* Perform about one pages worth of marking */ /* work of whatever kind is needed. Returns */ /* quickly if no collection is in progress. */ /* Return TRUE if mark phase finished. */void GC_initiate_gc GC_PROTO((void)); /* initiate collection. */ /* If the mark state is invalid, this */ /* becomes full colleection. Otherwise */ /* it's partial. */void GC_push_all GC_PROTO((ptr_t bottom, ptr_t top)); /* Push everything in a range */ /* onto mark stack. */void GC_push_selected GC_PROTO(( \ ptr_t bottom, \ ptr_t top, \ int (*dirty_fn) GC_PROTO((struct hblk *h)), \ void (*push_fn) GC_PROTO((ptr_t bottom, ptr_t top)) )); /* Push all pages h in [b,t) s.t. */ /* select_fn(h) != 0 onto mark stack. */#ifndef SMALL_CONFIG void GC_push_conditional GC_PROTO((ptr_t b, ptr_t t, GC_bool all));#else# define GC_push_conditional(b, t, all) GC_push_all(b, t)#endif /* Do either of the above, depending */ /* on the third arg. */void GC_push_all_stack GC_PROTO((ptr_t b, ptr_t t)); /* As above, but consider */ /* interior pointers as valid */void GC_push_all_eager GC_PROTO((ptr_t b, ptr_t t)); /* Same as GC_push_all_stack, but */ /* ensures that stack is scanned */ /* immediately, not just scheduled */ /* for scanning. */#ifndef THREADS void GC_push_all_stack_partially_eager GC_PROTO(( \ ptr_t bottom, ptr_t top, ptr_t cold_gc_frame )); /* Similar to GC_push_all_eager, but only the */ /* part hotter than cold_gc_frame is scanned */ /* immediately. Needed to ensure that callee- */ /* save registers are not missed. */#else /* In the threads case, we push part of the current thread stack */ /* with GC_push_all_eager when we push the registers. This gets the */ /* callee-save registers that may disappear. The remainder of the */ /* stacks are scheduled for scanning in *GC_push_other_roots, which */ /* is thread-package-specific. */#endifvoid GC_push_current_stack GC_PROTO((ptr_t cold_gc_frame)); /* Push enough of the current stack eagerly to */ /* ensure that callee-save registers saved in */ /* GC frames are scanned. */ /* In the non-threads case, schedule entire */ /* stack for scanning. */void GC_push_roots GC_PROTO((GC_bool all, ptr_t cold_gc_frame)); /* Push all or dirty roots. */extern void (*GC_push_other_roots) GC_PROTO((void)); /* Push system or application specific roots */ /* onto the mark stack. In some environments */ /* (e.g. threads environments) this is */ /* predfined to be non-zero. A client supplied */ /* replacement should also call the original */ /* function. */extern void GC_push_gc_structures GC_PROTO((void)); /* Push GC internal roots. These are normally */ /* included in the static data segment, and */ /* Thus implicitly pushed. But we must do this */ /* explicitly if normal root processing is */ /* disabled. Calls the following: */ extern void GC_push_finalizer_structures GC_PROTO((void)); extern void GC_push_stubborn_structures GC_PROTO((void));# ifdef THREADS extern void GC_push_thread_structures GC_PROTO((void));# endifextern void (*GC_start_call_back) GC_PROTO((void)); /* Called at start of full collections. */ /* Not called if 0. Called with allocation */ /* lock held. */ /* 0 by default. */# if defined(USE_GENERIC_PUSH_REGS) void GC_generic_push_regs GC_PROTO((ptr_t cold_gc_frame));# else void GC_push_regs GC_PROTO((void));# endif# if defined(SPARC) || defined(IA64) /* Cause all stacked registers to be saved in memory. Return a */ /* pointer to the top of the corresponding memory stack. */ word GC_save_regs_in_stack GC_PROTO((void));# endif /* Push register contents onto mark stack. */ /* If NURSERY is defined, the default push */ /* action can be overridden with GC_push_proc */# ifdef NURSERY extern void (*GC_push_proc)(ptr_t);# endif# if defined(MSWIN32) || defined(MSWINCE) void __cdecl GC_push_one GC_PROTO((word p));# else void GC_push_one GC_PROTO((word p)); /* If p points to an object, mark it */ /* and push contents on the mark stack */ /* Pointer recognition test always */ /* accepts interior pointers, i.e. this */ /* is appropriate for pointers found on */ /* stack. */# endif# if defined(PRINT_BLACK_LIST) || defined(KEEP_BACK_PTRS) void GC_mark_and_push_stack GC_PROTO((word p, ptr_t source)); /* Ditto, omits plausibility test */# else void GC_mark_and_push_stack GC_PROTO((word p));# endifvoid GC_push_marked GC_PROTO((struct hblk * h, hdr * hhdr)); /* Push contents of all marked objects in h onto */ /* mark stack. */#ifdef SMALL_CONFIG# define GC_push_next_marked_dirty(h) GC_push_next_marked(h)#else struct hblk * GC_push_next_marked_dirty GC_PROTO((struct hblk * h)); /* Invoke GC_push_marked on next dirty block above h. */ /* Return a pointer just past the end of this block. */#endif /* !SMALL_CONFIG */struct hblk * GC_push_next_marked GC_PROTO((struct hblk * h)); /* Ditto, but also mark from clean pages. */struct hblk * GC_push_next_marked_uncollectable GC_PROTO((struct hblk * h)); /* Ditto, but mark only from uncollectable pages. */GC_bool GC_stopped_mark GC_PROTO((GC_stop_func stop_func)); /* Stop world and mark from all roots */ /* and rescuers. */void GC_clear_hdr_marks GC_PROTO((hdr * hhdr)); /* Clear the mark bits in a header */void GC_set_hdr_marks GC_PROTO((hdr * hhdr)); /* Set the mark bits in a header */void GC_set_fl_marks GC_PROTO((ptr_t p)); /* Set all mark bits associated with */ /* a free list. */void GC_add_roots_inner GC_PROTO((char * b, char * e, GC_bool tmp));void GC_remove_roots_inner GC_PROTO((char * b, char * e));GC_bool GC_is_static_root GC_PROTO((ptr_t p)); /* Is the address p in one of the registered static */ /* root sections? */# if defined(MSWIN32) || defined(_WIN32_WCE_EMULATION)GC_bool GC_is_tmp_root GC_PROTO((ptr_t p)); /* Is the address p in one of the temporary static */ /* root sections? */# endifvoid GC_register_dynamic_libraries GC_PROTO((void)); /* Add dynamic library data sections to the root set. */GC_bool GC_register_main_static_data GC_PROTO((void)); /* We need to register the main data segment. Returns */ /* TRUE unless this is done implicitly as part of */ /* dynamic library registration. */ /* Machine dependent startup routines */ptr_t GC_get_stack_base GC_PROTO((void)); /* Cold end of stack */#ifdef IA64 ptr_t GC_get_register_stack_base GC_PROTO((void)); /* Cold end of register stack. */#endifvoid GC_register_data_segments GC_PROTO((void)); /* Black listing: */void GC_bl_init GC_PROTO((void));# ifdef PRINT_BLACK_LIST void GC_add_to_black_list_normal GC_PROTO((word p, ptr_t source)); /* Register bits as a possible future false */ /* reference from the heap or static data */# define GC_ADD_TO_BLACK_LIST_NORMAL(bits, source) \ if (GC_all_interior_pointers) { \ GC_add_to_black_list_stack(bits, (ptr_t)(source)); \ } else { \ GC_add_to_black_list_normal(bits, (ptr_t)(source)); \ }# else void GC_add_to_black_list_normal GC_PROTO((word p));# define GC_ADD_TO_BLACK_LIST_NORMAL(bits, source) \ if (GC_all_interior_pointers) { \ GC_add_to_black_list_stack(bits); \ } else { \ GC_add_to_black_list_normal(bits); \ }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -