8205714: Initial class initialization
Ensure class is fully initialized before caching a resolved invokestatic, or patching the callsite Reviewed-by: acorn, coleenp, kvn, vlivanov
This commit is contained in:
parent
43b3a6a6bb
commit
4a157daf01
@ -253,11 +253,21 @@ void ConstantPoolCacheEntry::set_direct_or_vtable_call(Bytecodes::Code invoke_co
|
||||
if (byte_no == 1) {
|
||||
assert(invoke_code != Bytecodes::_invokevirtual &&
|
||||
invoke_code != Bytecodes::_invokeinterface, "");
|
||||
bool do_resolve = true;
|
||||
// Don't mark invokespecial to method as resolved if sender is an interface. The receiver
|
||||
// has to be checked that it is a subclass of the current class every time this bytecode
|
||||
// is executed.
|
||||
if (invoke_code != Bytecodes::_invokespecial || !sender_is_interface ||
|
||||
method->name() == vmSymbols::object_initializer_name()) {
|
||||
if (invoke_code == Bytecodes::_invokespecial && sender_is_interface &&
|
||||
method->name() != vmSymbols::object_initializer_name()) {
|
||||
do_resolve = false;
|
||||
}
|
||||
// Don't mark invokestatic to method as resolved if the holder class has not yet completed
|
||||
// initialization. An invokestatic must only proceed if the class is initialized, but if
|
||||
// we resolve it before then that class initialization check is skipped.
|
||||
if (invoke_code == Bytecodes::_invokestatic && !method->method_holder()->is_initialized()) {
|
||||
do_resolve = false;
|
||||
}
|
||||
if (do_resolve) {
|
||||
set_bytecode_1(invoke_code);
|
||||
}
|
||||
} else if (byte_no == 2) {
|
||||
|
@ -1376,6 +1376,14 @@ methodHandle SharedRuntime::resolve_sub_helper(JavaThread *thread,
|
||||
}
|
||||
#endif
|
||||
|
||||
// Do not patch call site for static call when the class is not
|
||||
// fully initialized.
|
||||
if (invoke_code == Bytecodes::_invokestatic &&
|
||||
!callee_method->method_holder()->is_initialized()) {
|
||||
assert(callee_method->method_holder()->is_linked(), "must be");
|
||||
return callee_method;
|
||||
}
|
||||
|
||||
// JSR 292 key invariant:
|
||||
// If the resolved method is a MethodHandle invoke target, the call
|
||||
// site must be a MethodHandle call site, because the lambda form might tail-call
|
||||
|
Loading…
Reference in New Issue
Block a user