Skip to content
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

Improvements to instance variable shaping #7516

Open
wants to merge 2 commits into
base: 9.5-dev
Choose a base branch
from

Commits on May 29, 2024

  1. Acquire variables in depth-first order

    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.
    headius committed May 29, 2024
    Configuration menu
    Copy the full SHA
    64a4196 View commit details
    Browse the repository at this point in the history
  2. Start moving shape reference into shaped objects

    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 committed May 29, 2024
    Configuration menu
    Copy the full SHA
    f432822 View commit details
    Browse the repository at this point in the history