Skip to content

Dynamic instance variables allocate too large of a table #9139

@headius

Description

@headius

Ruby classes with instance variables will attempt to pick the right "shape" on first allocation, by statically analyzing all methods in the class hierarchy and looking for variable accesses or accessors. These variables will then be stored in specialized Java fields rather than in the varTable array, improving locality.

When previously-undetected instance variables are assigned after this first instantiation, the varTable is used as a spill location to store those variables. However there are a few performance problems with how this is handled:

  • The varTable size is calculated based on the total number of variables at that point (including statically-detected variables), leaving slots empty and unused.
  • The index into the varTable for a new dynamic instance variable also reflects this total number of variables, rather than just the additional number of dynamic variables needed.

For a class with two statically-detected variables and two more dynamically allocated variables, this results in using an object with two fields (RubyObject2) with a varTable large enough for four values but only holding two non-null values.

This has greater impact for large and complex classes that have many statically-detected variables, since the size of the dynamic varTable array will waste 4 or 8 bytes per variable.

The correct logic would be that any spilled variables to go in varTable are indexed independently of the statically-detected field-based variables, and the array is allocated to hold exactly that many values.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions