📄 gc_priv.h
字号:
void **ok_freelist; /* Array of free listheaders for this kind of object */
/* Point either to GC_arrays or to storage allocated */
/* with GC_scratch_alloc. */
struct hblk **ok_reclaim_list;
/* List headers for lists of blocks waiting to be */
/* swept. */
/* Indexed by object size in granules. */
word ok_descriptor; /* Descriptor template for objects in this */
/* block. */
GC_bool ok_relocate_descr;
/* Add object size in bytes to descriptor */
/* template to obtain descriptor. Otherwise */
/* template is used as is. */
GC_bool ok_init; /* Clear objects before putting them on the free list. */
} GC_obj_kinds[MAXOBJKINDS];
# define beginGC_obj_kinds ((ptr_t)(&GC_obj_kinds))
# define endGC_obj_kinds (beginGC_obj_kinds + (sizeof GC_obj_kinds))
/* Variables that used to be in GC_arrays, but need to be accessed by */
/* inline allocation code. If they were in GC_arrays, the inlined */
/* allocation code would include GC_arrays offsets (as it did), which */
/* introduce maintenance problems. */
#ifdef SEPARATE_GLOBALS
word GC_bytes_allocd;
/* Number of words allocated during this collection cycle */
ptr_t GC_objfreelist[MAXOBJGRANULES+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[MAXOBJGRANULES+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)
# endif
extern 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. */
# endif
extern 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
#endif
extern 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. */
#endif
void 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);
# endif
extern 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);
# endif
void 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. */
#endif
void 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? */
# endif
void GC_register_dynamic_libraries(void);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -