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
Родитель 3f4d174c22
Коммит 08c9f030f6
9 изменённых файлов: 80 добавлений и 0 удалений

Просмотреть файл

@ -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:

Просмотреть файл

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

Просмотреть файл

@ -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

Просмотреть файл

@ -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

Просмотреть файл

@ -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]')

Просмотреть файл

@ -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
Просмотреть файл

@ -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
}

Просмотреть файл

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

Просмотреть файл

@ -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)
{