/* heap.h
*
* COPYRIGHT (c) 1993 by AT&T Bell Laboratories.
*
* These are the definitions for the heap structure.
*/
#ifndef _HEAP_
#define _HEAP_
#ifndef _ML_BASE_
#include "ml-base.h"
#endif
#ifndef _GC_
#include "gc.h"
#endif
#ifndef _ARENA_ID_
#include "arena-id.h"
#endif
#ifndef _TAGS_
#include "tags.h"
#endif
#ifndef _MEMORY_
typedef struct mem_obj mem_obj_t;
#endif
#ifndef _CARD_MAP_
typedef struct card_map card_map_t;
#endif
#if ((defined(COLLECT_STATS) || defined(GC_STATS)) && (! defined(_CNTR_)))
#include "cntr.h"
#endif
struct heap_params {
Addr_t allocSz; /* the size of the allocation arena */
int numGens;
int cacheGen;
};
typedef struct repair repair_t;
typedef struct arena arena_t;
typedef struct bigobj_region bigobj_region_t;
typedef struct bigobj_desc bigobj_desc_t;
typedef struct generation gen_t;
/* typedef struct heap heap_t; */ /** defined in ml-base.h **/
/** A heap **
* A heap consists of an allocation space and one or more generations.
*/
struct heap {
ml_val_t *allocBase; /* The base address of the allocation arena */
Addr_t allocSzB; /* The size in bytes of the allocation arena */
mem_obj_t *baseObj; /* The OS memory object that contains the */
/* BIBOP and allocation arena. */
int numGens; /* The number of active generations. */
int cacheGen; /* Cache the from-space for gens 1..cacheGen. */
int numMinorGCs; /* The number of times the allocation space */
/* has been collected. */
gen_t *gen[MAX_NUM_GENS]; /* generation #i is gen[i-1] */
int numBORegions; /* the number of active big-object regions */
bigobj_region_t *bigRegions; /* points to the list of big object regions. */
bigobj_desc_t *freeBigObjs; /* points to the header of the free-list */
/* of big objects. */
ml_val_t *weakList; /* A list of weak pointers forwarded*/
/* during GC. */
#if (defined(COLLECT_STATS) || defined(GC_STATS))
cntr_t numAlloc; /* Keep track of the number of bytes */
/* allocated and the number copied into */
#ifdef GC_STATS
cntr_t numCopied /* each arena. */
[MAX_NUM_GENS][NUM_ARENAS];
#endif
#endif
#ifdef HEAP_MONITOR
struct monitor *monitor; /* The various graphical data structures */
/* for monitoring the heap. */
#endif
};
#ifdef OLD
/* once we figure out multiple arenas for the MP version, we should
* be able to go back to the old version of this.
*/
#define HEAP_LIMIT(hp) \
(ml_val_t *)((Addr_t)((hp)->allocBase) + (hp)->allocSzB - HEAP_BUF_SZB)
#else
#define HEAP_LIMIT_SIZE(base,size) \
(ml_val_t *)((Addr_t)(base) + (size) - HEAP_BUF_SZB)
#define HEAP_LIMIT(hp) HEAP_LIMIT_SIZE((hp)->allocBase,(hp)->allocSzB)
#endif
/** A generation **/
struct generation {
heap_t *heap; /* A back pointer to the heap data structure */
int genNum; /* Which generation this is (1..numGens) */
int numGCs; /* The number of times this generation has been */
/* collected. */
int lastPrevGC; /* The number GCs of the previous (younger) generation */
/* the last time this generation was collected. */
int ratio; /* The desired number of collections of the previous */
/* generation for one collection of this generation */
arena_t *arena[NUM_ARENAS];
bigobj_desc_t *bigObjs[NUM_BIGOBJ_KINDS];
mem_obj_t *toObj; /* The O.S. memory objects that this generation is */
mem_obj_t *fromObj; /* using for the to-space and from-space */
mem_obj_t *cacheObj; /* For younger generations, we cache the virtual */
/* memory of from-space, instead of giving it back. */
card_map_t *dirty; /* The dirty cards in the array arena of this gen. */
};
/** An arena **/
struct arena {
aid_t id; /* The to-space version of this arena's identifier */
ml_val_t *nextw; /* The next word to allocate in this arena's to-space */
ml_val_t *tospBase; /* the base address and size of to-space. */
Addr_t tospSizeB;
ml_val_t *tospTop; /* The top of the to-space (tospBase+tospSizeB). */
ml_val_t *sweep_nextw; /* The next word to sweep in the to-space arena */
repair_t *repairList; /* points to the top of the repair list (for */
/* blasting out objects). The repair list grows */
/* down in to-space. */
ml_val_t *frspBase; /* the base address and size of from-space. */
Word_t frspSizeB;
ml_val_t *frspTop; /* The top of the used portion of from-space. */
ml_val_t *oldTop; /* The top of the "older" from-space region. Objects */
/* below oldTop get promoted, those above don't. */
arena_t *nextGen; /* The arena to promote objects to. */
bool_t needsRepair; /* Set to TRUE when exporting, if the arena had */
/* external references that require repair */
/* Heap sizing parameters: */
Word_t reqSizeB; /* requested minimum size for this arena (this is */
/* in addition to the required min. size). */
Word_t maxSizeB; /* a soft maximum size for this arena. */
};
/* Make to-space into from-space */
#define FLIP_ARENA(ap) { \
arena_t *__ap = (ap); \
__ap->frspBase = __ap->tospBase; \
__ap->frspSizeB = __ap->tospSizeB; \
__ap->frspTop = __ap->nextw; \
}
/* Return true if this arena has an allocated ToSpace */
#define isACTIVE(a) ((a)->tospSizeB > 0)
/* Return true if this arena's ToSpace needs sweeping */
#define NEEDS_SWEEPING(a) ((a)->sweep_nextw < (a)->nextw)
/* Return the amount of free space (in bytes) available in an arena */
#define AVAIL_SPACE(a) ((Addr_t)((a)->tospTop) - (Addr_t)((a)->nextw))
/* Return the amount of allocated space (in bytes) in an arena */
#define USED_SPACE(a) ((Addr_t)((a)->nextw) - (Addr_t)((a)->tospBase))
/* Return true if the address addr is an older object in this arena */
#define isOLDER(a,addr) ((addr) < (a)->oldTop)
/** Big object regions **
*
* Currently, the only big objects are code objects.
*/
/*#define BIGOBJ_PAGE_SHIFT 12*/ /* 4Kb */
#define BIGOBJ_PAGE_SHIFT 10 /* 1Kb */
#define BIGOBJ_PAGE_SZB (1 << BIGOBJ_PAGE_SHIFT)
#define MIN_BOREGION_SZB (128*ONE_K)
struct bigobj_region { /* A big-object region header */
Addr_t firstPage; /* the address of the first page of the region */
int nPages; /* the number of big-object pages in this region */
int nFree; /* the number of free pages */
int minGen; /* the minimum generation of the live objects in */
/* this region. */
mem_obj_t *memObj; /* the memory object that this is allocated in */
bigobj_region_t *next; /* the next region in the list of regions */
bigobj_desc_t *objMap[1]; /* the map from pages to big-object descriptors */
};
/* the size of a big-object region header */
#define BOREGION_HDR_SZB(NPAGES) \
(sizeof(bigobj_region_t) + ((NPAGES-1)*sizeof(bigobj_desc_t *)))
/* map an address to a big-object page index */
#define ADDR_TO_BOPAGE(R, ADDR) \
(((Addr_t)(ADDR) - (R)->firstPage) >> BIGOBJ_PAGE_SHIFT)
/* map an address to a big-object descriptor */
#define ADDR_TO_BODESC(R, ADDR) \
((R)->objMap[ADDR_TO_BOPAGE(R, ADDR)])
struct bigobj_desc { /* A big-object descriptor. */
Addr_t obj; /* the actual object */
Addr_t sizeB; /* the size of the object in bytes. When the object */
/* is in the free list, this will be a multiple of */
/* BIGOBJ_PAGE_SZB, otherwise it is the exact size. */
unsigned char objc; /* the object class */
unsigned char state; /* the state of the object */
unsigned char gen; /* the object's generation */
bigobj_region_t *region; /* the region this big object is in */
bigobj_desc_t *prev; /* the prev and next links. The big-object free */
bigobj_desc_t *next; /* list is a doubly linked list; the other lists */
/* are singly linked lists */
};
/* the rounded size of a big-object */
#define BO_ROUNDED_SZB(BDP) ROUNDUP((BDP)->sizeB, BIGOBJ_PAGE_SZB)
/* the number of big-object pages occupied by a big-object */
#define BO_NUM_BOPAGES(BDP) (BO_ROUNDED_SZB(BDP) >> BIGOBJ_PAGE_SHIFT)
/* big-object descriptor states */
#define BO_FREE 0 /* a free big-object */
#define BO_YOUNG 1 /* a young object (i.e., one that has never */
/* been forwarded in its generation */
#define BO_FORWARD 2 /* a forwarded young object */
#define BO_OLD 3 /* an old object */
#define BO_PROMOTE 4 /* a promoted old object */
#define BO_IS_FROM_SPACE(dp) (((dp)->state & 0x1) != 0)
#define BO_IS_FREE(dp) ((dp)->state == BO_FREE)
/* remove a descriptor from a doubly linked list */
#define REMOVE_BODESC(dp) { \
bigobj_desc_t *__dp = (dp), *__p, *__n; \
__p = __dp->prev; \
__n = __dp->next; \
__p->next = __n; \
__n->prev = __p; \
}
/* add a descriptor to a doubly linked list */
#define ADD_BODESC(hdr, desc) { \
bigobj_desc_t *__hdr = (hdr), *__dp = (desc); \
__dp->next = __hdr->next; \
__dp->prev = __hdr; \
__hdr->next->prev = __dp; \
__hdr->next = __dp; \
}
/** operations on forward pointers **/
/* follow a forward pointer. HDR is the object header, P is the pointer to
* the object.
* NOTE: we need the two type casts for 32/64 bit systems.
*/
#define FOLLOW_FWDOBJ(HDR) ((ml_val_t *)(((ml_val_t *)(HDR))[0]))
/* follow a pair-space forward pointer (this is tagged as a descriptor). */
#define FOLLOW_FWDPAIR(DESC, HDR) \
((ml_val_t *)(((Addr_t)(DESC)) & ~MAJOR_MASK))
/* make a pair-space forward pointer (this is tagged as a descriptor). */
#define MAKE_PAIR_FP(NEW_ADDR) ((ml_val_t)((Addr_t)(NEW_ADDR) | TAG_desc))
/** External GC functions **/
extern void MinorGC (ml_state_t *msp, ml_val_t **roots);
extern void MajorGC (ml_state_t *msp, ml_val_t **roots, int level);
extern int Flip (heap_t *heap, int min_gc_level);
extern status_t NewGeneration (gen_t *gen);
extern void FreeGeneration (heap_t *heap, int g);
extern void NewDirtyVector (gen_t *gen);
extern void MarkRegion (bibop_t bibop, ml_val_t *base, Word_t sizeB, aid_t id);
extern void ScanWeakPtrs (heap_t *heap);
extern bigobj_desc_t *BO_AllocRegion (heap_t *heap, Addr_t szB);
extern bigobj_desc_t *BO_Alloc (heap_t *heap, int gen, Addr_t objSzB);
extern void BO_Free (heap_t *heap, bigobj_desc_t *desc);
extern bigobj_desc_t *BO_GetDesc (ml_val_t addr);
extern Byte_t *BO_GetCodeObjTag (bigobj_desc_t *bdp);
#ifdef BO_DEBUG
extern void PrintRegionMap (bigobj_region_t *r);
#endif
#ifdef CHECK_GC
extern void CheckHeap (heap_t *heap, int maxSweptGen);
#endif
#endif /* !_HEAP_ */
syntax highlighted by Code2HTML, v. 0.9.1