зеркало из https://github.com/github/ruby.git
fix redefinition optimization for -"literal string" (UMinus)
Unfortunately this enlarges insns.def by yet another instruction. However, it is much prettier than opt_str_freeze in use, and maybe we can avoid having so many instructions in the future. [ruby-core:80368] * insns.def (DEFINE_INSN): new instruction: opt_str_uminus (maybe temporary) * compile.c (iseq_compile_each0): split instructions * test/ruby/test_optimization.rb (test_string_uminus): new test * vm.c (vm_init_redefined_flag): set redefinintion flag for uminus * vm_core.h (enum ruby_basic_operators): add BOP_UMINUS git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58144 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
833e42d120
Коммит
669a55dfed
|
@ -5211,7 +5211,12 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popp
|
|||
ISEQ_COMPILE_DATA(iseq)->option->specialized_instruction) {
|
||||
VALUE str = rb_fstring(node->nd_recv->nd_lit);
|
||||
iseq_add_mark_object(iseq, str);
|
||||
ADD_INSN1(ret, line, opt_str_freeze, str);
|
||||
if (node->nd_mid == idUMinus) {
|
||||
ADD_INSN1(ret, line, opt_str_uminus, str);
|
||||
}
|
||||
else {
|
||||
ADD_INSN1(ret, line, opt_str_freeze, str);
|
||||
}
|
||||
if (popped) {
|
||||
ADD_INSN(ret, line, pop);
|
||||
}
|
||||
|
|
14
insns.def
14
insns.def
|
@ -981,6 +981,20 @@ opt_str_freeze
|
|||
}
|
||||
}
|
||||
|
||||
DEFINE_INSN
|
||||
opt_str_uminus
|
||||
(VALUE str)
|
||||
()
|
||||
(VALUE val)
|
||||
{
|
||||
if (BASIC_OP_UNREDEFINED_P(BOP_UMINUS, STRING_REDEFINED_OP_FLAG)) {
|
||||
val = str;
|
||||
}
|
||||
else {
|
||||
val = rb_funcall(rb_str_resurrect(str), idUMinus, 0);
|
||||
}
|
||||
}
|
||||
|
||||
DEFINE_INSN
|
||||
opt_newarray_max
|
||||
(rb_num_t num)
|
||||
|
|
|
@ -104,6 +104,11 @@ class TestRubyOptimization < Test::Unit::TestCase
|
|||
assert_redefine_method('String', 'freeze', 'assert_nil "foo".freeze')
|
||||
end
|
||||
|
||||
def test_string_uminus
|
||||
assert_same "foo".freeze, -"foo"
|
||||
assert_redefine_method('String', '-@', 'assert_nil(-"foo")')
|
||||
end
|
||||
|
||||
def test_string_freeze_saves_memory
|
||||
n = 16384
|
||||
data = '.'.freeze
|
||||
|
|
1
vm.c
1
vm.c
|
@ -1569,6 +1569,7 @@ vm_init_redefined_flag(void)
|
|||
OP(Succ, SUCC), (C(Integer), C(String), C(Time));
|
||||
OP(EqTilde, MATCH), (C(Regexp), C(String));
|
||||
OP(Freeze, FREEZE), (C(String));
|
||||
OP(UMinus, UMINUS), (C(String));
|
||||
OP(Max, MAX), (C(Array));
|
||||
OP(Min, MIN), (C(Array));
|
||||
#undef C
|
||||
|
|
|
@ -454,6 +454,7 @@ enum ruby_basic_operators {
|
|||
BOP_NEQ,
|
||||
BOP_MATCH,
|
||||
BOP_FREEZE,
|
||||
BOP_UMINUS,
|
||||
BOP_MAX,
|
||||
BOP_MIN,
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче