8302795: Shared archive failed on old version class with jsr bytecode

Reviewed-by: minqi, matsaave
This commit is contained in:
Calvin Cheung 2023-03-14 17:15:19 +00:00
parent 4e631fa43f
commit 830fd41346
4 changed files with 158 additions and 1 deletions

View file

@ -2412,7 +2412,21 @@ void InstanceKlass::metaspace_pointers_do(MetaspaceClosure* it) {
#if INCLUDE_JVMTI
it->push(&_previous_versions);
#endif
it->push(&_methods);
#if INCLUDE_CDS
// For "old" classes with methods containing the jsr bytecode, the _methods array will
// be rewritten during runtime (see Rewriter::rewrite_jsrs()). So setting the _methods to
// be writable. The length check on the _methods is necessary because classes which
// don't have any methods share the Universe::_the_empty_method_array which is in the RO region.
if (_methods != nullptr && _methods->length() > 0 &&
!can_be_verified_at_dumptime() && methods_contain_jsr_bytecode()) {
// To handle jsr bytecode, new Method* maybe stored into _methods
it->push(&_methods, MetaspaceClosure::_writable);
} else {
#endif
it->push(&_methods);
#if INCLUDE_CDS
}
#endif
it->push(&_default_methods);
it->push(&_local_interfaces);
it->push(&_transitive_interfaces);
@ -2620,6 +2634,21 @@ bool InstanceKlass::can_be_verified_at_dumptime() const {
}
return true;
}
bool InstanceKlass::methods_contain_jsr_bytecode() const {
Thread* thread = Thread::current();
for (int i = 0; i < _methods->length(); i++) {
methodHandle m(thread, _methods->at(i));
BytecodeStream bcs(m);
while (!bcs.is_last_bytecode()) {
Bytecodes::Code opcode = bcs.next();
if (opcode == Bytecodes::_jsr || opcode == Bytecodes::_jsr_w) {
return true;
}
}
}
return false;
}
#endif // INCLUDE_CDS
#if INCLUDE_JVMTI