From: Eric Wong <e@80x24.org>
To: spew@80x24.org
Subject: [PATCH 1/2] compile.c: hide "literal" optimizations behind peephole optimize
Date: Sat, 15 Nov 2014 22:16:11 +0000 [thread overview]
Message-ID: <opt_str_lit-v8-prepare@0> (raw)
This allows us to disable/enable optimizations at runtime.
---
compile.c | 47 ++++++++++++++++++++++++++----------------
test/-ext-/symbol/test_type.rb | 1 +
test/lib/envutil.rb | 10 +++++++++
test/objspace/test_objspace.rb | 1 +
test/ruby/test_hash.rb | 2 ++
test/ruby/test_iseq.rb | 1 +
test/ruby/test_optimization.rb | 11 +++++++++-
7 files changed, 54 insertions(+), 19 deletions(-)
diff --git a/compile.c b/compile.c
index 4e4101f..9936647 100644
--- a/compile.c
+++ b/compile.c
@@ -1913,6 +1913,33 @@ 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 && !(ci->flag & ~VM_CALL_ARGS_SIMPLE)) {
+ /* obj["literal"] -> opt_aref_with(obj, "literal") */
+ 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;
}
@@ -4376,7 +4403,8 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
/* optimization shortcut
* "literal".freeze -> opt_str_freeze("literal")
*/
- if (node->nd_recv && nd_type(node->nd_recv) == NODE_STR &&
+ if (iseq->compile_data->option->peephole_optimization &&
+ 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);
@@ -4387,23 +4415,6 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
}
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, NULL), 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/lib/envutil.rb b/test/lib/envutil.rb
index 001753a..852cfe1 100644
--- a/test/lib/envutil.rb
+++ b/test/lib/envutil.rb
@@ -551,6 +551,16 @@ eom
values
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/objspace/test_objspace.rb b/test/objspace/test_objspace.rb
index f507562..cfdb908 100644
--- a/test/objspace/test_objspace.rb
+++ b/test/objspace/test_objspace.rb
@@ -194,6 +194,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/test_hash.rb b/test/ruby/test_hash.rb
index da07df9..370e8be 100644
--- a/test/ruby/test_hash.rb
+++ b/test/ruby/test_hash.rb
@@ -215,6 +215,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"] }
@@ -229,6 +230,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 79c41bb..e3a28fa 100644
--- a/test/ruby/test_iseq.rb
+++ b/test/ruby/test_iseq.rb
@@ -117,6 +117,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_optimization.rb b/test/ruby/test_optimization.rb
index 129f62a..79cfa1c 100644
--- a/test/ruby/test_optimization.rb
+++ b/test/ruby/test_optimization.rb
@@ -28,6 +28,13 @@ class TestRubyOptimization < Test::Unit::TestCase
end;
end
+ def assert_no_allocation(mesg = "", adjust = 0)
+ before = GC.stat(:total_allocated_objects)
+ yield
+ after = GC.stat(:total_allocated_objects)
+ assert_equal before, after - adjust, mesg
+ end
+
def test_fixnum_plus
a, b = 1, 2
assert_equal 3, a + b
@@ -117,8 +124,10 @@ class TestRubyOptimization < Test::Unit::TestCase
end
def test_string_freeze
- assert_equal "foo", "foo".freeze
assert_redefine_method('String', 'freeze', 'assert_nil "foo".freeze')
+ require_compile_option(:peephole_optimization)
+ assert_no_allocation { 5.times { "".freeze } }
+ assert_equal "foo", "foo".freeze
end
def test_string_eq_neq
--
EW
next reply other threads:[~2014-11-15 22:16 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-11-15 22:16 Eric Wong [this message]
2014-11-15 22:16 ` [PATCH 2/2] opt_str_lit-v8 Eric Wong
2014-11-16 9:21 ` [PATCH 2/2 v2] opt_str_lit-v9 Eric Wong
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=opt_str_lit-v8-prepare@0 \
--to=e@80x24.org \
--cc=spew@80x24.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).