Skip to content

Commit

Permalink
MJIT: Merge exivar guards as well
Browse files Browse the repository at this point in the history
obviating status->merge_ivar_guards_p as refactoring
  • Loading branch information
k0kubun committed Nov 29, 2022
1 parent 322e546 commit 2329cbe
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 13 deletions.
29 changes: 18 additions & 11 deletions lib/mjit/compiler.rb
Expand Up @@ -35,8 +35,6 @@ def compile(iseq, funcname, id)
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)
Expand Down Expand Up @@ -91,8 +89,13 @@ def compile_body(src, iseq, status)
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
Expand Down Expand Up @@ -383,7 +386,7 @@ def compile_ivar(insn_name, stack_size, pos, status, operands, body)
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"
Expand Down Expand Up @@ -716,7 +719,6 @@ def precompile_inlinable_child_iseq(src, child_iseq, status, ci, cc, pos)
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"
Expand Down Expand Up @@ -786,17 +788,22 @@ def init_compile_status(status, body, compile_root_p)
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.
Expand Down
1 change: 0 additions & 1 deletion mjit_c.h
Expand Up @@ -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;
Expand Down
1 change: 0 additions & 1 deletion mjit_c.rb
Expand Up @@ -240,7 +240,6 @@ def C.compile_status
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)")],
)
Expand Down

0 comments on commit 2329cbe

Please sign in to comment.