Bug #967

Results of const_missing are being cached incorrectly

Added by Charles Nutter about 3 years ago. Updated 10 months ago.

[ruby-core:21059]
Status:Closed Start date:01/02/2009
Priority:High Due date:
Assignee:Koichi Sasada % Done:

100%

Category:YARV
Target version:1.9.1 RC2
ruby -v:

Description

Ruby 1.9 sped up constant lookup by adding an inline cache, cleared by a global serial number incremented when any constant is set. This works well for normal constants, but unfortunately 1.9 is also caching the result of const_missing. For example, the following output:

◆ ruby1.9 -e "def Object.const_missing(sym); Time.now; end; 5.times { p XXX; sleep 1 }"
2009-01-01 23:59:33 -0600
2009-01-01 23:59:33 -0600
2009-01-01 23:59:33 -0600
2009-01-01 23:59:33 -0600
2009-01-01 23:59:33 -0600

The result of const_missing is being cached at the lookup site for XXX. Here's what the output should look like, with incrementing seconds:

◆ ruby -e "def Object.const_missing(sym); Time.now; end; 5.times { p XXX; sleep 1 }"
Fri Jan 02 00:02:09 -0600 2009
Fri Jan 02 00:02:10 -0600 2009
Fri Jan 02 00:02:11 -0600 2009
Fri Jan 02 00:02:12 -0600 2009
Fri Jan 02 00:02:13 -0600 2009

Note that this also affects colon2 and colon3 constant lookup:

◆ ruby1.9 -e "def Object.const_missing(sym); cls = Class.new; cls.class_eval 'Foo = Time.now'; cls; end; 5.times { p XXX::Foo; sleep 1 }"
2009-01-02 00:02:44 -0600
2009-01-02 00:02:44 -0600
2009-01-02 00:02:44 -0600
2009-01-02 00:02:44 -0600
2009-01-02 00:02:44 -0600

◆ ruby1.9 -e "def Object.const_missing(sym); Time.now; end; 5.times { p ::XXX; sleep 1 }"
2009-01-02 00:03:06 -0600
2009-01-02 00:03:06 -0600
2009-01-02 00:03:06 -0600
2009-01-02 00:03:06 -0600
2009-01-02 00:03:06 -0600

The result of const_missing should never be cached, since doing so would break code that expects const_missing to keep firing (some DSLs for example).

This was run against the just-released Ruby 1.9 RC.

Associated revisions

Revision 21536
Added by Koichi Sasada about 3 years ago

* vm.c (rb_vm_inc_const_missing_count, ruby_vm_const_missing_count): added. * vm_insnhelper.h: ditto. * variable.c (rb_const_get_0), insns.def: Constants should not be cached if const_missing is called. [ruby-core:21059] [Bug #967] * bootstraptest/test_class.rb: add a test.

Revision 21536
Added by Koichi Sasada about 3 years ago

* vm.c (rb_vm_inc_const_missing_count, ruby_vm_const_missing_count): added. * vm_insnhelper.h: ditto. * variable.c (rb_const_get_0), insns.def: Constants should not be cached if const_missing is called. [ruby-core:21059] [Bug #967] * bootstraptest/test_class.rb: add a test.

History

Updated by Yuki Sonoda about 3 years ago

  • Target version set to 1.9.1 RC2

Updated by Koichi Sasada about 3 years ago

  • Status changed from Open to Closed
  • % Done changed from 0 to 100
Applied in changeset r21536.

Also available in: Atom PDF