📄 gc_priv.h
字号:
/* though we should perhaps take advantage of the case in which *//* does. */struct hblk; /* See below. */# ifdef PCR char * real_malloc();# define GET_MEM(bytes) HBLKPTR(real_malloc((size_t)bytes + GC_page_size) \ + GC_page_size-1)# else# ifdef OS2 void * os2_alloc(size_t bytes);# define GET_MEM(bytes) HBLKPTR((ptr_t)os2_alloc((size_t)bytes \ + GC_page_size) \ + GC_page_size-1)# else# if defined(NEXT) || defined(MACOSX) || defined(DOS4GW) || \ (defined(AMIGA) && !defined(GC_AMIGA_FASTALLOC)) || \ (defined(SUNOS5) && !defined(USE_MMAP))# define GET_MEM(bytes) HBLKPTR((size_t) \ calloc(1, (size_t)bytes + GC_page_size) \ + GC_page_size-1)# else# ifdef MSWIN32 extern ptr_t GC_win32_get_mem();# define GET_MEM(bytes) (struct hblk *)GC_win32_get_mem(bytes)# else# ifdef MACOS# if defined(USE_TEMPORARY_MEMORY) extern Ptr GC_MacTemporaryNewPtr(size_t size, Boolean clearMemory);# define GET_MEM(bytes) HBLKPTR( \ GC_MacTemporaryNewPtr(bytes + GC_page_size, true) \ + GC_page_size-1)# else# define GET_MEM(bytes) HBLKPTR( \ NewPtrClear(bytes + GC_page_size) + GC_page_size-1)# endif# else# ifdef MSWINCE extern ptr_t GC_wince_get_mem();# define GET_MEM(bytes) (struct hblk *)GC_wince_get_mem(bytes)# else# if defined(AMIGA) && defined(GC_AMIGA_FASTALLOC) extern void *GC_amiga_get_mem(size_t size); define GET_MEM(bytes) HBLKPTR((size_t) \ GC_amiga_get_mem((size_t)bytes + GC_page_size) \ + GC_page_size-1)# else extern ptr_t GC_unix_get_mem();# define GET_MEM(bytes) (struct hblk *)GC_unix_get_mem(bytes)# endif# endif# endif# endif# endif# endif# endif/* Delay any interrupts or signals that may abort this thread. Data *//* structures are in a consistent state outside this pair of calls. *//* ANSI C allows both to be empty (though the standard isn't very *//* clear on that point). Standard malloc implementations are usually *//* neither interruptable nor thread-safe, and thus correspond to *//* empty definitions. *//* It probably doesn't make any sense to declare these to be nonempty *//* if the code is being optimized, since signal safety relies on some *//* ordering constraints that are typically not obeyed by optimizing *//* compilers. */# ifdef PCR# define DISABLE_SIGNALS() \ PCR_Th_SetSigMask(PCR_allSigsBlocked,&GC_old_sig_mask)# define ENABLE_SIGNALS() \ PCR_Th_SetSigMask(&GC_old_sig_mask, NIL)# else# if defined(THREADS) || defined(AMIGA) \ || defined(MSWIN32) || defined(MSWINCE) || defined(MACOS) \ || defined(DJGPP) || defined(NO_SIGNALS) /* Also useful for debugging. */ /* Should probably use thr_sigsetmask for GC_SOLARIS_THREADS. */# define DISABLE_SIGNALS()# define ENABLE_SIGNALS()# else# define DISABLE_SIGNALS() GC_disable_signals() void GC_disable_signals();# define ENABLE_SIGNALS() GC_enable_signals() void GC_enable_signals();# endif# endif/* * Stop and restart mutator threads. */# ifdef PCR# include "th/PCR_ThCtl.h"# define STOP_WORLD() \ PCR_ThCtl_SetExclusiveMode(PCR_ThCtl_ExclusiveMode_stopNormal, \ PCR_allSigsBlocked, \ PCR_waitForever)# define START_WORLD() \ PCR_ThCtl_SetExclusiveMode(PCR_ThCtl_ExclusiveMode_null, \ PCR_allSigsBlocked, \ PCR_waitForever);# else# if defined(GC_SOLARIS_THREADS) || defined(GC_WIN32_THREADS) \ || defined(GC_PTHREADS) void GC_stop_world(); void GC_start_world();# define STOP_WORLD() GC_stop_world()# define START_WORLD() GC_start_world()# else# define STOP_WORLD()# define START_WORLD()# endif# endif/* Abandon ship */# ifdef PCR# define ABORT(s) PCR_Base_Panic(s)# else# ifdef SMALL_CONFIG# define ABORT(msg) abort();# else GC_API void GC_abort();# define ABORT(msg) GC_abort(msg);# endif# endif/* Exit abnormally, but without making a mess (e.g. out of memory) */# ifdef PCR# define EXIT() PCR_Base_Exit(1,PCR_waitForever)# else# define EXIT() (void)exit(1)# endif/* Print warning message, e.g. almost out of memory. */# define WARN(msg,arg) (*GC_current_warn_proc)("GC Warning: " msg, (GC_word)(arg))extern GC_warn_proc GC_current_warn_proc;/* Get environment entry */#if !defined(NO_GETENV)# define GETENV(name) getenv(name)#else# define GETENV(name) 0#endif/*********************************//* *//* Word-size-dependent defines *//* *//*********************************/#if CPP_WORDSZ == 32# define WORDS_TO_BYTES(x) ((x)<<2)# define BYTES_TO_WORDS(x) ((x)>>2)# define LOGWL ((word)5) /* log[2] of CPP_WORDSZ */# define modWORDSZ(n) ((n) & 0x1f) /* n mod size of word */# if ALIGNMENT != 4# define UNALIGNED# endif#endif#if CPP_WORDSZ == 64# define WORDS_TO_BYTES(x) ((x)<<3)# define BYTES_TO_WORDS(x) ((x)>>3)# define LOGWL ((word)6) /* log[2] of CPP_WORDSZ */# define modWORDSZ(n) ((n) & 0x3f) /* n mod size of word */# if ALIGNMENT != 8# define UNALIGNED# endif#endif#define WORDSZ ((word)CPP_WORDSZ)#define SIGNB ((word)1 << (WORDSZ-1))#define BYTES_PER_WORD ((word)(sizeof (word)))#define ONES ((word)(signed_word)(-1))#define divWORDSZ(n) ((n) >> LOGWL) /* divide n by size of word *//*********************//* *//* Size Parameters *//* *//*********************//* heap block size, bytes. Should be power of 2 */#ifndef HBLKSIZE# ifdef SMALL_CONFIG# define CPP_LOG_HBLKSIZE 10# else# if (CPP_WORDSZ == 32) || (defined(HPUX) && defined(HP_PA)) /* HPUX/PA seems to use 4K pages with the 64 bit ABI */# define CPP_LOG_HBLKSIZE 12# else# define CPP_LOG_HBLKSIZE 13# endif# endif#else# if HBLKSIZE == 512# define CPP_LOG_HBLKSIZE 9# endif# if HBLKSIZE == 1024# define CPP_LOG_HBLKSIZE 10# endif# if HBLKSIZE == 2048# define CPP_LOG_HBLKSIZE 11# endif# if HBLKSIZE == 4096# define CPP_LOG_HBLKSIZE 12# endif# if HBLKSIZE == 8192# define CPP_LOG_HBLKSIZE 13# endif# if HBLKSIZE == 16384# define CPP_LOG_HBLKSIZE 14# endif# ifndef CPP_LOG_HBLKSIZE --> fix HBLKSIZE# endif# undef HBLKSIZE#endif# define CPP_HBLKSIZE (1 << CPP_LOG_HBLKSIZE)# define LOG_HBLKSIZE ((word)CPP_LOG_HBLKSIZE)# define HBLKSIZE ((word)CPP_HBLKSIZE)/* max size objects supported by freelist (larger objects may be *//* allocated, but less efficiently) */#define CPP_MAXOBJBYTES (CPP_HBLKSIZE/2)#define MAXOBJBYTES ((word)CPP_MAXOBJBYTES)#define CPP_MAXOBJSZ BYTES_TO_WORDS(CPP_HBLKSIZE/2)#define MAXOBJSZ ((word)CPP_MAXOBJSZ) # define divHBLKSZ(n) ((n) >> LOG_HBLKSIZE)# define HBLK_PTR_DIFF(p,q) divHBLKSZ((ptr_t)p - (ptr_t)q) /* Equivalent to subtracting 2 hblk pointers. */ /* We do it this way because a compiler should */ /* find it hard to use an integer division */ /* instead of a shift. The bundled SunOS 4.1 */ /* o.w. sometimes pessimizes the subtraction to */ /* involve a call to .div. */ # define modHBLKSZ(n) ((n) & (HBLKSIZE-1)) # define HBLKPTR(objptr) ((struct hblk *)(((word) (objptr)) & ~(HBLKSIZE-1)))# define HBLKDISPL(objptr) (((word) (objptr)) & (HBLKSIZE-1))/* Round up byte allocation requests to integral number of words, etc. */# define ROUNDED_UP_WORDS(n) \ BYTES_TO_WORDS((n) + (WORDS_TO_BYTES(1) - 1 + EXTRA_BYTES))# ifdef ALIGN_DOUBLE# define ALIGNED_WORDS(n) \ (BYTES_TO_WORDS((n) + WORDS_TO_BYTES(2) - 1 + EXTRA_BYTES) & ~1)# else# define ALIGNED_WORDS(n) ROUNDED_UP_WORDS(n)# endif# define SMALL_OBJ(bytes) ((bytes) < (MAXOBJBYTES - EXTRA_BYTES))# define ADD_SLOP(bytes) ((bytes) + EXTRA_BYTES)# ifndef MIN_WORDS /* MIN_WORDS is the size of the smallest allocated object. */ /* 1 and 2 are the only valid values. */ /* 2 must be used if: */ /* - GC_gcj_malloc can be used for objects of requested */ /* size smaller than 2 words, or */ /* - USE_MARK_BYTES is defined. */# if defined(USE_MARK_BYTES) || defined(GC_GCJ_SUPPORT)# define MIN_WORDS 2 /* Smallest allocated object. */# else# define MIN_WORDS 1# endif# endif/* * Hash table representation of sets of pages. This assumes it is * OK to add spurious entries to sets. * Used by black-listing code, and perhaps by dirty bit maintenance code. */ # ifdef LARGE_CONFIG# define LOG_PHT_ENTRIES 19 /* Collisions likely at 512K blocks, */ /* which is >= 2GB. Each table takes */ /* 64KB. */# else# ifdef SMALL_CONFIG# define LOG_PHT_ENTRIES 14 /* Collisions are likely if heap grows */ /* to more than 16K hblks = 64MB. */ /* Each hash table occupies 2K bytes. */# else /* default "medium" configuration */# define LOG_PHT_ENTRIES 16 /* Collisions are likely if heap grows */ /* to more than 16K hblks >= 256MB. */ /* Each hash table occupies 8K bytes. */# endif# endif# define PHT_ENTRIES ((word)1 << LOG_PHT_ENTRIES)# define PHT_SIZE (PHT_ENTRIES >> LOGWL)typedef word page_hash_table[PHT_SIZE];# define PHT_HASH(addr) ((((word)(addr)) >> LOG_HBLKSIZE) & (PHT_ENTRIES - 1))# define get_pht_entry_from_index(bl, index) \ (((bl)[divWORDSZ(index)] >> modWORDSZ(index)) & 1)# define set_pht_entry_from_index(bl, index) \ (bl)[divWORDSZ(index)] |= (word)1 << modWORDSZ(index)# define clear_pht_entry_from_index(bl, index) \ (bl)[divWORDSZ(index)] &= ~((word)1 << modWORDSZ(index))/* And a dumb but thread-safe version of set_pht_entry_from_index. *//* This sets (many) extra bits. */# define set_pht_entry_from_index_safe(bl, index) \ (bl)[divWORDSZ(index)] = ONES /********************************************//* *//* H e a p B l o c k s *//* *//********************************************//* heap block header */#define HBLKMASK (HBLKSIZE-1)#define BITS_PER_HBLK (CPP_HBLKSIZE * 8)#define MARK_BITS_PER_HBLK (BITS_PER_HBLK/CPP_WORDSZ) /* upper bound */ /* We allocate 1 bit/word, unless USE_MARK_BYTES */ /* is defined. Only the first word */ /* in each object is actually marked. */# ifdef USE_MARK_BYTES# define MARK_BITS_SZ (MARK_BITS_PER_HBLK/2) /* Unlike the other case, this is in units of bytes. */ /* We actually allocate only every second mark bit, since we */ /* force all objects to be doubleword aligned. */ /* However, each mark bit is allocated as a byte. */# else# define MARK_BITS_SZ (MARK_BITS_PER_HBLK/CPP_WORDSZ)# endif/* We maintain layout maps for heap blocks containing objects of a given *//* size. Each entry in this map describes a byte offset and has the *//* following type. */typedef unsigned char map_entry_type;struct hblkhdr { word hb_sz; /* If in use, size in words, of objects in the block. */ /* if free, the size in bytes of the whole block */ struct hblk * hb_next; /* Link field for hblk free list */ /* and for lists of chunks waiting to be */ /* reclaimed. */ struct hblk * hb_prev; /* Backwards link for free list. */ word hb_descr; /* object descriptor for marking. See */ /* mark.h. */ map_entry_type * hb_map; /* A pointer to a pointer validity map of the block. */ /* See GC_obj_map. */ /* Valid for all blocks with headers. */ /* Free blocks point to GC_invalid_map. */ unsigned char hb_obj_kind; /* Kind of objects in the block. Each kind */ /* identifies a mark procedure and a set of */ /* list headers. Sometimes called regions. */ unsigned char hb_flags;# define IGNORE_OFF_PAGE 1 /* Ignore pointers that do not */ /* point to the first page of */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -