runtime.h
上传用户:nthfjj
上传日期:2007-01-07
资源大小:37k
文件大小:20k
源码类别:

系统编程

开发平台:

Unix_Linux

  1. /* Copyright 1988,1989 Hans-J. Boehm, Alan J. Demers */
  2. /*********************************/
  3. /*                               */
  4. /* Definitions for conservative  */
  5. /* collector                     */
  6. /*                               */
  7. /*********************************/
  8. /*********************************/
  9. /*                               */
  10. /* Easily changeable parameters  */
  11. /*                               */
  12. /*********************************/
  13. # if defined(sun) && defined(mc68000)
  14. #    define M68K
  15. #    define mach_type_known
  16. # endif
  17. # if defined(vax)
  18. #    define VAX
  19. #    define mach_type_known
  20. # endif
  21. # if defined(mips)
  22. #    define MIPS
  23. #    define mach_type_known
  24. # endif
  25. # if defined(sequent) && defined(i386)
  26. #    define I386
  27. #    define mach_type_known
  28. # endif
  29. # if defined(ibm032)
  30. #   define RT
  31. #   define mach_type_known
  32. # endif
  33. # if defined(sun) && defined(sparc)
  34. #   define SPARC
  35. #   define mach_type_known
  36. # endif
  37. /* Feel free to add more clauses here */
  38. /* Or manually define the machine type here: */
  39. # ifndef mach_type_known
  40. #   define M68K     /* This is a Motorola 68000, as opposed to a SPARC, VAX, */
  41.     /* RT, I386, MIPS, or NS32K.                             */
  42.     /* We assume:  M68K ==> Sun3, I386 ==> Sequent Symmetry */
  43.     /* NS32K ==> Encore Multimax, MIPS ==> R2000 or R3000   */
  44. # endif
  45. #define PRINTSTATS  /* Print garbage collection statistics                  */
  46.     /* For less verbose output, undefine in reclaim.c      */
  47. #define PRINTTIMES  /* Print the amount of time consumed by each garbage   */
  48.     /* collection.                                         */
  49. #define PRINTBLOCKS /* Print object sizes associated with heap blocks,     */
  50.     /* whether the objects are atomic or composite, and    */
  51.     /* whether or not the block was found to be empty      */
  52.     /* duing the reclaim phase.  Typically generates       */
  53.     /* about one screenful per garbage collection.         */
  54. #undef PRINTBLOCKS
  55. #define HBLK_MAP    /* Maintain a map of all potential heap blocks        */
  56.     /* starting at heapstart.                             */
  57.     /* Normally, this performs about as well as the       */
  58.     /* standard stack of chunk pointers that is used      */
  59.     /* otherwise.  It loses if a small section of the     */
  60.     /* heap consists of garbage collected objects.        */
  61.     /* It is ESSENTIAL if pointers to object interiors    */
  62.     /* are considered valid, i.e. if INTERIOR_POINTERS    */
  63.     /* is defined.                                        */
  64. #undef HBLK_MAP
  65. #define MAP_SIZE 8192  /* total data size < MAP_SIZE * HBLKSIZE = 32 Meg  */
  66. #define MAXHBLKS 4096  /* Maximum number of chunks which can be           */
  67.        /* allocated                                       */
  68. #define INTERIOR_POINTERS
  69.     /* Follow pointers to the interior of an object.      */
  70.     /* Substantially increases the probability of         */
  71.     /* unnnecessary space retention.  May be necessary    */
  72.     /* with gcc -O or other C compilers that may clobber  */
  73.     /* values of dead variables prematurely.  Pcc         */
  74.     /* derived compilers appear to pose no such problems. */
  75.     /* Empirical evidence suggests that this is probably  */
  76.     /* still OK for most purposes, so long as pointers    */
  77.     /* are known to be 32 bit aligned.  The combination   */
  78.     /* of INTERIOR_POINTERS and UNALIGNED (e.g. on a      */
  79.     /* Sun 3 with the standard compiler) causes easily    */
  80.     /* observable spurious retention and performance      */
  81.     /* degradation.                                       */
  82. #undef INTERIOR_POINTERS
  83. #if defined(INTERIOR_POINTERS) && !defined(HBLK_MAP)
  84.     --> check for interior pointers requires a heap block map
  85. #endif
  86. #define MERGE_SIZES /* Round up some object sizes, so that fewer distinct */
  87.     /* free lists are actually maintained.  This applies  */
  88.     /* only to the top level routines in misc.c, not to   */
  89.     /* user generated code that calls allocobj and        */
  90.     /* allocaobj directly.                                */
  91.     /* Slows down average programs slightly.  May however */
  92.     /* substantially reduce fragmentation if allocation   */
  93.     /* request sizes are widely scattered.                */
  94. #undef MERGE_SIZES
  95. #ifdef M68K
  96. #  define UNALIGNED       /* Pointers are not longword aligned         */
  97. #  define ALIGNMENT   2   /* Pointers are aligned on 2 byte boundaries */
  98.   /* by the Sun C compiler.                    */
  99. #else
  100. #  ifdef VAX
  101. #    undef UNALIGNED      /* Pointers are longword aligned by 4.2 C compiler */
  102. #    define ALIGNMENT 4
  103. #  else
  104. #    ifdef RT
  105. #      undef UNALIGNED
  106. #      define ALIGNMENT 4
  107. #    else
  108. #      ifdef SPARC
  109. #        undef UNALIGNED
  110. #        define ALIGNMENT 4
  111. #      else
  112. #        ifdef I386
  113. #           undef UNALIGNED         /* Sequent compiler aligns pointers */
  114. #           define ALIGNMENT 4
  115. #        else
  116. #          ifdef NS32K
  117. #            undef UNALIGNED        /* Pointers are aligned on NS32K */
  118. #            define ALIGNMENT 4
  119. #          else
  120. #            ifdef MIPS
  121. #              undef UNALIGNED      /* MIPS hardware requires pointer */
  122.     /* alignment                      */
  123. #              define ALIGNMENT 4
  124. #            else
  125.  --> specify alignment <--
  126. #            endif
  127. #          endif
  128. #        endif
  129. #      endif
  130. #    endif
  131. #  endif
  132. # endif
  133. # ifdef M68K
  134. #   define STACKTOP ((char *)0xf000000) /* Beginning of stack on a Sun 3 */
  135. /* Sun 2 value is 0x1000000      */
  136. # else
  137. #   ifdef VAX
  138. #     define STACKTOP ((char *)0x80000000) /* Beginning of stack under 4.n BSD */
  139. #   else
  140. #     ifdef RT
  141. #       define STACKTOP ((char *) 0x1fffd800)
  142. #     else
  143. #       ifdef SPARC
  144. #         define STACKTOP ((char *) 0xf8000000)
  145. #       else
  146. #         ifdef I386
  147. #           define STACKTOP ((char *) 0x3ffff000)  /* For Sequent */
  148. #         else
  149. #           ifdef NS32K
  150. #             define STACKTOP ((char *) 0xfffff000) /* for Encore */
  151. #           else
  152. #             ifdef MIPS
  153. #               define STACKTOP ((char *) 0x7ffff000)
  154.       /* Could probably be slightly lower since  */
  155.       /* startup code allocates lots of junk     */
  156. #             else
  157. --> specify
  158. #             endif
  159. #           endif
  160. #         endif
  161. #       endif
  162. #     endif
  163. #   endif
  164. # endif
  165. /* Start of data segment for each of the above systems.  Note that the */
  166. /* default case works only for contiguous text and data, such as on a  */
  167. /* Vax.                                                                */
  168. # ifdef M68K
  169. #   define DATASTART ((char *)((((long) (&etext)) + 0x1ffff) & ~0x1ffff))
  170. # else
  171. #   ifdef RT
  172. #     define DATASTART ((char *) 0x10000000)
  173. #   else
  174. #     ifdef I386
  175. #       define DATASTART ((char *)((((long) (&etext)) + 0xfff) & ~0xfff))
  176. #     else
  177. #       ifdef NS32K
  178.   extern char **environ;
  179. #         define DATASTART ((char *)(&environ))
  180.       /* hideous kludge: environ is the first   */
  181.       /* word in crt0.o, and delimits the start */
  182.       /* of the data segment, no matter which   */
  183.       /* ld options were passed through.        */
  184. #       else
  185. #         ifdef MIPS
  186. #           define DATASTART 0x10000000
  187.       /* Could probably be slightly higher since */
  188.       /* startup code allocates lots of junk     */
  189. #         else
  190. #           define DATASTART (&etext)
  191. #         endif
  192. #       endif
  193. #     endif
  194. #   endif
  195. # endif
  196. # define HINCR 16          /* Initial heap increment, in blocks of 4K        */
  197. # define HINCR_MULT 3      /* After each new allocation, hincr is multiplied */
  198. # define HINCR_DIV 2       /* by HINCR_MULT/HINCR_DIV                        */
  199. # define GC_MULT 3         /* Don't collect if the fraction of   */
  200.    /* non-collectable memory in the heap */
  201.    /* exceeds GC_MUL/GC_DIV              */
  202. # define GC_DIV  4
  203. # define NON_GC_HINCR 8    /* Heap increment if most of heap if collection */
  204.    /* was suppressed because most of heap is not   */
  205.    /* collectable                                  */
  206. /*  heap address bounds.  These are extreme bounds used for sanity checks. */
  207. /*  HEAPLIM may have to be increased for machines with incredibly large    */
  208. /*  amounts of memory.                                                     */
  209. #ifdef RT
  210. #   define HEAPSTART 0x10000000
  211. #   define HEAPLIM   0x1fff0000
  212. #else
  213. # ifdef M68K
  214. #   define HEAPSTART 0x00010000
  215. #   define HEAPLIM   0x04000000
  216. # else
  217. #   ifdef SPARC
  218. #       define HEAPSTART 0x00010000
  219. #       define HEAPLIM   0x10000000
  220. #   else
  221. #     ifdef VAX
  222. #       define HEAPSTART 0x400
  223. #       define HEAPLIM   0x10000000
  224. #     else
  225. #       ifdef I386
  226. #         define HEAPSTART 0x1000
  227. #         define HEAPLIM 0x10000000
  228. #       else
  229. #         ifdef NS32K
  230. #           define HEAPSTART 0x2000
  231. #           define HEAPLIM   0x10000000
  232. #         else
  233. #           ifdef MIPS
  234. #             define HEAPSTART 0x10000000
  235. #             define HEAPLIM 0x20000000
  236. #           else
  237.        --> values unknown <--
  238. #           endif
  239. #         endif
  240. #       endif
  241. #     endif
  242. #   endif
  243. # endif
  244. #endif
  245. /*********************************/
  246. /*                               */
  247. /* Machine-dependent defines     */
  248. /*                               */
  249. /*********************************/
  250. #define WORDS_TO_BYTES(x)   ((x)<<2)
  251. #define BYTES_TO_WORDS(x)   ((x)>>2)
  252. #define WORDSZ              32
  253. #define LOGWL               5    /* log[2] of above */
  254. #define BYTES_PER_WORD      (sizeof (word))
  255. #define NREGS               16
  256. #define ONES                0xffffffff
  257. #define MSBYTE              0xff000000
  258. #define SIGNB               0x80000000
  259. #define MAXSHORT            0x7fff
  260. #define modHALFWORDSZ(n) ((n) & 0xf)    /* mod n by size of half word    */
  261. #define divHALFWORDSZ(n) ((n) >> 4) /* divide n by size of half word */
  262. #define modWORDSZ(n) ((n) & 0x1f)       /* mod n by size of word         */
  263. #define divWORDSZ(n) ((n) >> 5)         /* divide n by size of word      */
  264. #define twice(n) ((n) << 1)             /* double n                      */
  265. typedef unsigned long word;
  266. #define TRUE  1
  267. #define FALSE 0
  268. /*********************/
  269. /*                   */
  270. /*  Size Parameters  */
  271. /*                   */
  272. /*********************/
  273. /*  heap block size, bytes */
  274. /* for RT see comment below */
  275. #define HBLKSIZE   0x1000
  276. /*  max size objects supported by freelist (larger objects may be   */
  277. /*  allocated, but less efficiently)                                */
  278. /*      asm(".set MAXOBJSZ,0x200")      if HBLKSIZE/2 == 0x200          */
  279. #define MAXOBJSZ    (HBLKSIZE/8)
  280. /* Should be BYTES_TO_WORDS(HBLKSIZE/2), but a cpp */
  281. /* misfeature prevents that.                       */
  282. #define MAXAOBJSZ   (HBLKSIZE/8)
  283. # define divHBLKSZ(n) ((n) >> 12)
  284.  
  285. # define modHBLKSZ(n) ((n) & 0xfff)
  286.  
  287. # define HBLKPTR(objptr) ((struct hblk *)(((long) (objptr)) & ~0xfff))
  288. /********************************************/
  289. /*                                          */
  290. /*    H e a p   B l o c k s                 */
  291. /*                                          */
  292. /********************************************/
  293. /*  heap block header */
  294. #define HBLKMASK   (HBLKSIZE-1)
  295. #define BITS_PER_HBLK (HBLKSIZE * 8)
  296. #define MARK_BITS_PER_HBLK (BITS_PER_HBLK/WORDSZ)
  297.    /* upper bound                                    */
  298.    /* We allocate 1 bit/word.  Only the first word   */
  299.    /* in each object is actually marked.             */
  300. # define MARK_BITS_SZ ((MARK_BITS_PER_HBLK + WORDSZ - 1)/WORDSZ)
  301.    /* Upper bound on number of mark words per heap block  */
  302. struct hblkhdr {
  303.     long hbh_sz;    /* sz > 0 ==> objects are sz-tuples of poss. pointers */
  304.     /* sz < 0 ==> objects are sz-tuples not pointers      */
  305.     /* if free, the size in bytes of the whole block      */
  306.     /* Misc.c knows that hbh_sz comes first.              */
  307. # ifndef HBLK_MAP
  308.     struct hblk ** hbh_index;   /* Pointer to heap block list entry   */
  309. /* for this block                     */
  310. # endif
  311.     struct hblk * hbh_next; /* Link field for hblk free list */
  312.     long hbh_mask;      /* If hbh_mask >= 0 then:                          */
  313. /*   x % (4 * hbh_sz) == x & hbh_mask              */
  314. /*   sz is a power of 2 and < the size of a heap   */
  315. /*     block.                                      */
  316. /* A hack to speed up pointer validity check on    */
  317. /* machines with slow division.                    */
  318.     long hbh_marks[MARK_BITS_SZ];
  319.     /* Bits 2i and 2i+1 in the array refer to the   */
  320.     /* object starting at the ith word (header      */
  321.     /* INCLUDED) in the heap block.                 */
  322.     /* For free blocks, hbh_marks[0] = 1, indicates */
  323.     /* block is uninitialized.                      */
  324. };
  325. /*  heap block body */
  326. # define BODY_SZ ((HBLKSIZE-sizeof(struct hblkhdr))/sizeof(word))
  327. struct hblk {
  328.     struct hblkhdr hb_hdr;
  329.     word hb_body[BODY_SZ];
  330. };
  331. # define hb_sz hb_hdr.hbh_sz
  332. # ifndef HBLK_MAP
  333. #   define hb_index hb_hdr.hbh_index
  334. # endif
  335. # define hb_marks hb_hdr.hbh_marks
  336. # define hb_next hb_hdr.hbh_next
  337. # define hb_uninit hb_hdr.hbh_marks[0]
  338. # define hb_mask hb_hdr.hbh_mask
  339. /*  lists of all heap blocks and free lists  */
  340. /* Object declaration is in alloc.c          */
  341. /* These are grouped together in a struct    */
  342. /* so that they can be easily skipped by the */
  343. /* mark routine.                             */
  344. /* misc.c knows about their relative order.  */
  345. struct __gc_arrays {
  346.   struct obj * _aobjfreelist[MAXAOBJSZ+1];         /* free list for atomic objs*/
  347.   struct obj * _objfreelist[MAXOBJSZ+1];           /* free list for objects */
  348. # ifdef HBLK_MAP
  349.     char _hblkmap[MAP_SIZE];
  350. #   define HBLK_INVALID 0    /* Not administered by collector   */
  351. #   define HBLK_VALID 0x7f   /* Beginning of a valid heap block */
  352.     /* A value n, 0 < n < 0x7f denotes the continuation of a valid heap    */
  353.     /* block which starts at the current address - n * HBLKSIZE or earlier */
  354. # else
  355.     struct hblk * _hblklist[MAXHBLKS];
  356. # endif
  357. };
  358. extern struct __gc_arrays _gc_arrays; 
  359. # define objfreelist _gc_arrays._objfreelist
  360. # define aobjfreelist _gc_arrays._aobjfreelist
  361. # ifdef HBLK_MAP
  362. #   define hblkmap _gc_arrays._hblkmap
  363. # else
  364. #   define hblklist _gc_arrays._hblklist
  365. # endif
  366. # define begin_gc_arrays ((char *)(&_gc_arrays))
  367. # define end_gc_arrays (((char *)(&_gc_arrays)) + (sizeof _gc_arrays))
  368. struct hblk ** last_hblk;  /* Pointer to one past the real end of hblklist */
  369. struct hblk * hblkfreelist;
  370. extern long heapsize;       /* Heap size in bytes */
  371. # define HINCR 16          /* Initial heap increment, in blocks              */
  372. long hincr;                /* current heap increment, in blocks              */
  373. /* Operations */
  374. # define update_hincr  hincr = (hincr * HINCR_MULT)/HINCR_DIV
  375. # define HB_SIZE(p) abs((p) -> hb_sz)
  376. # define abs(x)  ((x) < 0? (-(x)) : (x))
  377. /*  procedures */
  378. extern void
  379. freehblk();
  380. extern struct hblk *
  381. allochblk();
  382. /****************************/
  383. /*                          */
  384. /*   Objects                */
  385. /*                          */
  386. /****************************/
  387. /*  object structure */
  388. struct obj {
  389.     union {
  390. struct obj *oun_link;   /* --> next object in freelist */
  391. #         define obj_link       obj_un.oun_link
  392. word oun_component[1];  /* treats obj as list of words */
  393. #         define obj_component  obj_un.oun_component
  394.     } obj_un;
  395. };
  396. /*  Test whether something points to a legitimate heap object */
  397. extern char end;
  398. # ifdef HBLK_MAP
  399.   char * heapstart; /* A lower bound on all heap addresses */
  400.     /* Known to be HBLKSIZE aligned.       */
  401. # endif
  402. char * heaplim;   /* 1 + last address in heap */
  403. char * startup_sfp; /* Frame pointer for Russell startup routine */
  404. /* Check whether the given HBLKSIZE aligned hblk pointer refers to the   */
  405. /* beginning of a legitimate chunk.                                      */
  406. /* Assumes that *p is addressable                                        */
  407. # ifdef HBLK_MAP
  408. #   define is_hblk(p)  (hblkmap[divHBLKSZ(((long)p) - ((long)heapstart))] 
  409. == HBLK_VALID)
  410. # else
  411. #   define is_hblk(p) ( (p) -> hb_index >= hblklist 
  412. && (p) -> hb_index < last_hblk 
  413. && *((p)->hb_index) == (p))
  414. # endif
  415. # ifdef INTERIOR_POINTERS
  416.     /* Return the hblk_map entry for the pointer p */
  417. #     define get_map(p)  (hblkmap[divHBLKSZ(((long)p) - ((long)heapstart))])
  418. # endif
  419. # ifdef INTERIOR_POINTERS
  420.   /* Return the word displacement of the beginning of the object to       */
  421.   /* which q points.  q is an address inside hblk p for objects of size s */
  422.   /* with mask m corresponding to s.                                      */
  423. #  define get_word_no(q,p,s,m) 
  424.     (((long)(m)) >= 0 ? 
  425. (((((long)q) - ((long)p) - (sizeof (struct hblkhdr))) & ~(m)) 
  426.  + (sizeof (struct hblkhdr)) >> 2) 
  427. : ((((long)q) - ((long)p) - (sizeof (struct hblkhdr)) >> 2) 
  428.    / (s)) * (s) 
  429.    + ((sizeof (struct hblkhdr)) >> 2))
  430. # else
  431.   /* Check whether q points to an object inside hblk p for objects of size s */
  432.   /* with mask m corresponding to s.                                         */
  433. #  define is_proper_obj(q,p,s,m) 
  434.     (((long)(m)) >= 0 ? 
  435. (((((long)(q)) - (sizeof (struct hblkhdr))) & (m)) == 0) 
  436. : (((long) (q)) - ((long)(p)) - (sizeof (struct hblkhdr))) 
  437.    % ((s) << 2) == 0)
  438. #  endif
  439. /* The following is a quick test whether something is an object pointer */
  440. /* It may err in the direction of identifying bogus pointers            */
  441. /* Assumes heap + text + data + bss < 64 Meg.                           */
  442. #ifdef M68K
  443. #   define TMP_POINTER_MASK 0xfc000003  /* pointer & POINTER_MASK should be 0 */
  444. #else
  445. # ifdef RT
  446. #   define TMP_POINTER_MASK 0xc0000003
  447. # else
  448. #   ifdef VAX
  449. #     define TMP_POINTER_MASK 0xfc000003
  450. #   else
  451. #     ifdef SPARC
  452. #       define TMP_POINTER_MASK 0xfc000003
  453. #     else
  454. #       ifdef I386
  455. #         define TMP_POINTER_MASK 0xfc000003
  456. #       else
  457. #         ifdef NS32K
  458. #           define TMP_POINTER_MASK 0xfc000003
  459. #         else
  460. #           ifdef MIPS
  461. #             define TMP_POINTER_MASK 0xc0000003
  462. #           else
  463.       --> dont know <--
  464. #           endif
  465. #         endif
  466. #       endif
  467. #     endif
  468. #   endif
  469. # endif
  470. #endif
  471. #ifdef INTERIOR_POINTERS
  472. #   define POINTER_MASK (TMP_POINTER_MASK & 0xfffffff8)
  473. /* Don't pay attention to whether address is properly aligned */
  474. #else
  475. #   define POINTER_MASK TMP_POINTER_MASK
  476. #endif
  477. #ifdef HBLK_MAP
  478. #  define quicktest(p) (((long)(p)) > ((long)(heapstart)) 
  479. && !(((unsigned long)(p)) & POINTER_MASK))
  480. #else
  481. # ifdef UNALIGNED
  482. #  define quicktest(p) (((long)(p)) > ((long)(&end)) 
  483.                         && !(((unsigned long)(p)) & POINTER_MASK) 
  484.                         && (((long)(p)) & HBLKMASK))
  485. /* The last test throws out pointers to the beginning of heap */
  486.         /* blocks.  Small integers shifted by 16 bits tend to look    */
  487.         /* like these.                                                */
  488. # else
  489. #  define quicktest(p) (((long)(p)) > ((long)(&end)) 
  490. && !(((unsigned long)(p)) & POINTER_MASK))
  491. # endif
  492. #endif
  493. /*  Marks are in a reserved area in                          */
  494. /*  each heap block.  Each word has one mark bits associated */
  495. /*  with it. Only those corresponding to the beginning of an */
  496. /*  object are used.                                         */
  497. /* Operations */
  498. /*
  499.  * Retrieve, set, clear the mark bit corresponding
  500.  * to the nth word in a given heap block.
  501.  * Note that retrieval will work, so long as *hblk is addressable.
  502.  * In particular, the check whether hblk is a legitimate heap block
  503.  * can be postponed until after the mark bit is examined.
  504.  *
  505.  * (Recall that bit n corresponds to object beginning at word n)
  506.  */
  507. # define mark_bit(hblk,n) (((hblk)->hb_marks[divWORDSZ(n)] 
  508.     >> (modWORDSZ(n))) & 1)
  509. /* The following assume the mark bit in question is either initially */
  510. /* cleared or it already has its final value                         */
  511. # define set_mark_bit(hblk,n) (hblk)->hb_marks[divWORDSZ(n)] 
  512. |= 1 << modWORDSZ(n)
  513. # define clear_mark_bit(hblk,n) (hblk)->hb_marks[divWORDSZ(n)] 
  514. &= ~(1 << modWORDSZ(n))
  515. /*  procedures */
  516. /* Small object allocation routines */
  517. extern struct obj * allocobj();
  518. extern struct obj * allocaobj();
  519. /* general purpose allocation routines */
  520. extern struct obj * gc_malloc();
  521. extern struct obj * gc_malloc_comp();