* [PATCH] compile.c: move some "literal" opts to peephole
@ 2014-10-08 1:56 Eric Wong
0 siblings, 0 replies; only message in thread
From: Eric Wong @ 2014-10-08 1:56 UTC (permalink / raw)
To: spew
`"literal".freeze', `obj["literal"]'
are all peephole optimizations and not appropriate for
iseq_compile_each.
TODO: move `obj["literal"] = val', too.
---
compile.c | 66 ++++++++++++++++++++++--------------------
test/-ext-/symbol/test_type.rb | 1 +
test/objspace/test_objspace.rb | 1 +
test/ruby/envutil.rb | 10 +++++++
test/ruby/test_hash.rb | 2 ++
test/ruby/test_iseq.rb | 1 +
test/ruby/test_string.rb | 7 +++++
7 files changed, 57 insertions(+), 31 deletions(-)
diff --git a/compile.c b/compile.c
index dda22b0..b38eedb 100644
--- a/compile.c
+++ b/compile.c
@@ -1819,6 +1819,41 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal
}
}
}
+
+ /* string literal optimizations */
+ if (iobj->insn_id == BIN(putstring)) {
+ INSN *niobj = (INSN *)get_next_insn((INSN *)list);
+
+ if (niobj && niobj->insn_id == BIN(send)) {
+ rb_call_info_t *ci = (rb_call_info_t *)niobj->operands[0];
+
+ if (ci->blockiseq == 0 &&
+ (ci->flag & ~VM_CALL_ARGS_SKIP_SETUP) == 0) {
+
+ /* "literal".freeze -> opt_str_freeze("literal") */
+ if (ci->mid == idFreeze && ci->orig_argc == 0) {
+ iobj->insn_id = BIN(opt_str_freeze);
+ REMOVE_ELEM((LINK_ELEMENT *)niobj);
+ }
+
+ /* obj["literal"] -> opt_aref_with(obj, "literal") */
+ else if (ci->mid == idAREF && ci->orig_argc == 1) {
+ VALUE *old_operands = iobj->operands;
+
+ iobj->insn_id = BIN(opt_aref_with);
+ iobj->operand_size = insn_len(iobj->insn_id) - 1;
+
+ iobj->operands = (VALUE *)compile_data_alloc(iseq,
+ iobj->operand_size * sizeof(VALUE));
+ iobj->operands[0] = (VALUE)ci;
+ iobj->operands[1] = old_operands[0];
+
+ REMOVE_ELEM((LINK_ELEMENT *)niobj);
+ }
+ }
+ }
+ }
+
return COMPILE_OK;
}
@@ -4238,37 +4273,6 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
break;
}
case NODE_CALL:
- /* optimization shortcut
- * "literal".freeze -> opt_str_freeze("literal")
- */
- if (node->nd_recv && nd_type(node->nd_recv) == NODE_STR &&
- node->nd_mid == idFreeze && node->nd_args == NULL)
- {
- VALUE str = rb_fstring(node->nd_recv->nd_lit);
- iseq_add_mark_object(iseq, str);
- ADD_INSN1(ret, line, opt_str_freeze, str);
- if (poped) {
- ADD_INSN(ret, line, pop);
- }
- break;
- }
- /* optimization shortcut
- * obj["literal"] -> opt_aref_with(obj, "literal")
- */
- if (node->nd_mid == idAREF && !private_recv_p(node) && node->nd_args &&
- nd_type(node->nd_args) == NODE_ARRAY && node->nd_args->nd_alen == 1 &&
- nd_type(node->nd_args->nd_head) == NODE_STR)
- {
- VALUE str = rb_fstring(node->nd_args->nd_head->nd_lit);
- node->nd_args->nd_head->nd_lit = str;
- COMPILE(ret, "recv", node->nd_recv);
- ADD_INSN2(ret, line, opt_aref_with,
- new_callinfo(iseq, idAREF, 1, 0, 0), str);
- if (poped) {
- ADD_INSN(ret, line, pop);
- }
- break;
- }
case NODE_FCALL:
case NODE_VCALL:{ /* VCALL: variable or call */
/*
diff --git a/test/-ext-/symbol/test_type.rb b/test/-ext-/symbol/test_type.rb
index f1749f5..5bd79b8 100644
--- a/test/-ext-/symbol/test_type.rb
+++ b/test/-ext-/symbol/test_type.rb
@@ -4,6 +4,7 @@ require "-test-/symbol"
module Test_Symbol
class TestType < Test::Unit::TestCase
def test_id2str_fstring_bug9171
+ require_compile_option(:peephole_optimization)
fstr = eval("# encoding: us-ascii
'foobar'.freeze")
assert_same fstr, Bug::Symbol.id2str(:foobar)
diff --git a/test/objspace/test_objspace.rb b/test/objspace/test_objspace.rb
index 8a5ed34..faacf48 100644
--- a/test/objspace/test_objspace.rb
+++ b/test/objspace/test_objspace.rb
@@ -195,6 +195,7 @@ class TestObjSpace < Test::Unit::TestCase
end
def test_dump_flags
+ require_compile_option(:peephole_optimization)
info = ObjectSpace.dump("foo".freeze)
assert_match /"wb_protected":true, "old":true, "long_lived":true, "marked":true/, info
assert_match /"fstring":true/, info
diff --git a/test/ruby/envutil.rb b/test/ruby/envutil.rb
index 81b982c..e844822 100644
--- a/test/ruby/envutil.rb
+++ b/test/ruby/envutil.rb
@@ -477,6 +477,16 @@ eom
AssertFile
end
+ def require_compile_option(opt)
+ case RubyVM::InstructionSequence.compile_option[opt]
+ when true
+ when false
+ skip(":#{opt} disabled")
+ else
+ raise ArgumentError, "unrecognized compile option: #{opt.inspect}"
+ end
+ end
+
class << (AssertFile = Struct.new(:failure_message).new)
include Assertions
def assert_file_predicate(predicate, *args)
diff --git a/test/ruby/test_hash.rb b/test/ruby/test_hash.rb
index 4431552..bb7e8b5 100644
--- a/test/ruby/test_hash.rb
+++ b/test/ruby/test_hash.rb
@@ -216,6 +216,7 @@ class TestHash < Test::Unit::TestCase
end
def test_AREF_fstring_key
+ require_compile_option(:peephole_optimization)
h = {"abc" => 1}
before = GC.stat(:total_allocated_objects)
5.times{ h["abc"] }
@@ -230,6 +231,7 @@ class TestHash < Test::Unit::TestCase
end
def test_NEWHASH_fstring_key
+ require_compile_option(:peephole_optimization)
a = {"ABC" => :t}
b = {"ABC" => :t}
assert_same a.keys[0], b.keys[0]
diff --git a/test/ruby/test_iseq.rb b/test/ruby/test_iseq.rb
index 94a814c..ac1c417 100644
--- a/test/ruby/test_iseq.rb
+++ b/test/ruby/test_iseq.rb
@@ -118,6 +118,7 @@ class TestISeq < Test::Unit::TestCase
end
def test_label_fstring
+ require_compile_option(:peephole_optimization)
c = Class.new{ def foobar() end }
a, b = eval("# encoding: us-ascii\n'foobar'.freeze"),
diff --git a/test/ruby/test_string.rb b/test/ruby/test_string.rb
index d82d2bc..4dc790f 100644
--- a/test/ruby/test_string.rb
+++ b/test/ruby/test_string.rb
@@ -1908,6 +1908,13 @@ class TestString < Test::Unit::TestCase
}
end
+ def test_literal_freeze
+ require_compile_option(:peephole_optimization)
+ before = GC.stat(:total_allocated_objects)
+ 5.times { "".freeze }
+ assert_equal before, GC.stat(:total_allocated_objects)
+ end
+
class S2 < String
end
def test_str_new4
--
EW
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2014-10-08 1:56 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-10-08 1:56 [PATCH] compile.c: move some "literal" opts to peephole Eric Wong
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).