예제 #1
0
void inline_cache_jit::emit_check(cell klass)
{
	cell code_template;
	if(TAG(klass) == FIXNUM_TYPE && untag_fixnum(klass) < HEADER_TYPE)
		code_template = parent->userenv[PIC_CHECK_TAG];
	else
		code_template = parent->userenv[PIC_CHECK];

	emit_with(code_template,klass);
}
예제 #2
0
/* index: 0 = top of stack, 1 = item underneath, etc
   cache_entries: array of class/method pairs */
void inline_cache_jit::compile_inline_cache(fixnum index,
					    cell generic_word_,
					    cell methods_,
					    cell cache_entries_,
					    bool tail_call_p)
{
	gc_root<word> generic_word(generic_word_,parent);
	gc_root<array> methods(methods_,parent);
	gc_root<array> cache_entries(cache_entries_,parent);

	cell inline_cache_type = parent->determine_inline_cache_type(cache_entries.untagged());
	parent->update_pic_count(inline_cache_type);

	/* Generate machine code to determine the object's class. */
	emit_class_lookup(index,inline_cache_type);

	/* Generate machine code to check, in turn, if the class is one of the cached entries. */
	cell i;
	for(i = 0; i < array_capacity(cache_entries.untagged()); i += 2)
	{
		/* Class equal? */
		cell klass = array_nth(cache_entries.untagged(),i);
		emit_check(klass);

		/* Yes? Jump to method */
		cell method = array_nth(cache_entries.untagged(),i + 1);
		emit_with(parent->userenv[PIC_HIT],method);
	}

	/* Generate machine code to handle a cache miss, which ultimately results in
	   this function being called again.

	   The inline-cache-miss primitive call receives enough information to
	   reconstruct the PIC. */
	push(generic_word.value());
	push(methods.value());
	push(tag_fixnum(index));
	push(cache_entries.value());
	word_special(parent->userenv[tail_call_p ? PIC_MISS_TAIL_WORD : PIC_MISS_WORD]);
}
예제 #3
0
파일: jit.hpp 프로젝트: azteca/factor
	void word_special(cell word) {
		emit_with(parent->userenv[JIT_WORD_SPECIAL],word);
	}
예제 #4
0
파일: jit.hpp 프로젝트: azteca/factor
	void word_call(cell word) {
		emit_with(parent->userenv[JIT_WORD_CALL],word);
	}
예제 #5
0
파일: jit.hpp 프로젝트: azteca/factor
	void push(cell literal) {
		emit_with(parent->userenv[JIT_PUSH_IMMEDIATE],literal);
	}
예제 #6
0
파일: jit.cpp 프로젝트: harold/factor
void jit::emit_class_lookup(fixnum index, cell type)
{
	emit_with(parent_vm->userenv[PIC_LOAD],tag_fixnum(-index * sizeof(cell)));
	emit(parent_vm->userenv[type]);
}