VM: rename compile_inline_cache and refactor the loop body into emit_check_and_jump

locals-and-roots
Björn Lindqvist 2016-05-31 01:55:35 +02:00
parent dae2229957
commit a58f8c76f4
1 changed files with 33 additions and 31 deletions

View File

@ -34,43 +34,17 @@ void factor_vm::update_pic_count(cell type) {
} }
struct inline_cache_jit : public jit { struct inline_cache_jit : public jit {
fixnum index;
inline_cache_jit(cell generic_word, factor_vm* vm) inline_cache_jit(cell generic_word, factor_vm* vm)
: jit(code_block_pic, generic_word, vm) {} : jit(code_block_pic, generic_word, vm) {}
;
void compile_inline_cache(fixnum index, cell generic_word_, cell methods_, void emit_check_and_jump(cell ic_type, cell i, cell klass, cell method);
void emit_inline_cache(fixnum index, cell generic_word_, cell methods_,
cell cache_entries_, bool tail_call_p); cell cache_entries_, bool tail_call_p);
}; };
/* index: 0 = top of stack, 1 = item underneath, etc void inline_cache_jit::emit_check_and_jump(cell ic_type, cell i,
cache_entries: array of class/method pairs */ cell klass, cell method) {
/* Allocates memory */
void inline_cache_jit::compile_inline_cache(fixnum index, cell generic_word_,
cell methods_, cell cache_entries_,
bool tail_call_p) {
data_root<word> generic_word(generic_word_, parent);
data_root<array> methods(methods_, parent);
data_root<array> cache_entries(cache_entries_, parent);
cell inline_cache_type =
determine_inline_cache_type(cache_entries.untagged());
parent->update_pic_count(inline_cache_type);
/* Generate machine code to determine the object's class. */
emit_with_literal(parent->special_objects[PIC_LOAD],
tag_fixnum(-index * sizeof(cell)));
/* Put the tag of the object, or class of the tuple in a register. */
emit(parent->special_objects[inline_cache_type]);
/* Generate machine code to check, in turn, if the class is one of the cached
* entries. */
for (cell i = 0; i < array_capacity(cache_entries.untagged()); i += 2) {
/* Class equal? */ /* Class equal? */
cell klass = array_nth(cache_entries.untagged(), i);
cell check_type = PIC_CHECK_TAG; cell check_type = PIC_CHECK_TAG;
if (TAG(klass) != FIXNUM_TYPE) if (TAG(klass) != FIXNUM_TYPE)
check_type = PIC_CHECK_TUPLE; check_type = PIC_CHECK_TUPLE;
@ -79,13 +53,41 @@ void inline_cache_jit::compile_inline_cache(fixnum index, cell generic_word_,
checking for the fixnum type which is 0. That is because the checking for the fixnum type which is 0. That is because the
AND instruction in the PIC_TAG template already sets the zero AND instruction in the PIC_TAG template already sets the zero
flag. */ flag. */
if (i > 0 || inline_cache_type == PIC_TUPLE || klass > 0) { if (!(i == 0 && ic_type == PIC_TAG && klass == 0)) {
emit_with_literal(parent->special_objects[check_type], klass); emit_with_literal(parent->special_objects[check_type], klass);
} }
/* Yes? Jump to method */ /* Yes? Jump to method */
cell method = array_nth(cache_entries.untagged(), i + 1);
emit_with_literal(parent->special_objects[PIC_HIT], method); emit_with_literal(parent->special_objects[PIC_HIT], method);
}
/* index: 0 = top of stack, 1 = item underneath, etc
cache_entries: array of class/method pairs */
/* Allocates memory */
void inline_cache_jit::emit_inline_cache(fixnum index, cell generic_word_,
cell methods_, cell cache_entries_,
bool tail_call_p) {
data_root<word> generic_word(generic_word_, parent);
data_root<array> methods(methods_, parent);
data_root<array> cache_entries(cache_entries_, parent);
cell ic_type = determine_inline_cache_type(cache_entries.untagged());
parent->update_pic_count(ic_type);
/* Generate machine code to determine the object's class. */
emit_with_literal(parent->special_objects[PIC_LOAD],
tag_fixnum(-index * sizeof(cell)));
/* Put the tag of the object, or class of the tuple in a register. */
emit(parent->special_objects[ic_type]);
/* Generate machine code to check, in turn, if the class is one of the cached
entries. */
for (cell i = 0; i < array_capacity(cache_entries.untagged()); i += 2) {
cell klass = array_nth(cache_entries.untagged(), i);
cell method = array_nth(cache_entries.untagged(), i + 1);
emit_check_and_jump(ic_type, i, klass, method);
} }
/* If none of the above conditionals tested true, then execution "falls /* If none of the above conditionals tested true, then execution "falls
@ -117,7 +119,7 @@ code_block* factor_vm::compile_inline_cache(fixnum index, cell generic_word_,
data_root<array> cache_entries(cache_entries_, this); data_root<array> cache_entries(cache_entries_, this);
inline_cache_jit jit(generic_word.value(), this); inline_cache_jit jit(generic_word.value(), this);
jit.compile_inline_cache(index, generic_word.value(), methods.value(), jit.emit_inline_cache(index, generic_word.value(), methods.value(),
cache_entries.value(), tail_call_p); cache_entries.value(), tail_call_p);
code_block* code = jit.to_code_block(JIT_FRAME_SIZE); code_block* code = jit.to_code_block(JIT_FRAME_SIZE);
initialize_code_block(code); initialize_code_block(code);