📄 gc_priv.h
字号:
/* 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 unsigned 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 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) \ { AO_or((volatile AO_t *)(addr), (AO_t)bits); }#else# define OR_WORD(addr, bits) *(addr) |= (bits)#endif/* Mark bit operations *//* * Retrieve, set, clear the nth mark bit in a given heap block. * * (Recall that bit n corresponds to nth object or allocation granule * 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])# define set_mark_bit_from_hdr(hhdr,n) ((hhdr)->hb_marks[n]) = 1# define clear_mark_bit_from_hdr(hhdr,n) ((hhdr)->hb_marks[n]) = 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 */#ifdef MARK_BIT_PER_OBJ# define MARK_BIT_NO(offset, sz) (((unsigned)(offset))/(sz)) /* Get the mark bit index corresponding to the given byte */ /* offset and size (in bytes). */# define MARK_BIT_OFFSET(sz) 1 /* Spacing between useful mark bits. */# define IF_PER_OBJ(x) x# define FINAL_MARK_BIT(sz) ((sz) > MAXOBJBYTES? 1 : HBLK_OBJS(sz)) /* Position of final, always set, mark bit. */#else /* MARK_BIT_PER_GRANULE */# define MARK_BIT_NO(offset, sz) BYTES_TO_GRANULES((unsigned)(offset))# define MARK_BIT_OFFSET(sz) BYTES_TO_GRANULES(sz)# define IF_PER_OBJ(x)# define FINAL_MARK_BIT(sz) \ ((sz) > MAXOBJBYTES? MARK_BITS_PER_HBLK \ : BYTES_TO_GRANULES(sz * HBLK_OBJS(sz)))#endif/* Important internal collector routines */ptr_t GC_approx_sp(void); GC_bool GC_should_collect(void); void GC_apply_to_all_blocks(void (*fn) (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(struct hblk * h); /* Return first in-use block >= h */struct hblk * GC_prev_block(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(void);void GC_clear_marks(void); /* Clear mark bits for all heap objects. */void GC_invalidate_mark_state(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(void);GC_bool GC_mark_some(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(void); /* initiate collection. */ /* If the mark state is invalid, this */ /* becomes full colleection. Otherwise */ /* it's partial. */void GC_push_all(ptr_t bottom, ptr_t top); /* Push everything in a range */ /* onto mark stack. */void GC_push_selected(ptr_t bottom, ptr_t top, int (*dirty_fn) (struct hblk *h), void (*push_fn) (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 (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 (ptr_t b, ptr_t t); /* As above, but consider */ /* interior pointers as valid */void GC_push_all_eager (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(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(ptr_t cold_gc_frame, void *context); /* 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. */ /* The second argument is a pointer to the */ /* (possibly null) thread context, for */ /* (currently hypothetical) more precise */ /* stack scanning. */void GC_push_roots(GC_bool all, ptr_t cold_gc_frame); /* Push all or dirty roots. */extern void (*GC_push_other_roots)(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(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(void); extern void GC_push_stubborn_structures (void);# ifdef THREADS extern void GC_push_thread_structures (void);# endifextern void (*GC_start_call_back) (void); /* Called at start of full collections. */ /* Not called if 0. Called with allocation */ /* lock held. */ /* 0 by default. */void GC_push_regs_and_stack(ptr_t cold_gc_frame);void GC_push_regs(void);void GC_with_callee_saves_pushed(void (*fn)(ptr_t, void *), ptr_t arg);# 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. */ ptr_t GC_save_regs_in_stack(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(word p);# else void GC_push_one(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(ptr_t p, ptr_t source); /* Ditto, omits plausibility test */# else void GC_mark_and_push_stack(ptr_t p);# endifvoid GC_push_marked(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(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(struct hblk * h); /* Ditto, but also mark from clean pages. */struct hblk * GC_push_next_marked_uncollectable(struct hblk * h); /* Ditto, but mark only from uncollectable pages. */GC_bool GC_stopped_mark(GC_stop_func stop_func); /* Stop world and mark from all roots */ /* and rescuers. */void GC_clear_hdr_marks(hdr * hhdr); /* Clear the mark bits in a header */void GC_set_hdr_marks(hdr * hhdr); /* Set the mark bits in a header */void GC_set_fl_marks(ptr_t p); /* Set all mark bits associated with */ /* a free list. */#ifdef GC_ASSERTIONS void GC_check_fl_marks(ptr_t p); /* Check that all mark bits */ /* associated with a free list are */ /* set. Abort if not. */#endifvoid GC_add_roots_inner(ptr_t b, ptr_t e, GC_bool tmp);void GC_remove_roots_inner(ptr_t b, ptr_t e);GC_bool GC_is_static_root(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(ptr_t p); /* Is the address p in one of the temporary static */ /* root sections? */# endifvoid GC_register_dynamic_libraries(void); /* Add dynamic library data sections to the root set. */void GC_cond_register_dynamic_libraries(void); /* Remove and reregister dynamic libraries if we're */ /* configured to do that at each GC. */GC_bool GC_register_main_static_data(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_main_stack_base(void); /* Cold end of stack */#ifdef IA64 ptr_t GC_get_register_stack_base(void); /* Cold end of register stack. */#endifvoid GC_register_data_segments(void); /* Black listing: */void GC_bl_init(void);# ifdef PRINT_BLACK_LIST void GC_add_to_black_list_normal(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((word)(bits), (source)); \ } else { \ GC_add_to_black_list_normal((word)(bits), (source)); \ }# else void GC_add_to_black_list_normal(word p);# define GC_ADD_TO_BLACK_LIST_NORMAL(bits, source) \ if (GC_all_interior_pointers) { \ GC_add_to_black_list_stack((word)(bits)); \ } else { \ GC_add_to_black_list_normal((word)(bits)); \ }# endif# ifdef PRINT_BLACK_LIST void GC_add_to_black_list_stack(word p, ptr_t source);# define GC_ADD_TO_BLACK_LIST_STACK(bits, source) \ GC_add_to_black_list_stack((word)(bits), (source))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -