diff --git a/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp b/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp index 8694734c751..82da7346116 100644 --- a/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp @@ -1391,6 +1391,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm, in_ByteSize(-1), oop_maps, exception_offset); + if (nm == nullptr) return nm; if (method->is_continuation_enter_intrinsic()) { ContinuationEntry::set_enter_code(nm, interpreted_entry_offset); } else if (method->is_continuation_yield_intrinsic()) { diff --git a/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp b/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp index 3382df355da..ebe918785ed 100644 --- a/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp +++ b/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp @@ -2039,6 +2039,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, in_ByteSize(-1), oop_maps, exception_offset); + if (nm == nullptr) return nm; if (method->is_continuation_enter_intrinsic()) { ContinuationEntry::set_enter_code(nm, interpreted_entry_offset); } else if (method->is_continuation_yield_intrinsic()) { diff --git a/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp b/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp index 01fe307bc27..9f04e20ea3b 100644 --- a/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp +++ b/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp @@ -1271,6 +1271,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm, in_ByteSize(-1), oop_maps, exception_offset); + if (nm == nullptr) return nm; if (method->is_continuation_enter_intrinsic()) { ContinuationEntry::set_enter_code(nm, interpreted_entry_offset); } else if (method->is_continuation_yield_intrinsic()) { diff --git a/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp b/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp index faa423bcf8e..cab50e85ec5 100644 --- a/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp +++ b/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp @@ -1744,6 +1744,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm, in_ByteSize(-1), oop_maps, exception_offset); + if (nm == nullptr) return nm; if (method->is_continuation_enter_intrinsic()) { ContinuationEntry::set_enter_code(nm, interpreted_entry_offset); } else if (method->is_continuation_yield_intrinsic()) { diff --git a/src/hotspot/share/interpreter/linkResolver.cpp b/src/hotspot/share/interpreter/linkResolver.cpp index ed85a07f708..38bef3e1e98 100644 --- a/src/hotspot/share/interpreter/linkResolver.cpp +++ b/src/hotspot/share/interpreter/linkResolver.cpp @@ -1085,13 +1085,6 @@ void LinkResolver::resolve_static_call(CallInfo& result, resolved_method = linktime_resolve_static_method(new_info, CHECK); } - if (resolved_method->is_continuation_native_intrinsic() - && resolved_method->from_interpreted_entry() == nullptr) { // does a load_acquire - methodHandle mh(THREAD, resolved_method); - // Generate a compiled form of the enterSpecial intrinsic. - AdapterHandlerLibrary::create_native_wrapper(mh); - } - // setup result result.set_static(resolved_klass, methodHandle(THREAD, resolved_method), CHECK); JFR_ONLY(Jfr::on_resolution(result, CHECK);) diff --git a/src/hotspot/share/oops/method.cpp b/src/hotspot/share/oops/method.cpp index 71a8253e244..a36974fc3f0 100644 --- a/src/hotspot/share/oops/method.cpp +++ b/src/hotspot/share/oops/method.cpp @@ -72,6 +72,7 @@ #include "runtime/safepointVerifiers.hpp" #include "runtime/sharedRuntime.hpp" #include "runtime/signature.hpp" +#include "runtime/threads.hpp" #include "runtime/vm_version.hpp" #include "utilities/align.hpp" #include "utilities/quickSort.hpp" @@ -1249,10 +1250,17 @@ void Method::link_method(const methodHandle& h_method, TRAPS) { // ONLY USE the h_method now as make_adapter may have blocked if (h_method->is_continuation_native_intrinsic()) { - // the entry points to this method will be set in set_code, called when first resolving this method _from_interpreted_entry = nullptr; _from_compiled_entry = nullptr; _i2i_entry = nullptr; + if (Continuations::enabled()) { + assert(!Threads::is_vm_complete(), "should only be called during vm init"); + AdapterHandlerLibrary::create_native_wrapper(h_method); + if (!h_method->has_compiled_code()) { + THROW_MSG(vmSymbols::java_lang_OutOfMemoryError(), "Initial size of CodeCache is too small"); + } + assert(_from_interpreted_entry == get_i2c_entry(), "invariant"); + } } } diff --git a/src/hotspot/share/runtime/threads.cpp b/src/hotspot/share/runtime/threads.cpp index 237e3a22451..d40fb3a9f91 100644 --- a/src/hotspot/share/runtime/threads.cpp +++ b/src/hotspot/share/runtime/threads.cpp @@ -749,6 +749,13 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) { // cache the system and platform class loaders SystemDictionary::compute_java_loaders(CHECK_JNI_ERR); + if (Continuations::enabled()) { + // Initialize Continuation class now so that failure to create enterSpecial/doYield + // special nmethods due to limited CodeCache size can be treated as a fatal error at + // startup with the proper message that CodeCache size is too small. + initialize_class(vmSymbols::jdk_internal_vm_Continuation(), CHECK_JNI_ERR); + } + #if INCLUDE_CDS // capture the module path info from the ModuleEntryTable ClassLoader::initialize_module_path(THREAD);