663 Commits

Author SHA1 Message Date
Peter Zhu
4c3cc25ea2 Use shape capacity transition for class ivars
This commit changes class ivars to respect the capacity transition in
shapes rather than growing the capacity independently.
2023-11-02 13:42:11 -04:00
Peter Zhu
38ba040d8b Make every initial size pool shape a root shape
This commit makes every initial size pool shape a root shape and assigns
it a capacity of 0.
2023-11-02 13:42:11 -04:00
Peter Zhu
5f130e2111 Fix write barrier in rb_copy_generic_ivar 2023-11-02 09:23:14 -04:00
Peter Zhu
944e0ae698 Remove duplicated code in generic_ivar_set
There is a duplicated check for the object is too complex.
2023-11-02 08:46:54 -04:00
Peter Zhu
bdf8ce807f Fix remove_class_variable for too complex classes 2023-11-01 13:13:51 -04:00
Peter Zhu
e6059d0c84 Refactor rb_obj_remove_instance_variable 2023-11-01 11:37:13 -04:00
Peter Zhu
70e3e08881 Optimize for too complex objects 2023-11-01 11:05:46 -04:00
Jean Boussier
b77148ae9f remove_instance_variable: Handle running out of shapes
`remove_shape_recursive` wasn't considering that if we run out of
shapes, it might have to transition to SHAPE_TOO_COMPLEX.

