示例#1
0
static void check_frame(stack_frame *frame)
{
#ifdef FACTOR_DEBUG
	check_code_pointer((cell)frame->xt);
	assert(frame->size != 0);
#endif
}
示例#2
0
void factor_vm::check_frame(stack_frame *frame)
{
#ifdef FACTOR_DEBUG
	check_code_pointer((cell)frame->entry_point);
	assert(frame->size != 0);
#endif
}
示例#3
0
/* The cache_entries parameter is either f (on cold call site) or an array (on cache miss).
Called from assembly with the actual return address */
void *factor_vm::inline_cache_miss(cell return_address)
{
	check_code_pointer(return_address);

	/* Since each PIC is only referenced from a single call site,
	   if the old call target was a PIC, we can deallocate it immediately,
	   instead of leaving dead PICs around until the next GC. */
	deallocate_inline_cache(return_address);

	gc_root<array> cache_entries(dpop(),this);
	fixnum index = untag_fixnum(dpop());
	gc_root<array> methods(dpop(),this);
	gc_root<word> generic_word(dpop(),this);
	gc_root<object> object(((cell *)ds)[-index],this);

	void *xt;

	cell pic_size = inline_cache_size(cache_entries.value());

	update_pic_transitions(pic_size);

	if(pic_size >= max_pic_size)
		xt = megamorphic_call_stub(generic_word.value());
	else
	{
		cell klass = object_class(object.value());
		cell method = lookup_method(object.value(),methods.value());

		gc_root<array> new_cache_entries(add_inline_cache_entry(
							   cache_entries.value(),
							   klass,
							   method),this);
		xt = compile_inline_cache(index,
					  generic_word.value(),
					  methods.value(),
					  new_cache_entries.value(),
					  tail_call_site_p(return_address))->xt();
	}

	/* Install the new stub. */
	set_call_target(return_address,xt);

#ifdef PIC_DEBUG
	printf("Updated %s call site 0x%lx with 0x%lx\n",
	       tail_call_site_p(return_address) ? "tail" : "non-tail",
	       return_address,
	       (cell)xt);
#endif

	return xt;
}
示例#4
0
void factor_vm::deallocate_inline_cache(cell return_address)
{
	/* Find the call target. */
	void *old_xt = get_call_target(return_address);
	check_code_pointer((cell)old_xt);

	code_block *old_block = (code_block *)old_xt - 1;
	cell old_type = old_block->type();

#ifdef FACTOR_DEBUG
	/* The call target was either another PIC,
	   or a compiled quotation (megamorphic stub) */
	assert(old_type == PIC_TYPE || old_type == QUOTATION_TYPE);
#endif

	if(old_type == PIC_TYPE)
		code->code_heap_free(old_block);
}