summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-02-28 14:04:53 +0000
committerko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-02-28 14:04:53 +0000
commit4cf0918e8e3d8b06d84c3cd3e875c82edb8b87e6 (patch)
tree986d16e605fee63e700b7e28a72aa0b00894728c
parent338ec3cee73f58091927d9282070efd0da0cca36 (diff)
* compile.c (iseq_compile_each): remove redundant trace(line)
instruction. for example, at the following script def m() p:xyzzy 1 2 end compiler ignores `1' because there is no effect. However, `trace(line)' instruction remains in bytecode. This modification removes such redundant trace(line) instruction. * test/ruby/test_iseq.rb: add a test. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@39539 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog15
-rw-r--r--compile.c9
-rw-r--r--test/ruby/test_iseq.rb31
3 files changed, 52 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index 28ddbbbfb7..8950e629ce 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+Thu Feb 28 22:57:48 2013 Koichi Sasada <ko1@atdot.net>
+
+ * compile.c (iseq_compile_each): remove redundant trace(line)
+ instruction. for example, at the following script
+ def m()
+ p:xyzzy
+ 1
+ 2
+ end
+ compiler ignores `1' because there is no effect. However,
+ `trace(line)' instruction remains in bytecode.
+ This modification removes such redundant trace(line) instruction.
+
+ * test/ruby/test_iseq.rb: add a test.
+
Thu Feb 28 22:23:27 2013 Tanaka Akira <akr@fsij.org>
* ext/socket/raddrinfo.c (inspect_sockaddr): don't show that Unix
diff --git a/compile.c b/compile.c
index fc5229fd9b..8441d97e09 100644
--- a/compile.c
+++ b/compile.c
@@ -3154,6 +3154,7 @@ static int
iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
{
enum node_type type;
+ LINK_ELEMENT *saved_last_element = 0;
if (node == 0) {
if (!poped) {
@@ -3170,6 +3171,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
if (node->flags & NODE_FL_NEWLINE) {
ADD_TRACE(ret, nd_line(node), RUBY_EVENT_LINE);
+ saved_last_element = ret->last;
}
switch (type) {
@@ -5295,6 +5297,13 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
return COMPILE_NG;
}
+ /* check & remove redundant trace(line) */
+ if (saved_last_element && ret /* ret can be 0 when error */ &&
+ ret->last == saved_last_element &&
+ ((INSN *)saved_last_element)->insn_id == BIN(trace)) {
+ POP_ELEMENT(ret);
+ }
+
debug_node_end();
return COMPILE_OK;
}
diff --git a/test/ruby/test_iseq.rb b/test/ruby/test_iseq.rb
index 230cea9b91..621320c2b0 100644
--- a/test/ruby/test_iseq.rb
+++ b/test/ruby/test_iseq.rb
@@ -9,6 +9,11 @@ class TestISeq < Test::Unit::TestCase
assert_normal_exit('p RubyVM::InstructionSequence.compile("1", "mac", "", 0).to_a', bug5894)
end
+ def lines src
+ body = RubyVM::InstructionSequence.new(src).to_a[13]
+ lines = body.find_all{|e| e.kind_of? Fixnum}
+ end
+
def test_to_a_lines
src = <<-EOS
p __LINE__ # 1
@@ -16,9 +21,29 @@ class TestISeq < Test::Unit::TestCase
# 3
p __LINE__ # 4
EOS
- body = RubyVM::InstructionSequence.new(src).to_a[13]
- lines = body.find_all{|e| e.kind_of? Fixnum}
- assert_equal [1, 2, 4], lines
+ assert_equal [1, 2, 4], lines(src)
+
+ src = <<-EOS
+ # 1
+ p __LINE__ # 2
+ # 3
+ p __LINE__ # 4
+ # 5
+ EOS
+ assert_equal [2, 4], lines(src)
+
+ src = <<-EOS
+ 1 # should be optimized out
+ 2 # should be optimized out
+ p __LINE__ # 3
+ p __LINE__ # 4
+ 5 # should be optimized out
+ 6 # should be optimized out
+ p __LINE__ # 7
+ 8 # should be optimized out
+ 9
+ EOS
+ assert_equal [3, 4, 7, 9], lines(src)
end
def test_unsupport_type