/* dataStructures.h

   All the data structures for the garbage collector.

   Notes: There are many "lists" in gcInfo.  These are actually circularl doubly
   linked lists with a dummy element(head).  The dummy element is stored in
   gcInfo.  It should never be cut out, inserted, or used in any way.
*/

#ifndef __DATA_STRUCTURES_H
#define __DATA_STRUCTURES_H

#include "debug.h"
#include "macros.h"

/* Defines ....................................................................*/
#define LOG_WORD_SIZE (5)
#define WORD_SIZE (0x1 << LOG_WORD_SIZE)
#define LOG_WORD_SIZE_BYTES (LOG_WORD_SIZE - 3)

#ifndef ALL_ONES
#define ALL_ONES ((unsigned int)~0)
#endif

#define LOG_PI_SIZE (2)
#define PI_SIZE (0x1 << LOG_PI_SIZE)

#define LOG_PI_SIZE_BYTES (LOG_PI_SIZE + LOG_WORD_SIZE_BYTES)
#define PI_SIZE_BYTES (0x1 << LOG_PI_SIZE_BYTES)

#define LOG_PAGE_SIZE (9)
#define PAGE_SIZE (0x1 << LOG_PAGE_SIZE)

#define LOG_PAGE_SIZE_BYTES (LOG_PAGE_SIZE + LOG_WORD_SIZE_BYTES)
#define PAGE_SIZE_BYTES (0x1 << LOG_PAGE_SIZE_BYTES)

#define COPYABLE_OBJECT (PAGE_SIZE >> 1)
#define PAGE_BITMASK_SIZE (PAGE_SIZE/WORD_SIZE)

#define DEQUE_BUFFER_SIZE (PAGE_SIZE)

/* BLOCK refers to a heap block. */
#define LOG_BLOCK_SIZE (17)
#define BLOCK_SIZE (0x1 << LOG_BLOCK_SIZE)

#define LOG_BLOCK_SIZE_BYTES (LOG_BLOCK_SIZE + LOG_WORD_SIZE_BYTES)

#define PAGES_PER_BLOCK (BLOCK_SIZE/PAGE_SIZE)
#define PI_WORDS_PER_BLOCK (PAGES_PER_BLOCK*sizeof(PageInfo)/sizeof(Word))

/* We need the extra page for the next pointer. */
#define SYSTEM_PAGES_PER_BLOCK (PI_WORDS_PER_BLOCK/PAGE_SIZE + \
				(PI_WORDS_PER_BLOCK%PAGE_SIZE ? 0 : 1))

#define FREE_PAGES_PER_BLOCK (PAGES_PER_BLOCK - SYSTEM_PAGES_PER_BLOCK)

/* All sizes in Words(= 4 bytes) */
#define MAXIMUM_HEAP_SIZE (0x1 << 26)
#define MAXIMUM_BLOCKS ((Word)(((Word)ALL_ONES) / BLOCK_SIZE) + 1)

/* GENERATIONS */
#define NUM_GENERATIONS 2
#define RATIO 0.3

#define CLEAR_STACK_FREQUENCY 50
/* Types ......................................................................*/

typedef unsigned int Word;

typedef struct PInfo
{
  Word header;
  struct PInfo *next;
  struct PInfo *prev;
  Word reserved;
#ifdef PAGE_BITMASKS
  Word bitmask[PAGE_BITMASK_SIZE];  
#endif
} PageInfo;

typedef struct 
{
 Word header;
 PageInfo *next;
 Word* start; /* Points to the first object in the Deque. */
 Word* end; /* Points one past the last object in the Deque. */
} Deque;

typedef struct
{
  PageInfo space;
  Deque *cObjects;
  
  unsigned int nPages;

  unsigned int nCollections;
} Generation;

/* HeapBlock is only used to determine where next is, and to coerce to pageInfo. */
typedef struct hb
{
  PageInfo pageInfo[PAGES_PER_BLOCK];
  struct hb *next; /* Points to the next heapBlock. */
} HeapBlock;

