ConstantPool::name_ref_at calls(int which) eventually comes to here with (uncached == false):
https://github.com/openjdk/jdk/blob/8c106b0c8e4562a44ecd1e069c0911acfc428ecf/src/hotspot/share/oops/constantPool.cpp#L689-L692
int ConstantPool::impl_name_and_type_ref_index_at(int which, bool uncached) {
int i = which;
if (!uncached && cache() != nullptr) { <<< HERE
if (ConstantPool::is_invokedynamic_index(which)) {
name_ref_at calls expects that the "which" parameter to be an index rewritten by rewriter.cpp. However, if the class is rewritten, cache() cannot be null.
The only reason we have the "&& cache() != nullptr" check is we have buggy code that calls name_ref_at calls not with a rewritten index, but with a regular constant pool index.
Example:
https://github.com/openjdk/jdk/blob/8c106b0c8e4562a44ecd1e069c0911acfc428ecf/src/hotspot/share/interpreter/rewriter.cpp#L231
void Rewriter::maybe_rewrite_invokehandle(address opc, int cp_index, int cache_index, bool reverse) {
if (!reverse) {
...
if (_pool->klass_ref_at_noresolve(cp_index) == vmSymbols::java_lang_invoke_MethodHandle() &&
MethodHandles::is_signature_polymorphic_name(vmClasses::MethodHandle_klass(),
_pool->name_ref_at(cp_index))) {
Here we clearly have a cp_index, and we are *before* the class was rewritten). This call should be changed to
_pool->uncached_name_ref_at(cp_index))) {
To catch all these errors we should change the (!uncached && cache() != nullptr) check to:
if (!uncached) {
assert(cache() != nullptr, "'which' is a rewritten index so this class must have been rewritten");
=================
Similarly, some other calls like uncached_klass_ref_index_at(), signature_ref_at(), etc, should be changed to their uncached_xxx() variant.
https://github.com/openjdk/jdk/blob/8c106b0c8e4562a44ecd1e069c0911acfc428ecf/src/hotspot/share/oops/constantPool.cpp#L689-L692
int ConstantPool::impl_name_and_type_ref_index_at(int which, bool uncached) {
int i = which;
if (!uncached && cache() != nullptr) { <<< HERE
if (ConstantPool::is_invokedynamic_index(which)) {
name_ref_at calls expects that the "which" parameter to be an index rewritten by rewriter.cpp. However, if the class is rewritten, cache() cannot be null.
The only reason we have the "&& cache() != nullptr" check is we have buggy code that calls name_ref_at calls not with a rewritten index, but with a regular constant pool index.
Example:
https://github.com/openjdk/jdk/blob/8c106b0c8e4562a44ecd1e069c0911acfc428ecf/src/hotspot/share/interpreter/rewriter.cpp#L231
void Rewriter::maybe_rewrite_invokehandle(address opc, int cp_index, int cache_index, bool reverse) {
if (!reverse) {
...
if (_pool->klass_ref_at_noresolve(cp_index) == vmSymbols::java_lang_invoke_MethodHandle() &&
MethodHandles::is_signature_polymorphic_name(vmClasses::MethodHandle_klass(),
_pool->name_ref_at(cp_index))) {
Here we clearly have a cp_index, and we are *before* the class was rewritten). This call should be changed to
_pool->uncached_name_ref_at(cp_index))) {
To catch all these errors we should change the (!uncached && cache() != nullptr) check to:
if (!uncached) {
assert(cache() != nullptr, "'which' is a rewritten index so this class must have been rewritten");
=================
Similarly, some other calls like uncached_klass_ref_index_at(), signature_ref_at(), etc, should be changed to their uncached_xxx() variant.