1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

Revert "Revert r64824 to fix build failure on AppVeyor"

This reverts commit r64829. I'll prepare another temporary fix, but I'll
separately commit that to make it easier to revert that later.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64838 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
k0kubun 2018-09-25 17:19:51 +00:00
parent 3f4d174c22
commit 08c9f030f6
9 changed files with 80 additions and 0 deletions

View file

@ -3245,6 +3245,8 @@ iseq_specialized_instruction(rb_iseq_t *iseq, INSN *iobj)
case idGE: SP_INSN(ge); return COMPILE_OK;
case idLTLT: SP_INSN(ltlt); return COMPILE_OK;
case idAREF: SP_INSN(aref); return COMPILE_OK;
case idAnd: SP_INSN(and); return COMPILE_OK;
case idOr: SP_INSN(or); return COMPILE_OK;
}
break;
case 2:

View file

@ -97,6 +97,8 @@ token_ops = %[\
Eqq === EQQ
Neq != NEQ
Not !
And &
Or |
Backquote `
EqTilde =~ MATCH
NeqTilde !~ NMATCH

View file

@ -1216,6 +1216,34 @@ opt_ltlt
}
}
/* optimized X&Y. */
DEFINE_INSN
opt_and
(CALL_INFO ci, CALL_CACHE cc)
(VALUE recv, VALUE obj)
(VALUE val)
{
val = vm_opt_and(recv, obj);
if (val == Qundef) {
CALL_SIMPLE_METHOD();
}
}
/* optimized X|Y. */
DEFINE_INSN
opt_or
(CALL_INFO ci, CALL_CACHE cc)
(VALUE recv, VALUE obj)
(VALUE val)
{
val = vm_opt_or(recv, obj);
if (val == Qundef) {
CALL_SIMPLE_METHOD();
}
}
/* [] */
DEFINE_INSN
opt_aref

View file

@ -478,6 +478,14 @@ class TestJIT < Test::Unit::TestCase
assert_compile_once('[1] << 2', result_inspect: '[1, 2]', insns: %i[opt_ltlt])
end
def test_compile_insn_opt_and
assert_compile_once('1 & 3', result_inspect: '1', insns: %i[opt_and])
end
def test_compile_insn_opt_or
assert_compile_once('1 | 3', result_inspect: '3', insns: %i[opt_or])
end
def test_compile_insn_opt_aref
skip_on_mswin
# optimized call (optimized JIT) -> send call

View file

@ -187,6 +187,16 @@ class TestRubyOptimization < Test::Unit::TestCase
assert_redefine_method('String', '<<', 'assert_equal "b", "a" << "b"')
end
def test_fixnum_and
assert_equal 1, 1&3
assert_redefine_method('Integer', '&', 'assert_equal 3, 1&3')
end
def test_fixnum_or
assert_equal 3, 1|3
assert_redefine_method('Integer', '|', 'assert_equal 1, 3|1')
end
def test_array_plus
assert_equal [1,2], [1]+[2]
assert_redefine_method('Array', '+', 'assert_equal [2], [1]+[2]')

View file

@ -52,6 +52,8 @@ module MJITHeader
'vm_opt_gt',
'vm_opt_ge',
'vm_opt_ltlt',
'vm_opt_and',
'vm_opt_or',
'vm_opt_aref',
'vm_opt_aset',
'vm_opt_aref_with',

2
vm.c
View file

@ -1610,6 +1610,8 @@ vm_init_redefined_flag(void)
OP(Max, MAX), (C(Array));
OP(Min, MIN), (C(Array));
OP(Call, CALL), (C(Proc));
OP(And, AND), (C(Integer));
OP(Or, OR), (C(Integer));
#undef C
#undef OP
}

View file

@ -531,6 +531,8 @@ enum ruby_basic_operators {
BOP_MAX,
BOP_MIN,
BOP_CALL,
BOP_AND,
BOP_OR,
BOP_LAST_
};

View file

@ -3652,6 +3652,30 @@ vm_opt_ltlt(VALUE recv, VALUE obj)
}
}
static VALUE
vm_opt_and(VALUE recv, VALUE obj)
{
if (FIXNUM_2_P(recv, obj) &&
BASIC_OP_UNREDEFINED_P(BOP_AND, INTEGER_REDEFINED_OP_FLAG)) {
return LONG2NUM(FIX2LONG(recv) & FIX2LONG(obj));
}
else {
return Qundef;
}
}
static VALUE
vm_opt_or(VALUE recv, VALUE obj)
{
if (FIXNUM_2_P(recv, obj) &&
BASIC_OP_UNREDEFINED_P(BOP_OR, INTEGER_REDEFINED_OP_FLAG)) {
return LONG2NUM(FIX2LONG(recv) | FIX2LONG(obj));
}
else {
return Qundef;
}
}
static VALUE
vm_opt_aref(VALUE recv, VALUE obj)
{