Project

General

Profile

Actions

Bug #21362

open

Namespace: Inline method caches poisoned with builtins

Added by jhawthorn (John Hawthorn) 3 days ago. Updated 3 days ago.

Status:
Open
Assignee:
-
Target version:
-
[ruby-core:122238]

Description

File.write("/tmp/ntest.rb", <<~'RUBY')
class Integer
  def succ = self + 2
end

module Test
  def self.run = 10.times.to_a
end
RUBY

module Test
  def self.run = 10.times.to_a
end

ns = Namespace.new
ns.require("/tmp/ntest.rb")

p namespaced: ns::Test.run
p main: Test.run
RUBY_NAMESPACE=1 ruby test_namespace_succ.rb
ruby: warning: Namespace is experimental, and the behavior may change in the future!
See doc/namespace.md for known issues, etc.
{namespaced: [0, 2, 4, 6, 8]}
{main: [0, 2, 4, 6, 8]}

What's happening here is that we have a number of "builtin" Ruby files which are loaded during the VM boot. The instruction sequences and method definitions from these files end up as part of the "root" namespace. However this iseq can still include inline caches, and in this example we see the cache poisoned by being run in a namespace with succ redefined. I was surprised by this, I expected it to call using the "root" namespace.

It's definitely a strange edge-case to redefine succ, but the namespace semantics here are important because how this is defined impacts how useful builtins can be:

  • If builtins inherit their namespace from the caller, then they cannot use inline caches (or inline caches must always check for namespace validity) and also cannot be JIT compiled (unless the JIT also checks for namespace validity, and given the complexity of rb_current_namespace, it would be very undesirable). This is very bad as converting C code to builtin Ruby has been important for getting better performance.

  • If builtins make calls using the "root" namespace, inline caching and the JIT should work (actually there may be advantages to both since the namespace is mostly immutable). However this will limit what we are able to move from C to Ruby, as it wouldn't be possible to have the same semantics as C methods (where the caller's namespace is used).

Actions

Also available in: Atom PDF

Like0
Like0