6993078: JSR 292 too many pushes: Lesp points into register window
Reviewed-by: kvn, never
--- a/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp Wed Apr 20 18:29:35 2011 -0700
+++ b/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp Thu Apr 21 00:25:40 2011 -0700
@@ -3289,8 +3289,6 @@
/*virtual*/ false, /*vfinal*/ false, /*indy*/ true);
__ mov(SP, O5_savedSP); // record SP that we wanted the callee to restore
- __ verify_oop(G5_callsite);
-
// profile this call
__ profile_call(O4);
@@ -3303,8 +3301,10 @@
__ sll(Rret, LogBytesPerWord, Rret);
__ ld_ptr(Rtemp, Rret, Rret); // get return address
+ __ verify_oop(G5_callsite);
__ load_heap_oop(G5_callsite, __ delayed_value(java_lang_invoke_CallSite::target_offset_in_bytes, Rscratch), G3_method_handle);
__ null_check(G3_method_handle);
+ __ verify_oop(G3_method_handle);
// Adjust Rret first so Llast_SP can be same as Rret
__ add(Rret, -frame::pc_return_offset, O7);
--- a/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp Wed Apr 20 18:29:35 2011 -0700
+++ b/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp Thu Apr 21 00:25:40 2011 -0700
@@ -3074,6 +3074,7 @@
void TemplateTable::invokedynamic(int byte_no) {
transition(vtos, vtos);
+ assert(byte_no == f1_oop, "use this argument");
if (!EnableInvokeDynamic) {
// We should not encounter this bytecode if !EnableInvokeDynamic.
@@ -3086,7 +3087,6 @@
return;
}
- assert(byte_no == f1_oop, "use this argument");
prepare_invoke(rax, rbx, byte_no);
// rax: CallSite object (f1)
@@ -3097,14 +3097,14 @@
Register rax_callsite = rax;
Register rcx_method_handle = rcx;
- if (ProfileInterpreter) {
- // %%% should make a type profile for any invokedynamic that takes a ref argument
- // profile this call
- __ profile_call(rsi);
- }
-
- __ load_heap_oop(rcx_method_handle, Address(rax_callsite, __ delayed_value(java_lang_invoke_CallSite::target_offset_in_bytes, rcx)));
+ // %%% should make a type profile for any invokedynamic that takes a ref argument
+ // profile this call
+ __ profile_call(rsi);
+
+ __ verify_oop(rax_callsite);
+ __ load_heap_oop(rcx_method_handle, Address(rax_callsite, __ delayed_value(java_lang_invoke_CallSite::target_offset_in_bytes, rdx)));
__ null_check(rcx_method_handle);
+ __ verify_oop(rcx_method_handle);
__ prepare_to_jump_from_interpreted();
__ jump_to_method_handle_entry(rcx_method_handle, rdx);
}
--- a/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp Wed Apr 20 18:29:35 2011 -0700
+++ b/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp Thu Apr 21 00:25:40 2011 -0700
@@ -3128,7 +3128,6 @@
return;
}
- assert(byte_no == f1_oop, "use this argument");
prepare_invoke(rax, rbx, byte_no);
// rax: CallSite object (f1)
@@ -3139,14 +3138,14 @@
Register rax_callsite = rax;
Register rcx_method_handle = rcx;
- if (ProfileInterpreter) {
- // %%% should make a type profile for any invokedynamic that takes a ref argument
- // profile this call
- __ profile_call(r13);
- }
-
- __ load_heap_oop(rcx_method_handle, Address(rax_callsite, __ delayed_value(java_lang_invoke_CallSite::target_offset_in_bytes, rcx)));
+ // %%% should make a type profile for any invokedynamic that takes a ref argument
+ // profile this call
+ __ profile_call(r13);
+
+ __ verify_oop(rax_callsite);
+ __ load_heap_oop(rcx_method_handle, Address(rax_callsite, __ delayed_value(java_lang_invoke_CallSite::target_offset_in_bytes, rdx)));
__ null_check(rcx_method_handle);
+ __ verify_oop(rcx_method_handle);
__ prepare_to_jump_from_interpreted();
__ jump_to_method_handle_entry(rcx_method_handle, rdx);
}
--- a/hotspot/src/share/vm/ci/ciEnv.cpp Wed Apr 20 18:29:35 2011 -0700
+++ b/hotspot/src/share/vm/ci/ciEnv.cpp Thu Apr 21 00:25:40 2011 -0700
@@ -756,7 +756,7 @@
assert(bc == Bytecodes::_invokedynamic, "must be invokedynamic");
bool is_resolved = cpool->cache()->main_entry_at(index)->is_resolved(bc);
- if (is_resolved && (oop) cpool->cache()->secondary_entry_at(index)->f1() == NULL)
+ if (is_resolved && cpool->cache()->secondary_entry_at(index)->is_f1_null())
// FIXME: code generation could allow for null (unlinked) call site
is_resolved = false;
@@ -770,7 +770,7 @@
// Get the invoker methodOop from the constant pool.
oop f1_value = cpool->cache()->main_entry_at(index)->f1();
- methodOop signature_invoker = methodOop(f1_value);
+ methodOop signature_invoker = (methodOop) f1_value;
assert(signature_invoker != NULL && signature_invoker->is_method() && signature_invoker->is_method_handle_invoke(),
"correct result from LinkResolver::resolve_invokedynamic");
--- a/hotspot/src/share/vm/oops/cpCacheOop.cpp Wed Apr 20 18:29:35 2011 -0700
+++ b/hotspot/src/share/vm/oops/cpCacheOop.cpp Thu Apr 21 00:25:40 2011 -0700
@@ -104,7 +104,7 @@
void* result = Atomic::cmpxchg_ptr(f1, f1_addr, NULL);
bool success = (result == NULL);
if (success) {
- update_barrier_set(f1_addr, f1);
+ update_barrier_set((void*) f1_addr, f1);
}
}
@@ -275,21 +275,23 @@
return (int) bsm_cache_index;
}
-void ConstantPoolCacheEntry::set_dynamic_call(Handle call_site,
- methodHandle signature_invoker) {
+void ConstantPoolCacheEntry::set_dynamic_call(Handle call_site, methodHandle signature_invoker) {
assert(is_secondary_entry(), "");
+ // NOTE: it's important that all other values are set before f1 is
+ // set since some users short circuit on f1 being set
+ // (i.e. non-null) and that may result in uninitialized values for
+ // other racing threads (e.g. flags).
int param_size = signature_invoker->size_of_parameters();
assert(param_size >= 1, "method argument size must include MH.this");
- param_size -= 1; // do not count MH.this; it is not stacked for invokedynamic
- if (Atomic::cmpxchg_ptr(call_site(), &_f1, NULL) == NULL) {
- // racing threads might be trying to install their own favorites
- set_f1(call_site());
- }
+ param_size -= 1; // do not count MH.this; it is not stacked for invokedynamic
bool is_final = true;
assert(signature_invoker->is_final_method(), "is_final");
- set_flags(as_flags(as_TosState(signature_invoker->result_type()), is_final, false, false, false, true) | param_size);
+ int flags = as_flags(as_TosState(signature_invoker->result_type()), is_final, false, false, false, true) | param_size;
+ assert(_flags == 0 || _flags == flags, "flags should be the same");
+ set_flags(flags);
// do not do set_bytecode on a secondary CP cache entry
//set_bytecode_1(Bytecodes::_invokedynamic);
+ set_f1_if_null_atomic(call_site()); // This must be the last one to set (see NOTE above)!
}