--- old/src/cpu/ppc/vm/templateTable_ppc_64.cpp 2015-03-04 19:29:51.985513007 -0800 +++ new/src/cpu/ppc/vm/templateTable_ppc_64.cpp 2015-03-04 19:29:51.860506724 -0800 @@ -438,6 +438,14 @@ } void TemplateTable::iload() { + iload_internal(); +} + +void TemplateTable::nofast_iload() { + iload_internal(MAY_NOT_REWRITE); +} + +void TemplateTable::iload_internal(RewriteControl rc) { transition(vtos, itos); // Get the local value into tos @@ -446,7 +454,7 @@ // Rewrite iload,iload pair into fast_iload2 // iload,caload pair into fast_icaload - if (RewriteFrequentPairs) { + if (RewriteFrequentPairs && rc == MAY_REWRITE) { Label Lrewrite, Ldone; Register Rnext_byte = R3_ARG1, Rrewrite_to = R6_ARG4, @@ -710,6 +718,14 @@ } void TemplateTable::aload_0() { + aload_0_internal(); +} + +void TemplateTable::nofast_aload_0() { + aload_0_internal(MAY_NOT_REWRITE); +} + +void TemplateTable::aload_0_internal(RewriteControl rc) { transition(vtos, atos); // According to bytecode histograms, the pairs: // @@ -733,7 +749,7 @@ // These bytecodes with a small amount of code are most profitable // to rewrite. - if (RewriteFrequentPairs) { + if (RewriteFrequentPairs && rc == MAY_REWRITE) { Label Lrewrite, Ldont_rewrite; Register Rnext_byte = R3_ARG1, @@ -2145,6 +2161,13 @@ __ get_cache_and_index_at_bcp(Rcache, 1, index_size); Label Lresolved, Ldone; + Bytecodes::Code code = bytecode(); + switch (code) { + case Bytecodes::_nofast_getfield: code = Bytecodes::_getfield; break; + case Bytecodes::_nofast_putfield: code = Bytecodes::_putfield; break; + case Bytecodes::_nofast_invokevirtual: code = Bytecodes::_invokevirtual; + } + assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range"); // We are resolved if the indices offset contains the current bytecode. #if defined(VM_LITTLE_ENDIAN) @@ -2153,11 +2176,11 @@ __ lbz(Rscratch, in_bytes(ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::indices_offset()) + 7 - (byte_no + 1), Rcache); #endif // Acquire by cmp-br-isync (see below). - __ cmpdi(CCR0, Rscratch, (int)bytecode()); + __ cmpdi(CCR0, Rscratch, code); __ beq(CCR0, Lresolved); address entry = NULL; - switch (bytecode()) { + switch (code) { case Bytecodes::_getstatic : // fall through case Bytecodes::_putstatic : // fall through case Bytecodes::_getfield : // fall through @@ -2170,7 +2193,7 @@ case Bytecodes::_invokedynamic : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokedynamic); break; default : ShouldNotReachHere(); break; } - __ li(R4_ARG2, (int)bytecode()); + __ li(R4_ARG2, code); __ call_VM(noreg, entry, R4_ARG2, true); // Update registers with resolved info. @@ -2351,7 +2374,7 @@ } // PPC64: implement volatile loads as fence-store-acquire. -void TemplateTable::getfield_or_static(int byte_no, bool is_static) { +void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteControl rc) { transition(vtos, vtos); Label Lacquire, Lisync; @@ -2435,7 +2458,7 @@ branch_table[dtos] = __ pc(); // non-volatile_entry point __ lfdx(F15_ftos, Rclass_or_obj, Roffset); __ push(dtos); - if (!is_static) patch_bytecode(Bytecodes::_fast_dgetfield, Rbc, Rscratch); + if (!is_static && rc == MAY_REWRITE) patch_bytecode(Bytecodes::_fast_dgetfield, Rbc, Rscratch); { Label acquire_double; __ beq(CCR6, acquire_double); // Volatile? @@ -2454,7 +2477,7 @@ branch_table[ftos] = __ pc(); // non-volatile_entry point __ lfsx(F15_ftos, Rclass_or_obj, Roffset); __ push(ftos); - if (!is_static) { patch_bytecode(Bytecodes::_fast_fgetfield, Rbc, Rscratch); } + if (!is_static && rc == MAY_REWRITE) { patch_bytecode(Bytecodes::_fast_fgetfield, Rbc, Rscratch); } { Label acquire_float; __ beq(CCR6, acquire_float); // Volatile? @@ -2473,7 +2496,7 @@ branch_table[itos] = __ pc(); // non-volatile_entry point __ lwax(R17_tos, Rclass_or_obj, Roffset); __ push(itos); - if (!is_static) patch_bytecode(Bytecodes::_fast_igetfield, Rbc, Rscratch); + if (!is_static && rc == MAY_REWRITE) patch_bytecode(Bytecodes::_fast_igetfield, Rbc, Rscratch); __ beq(CCR6, Lacquire); // Volatile? __ dispatch_epilog(vtos, Bytecodes::length_for(bytecode())); @@ -2484,7 +2507,7 @@ branch_table[ltos] = __ pc(); // non-volatile_entry point __ ldx(R17_tos, Rclass_or_obj, Roffset); __ push(ltos); - if (!is_static) patch_bytecode(Bytecodes::_fast_lgetfield, Rbc, Rscratch); + if (!is_static && rc == MAY_REWRITE) patch_bytecode(Bytecodes::_fast_lgetfield, Rbc, Rscratch); __ beq(CCR6, Lacquire); // Volatile? __ dispatch_epilog(vtos, Bytecodes::length_for(bytecode())); @@ -2496,7 +2519,7 @@ __ lbzx(R17_tos, Rclass_or_obj, Roffset); __ extsb(R17_tos, R17_tos); __ push(btos); - if (!is_static) patch_bytecode(Bytecodes::_fast_bgetfield, Rbc, Rscratch); + if (!is_static && rc == MAY_REWRITE) patch_bytecode(Bytecodes::_fast_bgetfield, Rbc, Rscratch); __ beq(CCR6, Lacquire); // Volatile? __ dispatch_epilog(vtos, Bytecodes::length_for(bytecode())); @@ -2507,7 +2530,7 @@ branch_table[ctos] = __ pc(); // non-volatile_entry point __ lhzx(R17_tos, Rclass_or_obj, Roffset); __ push(ctos); - if (!is_static) patch_bytecode(Bytecodes::_fast_cgetfield, Rbc, Rscratch); + if (!is_static && rc == MAY_REWRITE) patch_bytecode(Bytecodes::_fast_cgetfield, Rbc, Rscratch); __ beq(CCR6, Lacquire); // Volatile? __ dispatch_epilog(vtos, Bytecodes::length_for(bytecode())); @@ -2518,7 +2541,7 @@ branch_table[stos] = __ pc(); // non-volatile_entry point __ lhax(R17_tos, Rclass_or_obj, Roffset); __ push(stos); - if (!is_static) patch_bytecode(Bytecodes::_fast_sgetfield, Rbc, Rscratch); + if (!is_static && rc == MAY_REWRITE) patch_bytecode(Bytecodes::_fast_sgetfield, Rbc, Rscratch); __ beq(CCR6, Lacquire); // Volatile? __ dispatch_epilog(vtos, Bytecodes::length_for(bytecode())); @@ -2531,7 +2554,7 @@ __ verify_oop(R17_tos); __ push(atos); //__ dcbt(R17_tos); // prefetch - if (!is_static) patch_bytecode(Bytecodes::_fast_agetfield, Rbc, Rscratch); + if (!is_static && rc == MAY_REWRITE) patch_bytecode(Bytecodes::_fast_agetfield, Rbc, Rscratch); __ beq(CCR6, Lacquire); // Volatile? __ dispatch_epilog(vtos, Bytecodes::length_for(bytecode())); @@ -2554,6 +2577,10 @@ getfield_or_static(byte_no, false); } +void TemplateTable::nofast_getfield(int byte_no) { + getfield_or_static(byte_no, false, MAY_NOT_REWRITE); +} + void TemplateTable::getstatic(int byte_no) { getfield_or_static(byte_no, true); } @@ -2644,7 +2671,7 @@ } // PPC64: implement volatile stores as release-store (return bytecode contains an additional release). -void TemplateTable::putfield_or_static(int byte_no, bool is_static) { +void TemplateTable::putfield_or_static(int byte_no, bool is_static, RewriteControl rc) { Label Lvolatile; const Register Rcache = R5_ARG3, // Do not use ARG1/2 (causes trouble in jvmti_post_field_mod). @@ -2718,7 +2745,7 @@ __ pop(dtos); if (!is_static) { pop_and_check_object(Rclass_or_obj); } // Kills R11_scratch1. __ stfdx(F15_ftos, Rclass_or_obj, Roffset); - if (!is_static) { patch_bytecode(Bytecodes::_fast_dputfield, Rbc, Rscratch, true, byte_no); } + if (!is_static && rc == MAY_REWRITE) { patch_bytecode(Bytecodes::_fast_dputfield, Rbc, Rscratch, true, byte_no); } if (!support_IRIW_for_not_multiple_copy_atomic_cpu) { __ beq(CR_is_vol, Lvolatile); // Volatile? } @@ -2732,7 +2759,7 @@ __ pop(ftos); if (!is_static) { pop_and_check_object(Rclass_or_obj); } // Kills R11_scratch1. __ stfsx(F15_ftos, Rclass_or_obj, Roffset); - if (!is_static) { patch_bytecode(Bytecodes::_fast_fputfield, Rbc, Rscratch, true, byte_no); } + if (!is_static && rc == MAY_REWRITE) { patch_bytecode(Bytecodes::_fast_fputfield, Rbc, Rscratch, true, byte_no); } if (!support_IRIW_for_not_multiple_copy_atomic_cpu) { __ beq(CR_is_vol, Lvolatile); // Volatile? } @@ -2746,7 +2773,7 @@ __ pop(itos); if (!is_static) { pop_and_check_object(Rclass_or_obj); } // Kills R11_scratch1. __ stwx(R17_tos, Rclass_or_obj, Roffset); - if (!is_static) { patch_bytecode(Bytecodes::_fast_iputfield, Rbc, Rscratch, true, byte_no); } + if (!is_static && rc == MAY_REWRITE) { patch_bytecode(Bytecodes::_fast_iputfield, Rbc, Rscratch, true, byte_no); } if (!support_IRIW_for_not_multiple_copy_atomic_cpu) { __ beq(CR_is_vol, Lvolatile); // Volatile? } @@ -2760,7 +2787,7 @@ __ pop(ltos); if (!is_static) { pop_and_check_object(Rclass_or_obj); } // Kills R11_scratch1. __ stdx(R17_tos, Rclass_or_obj, Roffset); - if (!is_static) { patch_bytecode(Bytecodes::_fast_lputfield, Rbc, Rscratch, true, byte_no); } + if (!is_static && rc == MAY_REWRITE) { patch_bytecode(Bytecodes::_fast_lputfield, Rbc, Rscratch, true, byte_no); } if (!support_IRIW_for_not_multiple_copy_atomic_cpu) { __ beq(CR_is_vol, Lvolatile); // Volatile? } @@ -2774,7 +2801,7 @@ __ pop(btos); if (!is_static) { pop_and_check_object(Rclass_or_obj); } // Kills R11_scratch1. __ stbx(R17_tos, Rclass_or_obj, Roffset); - if (!is_static) { patch_bytecode(Bytecodes::_fast_bputfield, Rbc, Rscratch, true, byte_no); } + if (!is_static && rc == MAY_REWRITE) { patch_bytecode(Bytecodes::_fast_bputfield, Rbc, Rscratch, true, byte_no); } if (!support_IRIW_for_not_multiple_copy_atomic_cpu) { __ beq(CR_is_vol, Lvolatile); // Volatile? } @@ -2788,7 +2815,7 @@ __ pop(ctos); if (!is_static) { pop_and_check_object(Rclass_or_obj); } // Kills R11_scratch1.. __ sthx(R17_tos, Rclass_or_obj, Roffset); - if (!is_static) { patch_bytecode(Bytecodes::_fast_cputfield, Rbc, Rscratch, true, byte_no); } + if (!is_static && rc == MAY_REWRITE) { patch_bytecode(Bytecodes::_fast_cputfield, Rbc, Rscratch, true, byte_no); } if (!support_IRIW_for_not_multiple_copy_atomic_cpu) { __ beq(CR_is_vol, Lvolatile); // Volatile? } @@ -2802,7 +2829,7 @@ __ pop(stos); if (!is_static) { pop_and_check_object(Rclass_or_obj); } // Kills R11_scratch1. __ sthx(R17_tos, Rclass_or_obj, Roffset); - if (!is_static) { patch_bytecode(Bytecodes::_fast_sputfield, Rbc, Rscratch, true, byte_no); } + if (!is_static && rc == MAY_REWRITE) { patch_bytecode(Bytecodes::_fast_sputfield, Rbc, Rscratch, true, byte_no); } if (!support_IRIW_for_not_multiple_copy_atomic_cpu) { __ beq(CR_is_vol, Lvolatile); // Volatile? } @@ -2816,7 +2843,7 @@ __ pop(atos); if (!is_static) { pop_and_check_object(Rclass_or_obj); } // kills R11_scratch1 do_oop_store(_masm, Rclass_or_obj, Roffset, R17_tos, Rscratch, Rscratch2, Rscratch3, _bs->kind(), false /* precise */, true /* check null */); - if (!is_static) { patch_bytecode(Bytecodes::_fast_aputfield, Rbc, Rscratch, true, byte_no); } + if (!is_static && rc == MAY_REWRITE) { patch_bytecode(Bytecodes::_fast_aputfield, Rbc, Rscratch, true, byte_no); } if (!support_IRIW_for_not_multiple_copy_atomic_cpu) { __ beq(CR_is_vol, Lvolatile); // Volatile? __ dispatch_epilog(vtos, Bytecodes::length_for(bytecode())); @@ -2840,6 +2867,10 @@ putfield_or_static(byte_no, false); } +void TemplateTable::nofast_putfield(int byte_no) { + putfield_or_static(byte_no, false, MAY_NOT_REWRITE); +} + void TemplateTable::putstatic(int byte_no) { putfield_or_static(byte_no, true); } @@ -3166,7 +3197,7 @@ Register Rscratch ) { // Determine flags. - const Bytecodes::Code code = bytecode(); + const Bytecodes::Code code = bytecode() == Bytecodes::_nofast_invokevirtual ? Bytecodes::_invokevirtual : bytecode(); const bool is_invokeinterface = code == Bytecodes::_invokeinterface; const bool is_invokedynamic = code == Bytecodes::_invokedynamic; const bool is_invokehandle = code == Bytecodes::_invokehandle; @@ -3239,9 +3270,16 @@ __ call_from_interpreter(Rtarget_method, Rret, Rrecv_klass /* scratch1 */, Rtemp /* scratch2 */); } -// Virtual or final call. Final calls are rewritten on the fly to run through "fast_finalcall" next time. void TemplateTable::invokevirtual(int byte_no) { - transition(vtos, vtos); + invokevirtual_internal(byte_no); +} + +void TemplateTable::nofast_invokevirtual(int byte_no) { + invokevirtual_internal(byte_no, MAY_NOT_REWRITE); +} + +// Virtual or final call. Final calls are rewritten on the fly to run through "fast_finalcall" next time. +void TemplateTable::invokevirtual_internal(int byte_no, RewriteControl rc) { Register Rtable_addr = R11_scratch1, Rret_type = R12_scratch2, @@ -3259,8 +3297,10 @@ __ testbitdi(CCR0, R0, Rflags, ConstantPoolCacheEntry::is_vfinal_shift); __ bfalse(CCR0, LnotFinal); - - patch_bytecode(Bytecodes::_fast_invokevfinal, Rnew_bc, R12_scratch2); + + if (rc == MAY_REWRITE) { + patch_bytecode(Bytecodes::_fast_invokevfinal, Rnew_bc, R12_scratch2); + } invokevfinal_helper(Rvtableindex_or_method, Rflags, R11_scratch1, R12_scratch2); __ align(32, 12);