/* heap.c
   Basic heap routines.
*/
#include <stdlib.h>
#include <assert.h>

#include "prototypes.h"
#include "pageHeader.h"

void allocateHeapBlock(void)
{
 HeapBlock *currentHeap;
 HeapBlock *hb;
 PageInfo *pi;
 PageInfo *piEnd;
 PageInfo *tempList, *tempListTail;
 Word *p;
 Word blockNumber;

#ifdef HARD_LIMIT
 if(gcInfo.hardLimit)
   {
     fprintf(stderr,"Attempt to expand heap beyond hard limit set.(%d)\n",
	     gcInfo.heapSize);
     exit(0-1);
   }
#endif

 hb = (HeapBlock *)memalign(BLOCK_SIZE * sizeof(Word),BLOCK_SIZE *
			    sizeof(Word));
 if(hb==NULL)
   {
     LOG_MESSAGE_ALWAYS("Failed to allocate a new heap block. Exiting.\n");
     exit(-1);
   }

 hb->next = NULL;

 currentHeap = (HeapBlock *)gcInfo.blockTail;
 if(currentHeap == NULL)  /* First element allocated. */
   {
     gcInfo.blockHead = (Word *)hb;
     gcInfo.blockTail = gcInfo.blockHead;
     gcInfo.heap = (Word *)hb;
     gcInfo.heapEnd = (Word *)hb + BLOCK_SIZE;
   }
 else /* It is crucial that this be added to the end of the  list. */
   {
     currentHeap->next = hb;
     gcInfo.blockTail = (Word *)hb;
   }

 blockNumber = BLOCK_NUMBER(hb);
 assert(blockNumber < MAXIMUM_BLOCKS);
 assert(blockNumber >= 0);

 gcInfo.blockBitmask[BITMASK_WORD_OFFSET(blockNumber)] |= 
   (0x1 << BITMASK_BIT_OFFSET(blockNumber));

 gcInfo.nBlocks++;
 gcInfo.nPages += PAGES_PER_BLOCK;
 gcInfo.heapSize += BLOCK_SIZE;
 
 if(gcInfo.heap > (Word *)hb)
   {
     gcInfo.heap = (Word *)hb;
   }

 if(gcInfo.heapEnd < (((Word *)hb) + BLOCK_SIZE))
   {
     gcInfo.heapEnd = (((Word *)hb) + BLOCK_SIZE);
   }

 pi = (PageInfo *)hb;
 piEnd = pi + PAGES_PER_BLOCK;
 p = (Word *)hb;

 /* Setup pages with pageInfo structures on them. */
 for(;p < GC_PAGE_END(&(hb->next)); pi++, p+=PAGE_SIZE)
   {
     assert(pi < piEnd);

     pi->header = PAGE_SYSTEM | PAGE_RESERVED;

     STATS(gcInfo.nSystemPages++);
     gcInfo.nPagesInUse++;

     pi->next = NULL;
     pi->prev = NULL;
     pi->reserved = 0;
   }


 /*Add free pages onto the freeList. */
 tempList=pi;
 tempListTail=NULL;
 for(; pi < piEnd; pi++)
   {
     pi->header = PAGE_FREE;
     pi->reserved = 0;
     
     pi->prev = tempListTail;
     pi->next = pi+1;
     tempListTail = pi;
   }

 assert(tempListTail == pi-1);

 LIST_APPEND_DOUBLY_LINKED(&gcInfo.freeList,tempList,tempListTail);

}
/* EOF: heap.c */

/* (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.
 */
