Exemple #1
0
//------------ Begin of function HillRes::scan -----------//
short HillRes::scan(char patternId, char searchPriority, char specialFlag, char findFirst)
{
	err_when(patternId < 1 || patternId > max_pattern_id);

	// ------- find the range which patternId may exist ------//
	// find the start of this pattern and next pattern
	short startBlockIdx = first_block(patternId);
	short endBlockIdx = first_block(patternId+1);
	short foundBlockId = 0;
	short foundCount = 0;

	for(short j = startBlockIdx; j < endBlockIdx; ++j)
	{
		HillBlockInfo *hillBlockInfo = hill_block_info_array+j-1;
		if( hillBlockInfo->pattern_id == patternId &&
			hillBlockInfo->priority == searchPriority &&
			hillBlockInfo->special_flag == specialFlag)
		{
			if( findFirst)
				return j;
			if( misc.random(++foundCount) == 0)
			{
				foundBlockId = j;
			}
		}
	}
	return foundBlockId;	// not found
}
Exemple #2
0
static void load_code_heap(FILE *file, image_header *h, vm_parameters *p)
{
	cell good_size = h->code_size + (1 << 19);

	if(good_size > p->code_size)
		p->code_size = good_size;

	init_code_heap(p->code_size);

	if(h->code_size != 0)
	{
		size_t bytes_read = fread(first_block(&code),1,h->code_size,file);
		if(bytes_read != h->code_size)
		{
			print_string("truncated image: ");
			print_fixnum(bytes_read);
			print_string(" bytes read, ");
			print_cell(h->code_size);
			print_string(" bytes expected\n");
			fatal_error("load_code_heap failed",0);
		}
	}

	code_relocation_base = h->code_relocation_base;
	build_free_list(&code,h->code_size);
}
Exemple #3
0
/* After code GC, all referenced code blocks have status set to B_MARKED, so any
which are allocated and not marked can be reclaimed. */
void free_unmarked(F_HEAP *heap)
{
	F_BLOCK *prev = NULL;
	F_BLOCK *scan = first_block(heap);

	while(scan)
	{
		switch(scan->status)
		{
		case B_ALLOCATED:
			if(prev && prev->status == B_FREE)
				prev->size += scan->size;
			else
			{
				scan->status = B_FREE;
				prev = scan;
			}
			break;
		case B_FREE:
			if(prev && prev->status == B_FREE)
				prev->size += scan->size;
			break;
		case B_MARKED:
			scan->status = B_ALLOCATED;
			prev = scan;
			break;
		default:
			critical_error("Invalid scan->status",(CELL)scan);
		}

		scan = next_block(heap,scan);
	}

	build_free_list(heap,heap->segment->size);
}
Exemple #4
0
/* Compute total sum of sizes of free blocks, and size of largest free block */
void heap_usage(F_HEAP *heap, CELL *used, CELL *total_free, CELL *max_free)
{
	*used = 0;
	*total_free = 0;
	*max_free = 0;

	F_BLOCK *scan = first_block(heap);

	while(scan)
	{
		switch(scan->status)
		{
		case B_ALLOCATED:
			*used += scan->size;
			break;
		case B_FREE:
			*total_free += scan->size;
			if(scan->size > *max_free)
				*max_free = scan->size;
			break;
		default:
			critical_error("Invalid scan->status",(CELL)scan);
		}

		scan = next_block(heap,scan);
	}
}
Exemple #5
0
/* Compute total sum of sizes of free blocks, and size of largest free block */
void heap::heap_usage(cell *used, cell *total_free, cell *max_free)
{
	*used = 0;
	*total_free = 0;
	*max_free = 0;

	heap_block *scan = first_block();

	while(scan)
	{
		switch(scan->status)
		{
		case B_ALLOCATED:
			*used += scan->size;
			break;
		case B_FREE:
			*total_free += scan->size;
			if(scan->size > *max_free)
				*max_free = scan->size;
			break;
		default:
			myvm->critical_error("Invalid scan->status",(cell)scan);
		}

		scan = next_block(scan);
	}
}
Exemple #6
0
bool WavpackSource::parseWrapper()
{
    int fd = fileno(m_fp.get());
    util::FilePositionSaver saver__(fd);
    _lseeki64(fd, 0, SEEK_SET);

    WavpackHeader hdr;
    if (read(fd, &hdr, sizeof(hdr)) != sizeof(hdr))
        return false;
    if (std::memcmp(hdr.ckID, "wvpk", 4) != 0)
        return false;
    if (hdr.ckSize < sizeof(hdr) || hdr.ckSize > 0x1000000)
        return false;
    std::vector<char> first_block(hdr.ckSize);

    _lseeki64(fd, 0, SEEK_SET);
    if (read(fd, &first_block[0], hdr.ckSize) != hdr.ckSize)
        return false;
    void *loc = m_module.GetWrapperLocation(&first_block[0], 0);
    if (!loc)
        return false;
    ptrdiff_t off = static_cast<char *>(loc) - &first_block[0];
    _lseeki64(fd, off, SEEK_SET);

    try {
        WaveSource src(m_fp, false);
        memcpy(&m_asbd, &src.getSampleFormat(), sizeof(m_asbd));
        return true;
    } catch (const std::runtime_error &) {
        return false;
    }
}
Exemple #7
0
/* Save the current image to disk */
bool save_image(const F_CHAR *filename)
{
	FILE* file;
	F_HEADER h;

	FPRINTF(stderr,"*** Saving %s...\n",filename);

	file = OPEN_WRITE(filename);
	if(file == NULL)
	{
		fprintf(stderr,"Cannot open image file: %s\n",strerror(errno));
		return false;
	}

	F_ZONE *tenured = &data_heap->generations[TENURED];

	h.magic = IMAGE_MAGIC;
	h.version = IMAGE_VERSION;
	h.data_relocation_base = tenured->start;
	h.data_size = tenured->here - tenured->start;
	h.code_relocation_base = code_heap.segment->start;
	h.code_size = heap_size(&code_heap);

	h.t = T;
	h.bignum_zero = bignum_zero;
	h.bignum_pos_one = bignum_pos_one;
	h.bignum_neg_one = bignum_neg_one;

	CELL i;
	for(i = 0; i < USER_ENV; i++)
	{
		if(i < FIRST_SAVE_ENV)
			h.userenv[i] = F;
		else
			h.userenv[i] = userenv[i];
	}

	fwrite(&h,sizeof(F_HEADER),1,file);

	if(fwrite((void*)tenured->start,h.data_size,1,file) != 1)
	{
		fprintf(stderr,"Save data heap failed: %s\n",strerror(errno));
		return false;
	}

	if(fwrite(first_block(&code_heap),h.code_size,1,file) != 1)
	{
		fprintf(stderr,"Save code heap failed: %s\n",strerror(errno));
		return false;
	}

	if(fclose(file))
	{
		fprintf(stderr,"Failed to close image file: %s\n",strerror(errno));
		return false;
	}

	return true;
}
Exemple #8
0
/* Compute where each block is going to go, after compaction */
cell heap::compute_heap_forwarding()
{
	heap_block *scan = first_block();
	char *address = (char *)first_block();

	while(scan)
	{
		if(scan->type() != FREE_BLOCK_TYPE)
		{
			forwarding[scan] = address;
			address += scan->size();
		}
		scan = next_block(scan);
	}

	return (cell)address - seg->start;
}
Exemple #9
0
void heap::clear_mark_bits()
{
	heap_block *scan = first_block();

	while(scan)
	{
		scan->set_marked_p(false);
		scan = next_block(scan);
	}
}
Exemple #10
0
/* Compute where each block is going to go, after compaction */
cell heap::compute_heap_forwarding(unordered_map<heap_block *,char *> &forwarding)
{
	heap_block *scan = first_block();
	char *address = (char *)first_block();

	while(scan)
	{
		if(scan->status == B_ALLOCATED)
		{
			forwarding[scan] = address;
			address += scan->size;
		}
		else if(scan->status == B_MARKED)
			myvm->critical_error("Why is the block marked?",0);

		scan = next_block(scan);
	}

	return (cell)address - seg->start;
}
Exemple #11
0
/* Apply a function to every code block */
void iterate_code_heap(CODE_HEAP_ITERATOR iter)
{
	F_BLOCK *scan = first_block(&code_heap);

	while(scan)
	{
		if(scan->status != B_FREE)
			iterate_code_heap_step(block_to_compiled(scan),iter);
		scan = next_block(&code_heap,scan);
	}
}
Exemple #12
0
/* Compute where each block is going to go, after compaction */
CELL compute_heap_forwarding(F_HEAP *heap)
{
	F_BLOCK *scan = first_block(heap);
	CELL address = (CELL)first_block(heap);

	while(scan)
	{
		if(scan->status == B_ALLOCATED)
		{
			scan->forwarding = (F_BLOCK *)address;
			address += scan->size;
		}
		else if(scan->status == B_MARKED)
			critical_error("Why is the block marked?",0);

		scan = next_block(heap,scan);
	}

	return address - heap->segment->start;
}
Exemple #13
0
/* If in the middle of code GC, we have to grow the heap, data GC restarts from
scratch, so we have to unmark any marked blocks. */
void heap::unmark_marked()
{
	heap_block *scan = first_block();

	while(scan)
	{
		if(scan->status == B_MARKED)
			scan->status = B_ALLOCATED;

		scan = next_block(scan);
	}
}
Exemple #14
0
/* Called after reading the code heap from the image file, and after code GC.

In the former case, we must add a large free block from compiling.base + size to
compiling.limit. */
void build_free_list(F_HEAP *heap, CELL size)
{
	F_BLOCK *prev = NULL;
	F_BLOCK *prev_free = NULL;
	F_BLOCK *scan = first_block(heap);
	F_BLOCK *end = (F_BLOCK *)(heap->segment->start + size);

	/* Add all free blocks to the free list */
	while(scan && scan < end)
	{
		switch(scan->status)
		{
		case B_FREE:
			update_free_list(heap,prev_free,scan);
			prev_free = scan;
			break;
		case B_ALLOCATED:
			break;
		default:
			critical_error("Invalid scan->status",(CELL)scan);
			break;
		}

		prev = scan;
		scan = next_block(heap,scan);
	}

	/* If there is room at the end of the heap, add a free block. This
	branch is only taken after loading a new image, not after code GC */
	if((CELL)(end + 1) <= heap->segment->end)
	{
		end->status = B_FREE;
		end->next_free = NULL;
		end->size = heap->segment->end - (CELL)end;

		/* add final free block */
		update_free_list(heap,prev_free,end);
	}
	/* This branch is taken if the newly loaded image fits exactly, or
	after code GC */
	else
	{
		/* even if there's no room at the end of the heap for a new
		free block, we might have to jigger it up by a few bytes in
		case prev + prev->size */
		if(prev)
			prev->size = heap->segment->end - (CELL)prev;

		/* this is the last free block */
		update_free_list(heap,prev_free,NULL);
	}

}
Exemple #15
0
/* If in the middle of code GC, we have to grow the heap, GC restarts from
scratch, so we have to unmark any marked blocks. */
void unmark_marked(F_HEAP *heap)
{
	F_BLOCK *scan = first_block(heap);

	while(scan)
	{
		if(scan->status == B_MARKED)
			scan->status = B_ALLOCATED;

		scan = next_block(heap,scan);
	}
}
Exemple #16
0
void heap::compact_heap(unordered_map<heap_block *,char *> &forwarding)
{
	heap_block *scan = first_block();

	while(scan)
	{
		heap_block *next = next_block(scan);

		if(scan->status == B_ALLOCATED)
			memmove(forwarding[scan],scan,scan->size);
		scan = next;
	}
}
Exemple #17
0
// ####### begin Gilbert 28/1 #######//
//------------ Begin of function HillRes::locate -----------//
short HillRes::locate(char patternId, char subPattern, char searchPriority, char specialFlag)
{
	err_when(patternId < 1 || patternId > max_pattern_id);

	// ------- find the range which patternId may exist ------//
	// find the start of this pattern and next pattern
	short startBlockIdx = first_block(patternId);
	short endBlockIdx = first_block(patternId+1);
	for(short j = startBlockIdx; j < endBlockIdx; ++j)
	{
		HillBlockInfo *hillBlockInfo = hill_block_info_array+j-1;
		if( hillBlockInfo->pattern_id == patternId &&
			hillBlockInfo->sub_pattern_id == subPattern &&
			hillBlockInfo->priority == searchPriority &&
			hillBlockInfo->special_flag == specialFlag)
		{
			return j;
		}
	}
	return 0;	// not found

}
Exemple #18
0
void compact_heap(F_HEAP *heap)
{
	F_BLOCK *scan = first_block(heap);

	while(scan)
	{
		F_BLOCK *next = next_block(heap,scan);

		if(scan->status == B_ALLOCATED && scan != scan->forwarding)
			memcpy(scan->forwarding,scan,scan->size);
		scan = next;
	}
}
Exemple #19
0
void heap::compact_heap()
{
	heap_block *scan = first_block();

	while(scan)
	{
		heap_block *next = next_block(scan);

		if(scan->type() != FREE_BLOCK_TYPE)
			memmove(forwarding[scan],scan,scan->size());
		scan = next;
	}
}
Exemple #20
0
/* Called after reading the code heap from the image file, and after code GC.

In the former case, we must add a large free block from compiling.base + size to
compiling.limit. */
void heap::build_free_list(cell size)
{
	heap_block *prev = NULL;

	clear_free_list();

	size = (size + block_size_increment - 1) & ~(block_size_increment - 1);

	heap_block *scan = first_block();
	free_heap_block *end = (free_heap_block *)(seg->start + size);

	/* Add all free blocks to the free list */
	while(scan && scan < (heap_block *)end)
	{
		switch(scan->status)
		{
		case B_FREE:
			add_to_free_list((free_heap_block *)scan);
			break;
		case B_ALLOCATED:
			break;
		default:
			myvm->critical_error("Invalid scan->status",(cell)scan);
			break;
		}

		prev = scan;
		scan = next_block(scan);
	}

	/* If there is room at the end of the heap, add a free block. This
	branch is only taken after loading a new image, not after code GC */
	if((cell)(end + 1) <= seg->end)
	{
		end->status = B_FREE;
		end->size = seg->end - (cell)end;

		/* add final free block */
		add_to_free_list(end);
	}
	/* This branch is taken if the newly loaded image fits exactly, or
	after code GC */
	else
	{
		/* even if there's no room at the end of the heap for a new
		free block, we might have to jigger it up by a few bytes in
		case prev + prev->size */
		if(prev) prev->size = seg->end - (cell)prev;
	}

}
Exemple #21
0
/* The size of the heap, not including the last block if it's free */
cell heap::heap_size()
{
	heap_block *scan = first_block();

	while(next_block(scan) != NULL)
		scan = next_block(scan);

	/* this is the last block in the heap, and it is free */
	if(scan->type() == FREE_BLOCK_TYPE)
		return (cell)scan - seg->start;
	/* otherwise the last block is allocated */
	else
		return seg->size;
}
Exemple #22
0
/* The size of the heap, not including the last block if it's free */
CELL heap_size(F_HEAP *heap)
{
	F_BLOCK *scan = first_block(heap);

	while(next_block(heap,scan) != NULL)
		scan = next_block(heap,scan);

	/* this is the last block in the heap, and it is free */
	if(scan->status == B_FREE)
		return (CELL)scan - heap->segment->start;
	/* otherwise the last block is allocated */
	else
		return heap->segment->size;
}
Exemple #23
0
INLINE void load_code_heap(FILE *file, F_HEADER *h, F_PARAMETERS *p)
{
	CELL good_size = h->code_size + (1 << 19);

	if(good_size > p->code_size)
		p->code_size = good_size;

	init_code_heap(p->code_size);

	if(h->code_size != 0
		&& fread(first_block(&code_heap),h->code_size,1,file) != 1)
		fatal_error("load_code_heap failed",0);

	code_relocation_base = h->code_relocation_base;
	build_free_list(&code_heap,h->code_size);
}
Exemple #24
0
/* Save the current image to disk */
bool save_image(const vm_char *filename)
{
	FILE* file;
	image_header h;

	file = OPEN_WRITE(filename);
	if(file == NULL)
	{
		print_string("Cannot open image file: "); print_native_string(filename); nl();
		print_string(strerror(errno)); nl();
		return false;
	}

	zone *tenured = &data->generations[data->tenured()];

	h.magic = image_magic;
	h.version = image_version;
	h.data_relocation_base = tenured->start;
	h.data_size = tenured->here - tenured->start;
	h.code_relocation_base = code.seg->start;
	h.code_size = heap_size(&code);

	h.t = T;
	h.bignum_zero = bignum_zero;
	h.bignum_pos_one = bignum_pos_one;
	h.bignum_neg_one = bignum_neg_one;

	for(cell i = 0; i < USER_ENV; i++)
		h.userenv[i] = (save_env_p(i) ? userenv[i] : F);

	bool ok = true;

	if(fwrite(&h,sizeof(image_header),1,file) != 1) ok = false;
	if(fwrite((void*)tenured->start,h.data_size,1,file) != 1) ok = false;
	if(fwrite(first_block(&code),h.code_size,1,file) != 1) ok = false;
	if(fclose(file)) ok = false;

	if(!ok)
	{
		print_string("save-image failed: "); print_string(strerror(errno)); nl();
	}

	return ok;
}
Exemple #25
0
/* Called after reading the code heap from the image file, and after code GC.

In the former case, we must add a large free block from compiling.base + size to
compiling.limit. */
void heap::build_free_list(cell size)
{
	heap_block *prev = NULL;

	clear_free_list();

	size = (size + block_size_increment - 1) & ~(block_size_increment - 1);

	heap_block *scan = first_block();
	free_heap_block *end = (free_heap_block *)(seg->start + size);

	/* Add all free blocks to the free list */
	while(scan && scan < (heap_block *)end)
	{
		if(scan->type() == FREE_BLOCK_TYPE)
			add_to_free_list((free_heap_block *)scan);

		prev = scan;
		scan = next_block(scan);
	}

	/* If there is room at the end of the heap, add a free block. This
	branch is only taken after loading a new image, not after code GC */
	if((cell)(end + 1) <= seg->end)
	{
		end->set_marked_p(false);
		end->set_type(FREE_BLOCK_TYPE);
		end->set_size(seg->end - (cell)end);

		/* add final free block */
		add_to_free_list(end);
	}
	/* This branch is taken if the newly loaded image fits exactly, or
	after code GC */
	else
	{
		/* even if there's no room at the end of the heap for a new
		free block, we might have to jigger it up by a few bytes in
		case prev + prev->size */
		if(prev) prev->set_size(seg->end - (cell)prev);
	}

}
Exemple #26
0
INLINE void load_code_heap(FILE *file, F_HEADER *h, F_PARAMETERS *p)
{
	CELL good_size = h->code_size + (1 << 19);

	if(good_size > p->code_size)
		p->code_size = good_size;

	init_code_heap(p->code_size);

	if(h->code_size != 0)
	{
		long int bytes_read = fread(first_block(&code_heap),1,h->code_size,file);
		if(bytes_read != h->code_size)
		{
			fprintf(stderr,"truncated image: %ld bytes read, %ld bytes expected\n",
				bytes_read,h->code_size);
			fatal_error("load_code_heap failed",0);
		}
	}

	code_relocation_base = h->code_relocation_base;
	build_free_list(&code_heap,h->code_size);
}
Exemple #27
0
/*
 * For any block B_i in the queue, we know that the bsize for
 * that block is at least (f->length - B_i->col).
 *
 * If (f->length - B_0->col > f->max_width) then we can set B_0's
 * bsize to infinity (PP_MAX_BSIZE), update the csize of the head
 * token, and remove B_0 from the queue. The head token is ready to be
 * printed at this point (since its csize, bsize and fsize fields are
 * known).
 */
