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.

_(For anyone interested, a much lengthier writeup is available in [my 
blog](https://jbachorik.github.io/posts/mysterious-jmethodid))_

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

Commit messages:
 - 8313816: Accessing jmethodID might lead to spurious crashes

Changes: https://git.openjdk.org/jdk/pull/16662/files
 Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=16662&range=00
  Issue: https://bugs.openjdk.org/browse/JDK-8313816
  Stats: 282 lines in 9 files changed: 278 ins; 0 del; 4 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