From: ko1@... Date: 2018-03-28T06:13:18+00:00 Subject: [ruby-core:86352] [Ruby trunk Bug#14605] Remove `original_iseq` from `rb_iseq_constant_body` Issue #14605 has been updated by ko1 (Koichi Sasada). > but we don't use the encoded instructions very often, and this patch 1) ensures that the decoded instructions get GC'd, and 2) reduces the size of rb_iseq_constant_body. "we don't use the decoded instructions very often"? ---------------------------------------- Bug #14605: Remove `original_iseq` from `rb_iseq_constant_body` https://bugs.ruby-lang.org/issues/14605#change-71278 * Author: tenderlovemaking (Aaron Patterson) * Status: Open * Priority: Normal * Assignee: * Target version: * ruby -v: * Backport: 2.3: UNKNOWN, 2.4: UNKNOWN, 2.5: UNKNOWN ---------------------------------------- I've attached a patch that removes `original_iseq` from the `rb_iseq_constant_body` definition. In order to do this, I had to replace `rb_iseq_original_iseq` with a function that calls a callback along with the decoded instructions. The decoded instructions should be kept alive on the stack, and will automatically get garbage collected when we're done with them. I think this makes it a little harder to access the decoded instructions, but we don't use the encoded instructions very often, and this patch 1) ensures that the decoded instructions get GC'd, and 2) reduces the size of `rb_iseq_constant_body`. Here is a script to demonstrate: ~~~ruby require 'objspace' def foo puts "hello" end 2.times do |i| puts "Decode number #{i}" iseq = RubyVM::InstructionSequence.of method(:foo) x = ObjectSpace.reachable_objects_from(iseq).last p ObjectSpace.reachable_objects_from(x) iseq.to_a p ObjectSpace.reachable_objects_from(x) end ~~~ If you run this with trunk, the output is this: ~~~ Decode number 0 ["hello", "foo", ["thing.rb", "/Users/aaron/git/ruby/thing.rb"]] ["hello", #, "foo", ["thing.rb", "/Users/aaron/git/ruby/thing.rb"]] Decode number 1 ["hello", #, "foo", ["thing.rb", "/Users/aaron/git/ruby/thing.rb"]] ["hello", #, "foo", ["thing.rb", "/Users/aaron/git/ruby/thing.rb"]] ~~~ The first time the instructions are decoded, they get cached in the iseq, and never go away. With my patch, the output is this: ~~~ Decode number 0 ["hello", "foo", ["thing.rb", "/Users/aaron/git/ruby/thing.rb"]] ["hello", "foo", ["thing.rb", "/Users/aaron/git/ruby/thing.rb"]] Decode number 1 ["hello", "foo", ["thing.rb", "/Users/aaron/git/ruby/thing.rb"]] ["hello", "foo", ["thing.rb", "/Users/aaron/git/ruby/thing.rb"]] ~~~ The diff is kind of large, but I'm mostly moving things around to accommodate the callback. ---Files-------------------------------- 0001-Remove-original_iseq-from-rb_iseq_constant_body.patch (18.7 KB) -- https://bugs.ruby-lang.org/ Unsubscribe: