diff --git a/src/hotspot/share/ci/ciReplay.cpp b/src/hotspot/share/ci/ciReplay.cpp index 587caa22aab42..dc251f052506c 100644 --- a/src/hotspot/share/ci/ciReplay.cpp +++ b/src/hotspot/share/ci/ciReplay.cpp @@ -843,9 +843,7 @@ class CompileReplay : public StackObj { // method to be rewritten (number of arguments at a call for instance) method->method_holder()->link_class(CHECK); assert(method->method_data() == nullptr, "Should only be initialized once"); - ClassLoaderData* loader_data = method->method_holder()->class_loader_data(); - MethodData* method_data = MethodData::allocate(loader_data, methodHandle(THREAD, method), CHECK); - method->set_method_data(method_data); + method->build_profiling_method_data(methodHandle(THREAD, method), CHECK); // collect and record all the needed information for later ciMethodDataRecord* rec = new_ciMethodData(method); diff --git a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp index b5325611835d3..a46be0af239a6 100644 --- a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp +++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp @@ -1282,6 +1282,18 @@ C2V_VMENTRY_0(jint, getLocalVariableTableLength, (JNIEnv* env, jobject, ARGUMENT return method->localvariable_table_length(); C2V_END +static MethodData* get_profiling_method_data(const methodHandle& method, TRAPS) { + MethodData* method_data = method->method_data(); + if (method_data == nullptr) { + method->build_profiling_method_data(method, CHECK_NULL); + method_data = method->method_data(); + if (method_data == nullptr) { + THROW_MSG_NULL(vmSymbols::java_lang_OutOfMemoryError(), "cannot allocate MethodData") + } + } + return method_data; +} + C2V_VMENTRY(void, reprofile, (JNIEnv* env, jobject, ARGUMENT_PAIR(method))) methodHandle method(THREAD, UNPACK_PAIR(Method, method)); MethodCounters* mcs = method->method_counters(); @@ -1297,9 +1309,7 @@ C2V_VMENTRY(void, reprofile, (JNIEnv* env, jobject, ARGUMENT_PAIR(method))) MethodData* method_data = method->method_data(); if (method_data == nullptr) { - ClassLoaderData* loader_data = method->method_holder()->class_loader_data(); - method_data = MethodData::allocate(loader_data, method, CHECK); - method->set_method_data(method_data); + method_data = get_profiling_method_data(method, CHECK); } else { method_data->initialize(); } @@ -2976,12 +2986,7 @@ C2V_END C2V_VMENTRY_0(jlong, getFailedSpeculationsAddress, (JNIEnv* env, jobject, ARGUMENT_PAIR(method))) methodHandle method(THREAD, UNPACK_PAIR(Method, method)); - MethodData* method_data = method->method_data(); - if (method_data == nullptr) { - ClassLoaderData* loader_data = method->method_holder()->class_loader_data(); - method_data = MethodData::allocate(loader_data, method, CHECK_0); - method->set_method_data(method_data); - } + MethodData* method_data = get_profiling_method_data(method, CHECK_0); return (jlong) method_data->get_failed_speculations_address(); C2V_END diff --git a/src/hotspot/share/oops/method.cpp b/src/hotspot/share/oops/method.cpp index 1a736fbbb4985..a94698c560543 100644 --- a/src/hotspot/share/oops/method.cpp +++ b/src/hotspot/share/oops/method.cpp @@ -102,7 +102,7 @@ Method::Method(ConstMethod* xconst, AccessFlags access_flags, Symbol* name) { set_constMethod(xconst); set_access_flags(access_flags); set_intrinsic_id(vmIntrinsics::_none); - set_method_data(nullptr); + clear_method_data(); clear_method_counters(); set_vtable_index(Method::garbage_vtable_index); @@ -127,7 +127,7 @@ void Method::deallocate_contents(ClassLoaderData* loader_data) { MetadataFactory::free_metadata(loader_data, constMethod()); set_constMethod(nullptr); MetadataFactory::free_metadata(loader_data, method_data()); - set_method_data(nullptr); + clear_method_data(); MetadataFactory::free_metadata(loader_data, method_counters()); clear_method_counters(); // The nmethod will be gone when we get here. @@ -1179,7 +1179,7 @@ void Method::unlink_method() { } NOT_PRODUCT(set_compiled_invocation_count(0);) - set_method_data(nullptr); + clear_method_data(); clear_method_counters(); remove_unshareable_flags(); } diff --git a/src/hotspot/share/oops/method.hpp b/src/hotspot/share/oops/method.hpp index 51458dfa91e0b..1dab585a66069 100644 --- a/src/hotspot/share/oops/method.hpp +++ b/src/hotspot/share/oops/method.hpp @@ -308,8 +308,6 @@ class Method : public Metadata { return _method_data; } - void set_method_data(MethodData* data); - MethodCounters* method_counters() const { return _method_counters; } @@ -361,6 +359,10 @@ class Method : public Metadata { // Either called with CompiledMethod_lock held or from constructor. void clear_code(); + void clear_method_data() { + _method_data = nullptr; + } + public: static void set_code(const methodHandle& mh, CompiledMethod* code); void set_adapter_entry(AdapterHandlerEntry* adapter) { diff --git a/src/hotspot/share/oops/method.inline.hpp b/src/hotspot/share/oops/method.inline.hpp index 2116d59f440fa..bb83615d39e8b 100644 --- a/src/hotspot/share/oops/method.inline.hpp +++ b/src/hotspot/share/oops/method.inline.hpp @@ -39,13 +39,6 @@ inline address Method::from_interpreted_entry() const { return Atomic::load_acquire(&_from_interpreted_entry); } -inline void Method::set_method_data(MethodData* data) { - // The store into method must be released. On platforms without - // total store order (TSO) the reference may become visible before - // the initialization of data otherwise. - Atomic::release_store(&_method_data, data); -} - inline CompiledMethod* Method::code() const { assert( check_code(), "" ); return Atomic::load_acquire(&_code);