home *** CD-ROM | disk | FTP | other *** search
/ PC World 1998 October / PCWorld_1998-10_cd.bin / software / prehled / inprise / JRUNTIME.Z / gc.h < prev    next >
C/C++ Source or Header  |  1998-05-08  |  13KB  |  342 lines

  1. /*
  2.  * @(#)gc.h    1.10 97/01/24
  3.  * 
  4.  * Copyright (c) 1995, 1996 Sun Microsystems, Inc. All Rights Reserved.
  5.  * 
  6.  * This software is the confidential and proprietary information of Sun
  7.  * Microsystems, Inc. ("Confidential Information").  You shall not
  8.  * disclose such Confidential Information and shall use it only in
  9.  * accordance with the terms of the license agreement you entered into
  10.  * with Sun.
  11.  * 
  12.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
  13.  * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  14.  * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
  15.  * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
  16.  * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
  17.  * THIS SOFTWARE OR ITS DERIVATIVES.
  18.  * 
  19.  * CopyrightVersion 1.1_beta
  20.  * 
  21.  */
  22.  
  23. #ifndef _GC_H_
  24. #define _GC_H_
  25.  
  26. #include "gc_md.h"
  27.  
  28.  
  29. /*
  30.  * Lock against heap modification.
  31.  */
  32. extern sys_mon_t *_heap_lock;
  33. #define HEAP_LOCK_INIT()    monitorRegister(_heap_lock, "Heap lock")
  34. #define HEAP_LOCK()        sysMonitorEnter(_heap_lock)
  35. #define HEAP_UNLOCK()        sysMonitorExit(_heap_lock)
  36. #define HEAP_LOCKED()        sysMonitorEntered( _heap_lock)
  37.  
  38. /*
  39.  * Define this if you want the mark phase to detect pointers into the
  40.  * interior of objects.
  41.  */
  42. /* #define CHECK_INTERIOR_POINTERS */
  43.  
  44. #define OBJECTGRAIN     8
  45. #define HANDLEGRAIN     8
  46. #define BITSPERCHAR     8
  47.  
  48. /*
  49.  * Types of overflows: we might respond to an overflow of a particular
  50.  * error differently, e.g. expanding only the overflowing area.
  51.  */
  52. #define OVERFLOW_NONE     0
  53. #define OVERFLOW_OBJECTS 1
  54. #define OVERFLOW_HANDLES 2
  55.  
  56. /*
  57.  * Possible actions to take on overflows.  manageAllocFailure()
  58.  * decides between these.
  59.  */
  60. #define OVERFLOW_ACT_FAIL    0
  61. #define OVERFLOW_ACT_GC        1
  62. #define OVERFLOW_ACT_FINALIZE    2
  63. #define OVERFLOW_ACT_REFS    3
  64. #define OVERFLOW_ACT_EXPAND    4
  65. #define OVERFLOW_ACT_DESPERATE    5
  66.  
  67. /*
  68.  * Memory block header (bottom three bits are flags):
  69.  *
  70.  * -------------------------------------------------------------
  71.  * | <--- length --->| pinned | <- obj swapped -> | <- free -> |
  72.  * -------------------------------------------------------------
  73.  * 31             3          2              1           0
  74.  */
  75. typedef long hdr;
  76.  
  77. #define obj_geth(p) (*((hdr *)(p)))
  78. #define obj_seth(p, h) (*((hdr *)(p)) = (h))
  79. #define h_len(h) ((h) & ~(OBJECTGRAIN-1))
  80. #define h_free(h) ((h) & 1)
  81. #define h_bumplen(h, l) ((h) += (l))
  82.  
  83. #define obj_len(p) (obj_geth(p)&~(OBJECTGRAIN-1))
  84. #define obj_setlf(p, l, f) (obj_geth(p) = (l)|(f))
  85. #define obj_bumplen(p, l) (obj_geth(p) += (l))
  86. #define obj_free(p) (obj_geth(p)&1)
  87. #define obj_setfree(p) (obj_geth(p) |= 1)
  88. #define obj_clearfree(p) (obj_geth(p) &= ~1)
  89. #define obj_pinned(p) (obj_geth(p) & 4)
  90. #define obj_pin(p) (obj_geth(p) |= 4)
  91. #define obj_unpin(p) (obj_geth(p) &= ~4)
  92.  
  93. /*
  94.  * The marking code relies upon the values representing the three mark
  95.  * states to be ordered numerically: NoMark < SoftMark < HardMark.
  96.  */
  97. #define NoMark   0
  98. #define SoftMark 1
  99. #define HardMark 3
  100.  
  101. #define MarkPtr(p, v) _MarkPtr(((unsigned int) (p) & ~(OBJECTGRAIN - 1)), v)
  102. #define ClearMarkPtr(p, v) _ClearMarkPtr(((unsigned int)(p)&~(OBJECTGRAIN-1)),v)
  103. #define IsMarked(p) _IsMarked((unsigned int) (p) & ~(OBJECTGRAIN - 1))
  104.  
  105. #define SOFTREFBAGSIZE 200  /* max number of soft refs to kill in one cycle */
  106.  
  107.  
  108. #ifndef PAGED_HEAPS /************ CONTIGUOUS HEAPS: ********************/
  109.  
  110. #define ValidObject(p)    ((((int)(p)) & (OBJECTGRAIN-1)) == 0 &&            \
  111.              (unsigned char *)(p) >= opmin &&              \
  112.              (unsigned char *)(p) <  opmax)
  113. #define ValidHandle(p)    (((int) (p) & (sizeof(JHandle)-1)) == 0 &&      \
  114.              (unsigned char *)(p) >= hpmin &&            \
  115.              (unsigned char *)(p) <= hpmax)
  116. /* ValidHorO() assumes OBJECTGRAIN=sizeof(JHandle)... */
  117. #define ValidHorO(p)    (((int) (p) & (OBJECTGRAIN-1)) == 0 &&            \
  118.              (unsigned char *)(p) >= hpmin &&        \
  119.              (unsigned char *)(p) <= opmax)
  120. #define SetLimits()                            \
  121.     register unsigned char *const opmin = opool,                \
  122.                            *const opmax = opoollimit,                \
  123.                    *const hpmin = hpool,                      \
  124.                    *const hpmax = hpoollimit-sizeof(JHandle)
  125.  
  126. #define POP_FREE_HANDLE(hp)                         \
  127.     hp = (JHandle *)hpoolfreelist;                     \
  128.     if (hp) {                                \
  129.         hpoolfreelist = (unsigned char *)hp->methods;            \
  130.     }
  131.  
  132. #define PUSH_FREE_HANDLE(hp) \
  133.     hp->methods = (struct methodtable *)hpoolfreelist; \
  134.     hpoolfreelist = (unsigned char *)hp;
  135.  
  136. /* Mark bit access assumes contiguity of handles and objects */
  137. #define MARKINDEX(p)    (((unsigned char *)(p) - hpmin) >> 7)
  138. #define BITOFFSET(p)    ((((unsigned char *)(p) - hpmin) >> 2) & 0x1e)
  139.  
  140. #define _MarkPtr(p, v)    (markbits[MARKINDEX(p)] |= (v) << BITOFFSET(p))
  141. #define _ClearMarkPtr(p, v) (markbits[MARKINDEX(p)] &= ~((v) << BITOFFSET(p)))
  142. #define _IsMarked(p)    ((markbits[MARKINDEX(p)] >> BITOFFSET(p)) &3)
  143.  
  144. /* set the second word in an object (from ptr to header) to 0x55555555 */
  145. #define CHECK_WORD_INDEX 1
  146.  
  147. #define MAP_OVER_HANDLES_FROM_START(MO_hp) {        \
  148.     JHandle *MOH_limit = (JHandle *) hpmax;        \
  149.     for (MO_hp = (JHandle *) hpool; MO_hp <= MOH_limit; MO_hp++) {
  150.  
  151. #define END_MAP_OVER_HANDLES_FROM_START            \
  152.     } /* end for */                    \
  153. } /* end MAP_OVER_HANDLES_FROM_START */
  154.  
  155. #define MAP_OVER_OBJECTS_FROM_START(p) {        \
  156.     unsigned char *MOO_limit = opmax;            \
  157.     unsigned char *MOO_start = opmin;            \
  158.     for (p = opmin;                    \
  159.      p < MOO_limit;                    \
  160.      p += obj_len(p)) {
  161.  
  162. #define END_MAP_OVER_OBJECTS_FROM_START            \
  163.     } /* end for */                    \
  164. } /* end END_MAP_OVER_OBJECTS_FROM_START */
  165.  
  166.  
  167. #else /************ PAGED HEAPS: ********************/
  168.  
  169. /* gc philosophy makes it necessary to detect if an arbitrary int is
  170.  * (possibly) a handle or object ref.
  171.  * A value is (possibly) valid if it is properly aligned, and it 
  172.  * points into a page that has a page map entry of the proper type.
  173.  */
  174. /* assumes ValidHorO already */
  175. #define GetPageMapEntry(p)                          \
  176.          (page_map[((int)(p) - (int)mem_base) >> PTR_2_PAGE_SHIFT])
  177.  
  178. #define ValidObject(p)    ((((int)(p)) & (OBJECTGRAIN-1)) == 0 &&            \
  179.          (void *)(p) >= mem_base &&                        \
  180.          (void *)(p) <  mem_top &&                        \
  181.          (GetPageMapEntry((p)).chunk_size > 0))
  182. #define ValidHandle(p)    (((((int)(p)) & (HANDLEGRAIN-1)) == 0) &&       \
  183.          ((void *)(p) >= mem_base) &&                    \
  184.          ((void *)(p) <  mem_top) &&                    \
  185.          (GetPageMapEntry((p)).chunk_size < 0))
  186. /* ValidHorO() assumes OBJECTGRAIN == HANDLEGRAIN... */
  187. #define ValidHorO(p)    ((((int)(p)) & (HANDLEGRAIN-1)) == 0 &&            \
  188.          (void *)(p) >= mem_base &&                        \
  189.          (void *)(p) <  mem_top &&                        \
  190.          (GetPageMapEntry((p)).chunk_size != 0))
  191.  
  192. #define SetLimits() int SL_dufus = 0
  193.  
  194. /* assumes ValidHorO already */
  195. #define ChunkBase(p)    (void *)                        \
  196.          (((int)(p) & ~(PAGE_ALIGNMENT - 1)) -            \
  197.           (GetPageMapEntry((p)).page_number << PTR_2_PAGE_SHIFT))
  198.          
  199. /* curHanBlkP must be set in advance!!! */
  200. #define POP_FREE_HANDLE(hp)                         \
  201.     hp = (JHandle *)curHanBlkP->freePtr;                     \
  202.     if (hp) {                                    \
  203.         curHanBlkP->freePtr = (unsigned char *)hp->methods;            \
  204.     }
  205.  
  206. /* Can only be called within a MAP_OVER_HANDLES_FROM_START loop 
  207.  * - uses MOH_chunk instead of curHanBlkP for efficiency.
  208.  */
  209. #define PUSH_FREE_HANDLE(hp) \
  210.     hp->methods = (struct methodtable *)MOH_chunk->freePtr; \
  211.     MOH_chunk->freePtr = (unsigned char *)hp;
  212.  
  213. #define MARKINDEX(p)    (((int)(p) & (PAGE_ALIGNMENT - 1)) >> 7)
  214. #define BITOFFSET(p)    ((((int)(p) & (PAGE_ALIGNMENT - 1)) >> 2) & 0x1e)
  215.  
  216. #define _MarkPtr(p, v)    (GetPageMapEntry(p).mark_bits[MARKINDEX(p)] |=       \
  217.                          (v) << BITOFFSET(p))
  218. #define _ClearMarkPtr(p, v) (GetPageMapEntry(p).mark_bits[MARKINDEX(p)] &= \
  219.                              ~((v) << BITOFFSET(p)))
  220. #define _IsMarked(p)    ((GetPageMapEntry(p).mark_bits[MARKINDEX(p)]       \
  221.                           >> BITOFFSET(p)) & 3)
  222.  
  223. /* # of bytes of markbits we need per page: */
  224. #define MARK_BITS_SIZE        ((PAGE_ALIGNMENT / (OBJECTGRAIN * BITSPERCHAR)) * 2)
  225.  
  226. /*
  227.  * Part of Java memory management and garbage collection.
  228.  *
  229.  * This supports a discontiguous gcable heap, which is useful for the
  230.  * Mac OS, or other platforms without good memory mapping support.
  231.  *
  232.  * CHUNKS:
  233.  * Memory is requested from the OS in "Chunks" of n pages, which are
  234.  * PAGE_ALIGNMENT aligned and sized. Handles and objects are allocated out of
  235.  * different chunks.  When more memory is needed, additional chunks can be
  236.  * allocated.  When chunks are free, they may be returned to  the OS.  Chunks
  237.  * don't need to be contiguous.  Handle chunks and object chunks are linked 
  238.  * into seperate, doubly linked lists, which are sorted by chunk address.  On
  239.  * platforms without real "memalign" support, there may be unaligned (wasted)
  240.  * space that precedes the true chunk that we can use for something else 
  241.  * (markbits come to mind).
  242.  */
  243.  
  244. /* fields marked ### MUST BE OBJECT AND/OR HANDLE GRAIN ALIGNED */
  245. typedef struct CHUNK_BLK {    /* a chunk of pages */
  246.     void* chunkHandle;        /* OS handle to this chunk */
  247.     struct CHUNK_BLK *nextPtr;    /* ptr to next chunk header */
  248.     struct CHUNK_BLK *prevPtr;    /* ptr to previous chunk header */
  249.     long chunkFlags;        /* misc flags */
  250.     long allocSize;        /* == (endPtr - startPtr)### */
  251.     long freeCnt;        /* # of free bytes in this chunk */
  252.     unsigned char *startPtr;    /* ptr to starting byte### */
  253.     unsigned char *endPtr;    /* ptr past last byte### */
  254.     unsigned char *freePtr;    /* ptr to first free space CANDIDATE 
  255.     * (may not really be free), or it might be a ptr to a free list
  256.     * of objects, depending on phase of the moon.
  257.     */
  258.     /* users may modify start and end ptrs, but not this one: */
  259.     unsigned char *physEndPtr;                
  260. #ifdef WASTED_SPACE_IN_LEADER
  261.     /* WARNING:  clearLocalMarkBits assumes that only markbits are stored
  262.           * in the waste !!!
  263.           */
  264.     unsigned char *wasteStartPtr; /* ptr to starting wasted byte */
  265.     unsigned char *wasteFreePtr;  /* ptr to first free wasted byte */
  266.                       /* wasteEndPtr == the ChunkBlk pointer */
  267. #endif /* WASTED_SPACE_IN_LEADER*/
  268. } ChunkBlk, *ChunkBlkP;
  269.  
  270. /* CHUNK_BLK->chunkFlags bits: */
  271.      /* set this bit in chunkFlags if any objects in the chunk are pinned */
  272. #define CHUNK_PINNED 1        
  273.  
  274. /* doubly-linked list of handle chunks, in address order: */
  275. extern ChunkBlkP firstHanBlkP;      
  276. extern ChunkBlkP lastHanBlkP;
  277. extern ChunkBlkP curHanBlkP;
  278. /* doubly-linked list of object chunks, in address order: */
  279. extern ChunkBlkP firstObjBlkP;
  280. extern ChunkBlkP lastObjBlkP;
  281. extern ChunkBlkP curObjBlkP;
  282.  
  283. /* store this into the last two words of the chunk to detect overwrites */
  284. /* Odd to make a poor pointer, 111 in the low bits looks like a swapped 
  285.  * free block if a header! */
  286. #define ALMOST_WORD    0x77777777
  287. #define ULTIMATE_WORD  0xBAADDEED  /* Why not. */
  288. /* set the third word in an object (from ptr to header) to 0x55555555 */
  289. #define CHECK_WORD_INDEX 2       
  290.  
  291. /* Macros to abstract out looping over all handles or objects.
  292.  * Note that you can't "break" out of this loop. Use goto or return instead.
  293.  */
  294. #define MAP_OVER_HANDLES_FROM_START(MO_hp) {        \
  295.     ChunkBlkP MOH_chunk = firstHanBlkP;            \
  296.     JHandle *MOH_limit;                    \
  297.     do {                        \
  298.     for (MO_hp = (JHandle *)MOH_chunk->startPtr,    \
  299.          MOH_limit = (JHandle *)MOH_chunk->endPtr;    \
  300.          MO_hp < MOH_limit; MO_hp++) {
  301.  
  302. #define END_MAP_OVER_HANDLES_FROM_START            \
  303.     }  /* end for */                \
  304.     MOH_chunk = MOH_chunk->nextPtr;            \
  305.     } while (MOH_chunk != firstHanBlkP);        \
  306. } /* end MAP_OVER_HANDLES_FROM_START */
  307.  
  308. #define MAP_OVER_OBJECTS_FROM_START(MO_p)   {        \
  309.     ChunkBlkP MOO_chunk = firstObjBlkP;            \
  310.     unsigned char *MOO_limit;                \
  311.     unsigned char *MOO_start;                \
  312.     do {                        \
  313.     for ((MO_p) = MOO_chunk->startPtr,         \
  314.          MOO_start = MOO_chunk->startPtr,        \
  315.          MOO_limit = MOO_chunk->endPtr;        \
  316.          (MO_p) < MOO_limit;            \
  317.          (MO_p) += obj_len(MO_p)) {
  318.  
  319. #define END_MAP_OVER_OBJECTS_FROM_START            \
  320.     }  /* end for */                \
  321.     MOO_chunk = MOO_chunk->nextPtr;            \
  322.     } while (MOO_chunk != firstObjBlkP);        \
  323. } /* end END_MAP_OVER_OBJECTS_FROM_START */
  324.  
  325. #endif /************ END PAGED HEAPS ********************/    
  326.  
  327.  
  328. #ifdef WASTED_SPACE_IN_LEADER
  329. /* following functions defined in gc_md.c: */
  330. void initWastedSpaceInChunk(ChunkBlkP chunk);
  331. void sysCheckWastedSpace(ChunkBlkP chunk);
  332. void clearLocalMarkBits(void);
  333. void* allocMarkBitsLocally(ChunkBlkP blkP);
  334. #else
  335. #define initWastedSpaceInChunk(xxx) 0
  336. #define sysCheckWastedSpace(xxx) 0
  337. #define clearLocalMarkBits() 0
  338. #define allocMarkBitsLocally(xxx) 0
  339. #endif
  340.  
  341. #endif /* !_GC_H_ */
  342.