> Please, review this fix for a corner case handling of `jmethodID` values.
> 
> The issue is related to the interplay between `jmethodID` values and method 
> redefinitions. Each `jmethodID` value is effectively a pointer to a `Method` 
> instance. Once that method gets redefined, the `jmethodID` is updated to 
> point to the last `Method` version. 
> Unless the method is still on stack/running, in which case the original 
> `jmethodID` will be redirected to the latest `Method` version and at the same 
> time the 'previous' `Method` version will receive a new `jmethodID` pointing 
> to that previous version.
> 
> If we happen to capture stacktrace via `GetStackTrace` or `GetAllStackTraces` 
> JVMTI calls while this previous `Method` version is still on stack we will 
> have the corresponding frame identified by a `jmethodID` pointing to that 
> version.
> However, sooner or later the 'previous' class version becomes eligible for 
> cleanup at what time all contained `Method` instances. The cleanup process 
> will not perform the `jmethodID` pointer maintenance and we will end up with 
> pointers to deallocated memory. 
> This is caused by the fact that the `jmethodID` lifecycle is bound to 
> `ClassLoaderData` instance and all relevant `jmethodID`s will get 
> batch-updated when the class loader is being released and all its classes are 
> getting unloaded. 
> 
> This means that we need to make sure that if a `Method` instance is being 
> deallocate the associated `jmethodID` (if any) must not point to the 
> deallocated instance once we are finished. Unfortunately, we can not just 
> update the `jmethodID` values in bulk when purging an old class version - the 
> per `InstanceKlass` jmethodID cache is present only for the main class 
> version and contains `jmethodID` values for both the old and current method 
> versions. 
> 
> ~Therefore we need to perform `jmethodID` lookup when we are about to 
> deallocate a `Method` instance and clean up the pointer only if that 
> `jmethodID` is pointing to the `Method` instance which is being deallocated.~
> 
> Therefore, we need to perform `jmethodID` lookup for each method in an old 
> class version that is getting purged, and null out the pointer of that 
> `jmethodID` to break the link from `jmethodID` to the method instance that is 
> about to get deallocated.
> 
> _(For anyone interested, a much lengthier writeup is available in [my 
> blog](https://jbachorik.github.io/posts/mysterious-jmethodid))_

Jaroslav Bachorik has updated the pull request incrementally with one 
additional commit since the last revision:

  Restrict cleanup to obsolete methods only

-------------

Changes:
  - all: https://git.openjdk.org/jdk/pull/16662/files
  - new: https://git.openjdk.org/jdk/pull/16662/files/81e31dae..aae367fb

Webrevs:
 - full: https://webrevs.openjdk.org/?repo=jdk&pr=16662&range=10
 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=16662&range=09-10

  Stats: 1 line in 1 file changed: 0 ins; 0 del; 1 mod
  Patch: https://git.openjdk.org/jdk/pull/16662.diff
  Fetch: git fetch https://git.openjdk.org/jdk.git pull/16662/head:pull/16662

PR: https://git.openjdk.org/jdk/pull/16662

Reply via email to