Age | Commit message (Collapse) | Author |
|
|
|
We weren't taking in to account that objects with generic IV tables
could go "too complex" in the IV set code. This commit takes that in to
account and also ensures FL_EXIVAR is set when a geniv object
transitions to "too complex"
Co-Authored-By: Jean Boussier <[email protected]>
|
|
|
|
If it runs out of shapes, or new variations aren't allowed, it will
return "too complex"
|
|
|
|
|
|
This way the groth factor is encapsulated, which allows
rb_shape_transition_shape_capa to be smarter about ideal sizes.
|
|
We don't really need obj_ivar_heap_alloc and obj_ivar_heap_realloc since
they're just one liners.
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/7942
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/8035
|
|
Co-authored-by: Nobuyoshi Nakada <[email protected]>
Notes:
Merged: https://github.com/ruby/ruby/pull/8035
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/7983
|
|
http://ci.rvm.jp/results/trunk-random1@ruby-sp2-docker/4612360
|
|
Introduce `Module#set_temporary_name` for setting identifiers for otherwise
anonymous modules/classes.
Notes:
Merged-By: ioquatix <[email protected]>
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/7962
|
|
This reverts commit 10621f7cb9a0c70e568f89cce47a02e878af6778.
This was reverted because the gc integrity build started failing. We
have figured out a fix so I'm reopening the PR.
Original commit message:
Fix cvar caching when class is cloned
The class variable cache that was added in
ruby#4544 changed the behavior of class
variables on cloned classes. As reported when a class is cloned AND a
class variable was set, and the class variable was read from the
original class, reading a class variable from the cloned class would
return the value from the original class.
This was happening because the IC (inline cache) is stored on the ISEQ
which is shared between the original and cloned class, therefore they
share the cache too.
To fix this we are now storing the `cref` in the cache so that we can
check if it's equal to the current `cref`. If it's different we don't
want to read from the cache. If it's the same we do. Cloned classes
don't share the same cref with their original class.
This will need to be backported to 3.1 in addition to 3.2 since the bug
exists in both versions.
We also added a marking function which was missing.
Fixes [Bug #19379]
Co-authored-by: Aaron Patterson <[email protected]>
Notes:
Merged: https://github.com/ruby/ruby/pull/7900
|
|
This reverts commit 77d1b082470790c17c24a2f406b4fec5d522636b.
|
|
The class variable cache that was added in
https://github.com/ruby/ruby/pull/4544 changed the behavior of class
variables on cloned classes. As reported when a class is cloned AND a
class variable was set, and the class variable was read from the
original class, reading a class variable from the cloned class would
return the value from the original class.
This was happening because the IC (inline cache) is stored on the ISEQ
which is shared between the original and cloned class, therefore they
share the cache too.
To fix this we are now storing the `cref` in the cache so that we can
check if it's equal to the current `cref`. If it's different we don't
want to read from the cache. If it's the same we do. Cloned classes
don't share the same cref with their original class.
This will need to be backported to 3.1 in addition to 3.2 since the bug
exists in both versions.
We also added a marking function which was missing.
Fixes [Bug #19379]
Co-authored-by: Aaron Patterson <[email protected]>
Notes:
Merged: https://github.com/ruby/ruby/pull/7265
|
|
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/7813
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/7746
|
|
The following code produces two NameErrors respectively
and they are independent, but the second one can show
`private constant` message because of first NameError.
```ruby
class C
class PrivateClass; end
private_constant :PrivateClass
end
begin
eval('class C::PrivateClass; end')
rescue => e
p e
end
begin
Object.const_get 'Foo'
rescue => e
p e
end
#<NameError: private constant C::PrivateClass referenced>
#<NameError: private constant C::Foo referenced>
#=> should be #<NameError: uninitialized constant Foo>
```
It fails the test-all tests with
`make test-all TESTS='ruby/class ruby/parse --seed=58891 -v`.
The reason is clear miss from https://github.com/ruby/ruby/commit/7387c08373a
Notes:
Merged: https://github.com/ruby/ruby/pull/7736
|
|
Moves shape ID to FL_USER4 to FL_USER19 for the shape ID on 32 bit
systems. This makes the rb_classext_struct smaller so that it can be
embedded.
Notes:
Merged: https://github.com/ruby/ruby/pull/7719
|
|
st tables will maintain insertion order so we can marshal dump / load
objects with instance variables in the same order they were set on that
particular instance
[ruby-core:112926] [Bug #19535]
Co-Authored-By: Jemma Issroff <[email protected]>
Notes:
Merged: https://github.com/ruby/ruby/pull/7560
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/7503
|
|
This reverts commit 69465df4242f3b2d8e55fbe18d7c45b47b40a626.
|
|
This makes the behavior of classes and modules when there are too many instance variables match the behavior of objects with too many instance variables.
Notes:
Merged: https://github.com/ruby/ruby/pull/7349
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/7459
|
|
The following script can sometimes trigger a crash:
```ruby
GC.stress = true
class Array
def foo(bool)
if bool
@a = 1
@b = 2
@c = 1
else
@c = 1
end
end
end
obj = []
obj.foo(true)
obj2 = []
obj2.foo(false)
obj3 = []
obj3.foo(true)
```
This is because vm_setivar_default calls rb_ensure_generic_iv_list_size
to resize the iv list. However, the call to gen_ivtbl_resize reallocs
the iv list, and then inserts into the generic iv table. If the
st_insert triggers a GC then the old iv list will be read during
marking, causing a use-after-free bug.
Co-Authored-By: Jemma Issroff <[email protected]>
Notes:
Merged: https://github.com/ruby/ruby/pull/7407
|
|
It's just a decorated st_table, so we call `RB_OBJ_WRITTEN` after
inserting to it.
We also call `RB_OBJ_WRITTEN` on delete for completeness even though
it's a noop.
Notes:
Merged: https://github.com/ruby/ruby/pull/7402
|
|
Notes:
Merged-By: k0kubun <[email protected]>
|
|
It's not uncommon for libraries to add thing sinto
autoload that won't necessarily be loaded.
This can cause hundreds or thousands of entries to be
left over in the autoload table, so it's best not to
mark them on every minor.
Notes:
Merged: https://github.com/ruby/ruby/pull/7392
|
|
Right now the attached object is stored as an instance variable
and all the call sites that either get or set it have to know how it's
stored.
It's preferable to hide this implementation detail behind accessors
so that it is easier to change how it's stored.
Notes:
Merged: https://github.com/ruby/ruby/pull/7308
|
|
Instance variables held in gen_ivtbl are marked with rb_gc_mark. It
prevents the referenced objects from moving, which is bad for copying
garbage collectors.
This commit allows those instance variables to be updated during
gc_update_object_references.
Notes:
Merged: https://github.com/ruby/ruby/pull/7206
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/7124
|
|
This commit moves the classpath (and tmp_classpath) from instance
variables to the rb_classext_t. This improves performance as we no
longer need to set an instance variable when assigning a classpath to
a class.
I benchmarked with the following script:
```ruby
name = :MyClass
puts(Benchmark.measure do
10_000_000.times do |i|
Object.const_set(name, Class.new)
Object.send(:remove_const, name)
end
end)
```
Before this patch:
```
5.440119 0.025264 5.465383 ( 5.467105)
```
After this patch:
```
4.889646 0.028325 4.917971 ( 4.942678)
```
Notes:
Merged: https://github.com/ruby/ruby/pull/7096
|
|
A class/module should always have a RCLASS_EXT, so we shouldn't need to
check that it exists.
Notes:
Merged: https://github.com/ruby/ruby/pull/7095
|
|
The following script crashes:
```ruby
GC.auto_compact = true
GC.stress = true
class Foo
def initialize
@a = @b = @c = 0
end
def add_ivars
@d = @e = @f = 0
end
end
ary = 1_000.times.map { Foo.new }
ary.each { |f| f.add_ivars }
```
This is because in rb_grow_iv_list, it first calls
rb_ensure_iv_list_size to allocate the buffer (and also unsets the
embed bit) then rb_shape_transition_shape_capa to get the new shape.
However, auto-compact can trigger in rb_shape_transition_shape_capa
which would re-embed the object since it doesn't have the new shape yet.
This causes a crash as the object is now embedded but has a non-embed
shape which would cause the object to have a buffer overrun.
Notes:
Merged: https://github.com/ruby/ruby/pull/6986
|
|
When an object becomes "too complex" (in other words it has too many
variations in the shape tree), we transition it to use a "too complex"
shape and use a hash for storing instance variables.
Without this patch, there were rare cases where shape tree growth could
"explode" and cause performance degradation on what would otherwise have
been cached fast paths.
This patch puts a limit on shape tree growth, and gracefully degrades in
the rare case where there could be a factorial growth in the shape tree.
For example:
```ruby
class NG; end
HUGE_NUMBER.times do
NG.new.instance_variable_set(:"@unique_ivar_#{_1}", 1)
end
```
We consider objects to be "too complex" when the object's class has more
than SHAPE_MAX_VARIATIONS (currently 8) leaf nodes in the shape tree and
the object introduces a new variation (a new leaf node) associated with
that class.
For example, new variations on instances of the following class would be
considered "too complex" because those instances create more than 8
leaves in the shape tree:
```ruby
class Foo; end
9.times { Foo.new.instance_variable_set(":@uniq_#{_1}", 1) }
```
However, the following class is *not* too complex because it only has
one leaf in the shape tree:
```ruby
class Foo
def initialize
@a = @b = @c = @d = @e = @f = @g = @h = @i = nil
end
end
9.times { Foo.new }
``
This case is rare, so we don't expect this change to impact performance
of most applications, but it needs to be handled.
Co-Authored-By: Aaron Patterson <[email protected]>
Notes:
Merged: https://github.com/ruby/ruby/pull/6931
|
|
Cases like this:
```ruby
obj = Object.new
loop do
obj.instance_variable_set(:@foo, 1)
obj.remove_instance_variable(:@foo)
end
```
can cause us to use many more shapes than we want (and even run out).
This commit changes the code such that when an instance variable is
removed, we'll walk up the shape tree, find the shape, then rebuild any
child nodes that happened to be below the "targetted for removal" IV.
This also requires moving any instance variables so that indexes derived
from the shape tree will work correctly.
Co-Authored-By: Jemma Issroff <[email protected]>
Co-authored-by: John Hawthorn <[email protected]>
Notes:
Merged: https://github.com/ruby/ruby/pull/6866
|
|
|
|
This commit significantly speeds up shape transitions as it changes
get_next_shape_internal to not perform a lookup (and instead require
the caller to perform the lookup). This avoids double lookups during
shape transitions.
There is a significant (~2x) speedup in the following micro-benchmark:
puts(Benchmark.measure do
o = Object.new
100_000.times do |i|
o.instance_variable_set(:"@a#{i}", 0)
end
end)
Before:
22.393194 0.201639 22.594833 ( 22.684237)
After:
11.323086 0.022284 11.345370 ( 11.389346)
Notes:
Merged: https://github.com/ruby/ruby/pull/6751
|
|
obj_ivar_set and vm_setivar_slowpath is essentially doing the same thing,
but the code is duplicated and not quite implemented in the same way,
which could cause bugs. This commit refactors vm_setivar_slowpath to use
obj_ivar_set.
Notes:
Merged: https://github.com/ruby/ruby/pull/6732
|
|
We would like to differentiate types of objects via their shape. This
commit adds a special T_OBJECT shape when we allocate an instance of
T_OBJECT. This allows us to avoid testing whether an object is an
instance of a T_OBJECT or not, we can just check the shape.
Notes:
Merged: https://github.com/ruby/ruby/pull/6758
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/6721
|
|
Extract an `rb_shape_get_parent` method instead of continually calling
`rb_shape_get_shape_by_id(shape->parent_id)`
Notes:
Merged: https://github.com/ruby/ruby/pull/6708
|
|
Since object shapes store the capacity of an object, we no longer
need the numiv field on RObjects. This gives us one extra slot which
we can use to give embedded objects one more instance variable (for a
total of 3 ivs). This commit removes the concept of numiv from RObject.
Notes:
Merged: https://github.com/ruby/ruby/pull/6699
|
|
This commit adds a `capacity` field to shapes, and adds shape
transitions whenever an object's capacity changes. Objects which are
allocated out of a bigger size pool will also make a transition from the
root shape to the shape with the correct capacity for their size pool
when they are allocated.
This commit will allow us to remove numiv from objects completely, and
will also mean we can guarantee that if two objects share shapes, their
IVs are in the same positions (an embedded and extended object cannot
share shapes). This will enable us to implement ivar sets in YJIT using
object shapes.
Co-Authored-By: Aaron Patterson <[email protected]>
Notes:
Merged: https://github.com/ruby/ruby/pull/6699
|
|
|
|
|