зеркало из https://github.com/github/ruby.git
Add setclassvariable to yjit (#5127)
Implements setclassvariable in yjit. Note that this version is not faster than the standard version because we aren't handling the inline cache in assembly. This is still important to implement because it will prevent yjit from exiting in methods that call both a cvar setter and other code that yjit can compile. Co-authored-by: Aaron Patterson tenderlove@ruby-lang.org
This commit is contained in:
Родитель
fb9d67742b
Коммит
459f9e3df8
|
@ -52,6 +52,11 @@ class TestYJIT < Test::Unit::TestCase
|
|||
assert_in_out_err([yjit_child_env, '-e p RubyVM::YJIT.enabled?'], '', ['true'])
|
||||
end
|
||||
|
||||
def test_compile_setclassvariable
|
||||
script = 'class Foo; def self.foo; @@foo = 1; end; end; Foo.foo'
|
||||
assert_compiles(script, insns: %i[setclassvariable], result: 1)
|
||||
end
|
||||
|
||||
def test_compile_getclassvariable
|
||||
script = 'class Foo; @@foo = 1; def self.foo; @@foo; end; end; Foo.foo'
|
||||
assert_compiles(script, insns: %i[getclassvariable], result: 1)
|
||||
|
|
|
@ -1367,6 +1367,12 @@ vm_setclassvariable(const rb_iseq_t *iseq, const rb_control_frame_t *reg_cfp, ID
|
|||
update_classvariable_cache(iseq, klass, id, ic);
|
||||
}
|
||||
|
||||
void
|
||||
rb_vm_setclassvariable(const rb_iseq_t *iseq, const rb_control_frame_t *cfp, ID id, VALUE val, ICVARC ic)
|
||||
{
|
||||
vm_setclassvariable(iseq, cfp, id, val, ic);
|
||||
}
|
||||
|
||||
static inline VALUE
|
||||
vm_getinstancevariable(const rb_iseq_t *iseq, VALUE obj, ID id, IVC ic)
|
||||
{
|
||||
|
|
|
@ -4488,6 +4488,26 @@ gen_getclassvariable(jitstate_t* jit, ctx_t* ctx, codeblock_t* cb)
|
|||
return YJIT_KEEP_COMPILING;
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_vm_setclassvariable(const rb_iseq_t *iseq, const rb_control_frame_t *cfp, ID id, VALUE val, ICVARC ic);
|
||||
|
||||
static codegen_status_t
|
||||
gen_setclassvariable(jitstate_t* jit, ctx_t* ctx, codeblock_t* cb)
|
||||
{
|
||||
// rb_vm_setclassvariable can raise exceptions.
|
||||
jit_prepare_routine_call(jit, ctx, REG0);
|
||||
|
||||
mov(cb, C_ARG_REGS[0], member_opnd(REG_CFP, rb_control_frame_t, iseq));
|
||||
mov(cb, C_ARG_REGS[1], REG_CFP);
|
||||
mov(cb, C_ARG_REGS[2], imm_opnd(jit_get_arg(jit, 0)));
|
||||
mov(cb, C_ARG_REGS[3], ctx_stack_pop(ctx, 1));
|
||||
mov(cb, C_ARG_REGS[4], imm_opnd(jit_get_arg(jit, 1)));
|
||||
|
||||
call_ptr(cb, REG0, (void *)rb_vm_setclassvariable);
|
||||
|
||||
return YJIT_KEEP_COMPILING;
|
||||
}
|
||||
|
||||
static codegen_status_t
|
||||
gen_opt_getinlinecache(jitstate_t *jit, ctx_t *ctx, codeblock_t *cb)
|
||||
{
|
||||
|
@ -4886,6 +4906,7 @@ yjit_init_codegen(void)
|
|||
yjit_reg_op(BIN(toregexp), gen_toregexp);
|
||||
yjit_reg_op(BIN(getspecial), gen_getspecial);
|
||||
yjit_reg_op(BIN(getclassvariable), gen_getclassvariable);
|
||||
yjit_reg_op(BIN(setclassvariable), gen_setclassvariable);
|
||||
|
||||
yjit_method_codegen_table = st_init_numtable();
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче