зеркало из https://github.com/github/ruby.git
MJIT: Merge exivar guards as well
obviating status->merge_ivar_guards_p as refactoring
This commit is contained in:
Родитель
322e546f60
Коммит
2329cbeb5b
|
@ -35,8 +35,6 @@ class RubyVM::MJIT::Compiler
|
|||
return nil
|
||||
end
|
||||
|
||||
init_ivar_compile_status(iseq.body, status)
|
||||
|
||||
src = +''
|
||||
if !status.compile_info.disable_send_cache && !status.compile_info.disable_inlining
|
||||
unless precompile_inlinable_iseqs(src, iseq, status)
|
||||
|
@ -91,8 +89,13 @@ class RubyVM::MJIT::Compiler
|
|||
end
|
||||
|
||||
# Generate merged ivar guards first if needed
|
||||
if !status.compile_info.disable_ivar_cache && status.merge_ivar_guards_p
|
||||
src << " if (UNLIKELY(!(RB_TYPE_P(GET_SELF(), T_OBJECT)))) {"
|
||||
has_getivar, has_setivar = ivar_usages(iseq.body)
|
||||
if !status.compile_info.disable_ivar_cache && (has_getivar || has_setivar)
|
||||
src << " if (UNLIKELY(!RB_TYPE_P(GET_SELF(), T_OBJECT))) {"
|
||||
src << " goto ivar_cancel;\n"
|
||||
src << " }\n"
|
||||
elsif !status.compile_info.disable_exivar_cache && has_getivar
|
||||
src << " if (UNLIKELY(!FL_TEST_RAW(GET_SELF(), FL_EXIVAR))) {"
|
||||
src << " goto ivar_cancel;\n"
|
||||
src << " }\n"
|
||||
end
|
||||
|
@ -383,7 +386,7 @@ class RubyVM::MJIT::Compiler
|
|||
src << " const uint32_t index = #{attr_index - 1};\n"
|
||||
# JIT: cache hit path of vm_getivar, or cancel JIT (recompile it without any ivar optimization)
|
||||
src << " struct gen_ivtbl *ivtbl;\n"
|
||||
src << " if (LIKELY(FL_TEST_RAW(obj, FL_EXIVAR) && source_shape_id == rb_shape_get_shape_id(obj) && rb_ivar_generic_ivtbl_lookup(obj, &ivtbl))) {\n"
|
||||
src << " if (LIKELY(source_shape_id == rb_shape_get_shape_id(obj) && rb_ivar_generic_ivtbl_lookup(obj, &ivtbl))) {\n"
|
||||
src << " stack[#{stack_size}] = ivtbl->ivptr[index];\n"
|
||||
src << " }\n"
|
||||
src << " else {\n"
|
||||
|
@ -716,7 +719,6 @@ class RubyVM::MJIT::Compiler
|
|||
if child_iseq.body.ci_size > 0 && child_status.cc_entries_index == -1
|
||||
return false
|
||||
end
|
||||
init_ivar_compile_status(child_iseq.body, child_status)
|
||||
|
||||
src << "ALWAYS_INLINE(static VALUE _mjit#{status.compiled_id}_inlined_#{pos}(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, const VALUE orig_self, const rb_iseq_t *original_iseq));\n"
|
||||
src << "static inline VALUE\n_mjit#{status.compiled_id}_inlined_#{pos}(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, const VALUE orig_self, const rb_iseq_t *original_iseq)\n{\n"
|
||||
|
@ -786,17 +788,22 @@ class RubyVM::MJIT::Compiler
|
|||
end
|
||||
end
|
||||
|
||||
def init_ivar_compile_status(body, status)
|
||||
def ivar_usages(body)
|
||||
has_getivar = false
|
||||
has_setivar = false
|
||||
pos = 0
|
||||
|
||||
while pos < body.iseq_size
|
||||
insn = INSNS.fetch(C.rb_vm_insn_decode(body.iseq_encoded[pos]))
|
||||
if insn.name == :getinstancevariable || insn.name == :setinstancevariable
|
||||
status.merge_ivar_guards_p = true
|
||||
return
|
||||
case insn.name
|
||||
when :getinstancevariable
|
||||
has_getivar = true
|
||||
when :setinstancevariable
|
||||
has_setivar = true
|
||||
end
|
||||
break if has_getivar && has_setivar
|
||||
pos += insn.len
|
||||
end
|
||||
return has_getivar, has_setivar
|
||||
end
|
||||
|
||||
# Expand simple macro that doesn't require dynamic C code.
|
||||
|
|
1
mjit_c.h
1
mjit_c.h
|
@ -46,7 +46,6 @@ struct compile_status {
|
|||
int compiled_id; // Just a copy of compiled_iseq->jit_unit->id
|
||||
// Mutated optimization levels
|
||||
struct rb_mjit_compile_info *compile_info;
|
||||
bool merge_ivar_guards_p; // If true, merge guards of ivar accesses
|
||||
// If `inlined_iseqs[pos]` is not NULL, `mjit_compile_body` tries to inline ISeq there.
|
||||
const struct rb_iseq_constant_body **inlined_iseqs;
|
||||
struct inlined_call_context inline_context;
|
||||
|
|
|
@ -240,7 +240,6 @@ module RubyVM::MJIT
|
|||
compiled_iseq: [CType::Pointer.new { self.rb_iseq_constant_body }, Primitive.cexpr!("OFFSETOF((*((struct compile_status *)NULL)), compiled_iseq)")],
|
||||
compiled_id: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF((*((struct compile_status *)NULL)), compiled_id)")],
|
||||
compile_info: [CType::Pointer.new { self.rb_mjit_compile_info }, Primitive.cexpr!("OFFSETOF((*((struct compile_status *)NULL)), compile_info)")],
|
||||
merge_ivar_guards_p: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct compile_status *)NULL)), merge_ivar_guards_p)")],
|
||||
inlined_iseqs: [CType::Pointer.new { CType::Pointer.new { self.rb_iseq_constant_body } }, Primitive.cexpr!("OFFSETOF((*((struct compile_status *)NULL)), inlined_iseqs)")],
|
||||
inline_context: [self.inlined_call_context, Primitive.cexpr!("OFFSETOF((*((struct compile_status *)NULL)), inline_context)")],
|
||||
)
|
||||
|
|
Загрузка…
Ссылка в новой задаче