diff options
author | Jean Boussier <byroot@ruby-lang.org> | 2023-11-07 18:09:55 +0100 |
---|---|---|
committer | Jean Boussier <jean.boussier@gmail.com> | 2023-11-08 11:02:55 +0100 |
commit | d898e8d6f89fba34a9ee5c0e139f38ac807059e6 (patch) | |
tree | bf9d79ff3b3502565b5b718427f192bcd472dc64 /lib | |
parent | 4abf6cde583f3ebe562bd9d62e0126b2cbf4dfac (diff) |
Refactor rb_shape_transition_shape_capa out
Right now the `rb_shape_get_next` shape caller need to
first check if there is capacity left, and if not call
`rb_shape_transition_shape_capa` before it can call `rb_shape_get_next`.
And on each of these it needs to checks if we got a TOO_COMPLEX
back.
All this logic is duplicated in the interpreter, YJIT and RJIT.
Instead we can have `rb_shape_get_next` do the capacity transition
when needed. The caller can compare the old and new shapes capacity
to know if resizing is needed. It also can check for TOO_COMPLEX
only once.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/ruby_vm/rjit/insn_compiler.rb | 31 |
1 files changed, 8 insertions, 23 deletions
diff --git a/lib/ruby_vm/rjit/insn_compiler.rb b/lib/ruby_vm/rjit/insn_compiler.rb index 12f9a6c505..74a982e898 100644 --- a/lib/ruby_vm/rjit/insn_compiler.rb +++ b/lib/ruby_vm/rjit/insn_compiler.rb @@ -502,28 +502,7 @@ module RubyVM::RJIT shape = C.rb_shape_get_shape_by_id(shape_id) current_capacity = shape.capacity - # If the object doesn't have the capacity to store the IV, - # then we'll need to allocate it. - needs_extension = shape.next_iv_index >= current_capacity - - # We can write to the object, but we need to transition the shape - ivar_index = shape.next_iv_index - - capa_shape = - if needs_extension - # We need to add an extended table to the object - # First, create an outgoing transition that increases the capacity - C.rb_shape_transition_shape_capa(shape) - else - nil - end - - dest_shape = - if capa_shape - C.rb_shape_get_next(capa_shape, comptime_receiver, ivar_name) - else - C.rb_shape_get_next(shape, comptime_receiver, ivar_name) - end + dest_shape = C.rb_shape_get_next(shape, comptime_receiver, ivar_name) new_shape_id = C.rb_shape_id(dest_shape) if new_shape_id == C::OBJ_TOO_COMPLEX_SHAPE_ID @@ -531,12 +510,18 @@ module RubyVM::RJIT return CantCompile end + ivar_index = shape.next_iv_index + + # If the new shape has a different capacity, we need to + # reallocate the object. + needs_extension = dest_shape.capacity != shape.capacity + if needs_extension # Generate the C call so that runtime code will increase # the capacity and set the buffer. asm.mov(C_ARGS[0], :rax) asm.mov(C_ARGS[1], current_capacity) - asm.mov(C_ARGS[2], capa_shape.capacity) + asm.mov(C_ARGS[2], dest_shape.capacity) asm.call(C.rb_ensure_iv_list_size) # Load the receiver again after the function call |