# HG changeset patch # User twisti # Date 1303370740 25200 # Node ID 08ccee2c4dbf2e8d97a80c10287d595bcf904c8a # Parent 66b0e2371912f0da63aece5ab8040fdf817ef01d 6993078: JSR 292 too many pushes: Lesp points into register window Reviewed-by: kvn, never diff -r 66b0e2371912 -r 08ccee2c4dbf src/cpu/sparc/vm/templateTable_sparc.cpp --- a/src/cpu/sparc/vm/templateTable_sparc.cpp Wed Apr 20 18:29:35 2011 -0700 +++ b/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); diff -r 66b0e2371912 -r 08ccee2c4dbf src/cpu/x86/vm/templateTable_x86_32.cpp --- a/src/cpu/x86/vm/templateTable_x86_32.cpp Wed Apr 20 18:29:35 2011 -0700 +++ b/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); } diff -r 66b0e2371912 -r 08ccee2c4dbf src/cpu/x86/vm/templateTable_x86_64.cpp --- a/src/cpu/x86/vm/templateTable_x86_64.cpp Wed Apr 20 18:29:35 2011 -0700 +++ b/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); } diff -r 66b0e2371912 -r 08ccee2c4dbf src/share/vm/ci/ciEnv.cpp --- a/src/share/vm/ci/ciEnv.cpp Wed Apr 20 18:29:35 2011 -0700 +++ b/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"); diff -r 66b0e2371912 -r 08ccee2c4dbf src/share/vm/oops/cpCacheOop.cpp --- a/src/share/vm/oops/cpCacheOop.cpp Wed Apr 20 18:29:35 2011 -0700 +++ b/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)! }