When this happens, we now return with an error and the caller
initiates the evacuation.
2023-11-01 15:21:55 +01:00
Peter Zhu
9c6dd25093 Fix removing non-existent ivar for too complex 2023-11-01 08:25:09 -04:00
Peter Zhu
c3b7f27561 Fix remove_instance_variable for too complex generic ivar 2023-10-31 17:04:40 -04:00
Peter Zhu
8889992b75 Fix remove_instance_variable for too complex class 2023-10-31 16:38:05 -04:00
Peter Zhu
e2d950733e Add ST table to gen_ivtbl for complex shapes
On 32-bit systems, we must store the shape ID in the gen_ivtbl to not
lose the shape. If we directly store the ST table into the generic
ivar table, then we lose the shape. This makes it impossible to
determine the shape of the object and whether it is too complex or not.
2023-10-31 12:07:54 -04:00
Peter Zhu
1c45124c49 Create table for too complex generic variables 2023-10-31 12:07:54 -04:00
Aaron Patterson
6f5e378057 Fix "too complex" iv sets on generic ivar objects
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 <byroot@ruby-lang.org>
2023-10-31 12:07:54 -04:00
Jean Boussier
ac7f913ca3 Handle SHAPE_TOO_COMPLEX in generic_ivar_set 2023-10-31 12:07:54 -04:00
Aaron Patterson
afae8df373 get_next_shape_internal should always return a shape
If it runs out of shapes, or new variations aren't allowed, it will
return "too complex"
2023-10-24 14:23:17 -07:00
Aaron Patterson
a3f66e09f6 geniv objects can become too complex 2023-10-24 10:52:06 -07:00
Aaron Patterson
caf6a72348 remove IV limit / support complex shapes on classes 2023-10-24 10:52:06 -07:00
Jean Boussier
5cc44f48c5 Refactor rb_shape_transition_shape_capa to not accept capacity
This way the groth factor is encapsulated, which allows
rb_shape_transition_shape_capa to be smarter about ideal sizes.
2023-10-10 14:47:54 +02:00
Peter Zhu
196116e576 Refactor rb_ensure_iv_list_size
We don't really need obj_ivar_heap_alloc and obj_ivar_heap_realloc since
they're just one liners.
2023-08-21 09:13:36 -04:00
Peter Zhu
1e7b67f733 [Feature #19730] Remove transient heap 2023-07-13 09:27:33 -04:00
Benoit Daloze
055f7219bc Improve ArgumentError message for Module#set_temporary_name 2023-07-06 18:27:13 +02:00
Benoit Daloze
9ee1877e4a Ensure the name given to Module#set_temporary_name is not a valid constant path
Co-authored-by: Nobuyoshi Nakada <nobu@ruby-lang.org>
2023-07-06 18:27:13 +02:00
Nobuyoshi Nakada
df5ae0a550
Use rb_reg_nth_defined instead of rb_match_nth_defined 2023-06-27 22:39:15 +09:00
Takashi Kokubun
2beb14506f Handle non-enum values to fix -Wreturn-type
http://ci.rvm.jp/results/trunk-random1@ruby-sp2-docker/4612360
2023-06-21 14:31:45 -07:00
Samuel Williams
a87bce86bb
Allow setting the name of a class or module. (#7483)
Introduce `Module#set_temporary_name` for setting identifiers for otherwise
anonymous modules/classes.
2023-06-21 16:49:51 +09:00
Nobuyoshi Nakada
2dfbe91cad
Stop rb_ivar_foreach when callback returned ST_STOP 2023-06-20 13:57:42 +09:00
eileencodes
40f090f433 Revert "Revert "Fix cvar caching when class is cloned""
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 <tenderlove@ruby-lang.org>
2023-06-05 11:11:12 -07:00
Aaron Patterson
10621f7cb9
Revert "Fix cvar caching when class is cloned"
This reverts commit 77d1b082470790c17c24a2f406b4fec5d522636b.
2023-06-01 14:55:36 -07:00
eileencodes
77d1b08247 Fix cvar caching when class is cloned
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 <tenderlove@ruby-lang.org>
2023-06-01 08:52:48 -07:00
Nobuyoshi Nakada
8d242a33af
rb_bug prints a newline after the message 2023-05-20 21:43:30 +09:00
S-H-GAMELINKS
0c3f699268 Introduce gc_mark_table macro 2023-05-19 01:05:43 +09:00
S-H-GAMELINKS
fef8cca822 Merge T_OBJECT case in rb_ivar_delete function 2023-04-27 15:16:42 +02:00
Koichi Sasada
628e432739 fix NameError message
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
2023-04-19 14:53:56 +09:00
Peter Zhu
24b137336b Move shape ID to flags for classes on 32 bit
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.
2023-04-16 11:06:31 -04:00
Aaron Patterson
54dbd8bea8 Use an st table for "too complex" objects
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 <jemmaissroff@gmail.com>
2023-03-20 13:54:18 -07:00
S-H-GAMELINKS
2d0dc376c4 Reuse CVAR_LOOKUP macro 2023-03-12 10:08:18 +09:00
Aaron Patterson
365fed6369
Revert "Allow classes and modules to become too complex"
This reverts commit 69465df4242f3b2d8e55fbe18d7c45b47b40a626.
2023-03-10 08:50:43 -08:00
HParker
69465df424 Allow classes and modules to become too complex
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.
2023-03-09 15:34:49 -08:00
Takashi Kokubun
233ddfac54 Stop exporting symbols for MJIT 2023-03-06 21:59:23 -08:00
Peter Zhu
62c2082f1f [Bug #19469] Fix crash when resizing generic iv list
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 <jemmaissroff@gmail.com>
2023-03-03 16:12:03 -05:00
Jean Boussier
40e5ee64f0 Implement Write Barrier for autoload_table_type
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.
2023-03-01 08:56:56 +01:00
John Bampton
c43fbe4ebd
Fix spelling (#7405) 2023-02-28 10:05:30 -08:00
Jean Boussier
cf18f0b868 Implement Write Barrier for autoload_data
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.
2023-02-28 09:27:55 +01:00
Jean Boussier
7413079dae Encapsulate RCLASS_ATTACHED_OBJECT
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.
2023-02-15 15:24:22 +01:00
Kunshan Wang
de724487f0 Copying GC support for EXIVAR
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.
2023-01-31 09:24:26 -05:00
lukeg
f66804e6f7 don't allow setting class variable on module that's frozen [Bug #19341] 2023-01-19 16:25:20 -05:00
Peter Zhu
abff5f6203 Move classpath to rb_classext_t
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)
```
2023-01-11 11:06:58 -05:00
Peter Zhu
ac8cf010bc Remove check for RCLASS_EXT in variable.c
A class/module should always have a RCLASS_EXT, so we shouldn't need to
check that it exists.
2023-01-11 09:16:34 -05:00
Peter Zhu
d7388f720c Fix buffer overrun with auto-compact for shapes
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.
2022-12-22 09:23:40 -05:00