static void flush_wide_blocks(formatter_t *f) {
  pp_block_t *b;
  pp_open_token_t *tk, *head;

  while (!block_queue_is_empty(&f->block_queue)) {
    b = first_block(&f->block_queue);
    assert(b->col <= f->length);
    if (f->length - b->col <= f->max_width) break;
    /*
     * b has bsize > max_width: set its bsize to MAX
     * then remove it from the block queue
     */
    tk = b->token;
    tk->bsize = PP_MAX_BSIZE;
    head = f->head_token;
    if (head != NULL) {
      // update csize and fsize of the head token
      head->csize = PP_MAX_BSIZE;
      if (head->fsize == 0) {
        head->fsize = PP_MAX_BSIZE;
      }
    }
    // print all queued tokens, until tk
    flush_tokens(f, tag_open(tk));

    // tk becomes the head token
    assert(ptr_queue_first(&f->token_queue) == tag_open(tk));
    f->head_token = tk;
    if (f->nclosed == f->queue_size) {
      f->nclosed --;
    }

    pop_first_block(&f->block_queue);
    f->queue_size --;
  }
}
Exemple #28
0
/* Compute total sum of sizes of free blocks, and size of largest free block */
void heap::heap_usage(cell *used, cell *total_free, cell *max_free)
{
	*used = 0;
	*total_free = 0;
	*max_free = 0;

	heap_block *scan = first_block();

	while(scan)
	{
		cell size = scan->size();

		if(scan->type() == FREE_BLOCK_TYPE)
		{
			*total_free += size;
			if(size > *max_free)
				*max_free = size;
		}
		else
			*used += size;

		scan = next_block(scan);
	}
}
Exemple #29
0
/* Dump all code blocks for debugging */
void dump_heap(F_HEAP *heap)
{
	CELL size = 0;

	F_BLOCK *scan = first_block(heap);

	while(scan)
	{
		char *status;
		switch(scan->status)
		{
		case B_FREE:
			status = "free";
			break;
		case B_ALLOCATED:
			size += object_size(block_to_compiled(scan)->relocation);
			status = "allocated";
			break;
		case B_MARKED:
			size += object_size(block_to_compiled(scan)->relocation);
			status = "marked";
			break;
		default:
			status = "invalid";
			break;
		}

		print_cell_hex((CELL)scan); print_string(" ");
		print_cell_hex(scan->size); print_string(" ");
		print_string(status); print_string("\n");

		scan = next_block(heap,scan);
	}
	
	print_cell(size); print_string(" bytes of relocation data\n");
}
bool Function::IsFirstBlock(uint32_t block_id) const {
  return !ordered_blocks_.empty() && *first_block() == block_id;
}