openj9 icon indicating copy to clipboard operation
openj9 copied to clipboard

Cache MemberName data on initialization and resolution

Open ThanHenderson opened this issue 8 months ago • 2 comments

State of Things

MemberNames -- specifically its vmtarget and vmindex members -- need to be fixed up on class redefinition. In the current implementation, each native J9Class instance has a memberNames which is a singly-linked list that holds weak references to all the MemberNames whose vmtarget is resolved one of the class' members.

Because we maintain a collection of weak references, a memberNames list node can become stale if the underlying MemberName is collected. To solve this potential memory leak scenario -- if there is no later call to redefineClassesCommon which will also force memberNames list's nodes to be cleaned up -- there is a finalize method on MemberName that indicates to the VM that a MemberName has become unreachable, and the that corresponding memberNames list node can be cleaned up the next time a node is added to the list.

The data reported here indicates that there can be many MemberNames that have the same vmtarget, suggesting that the MemberNames could share data representing their resolution.

Suggested New Approach

Adopt a cacheable structure to hold the the resolution data -- vmtarget and vmindex -- for a MemberName and intern those structures to share amongst MemberNames with the same resolution.

Such structure already exists on MemberName -- ResolvedMethodName -- but we don't use it; instead we inject vmtarget and vmindex directly into the MemberName.

A cache entry would hold a strong reference to a ResolvedMethodName, and on class redefinition, all entries in the cache corresponding to the class being redefined could be fixed up.

Considerations

  1. Owner of the cache. Should we have a per-class hash table for storing ResolvedMethodNames owned by a J9Class? Or a single global cache that considers a class as a part of the key?
  2. The extra level of indirection from the MemberName to the ResolvedMethodName to access the vmtarget and vmindex. I hadn't noticed any regressions in my initial benchmarking the use of ResolvedMethodName but some microbenchmarks may be necessary to quantify this.

Benefits

  • Removes the finalize method -- which is deprecated -- from the MemberName Java class.
  • Avoids the call to javaLookupMethod on cache hits during resolution.
  • Better GC integration.
  • Upper bound on number of cache entries for a class, whereas the MemberName list is unbounded.

This issues serves as a tracker for this work and a place for discussion on questions and about design details.

ThanHenderson avatar Jun 24 '24 14:06 ThanHenderson