--- a/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp Fri May 21 02:59:24 2010 -0700
+++ b/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp Sun May 23 01:38:26 2010 -0700
@@ -2012,22 +2012,29 @@
__ membar(order_constraint);
}
-void TemplateTable::resolve_cache_and_index(int byte_no, Register Rcache, Register index) {
- assert(byte_no == 1 || byte_no == 2, "byte_no out of range");
- bool is_invokedynamic = (bytecode() == Bytecodes::_invokedynamic);
-
+void TemplateTable::resolve_cache_and_index(int byte_no,
+ Register result,
+ Register Rcache,
+ Register index,
+ size_t index_size) {
Register temp = rbx;
- assert_different_registers(Rcache, index, temp);
-
- const int shift_count = (1 + byte_no)*BitsPerByte;
+ assert_different_registers(result, Rcache, index, temp);
+
Label resolved;
- __ get_cache_and_index_at_bcp(Rcache, index, 1, is_invokedynamic);
- if (is_invokedynamic) {
- // we are resolved if the f1 field contains a non-null CallSite object
- __ cmpptr(Address(Rcache, index, Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::f1_offset()), (int32_t) NULL_WORD);
+ __ 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)
+ __ 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?
@@ -2053,7 +2060,9 @@
__ movl(temp, (int)bytecode());
__ call_VM(noreg, entry, temp);
// Update registers with resolved info
- __ get_cache_and_index_at_bcp(Rcache, index, 1, is_invokedynamic);
+ __ get_cache_and_index_at_bcp(Rcache, index, 1, index_size);
+ if (result != noreg)
+ __ movptr(result, Address(Rcache, index, Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::f1_offset()));
__ bind(resolved);
}
@@ -2087,7 +2096,8 @@
Register itable_index,
Register flags,
bool is_invokevirtual,
- bool is_invokevfinal /*unused*/) {
+ bool is_invokevfinal /*unused*/,
+ bool is_invokedynamic) {
// setup registers
const Register cache = rcx;
const Register index = rdx;
@@ -2109,13 +2119,18 @@
const int index_offset = in_bytes(constantPoolCacheOopDesc::base_offset() +
ConstantPoolCacheEntry::f2_offset());
- resolve_cache_and_index(byte_no, cache, index);
-
- __ movptr(method, Address(cache, index, Address::times_ptr, method_offset));
+ if (byte_no == f1_oop) {
+ // Resolved f1_oop goes directly into 'method' register.
+ assert(is_invokedynamic, "");
+ resolve_cache_and_index(byte_no, method, cache, index, sizeof(u4));
+ } else {
+ resolve_cache_and_index(byte_no, noreg, cache, index, sizeof(u2));
+ __ movptr(method, Address(cache, index, Address::times_ptr, method_offset));
+ }
if (itable_index != noreg) {
__ movptr(itable_index, Address(cache, index, Address::times_ptr, index_offset));
}
- __ movl(flags , Address(cache, index, Address::times_ptr, flags_offset ));
+ __ movl(flags, Address(cache, index, Address::times_ptr, flags_offset));
}
@@ -2169,7 +2184,7 @@
const Register off = rbx;
const Register flags = rax;
- resolve_cache_and_index(byte_no, cache, index);
+ resolve_cache_and_index(byte_no, noreg, cache, index, sizeof(u2));
jvmti_post_field_access(cache, index, is_static, false);
load_field_cp_cache_entry(obj, cache, index, off, flags, is_static);
@@ -2378,7 +2393,7 @@
const Register off = rbx;
const Register flags = rax;
- resolve_cache_and_index(byte_no, cache, index);
+ resolve_cache_and_index(byte_no, noreg, cache, index, sizeof(u2));
jvmti_post_field_mod(cache, index, is_static);
load_field_cp_cache_entry(obj, cache, index, off, flags, is_static);
@@ -2815,10 +2830,11 @@
// save 'interpreter return address'
__ save_bcp();
- load_invoke_cp_cache_entry(byte_no, method, index, flags, is_invokevirtual);
+ load_invoke_cp_cache_entry(byte_no, method, index, flags, is_invokevirtual, false, is_invokedynamic);
// load receiver if needed (note: no return address pushed yet)
if (load_receiver) {
+ assert(!is_invokedynamic, "");
__ movl(recv, flags);
__ andl(recv, 0xFF);
// recv count is 0 based?
@@ -2910,6 +2926,7 @@
void TemplateTable::invokevirtual(int byte_no) {
transition(vtos, vtos);
+ assert(byte_no == f2_byte, "use this argument");
prepare_invoke(rbx, noreg, byte_no);
// rbx,: index
@@ -2922,6 +2939,7 @@
void TemplateTable::invokespecial(int byte_no) {
transition(vtos, vtos);
+ assert(byte_no == f1_byte, "use this argument");
prepare_invoke(rbx, noreg, byte_no);
// do the call
__ verify_oop(rbx);
@@ -2932,6 +2950,7 @@
void TemplateTable::invokestatic(int byte_no) {
transition(vtos, vtos);
+ assert(byte_no == f1_byte, "use this argument");
prepare_invoke(rbx, noreg, byte_no);
// do the call
__ verify_oop(rbx);
@@ -2942,12 +2961,14 @@
void TemplateTable::fast_invokevfinal(int byte_no) {
transition(vtos, vtos);
+ assert(byte_no == f2_byte, "use this argument");
__ stop("fast_invokevfinal not used on x86");
}
void TemplateTable::invokeinterface(int byte_no) {
transition(vtos, vtos);
+ assert(byte_no == f1_byte, "use this argument");
prepare_invoke(rax, rbx, byte_no);
// rax,: Interface
@@ -3036,11 +3057,11 @@
return;
}
+ assert(byte_no == f1_oop, "use this argument");
prepare_invoke(rax, rbx, byte_no);
// rax: CallSite object (f1)
// rbx: unused (f2)
- // rcx: receiver address
// rdx: flags (unused)
if (ProfileInterpreter) {