--- a/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp Thu Aug 11 12:08:11 2011 -0700
+++ b/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp Tue Aug 16 04:14:05 2011 -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);
-
- __ pop(dtos);
- if (!is_static) pop_and_check_object(obj);
- __ fstp_d(lo);
- if (!is_static) {
- patch_bytecode(Bytecodes::_fast_dputfield, rcx, rbx);
+#endif
+
+ // 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);