diff -r dfe27f03244a -r e9ff18c4ace7 src/cpu/x86/vm/templateTable_x86_32.cpp --- a/src/cpu/x86/vm/templateTable_x86_32.cpp Tue Jun 01 11:48:33 2010 -0700 +++ b/src/cpu/x86/vm/templateTable_x86_32.cpp Wed Jun 02 22:45:42 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) {