typedef struct
{
 unsigned int nCollections;

 unsigned int nPages;
 unsigned int nPagesInUse; 
 unsigned int nPagesAllocated; /* Number of pages that were allocated since the
				  last collection. */
 unsigned int collectionBoundary; /* # of pages that must be allocated to
				     trigger a collection when gen's are on. */

  /* The following two variables are used to determine when to collect.  They
     try to collect when the stack is small. */
 unsigned int goodStack;  /* bestStack from last sequence of attempts */
 unsigned int currentAttempt; /* What attempt are we on now. */
 unsigned int currentBestStack; /* Best stack we've seen in this run. */
 unsigned int maxAttempt; /* Maximum number of pages we are allowed to try
			     before we have to collect. 1% of heap. */

 Word *stackBottom;
 Word *stackTop;
 Word *staticBoundary; /* The beginning of the static area.  Opposite to end. */

 Word *clearedStackBottom; /* Address "above" which the stack has been
			      cleared. */ 
 Word *clearedStackTop; /* Address "below" which the stack has been cleared. */
 unsigned int clearStackCount;

 Word *heap;
 Word *heapEnd;
 unsigned int heapSize; /* in Words */
 unsigned int nBlocks; /* Number of heap blocks used. */
 
 Word *blockHead;
 Word *blockTail;
 Word blockBitmask[BITMASK_WORD_OFFSET(MAXIMUM_BLOCKS)];

 Generation generation[NUM_GENERATIONS]; /* For Generations only. */
 unsigned int nBasicCollections;

 unsigned int currentGeneration; /* For Generations only. */
 unsigned int pageCounter; /* For Generations only. */

 Deque *explicitQueue;

 Deque *cObjects;

 Deque *volatileObjects;

 PageInfo fromSpaceList;
 PageInfo toSpaceList;
 PageInfo pinnedPageList;
 PageInfo freeList;

 BLACKLIST(PageInfo blackList);
 BLACKLIST(unsigned int nBlackListedPages);

#ifdef HARD_LIMIT
 unsigned int hardLimit; /* Set to true once heap reaches specified upper
			    limit.  After that the heap may not expand. */
#endif

 DECL_ACCUM_ALWAYS(collectorTime);
 DECL_TIMER_ALWAYS(totalTime);

 DECL_ACCUM_ALWAYS(tAllocTime);
 unsigned int nAllocCalls;

 /* n short for numberOf */
 unsigned int nObjectsAllocated; /* STATS */
 unsigned int nWordsAllocated;   /* STATS */
 unsigned int nLargeObjectPages; /* STATS */

 unsigned int nLiveObjects;      /* STATS */
 unsigned int nLiveWords;        /* STATS */
 unsigned int nCObjects;         /* STATS */
 unsigned int nPinnedObjects;    /* STATS */
 unsigned int nTraversedObjects; /* STATS */

 unsigned int nRoots;            /* STATS */
 unsigned int nFalseRoots;       /* STATS */
 unsigned int nDeviousRoots;     /* STATS */
 unsigned int nDuplicates;       /* STATS */

 unsigned int nSystemPages;      /* STATS */
 unsigned int nPinnedPages;      /* STATS */
 unsigned int nWastedSpace;      /* STATS */ /* In Words */

} GcInfo;

/* Global variables .... */
extern GcInfo gcInfo;

#ifdef REGISTER_ALLOCATE
register Word *gcAllocPtr asm ("g6");
#else
extern Word *gcAllocPtr;
#endif 
 
#endif

/* EOF: dataStructures.h */

/* (c) Frederick Smith, Greg Morrisett.
 *     October 1998, all rights reserved.
 *
 *
 *              Copyright 1990-1993 Digital Equipment Corporation
 *                         All Rights Reserved
 *
 * Permission to use, copy, and modify this software and its documentation is
 * hereby granted only under the following terms and conditions.  Both the
 * above copyright notice and this permission notice must appear in all copies
 * of the software, derivative works or modified versions, and any portions
 * thereof, and both notices must appear in supporting documentation.
 *
 * Users of this software agree to the terms and conditions set forth herein,
 * and hereby grant back to Digital a non-exclusive, unrestricted, royalty-free
 * right and license under any changes, enhancements or extensions made to the
 * core functions of the software, including but not limited to those affording
 * compatibility with other hardware or software environments, but excluding
 * applications which incorporate this software.  Users further agree to use
 * their best efforts to return to Digital any such changes, enhancements or
 * extensions that they make and inform Digital of noteworthy uses of this
 * software.  Correspondence should be provided to Digital at:
 * 
 *                       Director of Licensing
 *                       Western Research Laboratory
 *                       Digital Equipment Corporation
 *                       250 University Avenue
 *                       Palo Alto, California  94301  
 * 
 * This software may be distributed (but not offered for sale or transferred
 * for compensation) to third parties, provided such third parties agree to
 * abide by the terms and conditions of this notice.  
 * 
 * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
 * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
 * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 * SOFTWARE.
 */
