From edafa3be09cfb52c4f1fcaf7030ebcc2c1582c55 Mon Sep 17 00:00:00 2001 From: twisti Date: Fri, 2 Sep 2011 00:36:18 -0700 Subject: [PATCH] 7085404: JSR 292: VolatileCallSites should have push notification too Reviewed-by: never, kvn --- src/share/vm/c1/c1_GraphBuilder.cpp | 32 ++++++++----------- src/share/vm/ci/ciField.hpp | 4 ++- .../vm/interpreter/interpreterRuntime.cpp | 2 +- src/share/vm/opto/callGenerator.cpp | 3 +- src/share/vm/opto/doCall.cpp | 12 ++----- src/share/vm/opto/parse3.cpp | 4 +-- src/share/vm/prims/unsafe.cpp | 13 ++++++++ 7 files changed, 36 insertions(+), 34 deletions(-) diff --git a/src/share/vm/c1/c1_GraphBuilder.cpp b/src/share/vm/c1/c1_GraphBuilder.cpp index 3faa312dd..e103fbf44 100644 --- a/src/share/vm/c1/c1_GraphBuilder.cpp +++ b/src/share/vm/c1/c1_GraphBuilder.cpp @@ -3744,26 +3744,20 @@ bool GraphBuilder::for_invokedynamic_inline(ciMethod* callee) { ciCallSite* call_site = stream()->get_call_site(); ciMethodHandle* method_handle = call_site->get_target(); - // Inline constant and mutable call sites. We don't inline - // volatile call sites optimistically since they are specified - // to change their value often and that would result in a lot of - // deoptimizations and recompiles. - if (call_site->is_constant_call_site() || call_site->is_mutable_call_site()) { - // Set the callee to have access to the class and signature in the - // MethodHandleCompiler. - method_handle->set_callee(callee); - method_handle->set_caller(method()); - - // Get an adapter for the MethodHandle. - ciMethod* method_handle_adapter = method_handle->get_invokedynamic_adapter(); - if (method_handle_adapter != NULL) { - if (try_inline(method_handle_adapter, /*holder_known=*/ true)) { - // Add a dependence for invalidation of the optimization. - if (!call_site->is_constant_call_site()) { - dependency_recorder()->assert_call_site_target_value(call_site, method_handle); - } - return true; + // Set the callee to have access to the class and signature in the + // MethodHandleCompiler. + method_handle->set_callee(callee); + method_handle->set_caller(method()); + + // Get an adapter for the MethodHandle. + ciMethod* method_handle_adapter = method_handle->get_invokedynamic_adapter(); + if (method_handle_adapter != NULL) { + if (try_inline(method_handle_adapter, /*holder_known=*/ true)) { + // Add a dependence for invalidation of the optimization. + if (!call_site->is_constant_call_site()) { + dependency_recorder()->assert_call_site_target_value(call_site, method_handle); } + return true; } } return false; diff --git a/src/share/vm/ci/ciField.hpp b/src/share/vm/ci/ciField.hpp index 1b481d93c..71145969f 100644 --- a/src/share/vm/ci/ciField.hpp +++ b/src/share/vm/ci/ciField.hpp @@ -175,7 +175,9 @@ public: bool is_volatile () { return flags().is_volatile(); } bool is_transient () { return flags().is_transient(); } - bool is_call_site_target() { return ((holder() == CURRENT_ENV->CallSite_klass()) && (name() == ciSymbol::target_name())); } + bool is_call_site_target() { + return (holder()->is_subclass_of(CURRENT_ENV->CallSite_klass()) && (name() == ciSymbol::target_name())); + } // Debugging output void print(); diff --git a/src/share/vm/interpreter/interpreterRuntime.cpp b/src/share/vm/interpreter/interpreterRuntime.cpp index 87bbcd393..3898078ec 100644 --- a/src/share/vm/interpreter/interpreterRuntime.cpp +++ b/src/share/vm/interpreter/interpreterRuntime.cpp @@ -555,7 +555,7 @@ IRT_ENTRY(void, InterpreterRuntime::resolve_get_put(JavaThread* thread, Bytecode assert(method_handle->is_a(SystemDictionary::MethodHandle_klass()), "must be"); { - // Walk all nmethods depending on CallSite + // Walk all nmethods depending on this call site. MutexLocker mu(Compile_lock, thread); Universe::flush_dependents_on(call_site, method_handle); } diff --git a/src/share/vm/opto/callGenerator.cpp b/src/share/vm/opto/callGenerator.cpp index e01e8fb3a..dc02770a9 100644 --- a/src/share/vm/opto/callGenerator.cpp +++ b/src/share/vm/opto/callGenerator.cpp @@ -726,7 +726,6 @@ CallGenerator* CallGenerator::for_method_handle_inline(Node* method_handle, JVMS CallGenerator* CallGenerator::for_invokedynamic_inline(ciCallSite* call_site, JVMState* jvms, ciMethod* caller, ciMethod* callee, ciCallProfile profile) { - assert(call_site->is_constant_call_site() || call_site->is_mutable_call_site(), "must be"); ciMethodHandle* method_handle = call_site->get_target(); // Set the callee to have access to the class and signature in the @@ -742,7 +741,7 @@ CallGenerator* CallGenerator::for_invokedynamic_inline(ciCallSite* call_site, JV CallGenerator* cg = C->call_generator(target_method, -1, false, jvms, true, PROB_ALWAYS); if (cg != NULL && cg->is_inline()) { // Add a dependence for invalidation of the optimization. - if (call_site->is_mutable_call_site()) { + if (!call_site->is_constant_call_site()) { C->dependencies()->assert_call_site_target_value(call_site, method_handle); } return cg; diff --git a/src/share/vm/opto/doCall.cpp b/src/share/vm/opto/doCall.cpp index de51329e8..b3c405ff5 100644 --- a/src/share/vm/opto/doCall.cpp +++ b/src/share/vm/opto/doCall.cpp @@ -136,15 +136,9 @@ CallGenerator* Compile::call_generator(ciMethod* call_method, int vtable_index, str.force_bci(jvms->bci()); // Set the stream to the invokedynamic bci. ciCallSite* call_site = str.get_call_site(); - // Inline constant and mutable call sites. We don't inline - // volatile call sites optimistically since they are specified - // to change their value often and that would result in a lot of - // deoptimizations and recompiles. - if (call_site->is_constant_call_site() || call_site->is_mutable_call_site()) { - CallGenerator* cg = CallGenerator::for_invokedynamic_inline(call_site, jvms, caller, call_method, profile); - if (cg != NULL) { - return cg; - } + CallGenerator* cg = CallGenerator::for_invokedynamic_inline(call_site, jvms, caller, call_method, profile); + if (cg != NULL) { + return cg; } // If something failed, generate a normal dynamic call. return CallGenerator::for_dynamic_call(call_method); diff --git a/src/share/vm/opto/parse3.cpp b/src/share/vm/opto/parse3.cpp index 1f0335cfe..4c482fbae 100644 --- a/src/share/vm/opto/parse3.cpp +++ b/src/share/vm/opto/parse3.cpp @@ -100,11 +100,11 @@ void Parse::do_field_access(bool is_get, bool is_field) { } } - // Deoptimize on putfield writes to CallSite.target + // Deoptimize on putfield writes to call site target field. if (!is_get && field->is_call_site_target()) { uncommon_trap(Deoptimization::Reason_unhandled, Deoptimization::Action_reinterpret, - NULL, "put to CallSite.target field"); + NULL, "put to call site target field"); return; } diff --git a/src/share/vm/prims/unsafe.cpp b/src/share/vm/prims/unsafe.cpp index 465205943..fbb723b77 100644 --- a/src/share/vm/prims/unsafe.cpp +++ b/src/share/vm/prims/unsafe.cpp @@ -302,6 +302,19 @@ UNSAFE_ENTRY(void, Unsafe_SetObjectVolatile(JNIEnv *env, jobject unsafe, jobject UnsafeWrapper("Unsafe_SetObjectVolatile"); oop x = JNIHandles::resolve(x_h); oop p = JNIHandles::resolve(obj); + // Catch VolatileCallSite.target stores (via + // CallSite.setTargetVolatile) and check call site dependencies. + if ((offset == java_lang_invoke_CallSite::target_offset_in_bytes()) && p->is_a(SystemDictionary::CallSite_klass())) { + oop call_site = p; + oop method_handle = x; + assert(call_site ->is_a(SystemDictionary::CallSite_klass()), "must be"); + assert(method_handle->is_a(SystemDictionary::MethodHandle_klass()), "must be"); + { + // Walk all nmethods depending on this call site. + MutexLocker mu(Compile_lock, thread); + Universe::flush_dependents_on(call_site, method_handle); + } + } void* addr = index_oop_from_field_offset_long(p, offset); OrderAccess::release(); if (UseCompressedOops) { -- GitLab