mirror of
https://github.com/ruby/ruby.git
synced 2026-01-26 20:19:19 +00:00
variable.c: handle cleared fields_obj in genfields cache
[Bug #21547] Followup: https://github.com/ruby/ruby/pull/14201 When adding an instance variable and the IMEMO/fields need to be larger, we allocate a new one and clear the old one. Since the old one may still be in other ec's cache, on a hit we must check the IMEMO/fields isn't a stale one.
This commit is contained in:
parent
a837ec0962
commit
b6bf44ae0f
3
depend
3
depend
@ -6306,6 +6306,7 @@ imemo.$(OBJEXT): $(top_srcdir)/internal/compilers.h
|
||||
imemo.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
||||
imemo.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
||||
imemo.$(OBJEXT): $(top_srcdir)/internal/namespace.h
|
||||
imemo.$(OBJEXT): $(top_srcdir)/internal/object.h
|
||||
imemo.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
||||
imemo.$(OBJEXT): $(top_srcdir)/internal/serial.h
|
||||
imemo.$(OBJEXT): $(top_srcdir)/internal/set_table.h
|
||||
@ -7159,7 +7160,6 @@ iseq.$(OBJEXT): $(top_srcdir)/prism/pack.h
|
||||
iseq.$(OBJEXT): $(top_srcdir)/prism/parser.h
|
||||
iseq.$(OBJEXT): $(top_srcdir)/prism/prettyprint.h
|
||||
iseq.$(OBJEXT): $(top_srcdir)/prism/prism.h
|
||||
iseq.$(OBJEXT): $(top_srcdir)/prism/prism.h
|
||||
iseq.$(OBJEXT): $(top_srcdir)/prism/regexp.h
|
||||
iseq.$(OBJEXT): $(top_srcdir)/prism/static_literals.h
|
||||
iseq.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h
|
||||
@ -11676,7 +11676,6 @@ prism/prism.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h
|
||||
prism/prism.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h
|
||||
prism/prism.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h
|
||||
prism/prism.$(OBJEXT): $(top_srcdir)/prism/version.h
|
||||
prism/prism.$(OBJEXT): $(top_srcdir)/prism/version.h
|
||||
prism/regexp.$(OBJEXT): $(top_srcdir)/prism/ast.h
|
||||
prism/regexp.$(OBJEXT): $(top_srcdir)/prism/defines.h
|
||||
prism/regexp.$(OBJEXT): $(top_srcdir)/prism/encoding.h
|
||||
|
||||
3
imemo.c
3
imemo.c
@ -3,6 +3,7 @@
|
||||
#include "id_table.h"
|
||||
#include "internal.h"
|
||||
#include "internal/imemo.h"
|
||||
#include "internal/object.h"
|
||||
#include "internal/st.h"
|
||||
#include "vm_callinfo.h"
|
||||
|
||||
@ -208,6 +209,8 @@ rb_imemo_fields_clear(VALUE fields_obj)
|
||||
else {
|
||||
RBASIC_SET_SHAPE_ID(fields_obj, ROOT_SHAPE_ID);
|
||||
}
|
||||
// Invalidate the ec->gen_fields_cache.
|
||||
RBASIC_CLEAR_CLASS(fields_obj);
|
||||
}
|
||||
|
||||
/* =========================================================================
|
||||
|
||||
@ -447,6 +447,19 @@ class TestVariable < Test::Unit::TestCase
|
||||
assert_equal(%i[α b], b.local_variables)
|
||||
end
|
||||
|
||||
def test_genivar_cache
|
||||
bug21547 = '[Bug #21547]'
|
||||
klass = Class.new(Array)
|
||||
instance = klass.new
|
||||
instance.instance_variable_set(:@a1, 1)
|
||||
instance.instance_variable_set(:@a2, 2)
|
||||
Fiber.new do
|
||||
instance.instance_variable_set(:@a3, 3)
|
||||
instance.instance_variable_set(:@a4, 4)
|
||||
end.resume
|
||||
assert_equal 4, instance.instance_variable_get(:@a4)
|
||||
end
|
||||
|
||||
private
|
||||
def with_kwargs_11(v1:, v2:, v3:, v4:, v5:, v6:, v7:, v8:, v9:, v10:, v11:)
|
||||
local_variables
|
||||
|
||||
@ -1247,7 +1247,7 @@ rb_obj_fields(VALUE obj, ID field_name)
|
||||
generic_fields:
|
||||
{
|
||||
rb_execution_context_t *ec = GET_EC();
|
||||
if (ec->gen_fields_cache.obj == obj) {
|
||||
if (ec->gen_fields_cache.obj == obj && rb_imemo_fields_owner(ec->gen_fields_cache.fields_obj) == obj) {
|
||||
fields_obj = ec->gen_fields_cache.fields_obj;
|
||||
}
|
||||
else {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user