--- old/src/cpu/x86/vm/templateTable_x86_32.cpp 2011-08-12 04:58:41.082393143 -0700 +++ new/src/cpu/x86/vm/templateTable_x86_32.cpp 2011-08-12 04:58:40.799853758 -0700 @@ -202,45 +202,74 @@ } -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(bc_reg, temp_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, rsi, bc); + __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::set_original_bytecode_at), temp_reg, rsi, 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)); - __ jccb(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)); + __ jccb(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); } //---------------------------------------------------------------------------------------------------- @@ -2060,24 +2089,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_4, 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); } @@ -2453,138 +2478,153 @@ __ shrl(flags, ConstantPoolCacheEntry::tosBits); assert(btos == 0, "change code, btos != 0"); - // btos __ andl(flags, 0x0f); __ jcc(Assembler::notZero, notByte); - __ pop(btos); - if (!is_static) pop_and_check_object(obj); - __ movb(lo, rax ); - if (!is_static) { - patch_bytecode(Bytecodes::_fast_bputfield, rcx, rbx); + // btos + { + __ pop(btos); + if (!is_static) pop_and_check_object(obj); + __ movb(lo, rax); + if (!is_static) { + patch_bytecode(Bytecodes::_fast_bputfield, rcx, rbx, true, byte_no); + } + __ jmp(Done); } - __ jmp(Done); __ bind(notByte); - // itos - __ cmpl(flags, itos ); + __ cmpl(flags, itos); __ jcc(Assembler::notEqual, notInt); - __ pop(itos); - if (!is_static) pop_and_check_object(obj); - - __ movl(lo, rax ); - if (!is_static) { - patch_bytecode(Bytecodes::_fast_iputfield, rcx, rbx); + // itos + { + __ pop(itos); + if (!is_static) pop_and_check_object(obj); + __ movl(lo, rax); + if (!is_static) { + patch_bytecode(Bytecodes::_fast_iputfield, rcx, rbx, true, byte_no); + } + __ jmp(Done); } - __ jmp(Done); __ bind(notInt); - // atos - __ cmpl(flags, atos ); + __ cmpl(flags, atos); __ jcc(Assembler::notEqual, notObj); - __ pop(atos); - if (!is_static) pop_and_check_object(obj); - - do_oop_store(_masm, lo, rax, _bs->kind(), false); - - if (!is_static) { - patch_bytecode(Bytecodes::_fast_aputfield, rcx, rbx); + // atos + { + __ pop(atos); + if (!is_static) pop_and_check_object(obj); + do_oop_store(_masm, lo, rax, _bs->kind(), false); + if (!is_static) { + patch_bytecode(Bytecodes::_fast_aputfield, rcx, rbx, true, byte_no); + } + __ jmp(Done); } - __ jmp(Done); - __ bind(notObj); - // ctos - __ cmpl(flags, ctos ); + __ cmpl(flags, ctos); __ jcc(Assembler::notEqual, notChar); - __ pop(ctos); - if (!is_static) pop_and_check_object(obj); - __ movw(lo, rax ); - if (!is_static) { - patch_bytecode(Bytecodes::_fast_cputfield, rcx, rbx); + // ctos + { + __ pop(ctos); + if (!is_static) pop_and_check_object(obj); + __ movw(lo, rax); + if (!is_static) { + patch_bytecode(Bytecodes::_fast_cputfield, rcx, rbx, true, byte_no); + } + __ jmp(Done); } - __ jmp(Done); __ bind(notChar); - // stos - __ cmpl(flags, stos ); + __ cmpl(flags, stos); __ jcc(Assembler::notEqual, notShort); - __ pop(stos); - if (!is_static) pop_and_check_object(obj); - __ movw(lo, rax ); - if (!is_static) { - patch_bytecode(Bytecodes::_fast_sputfield, rcx, rbx); + // stos + { + __ pop(stos); + if (!is_static) pop_and_check_object(obj); + __ movw(lo, rax); + if (!is_static) { + patch_bytecode(Bytecodes::_fast_sputfield, rcx, rbx, true, byte_no); + } + __ jmp(Done); } - __ jmp(Done); __ bind(notShort); - // ltos - __ cmpl(flags, ltos ); + __ cmpl(flags, ltos); __ jcc(Assembler::notEqual, notLong); - Label notVolatileLong; - __ testl(rdx, rdx); - __ jcc(Assembler::zero, notVolatileLong); - - __ pop(ltos); // overwrites rdx, do this after testing volatile. - if (!is_static) pop_and_check_object(obj); - - // Replace with real volatile test - __ push(rdx); - __ push(rax); // Must update atomically with FIST - __ fild_d(Address(rsp,0)); // So load into FPU register - __ fistp_d(lo); // and put into memory atomically - __ addptr(rsp, 2*wordSize); - // volatile_barrier(); - volatile_barrier(Assembler::Membar_mask_bits(Assembler::StoreLoad | - Assembler::StoreStore)); - // Don't rewrite volatile version - __ jmp(notVolatile); - - __ bind(notVolatileLong); - - __ pop(ltos); // overwrites rdx - if (!is_static) pop_and_check_object(obj); - NOT_LP64(__ movptr(hi, rdx)); - __ movptr(lo, rax); - if (!is_static) { - patch_bytecode(Bytecodes::_fast_lputfield, rcx, rbx); + // ltos + { + Label notVolatileLong; + __ testl(rdx, rdx); + __ jcc(Assembler::zero, notVolatileLong); + + __ pop(ltos); // overwrites rdx, do this after testing volatile. + if (!is_static) pop_and_check_object(obj); + + // Replace with real volatile test + __ push(rdx); + __ push(rax); // Must update atomically with FIST + __ fild_d(Address(rsp,0)); // So load into FPU register + __ fistp_d(lo); // and put into memory atomically + __ addptr(rsp, 2*wordSize); + // volatile_barrier(); + volatile_barrier(Assembler::Membar_mask_bits(Assembler::StoreLoad | + Assembler::StoreStore)); + // Don't rewrite volatile version + __ jmp(notVolatile); + + __ bind(notVolatileLong); + + __ pop(ltos); // overwrites rdx + if (!is_static) pop_and_check_object(obj); + NOT_LP64(__ movptr(hi, rdx)); + __ movptr(lo, rax); + if (!is_static) { + patch_bytecode(Bytecodes::_fast_lputfield, rcx, rbx, true, byte_no); + } + __ jmp(notVolatile); } - __ jmp(notVolatile); __ bind(notLong); - // ftos - __ cmpl(flags, ftos ); + __ cmpl(flags, ftos); __ jcc(Assembler::notEqual, notFloat); - __ pop(ftos); - if (!is_static) pop_and_check_object(obj); - __ fstp_s(lo); - if (!is_static) { - patch_bytecode(Bytecodes::_fast_fputfield, rcx, rbx); + // ftos + { + __ pop(ftos); + if (!is_static) pop_and_check_object(obj); + __ fstp_s(lo); + if (!is_static) { + patch_bytecode(Bytecodes::_fast_fputfield, rcx, rbx, true, byte_no); + } + __ jmp(Done); } - __ jmp(Done); __ bind(notFloat); - // dtos - __ cmpl(flags, dtos ); +#ifdef ASSERT + __ cmpl(flags, dtos); __ jcc(Assembler::notEqual, notDouble); +#endif - __ pop(dtos); - if (!is_static) pop_and_check_object(obj); - __ fstp_d(lo); - if (!is_static) { - patch_bytecode(Bytecodes::_fast_dputfield, rcx, rbx); + // dtos + { + __ pop(dtos); + if (!is_static) pop_and_check_object(obj); + __ fstp_d(lo); + if (!is_static) { + patch_bytecode(Bytecodes::_fast_dputfield, rcx, rbx, true, byte_no); + } + __ jmp(Done); } - __ jmp(Done); +#ifdef ASSERT __ bind(notDouble); - __ stop("Bad state"); +#endif __ bind(Done);