--- a/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp Thu Aug 11 12:08:11 2011 -0700
+++ b/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp Tue Aug 16 04:14:05 2011 -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;
+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);
+ }
}
- // the pair bytecodes have already done the load.
- if (load_bc_into_scratch) {
- __ movl(bc, bytecode);
- }
- 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);
+ {
+ __ 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);
}