src/interp/pvalalloc.c
/*========================================
 * alloc_pvalue_memory -- return new pvalue memory
 * We use a custom allocator, which lowers our overhead
 *  (no heap overhead per pvalue, only per block)
 *  and also allows us to clean them all up after the
 *  report.
 * NB: This is not traditional garbage collection - we're
 *  not doing any live/dead analysis; we depend entirely
 *  on carnal knowledge of the program.
 * We also mark freed ones, so we can scan the blocks
 *  to find leaked ones (which used to be nearly
 *  all of them)
 * Created: 2001/01/19, Perry Rapp
 *======================================*/
- return new pvalue memory
We use a custom allocator, which lowers our overhead
(no heap overhead per pvalue, only per block)
and also allows us to clean them all up after the
report.
NB: This is not traditional garbage collection - we're
not doing any live/dead analysis; we depend entirely
on carnal knowledge of the program.
We also mark freed ones, so we can scan the blocks
to find leaked ones (which used to be nearly
all of them)
Created: 2001/01/19, Perry Rapp
- return new pvalue memory We use a custom allocator which lowers our overhead ( no heap overhead per pvalue only per block ) and also allows us to clean them all up after the report . NB : This is not traditional garbage collection - we ' re not doing any live / dead analysis ; we depend entirely on carnal knowledge of the program . We also mark freed ones so we can scan the blocks to find leaked ones ( which used to be nearly all of them ) Created : 2001 / 01 / 19 Perry Rapp
PVALUE
alloc_pvalue_memory (void)
{
	PVALUE val;
	ASSERT(reports_time);
#ifdef NOBLOCKALLOCATOR
	val = stdalloc(sizeof(*val));
#else 
	if (!free_list) {
		PV_BLOCK new_block = stdalloc(sizeof(*new_block));
		INT i;
		new_block->next = block_list;
		block_list = new_block;
		for (i=0; i<(INT)BLOCK_VALUES; i++) {
			PVALUE val1 = &new_block->values[i];
			init_pvalue_vtable(val1);
			val1->type = PFREED;
			val1->value.pxd = free_list;
			free_list = val1;
			if (debugging_pvalues)
				debug_check();
		}
	}
	val = free_list;
	free_list = free_list->value.pxd;
	if (debugging_pvalues)
		debug_check();
	live_pvalues++;
#endif
	ptype(val) = PNULL;
	val->value.pxd = 0;
	return val;
}
PVALUE alloc_pvalue_memory ( void ) { PVALUE val ; ASSERT ( reports_time ) ; #ifdef NOBLOCKALLOCATOR val = stdalloc ( sizeof ( * val ) ) ; #else if ( ! free_list ) { PV_BLOCK new_block = stdalloc ( sizeof ( * new_block ) ) ; INT i ; new_block -> next = block_list ; block_list = new_block ; for ( i = 0 ; i < ( INT ) BLOCK_VALUES ; i ++ ) { PVALUE val1 = & new_block -> values [ i ] ; init_pvalue_vtable ( val1 ) ; val1 -> type = PFREED ; val1 -> value . pxd = free_list ; free_list = val1 ; if ( debugging_pvalues ) debug_check ( ) ; } } val = free_list ; free_list = free_list -> value . pxd ; if ( debugging_pvalues ) debug_check ( ) ; live_pvalues ++ ; #endif ptype ( val ) = PNULL ; val -> value . pxd = 0 ; return val ; }
alloc_pvalue_memory -- return new pvalue memory
 We use a custom allocator, which lowers our overhead
  (no heap overhead per pvalue, only per block)
  and also allows us to clean them all up after the
  report.
alloc_pvalue_memory -- return new pvalue memory We use a custom allocator which lowers our overhead ( no heap overhead per pvalue only per block ) and also allows us to clean them all up after the report .
/*
	We assume that all pvalues are scoped
	within report processing. If this ceases to
	be true, this has to be rethought.
	Eg, we could use a bitmask in the type field to mark
	truly heap-alloc'd pvalues, used outside of reports.
	*/ /* no pvalues available, make a new block */ /* add all pvalues in new block to free list */ /* pull pvalue off of free list */ /* set type to uninitialized - caller ought to set type */