--- old/src/cpu/x86/vm/templateTable_x86_64.cpp 2011-08-12 04:58:42.526432652 -0700 +++ new/src/cpu/x86/vm/templateTable_x86_64.cpp 2011-08-12 04:58:42.248164007 -0700 @@ -203,46 +203,74 @@ return Address(r13, offset); } -void TemplateTable::patch_bytecode(Bytecodes::Code bytecode, Register bc, - Register scratch, - bool load_bc_into_scratch/*=true*/) { - if (!RewriteBytecodes) { - return; - } - // the pair bytecodes have already done the load. - if (load_bc_into_scratch) { - __ movl(bc, bytecode); +void TemplateTable::patch_bytecode(Bytecodes::Code bc, Register bc_reg, + Register temp_reg, bool load_bc_into_bc_reg/*=true*/, + int byte_no) { + if (!RewriteBytecodes) return; + Label L_patch_done; + + switch (bc) { + case Bytecodes::_fast_aputfield: + case Bytecodes::_fast_bputfield: + case Bytecodes::_fast_cputfield: + case Bytecodes::_fast_dputfield: + case Bytecodes::_fast_fputfield: + case Bytecodes::_fast_iputfield: + case Bytecodes::_fast_lputfield: + case Bytecodes::_fast_sputfield: + { + // We skip bytecode quickening for putfield instructions when + // the put_code written to the constant pool cache is zero. + // This is required so that every execution of this instruction + // calls out to InterpreterRuntime::resolve_get_put to do + // additional, required work. + assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range"); + assert(load_bc_into_bc_reg, "we use bc_reg as temp"); + __ get_cache_and_index_and_bytecode_at_bcp(temp_reg, bc_reg, temp_reg, byte_no, 1); + __ movl(bc_reg, bc); + __ cmpl(temp_reg, (int) 0); + __ jcc(Assembler::zero, L_patch_done); // don't patch + } + break; + default: + assert(byte_no == -1, "sanity"); + // the pair bytecodes have already done the load. + if (load_bc_into_bc_reg) { + __ movl(bc_reg, bc); + } } - Label patch_done; + if (JvmtiExport::can_post_breakpoint()) { - Label fast_patch; + Label L_fast_patch; // if a breakpoint is present we can't rewrite the stream directly - __ movzbl(scratch, at_bcp(0)); - __ cmpl(scratch, Bytecodes::_breakpoint); - __ jcc(Assembler::notEqual, fast_patch); - __ get_method(scratch); + __ movzbl(temp_reg, at_bcp(0)); + __ cmpl(temp_reg, Bytecodes::_breakpoint); + __ jcc(Assembler::notEqual, L_fast_patch); + __ get_method(temp_reg); // Let breakpoint table handling rewrite to quicker bytecode - __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::set_original_bytecode_at), scratch, r13, bc); + __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::set_original_bytecode_at), temp_reg, r13, bc_reg); #ifndef ASSERT - __ jmpb(patch_done); + __ jmpb(L_patch_done); #else - __ jmp(patch_done); + __ jmp(L_patch_done); #endif - __ bind(fast_patch); + __ bind(L_fast_patch); } + #ifdef ASSERT - Label okay; - __ load_unsigned_byte(scratch, at_bcp(0)); - __ cmpl(scratch, (int) Bytecodes::java_code(bytecode)); - __ jcc(Assembler::equal, okay); - __ cmpl(scratch, bc); - __ jcc(Assembler::equal, okay); + Label L_okay; + __ load_unsigned_byte(temp_reg, at_bcp(0)); + __ cmpl(temp_reg, (int) Bytecodes::java_code(bc)); + __ jcc(Assembler::equal, L_okay); + __ cmpl(temp_reg, bc_reg); + __ jcc(Assembler::equal, L_okay); __ stop("patching the wrong bytecode"); - __ bind(okay); + __ bind(L_okay); #endif + // patch bytecode - __ movb(at_bcp(0), bc); - __ bind(patch_done); + __ movb(at_bcp(0), bc_reg); + __ bind(L_patch_done); } @@ -2098,24 +2126,20 @@ assert_different_registers(result, Rcache, index, temp); Label resolved; - __ get_cache_and_index_at_bcp(Rcache, index, 1, index_size); if (byte_no == f1_oop) { // We are resolved if the f1 field contains a non-null object (CallSite, etc.) // This kind of CP cache entry does not need to match the flags byte, because // there is a 1-1 relation between bytecode type and CP entry type. assert(result != noreg, ""); //else do cmpptr(Address(...), (int32_t) NULL_WORD) + __ get_cache_and_index_at_bcp(Rcache, index, 1, index_size); __ movptr(result, Address(Rcache, index, Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::f1_offset())); __ testptr(result, result); __ jcc(Assembler::notEqual, resolved); } else { assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range"); assert(result == noreg, ""); //else change code for setting result - const int shift_count = (1 + byte_no) * BitsPerByte; - __ movl(temp, Address(Rcache, index, Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::indices_offset())); - __ shrl(temp, shift_count); - // have we resolved this bytecode? - __ andl(temp, 0xFF); - __ cmpl(temp, (int) bytecode()); + __ get_cache_and_index_and_bytecode_at_bcp(Rcache, index, temp, byte_no, 1, index_size); + __ cmpl(temp, (int) bytecode()); // have we resolved this bytecode? __ jcc(Assembler::equal, resolved); } @@ -2507,101 +2531,123 @@ assert(btos == 0, "change code, btos != 0"); __ andl(flags, 0x0f); __ jcc(Assembler::notZero, notByte); + // btos - __ pop(btos); - if (!is_static) pop_and_check_object(obj); - __ movb(field, rax); - if (!is_static) { - patch_bytecode(Bytecodes::_fast_bputfield, bc, rbx); + { + __ pop(btos); + if (!is_static) pop_and_check_object(obj); + __ movb(field, rax); + if (!is_static) { + patch_bytecode(Bytecodes::_fast_bputfield, bc, rbx, true, byte_no); + } + __ jmp(Done); } - __ jmp(Done); __ bind(notByte); __ cmpl(flags, atos); __ jcc(Assembler::notEqual, notObj); - // atos - __ pop(atos); - if (!is_static) pop_and_check_object(obj); - // Store into the field - do_oop_store(_masm, field, rax, _bs->kind(), false); - - if (!is_static) { - patch_bytecode(Bytecodes::_fast_aputfield, bc, rbx); + // atos + { + __ pop(atos); + if (!is_static) pop_and_check_object(obj); + // Store into the field + do_oop_store(_masm, field, rax, _bs->kind(), false); + if (!is_static) { + patch_bytecode(Bytecodes::_fast_aputfield, bc, rbx, true, byte_no); + } + __ jmp(Done); } - __ jmp(Done); __ bind(notObj); __ cmpl(flags, itos); __ jcc(Assembler::notEqual, notInt); + // itos - __ pop(itos); - if (!is_static) pop_and_check_object(obj); - __ movl(field, rax); - if (!is_static) { - patch_bytecode(Bytecodes::_fast_iputfield, bc, rbx); + { + __ pop(itos); + if (!is_static) pop_and_check_object(obj); + __ movl(field, rax); + if (!is_static) { + patch_bytecode(Bytecodes::_fast_iputfield, bc, rbx, true, byte_no); + } + __ jmp(Done); } - __ jmp(Done); __ bind(notInt); __ cmpl(flags, ctos); __ jcc(Assembler::notEqual, notChar); + // ctos - __ pop(ctos); - if (!is_static) pop_and_check_object(obj); - __ movw(field, rax); - if (!is_static) { - patch_bytecode(Bytecodes::_fast_cputfield, bc, rbx); + { + __ pop(ctos); + if (!is_static) pop_and_check_object(obj); + __ movw(field, rax); + if (!is_static) { + patch_bytecode(Bytecodes::_fast_cputfield, bc, rbx, true, byte_no); + } + __ jmp(Done); } - __ jmp(Done); __ bind(notChar); __ cmpl(flags, stos); __ jcc(Assembler::notEqual, notShort); + // stos - __ pop(stos); - if (!is_static) pop_and_check_object(obj); - __ movw(field, rax); - if (!is_static) { - patch_bytecode(Bytecodes::_fast_sputfield, bc, rbx); + { + __ pop(stos); + if (!is_static) pop_and_check_object(obj); + __ movw(field, rax); + if (!is_static) { + patch_bytecode(Bytecodes::_fast_sputfield, bc, rbx, true, byte_no); + } + __ jmp(Done); } - __ jmp(Done); __ bind(notShort); __ cmpl(flags, ltos); __ jcc(Assembler::notEqual, notLong); + // ltos - __ pop(ltos); - if (!is_static) pop_and_check_object(obj); - __ movq(field, rax); - if (!is_static) { - patch_bytecode(Bytecodes::_fast_lputfield, bc, rbx); + { + __ pop(ltos); + if (!is_static) pop_and_check_object(obj); + __ movq(field, rax); + if (!is_static) { + patch_bytecode(Bytecodes::_fast_lputfield, bc, rbx, true, byte_no); + } + __ jmp(Done); } - __ jmp(Done); __ bind(notLong); __ cmpl(flags, ftos); __ jcc(Assembler::notEqual, notFloat); + // ftos - __ pop(ftos); - if (!is_static) pop_and_check_object(obj); - __ movflt(field, xmm0); - if (!is_static) { - patch_bytecode(Bytecodes::_fast_fputfield, bc, rbx); + { + __ pop(ftos); + if (!is_static) pop_and_check_object(obj); + __ movflt(field, xmm0); + if (!is_static) { + patch_bytecode(Bytecodes::_fast_fputfield, bc, rbx, true, byte_no); + } + __ jmp(Done); } - __ jmp(Done); __ bind(notFloat); #ifdef ASSERT __ cmpl(flags, dtos); __ jcc(Assembler::notEqual, notDouble); #endif + // dtos - __ pop(dtos); - if (!is_static) pop_and_check_object(obj); - __ movdbl(field, xmm0); - if (!is_static) { - patch_bytecode(Bytecodes::_fast_dputfield, bc, rbx); + { + __ pop(dtos); + if (!is_static) pop_and_check_object(obj); + __ movdbl(field, xmm0); + if (!is_static) { + patch_bytecode(Bytecodes::_fast_dputfield, bc, rbx, true, byte_no); + } } #ifdef ASSERT @@ -2612,12 +2658,12 @@ #endif __ bind(Done); + // Check for volatile store __ testl(rdx, rdx); __ jcc(Assembler::zero, notVolatile); volatile_barrier(Assembler::Membar_mask_bits(Assembler::StoreLoad | Assembler::StoreStore)); - __ bind(notVolatile); }