8000 Improvements to instance variable shaping by headius · Pull Request #8451 · jruby/jruby · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Improvements to instance variable shaping #8451

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

headius
Copy link
Member
@headius headius commented Nov 22, 2024

This PR will incorporate a few improvements to how we "right-size" user-defined objects to pack instance variables.

Better parent-driven layout of fields, so they can be shared across subclasses.
Persistent shapes for stale objects; after we realize it needs to grow, existing objects can continue living with the smaller shape.
Improved caching to avoid polymorphic thrashing when the fields are laid out the same.
Analysis of implementation and exploration of other improvements.
Stretch goals might include playing with field-doubling to store numeric values without wrappers, but the primary goal is to do a better job of choosing the right shape or evolving into the right shape over time.

See #7516.

We acquire a list of likely instance variables by walking the
target class and all parent classes looking for instance variable
instructions in the methods in the method table. Previously, this
logic would add variables from the bottom up, checking the current
class's methods first and then the superclass and so on. This had
the effect of creating new layouts for the shared instance vars
rather than storing vars from parent classes in the same slots for
all child classes.

The new logic use a recursive call to add variables starting with
the top class and progressing down the hierarchy. Variable names
are first inserted into a sorted TreeSet at east level, and then
any new variables go into a LinkedHashSet to ensure parent
variables are laaid out before child variables. This ensures that
all child classes will use the same slots for instance variables
originally accessed in a parent class.

This does not currently improve caching of variable accessors, but
it may in the future. If we cache accessors based on the class
they originate from, we can cache parent accessors in all children
without having to do more guarding than we do at present.

Example of multi-class hierarchy preserving layout:

class A; def initialize; @foo = 1; @baz = 1; end; end; class B < A; def initialize; @bar = 1; @foo = 2; end; end; class C < A; def initialize; @quux = 1; @baz = 2; end; end; A.new; B.new; C.ne

Printing out class and found variables:

A
[@baz, @foo]
B
[@baz, @foo, @bar]
C
[@baz, @foo, @quux]

Note that in all three instances, the @baz and @foo variables
occupy the same first two slots. As long as the hierarchy has not
changed, we can rely on this layout in child classes.
In order to evolve the shape of objects as more instance variables
are discovered, we need to be able to access  multiple different
shaped instances with their own layouts. Previously, only one
shape could be associated with a given class, based on a static
inspection of all instance variable accesses in the class's
hierarchy. In order to keep stale-shaped objects functional, this
commit adds a shape reference to all shaped RubyObject subtypes.
With this we can allocate a first object using no instance vars
(falling back on the default varTable layout) and as instance vars
are encountered modify allocation to create wider object shapes.

The step here simply adds the shape reference to all shaped
objects; evolving that shape and updating the allocator will come
in future commits.
@headius headius added this to the JRuby 10.0.0.0 milestone Nov 22, 2024
@headius headius changed the base branch from 10-dev to master March 10, 2025 22:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants
0