Mercurial > hg > truffle
comparison src/cpu/x86/vm/templateTable_x86_64.cpp @ 6266:1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
6984705: JSR 292 method handle creation should not go through JNI
Summary: remove assembly code for JDK 7 chained method handles
Reviewed-by: jrose, twisti, kvn, mhaupt
Contributed-by: John Rose <john.r.rose@oracle.com>, Christian Thalinger <christian.thalinger@oracle.com>, Michael Haupt <michael.haupt@oracle.com>
author | twisti |
---|---|
date | Tue, 24 Jul 2012 10:51:00 -0700 |
parents | 19e197e2a1af |
children | da91efe96a93 |
comparison
equal
deleted
inserted
replaced
6241:aba91a731143 | 6266:1d7922586cf6 |
---|---|
456 } | 456 } |
457 | 457 |
458 const Register cache = rcx; | 458 const Register cache = rcx; |
459 const Register index = rdx; | 459 const Register index = rdx; |
460 | 460 |
461 resolve_cache_and_index(f1_oop, rax, cache, index, wide ? sizeof(u2) : sizeof(u1)); | 461 resolve_cache_and_index(f12_oop, rax, cache, index, wide ? sizeof(u2) : sizeof(u1)); |
462 if (VerifyOops) { | 462 if (VerifyOops) { |
463 __ verify_oop(rax); | 463 __ verify_oop(rax); |
464 } | 464 } |
465 | 465 |
466 Label L_done, L_throw_exception; | 466 Label L_done, L_throw_exception; |
2123 size_t index_size) { | 2123 size_t index_size) { |
2124 const Register temp = rbx; | 2124 const Register temp = rbx; |
2125 assert_different_registers(result, Rcache, index, temp); | 2125 assert_different_registers(result, Rcache, index, temp); |
2126 | 2126 |
2127 Label resolved; | 2127 Label resolved; |
2128 if (byte_no == f1_oop) { | 2128 if (byte_no == f12_oop) { |
2129 // We are resolved if the f1 field contains a non-null object (CallSite, etc.) | 2129 // We are resolved if the f1 field contains a non-null object (CallSite, MethodType, etc.) |
2130 // This kind of CP cache entry does not need to match the flags byte, because | 2130 // This kind of CP cache entry does not need to match bytecode_1 or bytecode_2, because |
2131 // there is a 1-1 relation between bytecode type and CP entry type. | 2131 // there is a 1-1 relation between bytecode type and CP entry type. |
2132 // The caller will also load a methodOop from f2. | |
2132 assert(result != noreg, ""); //else do cmpptr(Address(...), (int32_t) NULL_WORD) | 2133 assert(result != noreg, ""); //else do cmpptr(Address(...), (int32_t) NULL_WORD) |
2133 __ get_cache_and_index_at_bcp(Rcache, index, 1, index_size); | 2134 __ get_cache_and_index_at_bcp(Rcache, index, 1, index_size); |
2134 __ movptr(result, Address(Rcache, index, Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::f1_offset())); | 2135 __ movptr(result, Address(Rcache, index, Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::f1_offset())); |
2135 __ testptr(result, result); | 2136 __ testptr(result, result); |
2136 __ jcc(Assembler::notEqual, resolved); | 2137 __ jcc(Assembler::notEqual, resolved); |
2155 case Bytecodes::_invokespecial: | 2156 case Bytecodes::_invokespecial: |
2156 case Bytecodes::_invokestatic: | 2157 case Bytecodes::_invokestatic: |
2157 case Bytecodes::_invokeinterface: | 2158 case Bytecodes::_invokeinterface: |
2158 entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invoke); | 2159 entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invoke); |
2159 break; | 2160 break; |
2161 case Bytecodes::_invokehandle: | |
2162 entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokehandle); | |
2163 break; | |
2160 case Bytecodes::_invokedynamic: | 2164 case Bytecodes::_invokedynamic: |
2161 entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokedynamic); | 2165 entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokedynamic); |
2162 break; | 2166 break; |
2163 case Bytecodes::_fast_aldc: | 2167 case Bytecodes::_fast_aldc: |
2164 entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc); | 2168 entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc); |
2165 break; | 2169 break; |
2166 case Bytecodes::_fast_aldc_w: | 2170 case Bytecodes::_fast_aldc_w: |
2167 entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc); | 2171 entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc); |
2168 break; | 2172 break; |
2169 default: | 2173 default: |
2170 ShouldNotReachHere(); | 2174 fatal(err_msg("unexpected bytecode: %s", Bytecodes::name(bytecode()))); |
2171 break; | 2175 break; |
2172 } | 2176 } |
2173 __ movl(temp, (int) bytecode()); | 2177 __ movl(temp, (int) bytecode()); |
2174 __ call_VM(noreg, entry, temp); | 2178 __ call_VM(noreg, entry, temp); |
2175 | 2179 |
2178 if (result != noreg) | 2182 if (result != noreg) |
2179 __ movptr(result, Address(Rcache, index, Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::f1_offset())); | 2183 __ movptr(result, Address(Rcache, index, Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::f1_offset())); |
2180 __ bind(resolved); | 2184 __ bind(resolved); |
2181 } | 2185 } |
2182 | 2186 |
2183 // The Rcache and index registers must be set before call | 2187 // The cache and index registers must be set before call |
2184 void TemplateTable::load_field_cp_cache_entry(Register obj, | 2188 void TemplateTable::load_field_cp_cache_entry(Register obj, |
2185 Register cache, | 2189 Register cache, |
2186 Register index, | 2190 Register index, |
2187 Register off, | 2191 Register off, |
2188 Register flags, | 2192 Register flags, |
2189 bool is_static = false) { | 2193 bool is_static = false) { |
2190 assert_different_registers(cache, index, flags, off); | 2194 assert_different_registers(cache, index, flags, off); |
2191 | 2195 |
2192 ByteSize cp_base_offset = constantPoolCacheOopDesc::base_offset(); | 2196 ByteSize cp_base_offset = constantPoolCacheOopDesc::base_offset(); |
2193 // Field offset | 2197 // Field offset |
2194 __ movptr(off, Address(cache, index, Address::times_8, | 2198 __ movptr(off, Address(cache, index, Address::times_ptr, |
2195 in_bytes(cp_base_offset + | 2199 in_bytes(cp_base_offset + |
2196 ConstantPoolCacheEntry::f2_offset()))); | 2200 ConstantPoolCacheEntry::f2_offset()))); |
2197 // Flags | 2201 // Flags |
2198 __ movl(flags, Address(cache, index, Address::times_8, | 2202 __ movl(flags, Address(cache, index, Address::times_ptr, |
2199 in_bytes(cp_base_offset + | 2203 in_bytes(cp_base_offset + |
2200 ConstantPoolCacheEntry::flags_offset()))); | 2204 ConstantPoolCacheEntry::flags_offset()))); |
2201 | 2205 |
2202 // klass overwrite register | 2206 // klass overwrite register |
2203 if (is_static) { | 2207 if (is_static) { |
2204 __ movptr(obj, Address(cache, index, Address::times_8, | 2208 __ movptr(obj, Address(cache, index, Address::times_ptr, |
2205 in_bytes(cp_base_offset + | 2209 in_bytes(cp_base_offset + |
2206 ConstantPoolCacheEntry::f1_offset()))); | 2210 ConstantPoolCacheEntry::f1_offset()))); |
2207 } | 2211 } |
2208 } | 2212 } |
2209 | 2213 |
2220 assert_different_registers(method, flags); | 2224 assert_different_registers(method, flags); |
2221 assert_different_registers(method, cache, index); | 2225 assert_different_registers(method, cache, index); |
2222 assert_different_registers(itable_index, flags); | 2226 assert_different_registers(itable_index, flags); |
2223 assert_different_registers(itable_index, cache, index); | 2227 assert_different_registers(itable_index, cache, index); |
2224 // determine constant pool cache field offsets | 2228 // determine constant pool cache field offsets |
2229 assert(is_invokevirtual == (byte_no == f2_byte), "is_invokevirtual flag redundant"); | |
2225 const int method_offset = in_bytes( | 2230 const int method_offset = in_bytes( |
2226 constantPoolCacheOopDesc::base_offset() + | 2231 constantPoolCacheOopDesc::base_offset() + |
2227 (is_invokevirtual | 2232 ((byte_no == f2_byte) |
2228 ? ConstantPoolCacheEntry::f2_offset() | 2233 ? ConstantPoolCacheEntry::f2_offset() |
2229 : ConstantPoolCacheEntry::f1_offset())); | 2234 : ConstantPoolCacheEntry::f1_offset())); |
2230 const int flags_offset = in_bytes(constantPoolCacheOopDesc::base_offset() + | 2235 const int flags_offset = in_bytes(constantPoolCacheOopDesc::base_offset() + |
2231 ConstantPoolCacheEntry::flags_offset()); | 2236 ConstantPoolCacheEntry::flags_offset()); |
2232 // access constant pool cache fields | 2237 // access constant pool cache fields |
2233 const int index_offset = in_bytes(constantPoolCacheOopDesc::base_offset() + | 2238 const int index_offset = in_bytes(constantPoolCacheOopDesc::base_offset() + |
2234 ConstantPoolCacheEntry::f2_offset()); | 2239 ConstantPoolCacheEntry::f2_offset()); |
2235 | 2240 |
2236 if (byte_no == f1_oop) { | 2241 if (byte_no == f12_oop) { |
2237 // Resolved f1_oop goes directly into 'method' register. | 2242 // Resolved f1_oop (CallSite, MethodType, etc.) goes into 'itable_index'. |
2238 assert(is_invokedynamic, ""); | 2243 // Resolved f2_oop (methodOop invoker) will go into 'method' (at index_offset). |
2239 resolve_cache_and_index(byte_no, method, cache, index, sizeof(u4)); | 2244 // See ConstantPoolCacheEntry::set_dynamic_call and set_method_handle. |
2245 size_t index_size = (is_invokedynamic ? sizeof(u4) : sizeof(u2)); | |
2246 resolve_cache_and_index(byte_no, itable_index, cache, index, index_size); | |
2247 __ movptr(method, Address(cache, index, Address::times_ptr, index_offset)); | |
2248 itable_index = noreg; // hack to disable load below | |
2240 } else { | 2249 } else { |
2241 resolve_cache_and_index(byte_no, noreg, cache, index, sizeof(u2)); | 2250 resolve_cache_and_index(byte_no, noreg, cache, index, sizeof(u2)); |
2242 __ movptr(method, Address(cache, index, Address::times_ptr, method_offset)); | 2251 __ movptr(method, Address(cache, index, Address::times_ptr, method_offset)); |
2243 } | 2252 } |
2244 if (itable_index != noreg) { | 2253 if (itable_index != noreg) { |
2254 // pick up itable index from f2 also: | |
2255 assert(byte_no == f1_byte, "already picked up f1"); | |
2245 __ movptr(itable_index, Address(cache, index, Address::times_ptr, index_offset)); | 2256 __ movptr(itable_index, Address(cache, index, Address::times_ptr, index_offset)); |
2246 } | 2257 } |
2247 __ movl(flags, Address(cache, index, Address::times_ptr, flags_offset)); | 2258 __ movl(flags, Address(cache, index, Address::times_ptr, flags_offset)); |
2248 } | 2259 } |
2249 | 2260 |
2315 const Address field(obj, off, Address::times_1); | 2326 const Address field(obj, off, Address::times_1); |
2316 | 2327 |
2317 Label Done, notByte, notInt, notShort, notChar, | 2328 Label Done, notByte, notInt, notShort, notChar, |
2318 notLong, notFloat, notObj, notDouble; | 2329 notLong, notFloat, notObj, notDouble; |
2319 | 2330 |
2320 __ shrl(flags, ConstantPoolCacheEntry::tosBits); | 2331 __ shrl(flags, ConstantPoolCacheEntry::tos_state_shift); |
2332 // Make sure we don't need to mask edx after the above shift | |
2321 assert(btos == 0, "change code, btos != 0"); | 2333 assert(btos == 0, "change code, btos != 0"); |
2322 | 2334 |
2323 __ andl(flags, 0x0F); | 2335 __ andl(flags, ConstantPoolCacheEntry::tos_state_mask); |
2324 __ jcc(Assembler::notZero, notByte); | 2336 __ jcc(Assembler::notZero, notByte); |
2325 // btos | 2337 // btos |
2326 __ load_signed_byte(rax, field); | 2338 __ load_signed_byte(rax, field); |
2327 __ push(btos); | 2339 __ push(btos); |
2328 // Rewrite bytecode to be faster | 2340 // Rewrite bytecode to be faster |
2464 // we must find the type to determine where the object is. | 2476 // we must find the type to determine where the object is. |
2465 __ movl(c_rarg3, Address(c_rarg2, rscratch1, | 2477 __ movl(c_rarg3, Address(c_rarg2, rscratch1, |
2466 Address::times_8, | 2478 Address::times_8, |
2467 in_bytes(cp_base_offset + | 2479 in_bytes(cp_base_offset + |
2468 ConstantPoolCacheEntry::flags_offset()))); | 2480 ConstantPoolCacheEntry::flags_offset()))); |
2469 __ shrl(c_rarg3, ConstantPoolCacheEntry::tosBits); | 2481 __ shrl(c_rarg3, ConstantPoolCacheEntry::tos_state_shift); |
2470 // Make sure we don't need to mask rcx for tosBits after the | 2482 // Make sure we don't need to mask rcx after the above shift |
2471 // above shift | 2483 ConstantPoolCacheEntry::verify_tos_state_shift(); |
2472 ConstantPoolCacheEntry::verify_tosBits(); | |
2473 __ movptr(c_rarg1, at_tos_p1()); // initially assume a one word jvalue | 2484 __ movptr(c_rarg1, at_tos_p1()); // initially assume a one word jvalue |
2474 __ cmpl(c_rarg3, ltos); | 2485 __ cmpl(c_rarg3, ltos); |
2475 __ cmovptr(Assembler::equal, | 2486 __ cmovptr(Assembler::equal, |
2476 c_rarg1, at_tos_p2()); // ltos (two word jvalue) | 2487 c_rarg1, at_tos_p2()); // ltos (two word jvalue) |
2477 __ cmpl(c_rarg3, dtos); | 2488 __ cmpl(c_rarg3, dtos); |
2514 // volatile_barrier(Assembler::Membar_mask_bits(Assembler::LoadStore | | 2525 // volatile_barrier(Assembler::Membar_mask_bits(Assembler::LoadStore | |
2515 // Assembler::StoreStore)); | 2526 // Assembler::StoreStore)); |
2516 | 2527 |
2517 Label notVolatile, Done; | 2528 Label notVolatile, Done; |
2518 __ movl(rdx, flags); | 2529 __ movl(rdx, flags); |
2519 __ shrl(rdx, ConstantPoolCacheEntry::volatileField); | 2530 __ shrl(rdx, ConstantPoolCacheEntry::is_volatile_shift); |
2520 __ andl(rdx, 0x1); | 2531 __ andl(rdx, 0x1); |
2521 | 2532 |
2522 // field address | 2533 // field address |
2523 const Address field(obj, off, Address::times_1); | 2534 const Address field(obj, off, Address::times_1); |
2524 | 2535 |
2525 Label notByte, notInt, notShort, notChar, | 2536 Label notByte, notInt, notShort, notChar, |
2526 notLong, notFloat, notObj, notDouble; | 2537 notLong, notFloat, notObj, notDouble; |
2527 | 2538 |
2528 __ shrl(flags, ConstantPoolCacheEntry::tosBits); | 2539 __ shrl(flags, ConstantPoolCacheEntry::tos_state_shift); |
2529 | 2540 |
2530 assert(btos == 0, "change code, btos != 0"); | 2541 assert(btos == 0, "change code, btos != 0"); |
2531 __ andl(flags, 0x0f); | 2542 __ andl(flags, ConstantPoolCacheEntry::tos_state_mask); |
2532 __ jcc(Assembler::notZero, notByte); | 2543 __ jcc(Assembler::notZero, notByte); |
2533 | 2544 |
2534 // btos | 2545 // btos |
2535 { | 2546 { |
2536 __ pop(btos); | 2547 __ pop(btos); |
2749 // [jk] not needed currently | 2760 // [jk] not needed currently |
2750 // volatile_barrier(Assembler::Membar_mask_bits(Assembler::LoadStore | | 2761 // volatile_barrier(Assembler::Membar_mask_bits(Assembler::LoadStore | |
2751 // Assembler::StoreStore)); | 2762 // Assembler::StoreStore)); |
2752 | 2763 |
2753 Label notVolatile; | 2764 Label notVolatile; |
2754 __ shrl(rdx, ConstantPoolCacheEntry::volatileField); | 2765 __ shrl(rdx, ConstantPoolCacheEntry::is_volatile_shift); |
2755 __ andl(rdx, 0x1); | 2766 __ andl(rdx, 0x1); |
2756 | 2767 |
2757 // Get object from stack | 2768 // Get object from stack |
2758 pop_and_check_object(rcx); | 2769 pop_and_check_object(rcx); |
2759 | 2770 |
2830 // [jk] not needed currently | 2841 // [jk] not needed currently |
2831 // if (os::is_MP()) { | 2842 // if (os::is_MP()) { |
2832 // __ movl(rdx, Address(rcx, rbx, Address::times_8, | 2843 // __ movl(rdx, Address(rcx, rbx, Address::times_8, |
2833 // in_bytes(constantPoolCacheOopDesc::base_offset() + | 2844 // in_bytes(constantPoolCacheOopDesc::base_offset() + |
2834 // ConstantPoolCacheEntry::flags_offset()))); | 2845 // ConstantPoolCacheEntry::flags_offset()))); |
2835 // __ shrl(rdx, ConstantPoolCacheEntry::volatileField); | 2846 // __ shrl(rdx, ConstantPoolCacheEntry::is_volatile_shift); |
2836 // __ andl(rdx, 0x1); | 2847 // __ andl(rdx, 0x1); |
2837 // } | 2848 // } |
2838 __ movptr(rbx, Address(rcx, rbx, Address::times_8, | 2849 __ movptr(rbx, Address(rcx, rbx, Address::times_8, |
2839 in_bytes(constantPoolCacheOopDesc::base_offset() + | 2850 in_bytes(constantPoolCacheOopDesc::base_offset() + |
2840 ConstantPoolCacheEntry::f2_offset()))); | 2851 ConstantPoolCacheEntry::f2_offset()))); |
2918 // if (os::is_MP()) { | 2929 // if (os::is_MP()) { |
2919 // Label notVolatile; | 2930 // Label notVolatile; |
2920 // __ movl(rdx, Address(rcx, rdx, Address::times_8, | 2931 // __ movl(rdx, Address(rcx, rdx, Address::times_8, |
2921 // in_bytes(constantPoolCacheOopDesc::base_offset() + | 2932 // in_bytes(constantPoolCacheOopDesc::base_offset() + |
2922 // ConstantPoolCacheEntry::flags_offset()))); | 2933 // ConstantPoolCacheEntry::flags_offset()))); |
2923 // __ shrl(rdx, ConstantPoolCacheEntry::volatileField); | 2934 // __ shrl(rdx, ConstantPoolCacheEntry::is_volatile_shift); |
2924 // __ testl(rdx, 0x1); | 2935 // __ testl(rdx, 0x1); |
2925 // __ jcc(Assembler::zero, notVolatile); | 2936 // __ jcc(Assembler::zero, notVolatile); |
2926 // __ membar(Assembler::LoadLoad); | 2937 // __ membar(Assembler::LoadLoad); |
2927 // __ bind(notVolatile); | 2938 // __ bind(notVolatile); |
2928 // } | 2939 // } |
2938 void TemplateTable::count_calls(Register method, Register temp) { | 2949 void TemplateTable::count_calls(Register method, Register temp) { |
2939 // implemented elsewhere | 2950 // implemented elsewhere |
2940 ShouldNotReachHere(); | 2951 ShouldNotReachHere(); |
2941 } | 2952 } |
2942 | 2953 |
2943 void TemplateTable::prepare_invoke(Register method, Register index, int byte_no) { | 2954 void TemplateTable::prepare_invoke(int byte_no, |
2955 Register method, // linked method (or i-klass) | |
2956 Register index, // itable index, MethodType, etc. | |
2957 Register recv, // if caller wants to see it | |
2958 Register flags // if caller wants to test it | |
2959 ) { | |
2944 // determine flags | 2960 // determine flags |
2945 Bytecodes::Code code = bytecode(); | 2961 const Bytecodes::Code code = bytecode(); |
2946 const bool is_invokeinterface = code == Bytecodes::_invokeinterface; | 2962 const bool is_invokeinterface = code == Bytecodes::_invokeinterface; |
2947 const bool is_invokedynamic = code == Bytecodes::_invokedynamic; | 2963 const bool is_invokedynamic = code == Bytecodes::_invokedynamic; |
2964 const bool is_invokehandle = code == Bytecodes::_invokehandle; | |
2948 const bool is_invokevirtual = code == Bytecodes::_invokevirtual; | 2965 const bool is_invokevirtual = code == Bytecodes::_invokevirtual; |
2949 const bool is_invokespecial = code == Bytecodes::_invokespecial; | 2966 const bool is_invokespecial = code == Bytecodes::_invokespecial; |
2950 const bool load_receiver = (code != Bytecodes::_invokestatic && code != Bytecodes::_invokedynamic); | 2967 const bool load_receiver = (recv != noreg); |
2951 const bool receiver_null_check = is_invokespecial; | 2968 const bool save_flags = (flags != noreg); |
2952 const bool save_flags = is_invokeinterface || is_invokevirtual; | 2969 assert(load_receiver == (code != Bytecodes::_invokestatic && code != Bytecodes::_invokedynamic), ""); |
2970 assert(save_flags == (is_invokeinterface || is_invokevirtual), "need flags for vfinal"); | |
2971 assert(flags == noreg || flags == rdx, ""); | |
2972 assert(recv == noreg || recv == rcx, ""); | |
2973 | |
2953 // setup registers & access constant pool cache | 2974 // setup registers & access constant pool cache |
2954 const Register recv = rcx; | 2975 if (recv == noreg) recv = rcx; |
2955 const Register flags = rdx; | 2976 if (flags == noreg) flags = rdx; |
2956 assert_different_registers(method, index, recv, flags); | 2977 assert_different_registers(method, index, recv, flags); |
2957 | 2978 |
2958 // save 'interpreter return address' | 2979 // save 'interpreter return address' |
2959 __ save_bcp(); | 2980 __ save_bcp(); |
2960 | 2981 |
2961 load_invoke_cp_cache_entry(byte_no, method, index, flags, is_invokevirtual, false, is_invokedynamic); | 2982 load_invoke_cp_cache_entry(byte_no, method, index, flags, is_invokevirtual, false, is_invokedynamic); |
2962 | 2983 |
2963 // load receiver if needed (note: no return address pushed yet) | 2984 // maybe push appendix to arguments (just before return address) |
2985 if (is_invokedynamic || is_invokehandle) { | |
2986 Label L_no_push; | |
2987 __ verify_oop(index); | |
2988 __ testl(flags, (1 << ConstantPoolCacheEntry::has_appendix_shift)); | |
2989 __ jccb(Assembler::zero, L_no_push); | |
2990 // Push the appendix as a trailing parameter. | |
2991 // This must be done before we get the receiver, | |
2992 // since the parameter_size includes it. | |
2993 __ push(index); // push appendix (MethodType, CallSite, etc.) | |
2994 __ bind(L_no_push); | |
2995 } | |
2996 | |
2997 // load receiver if needed (after appendix is pushed so parameter size is correct) | |
2998 // Note: no return address pushed yet | |
2964 if (load_receiver) { | 2999 if (load_receiver) { |
2965 assert(!is_invokedynamic, ""); | |
2966 __ movl(recv, flags); | 3000 __ movl(recv, flags); |
2967 __ andl(recv, 0xFF); | 3001 __ andl(recv, ConstantPoolCacheEntry::parameter_size_mask); |
2968 Address recv_addr(rsp, recv, Address::times_8, -Interpreter::expr_offset_in_bytes(1)); | 3002 const int no_return_pc_pushed_yet = -1; // argument slot correction before we push return address |
3003 const int receiver_is_at_end = -1; // back off one slot to get receiver | |
3004 Address recv_addr = __ argument_address(recv, no_return_pc_pushed_yet + receiver_is_at_end); | |
2969 __ movptr(recv, recv_addr); | 3005 __ movptr(recv, recv_addr); |
2970 __ verify_oop(recv); | 3006 __ verify_oop(recv); |
2971 } | 3007 } |
2972 | 3008 |
2973 // do null check if needed | |
2974 if (receiver_null_check) { | |
2975 __ null_check(recv); | |
2976 } | |
2977 | |
2978 if (save_flags) { | 3009 if (save_flags) { |
2979 __ movl(r13, flags); | 3010 __ movl(r13, flags); |
2980 } | 3011 } |
2981 | 3012 |
2982 // compute return type | 3013 // compute return type |
2983 __ shrl(flags, ConstantPoolCacheEntry::tosBits); | 3014 __ shrl(flags, ConstantPoolCacheEntry::tos_state_shift); |
2984 // Make sure we don't need to mask flags for tosBits after the above shift | 3015 // Make sure we don't need to mask flags after the above shift |
2985 ConstantPoolCacheEntry::verify_tosBits(); | 3016 ConstantPoolCacheEntry::verify_tos_state_shift(); |
2986 // load return address | 3017 // load return address |
2987 { | 3018 { |
2988 address table_addr; | 3019 const address table_addr = (is_invokeinterface || is_invokedynamic) ? |
2989 if (is_invokeinterface || is_invokedynamic) | 3020 (address)Interpreter::return_5_addrs_by_index_table() : |
2990 table_addr = (address)Interpreter::return_5_addrs_by_index_table(); | 3021 (address)Interpreter::return_3_addrs_by_index_table(); |
2991 else | |
2992 table_addr = (address)Interpreter::return_3_addrs_by_index_table(); | |
2993 ExternalAddress table(table_addr); | 3022 ExternalAddress table(table_addr); |
2994 __ lea(rscratch1, table); | 3023 __ lea(rscratch1, table); |
2995 __ movptr(flags, Address(rscratch1, flags, Address::times_ptr)); | 3024 __ movptr(flags, Address(rscratch1, flags, Address::times_ptr)); |
2996 } | 3025 } |
2997 | 3026 |
2998 // push return address | 3027 // push return address |
2999 __ push(flags); | 3028 __ push(flags); |
3000 | 3029 |
3001 // Restore flag field from the constant pool cache, and restore esi | 3030 // Restore flags value from the constant pool cache, and restore rsi |
3002 // for later null checks. r13 is the bytecode pointer | 3031 // for later null checks. r13 is the bytecode pointer |
3003 if (save_flags) { | 3032 if (save_flags) { |
3004 __ movl(flags, r13); | 3033 __ movl(flags, r13); |
3005 __ restore_bcp(); | 3034 __ restore_bcp(); |
3006 } | 3035 } |
3010 void TemplateTable::invokevirtual_helper(Register index, | 3039 void TemplateTable::invokevirtual_helper(Register index, |
3011 Register recv, | 3040 Register recv, |
3012 Register flags) { | 3041 Register flags) { |
3013 // Uses temporary registers rax, rdx | 3042 // Uses temporary registers rax, rdx |
3014 assert_different_registers(index, recv, rax, rdx); | 3043 assert_different_registers(index, recv, rax, rdx); |
3044 assert(index == rbx, ""); | |
3045 assert(recv == rcx, ""); | |
3015 | 3046 |
3016 // Test for an invoke of a final method | 3047 // Test for an invoke of a final method |
3017 Label notFinal; | 3048 Label notFinal; |
3018 __ movl(rax, flags); | 3049 __ movl(rax, flags); |
3019 __ andl(rax, (1 << ConstantPoolCacheEntry::vfinalMethod)); | 3050 __ andl(rax, (1 << ConstantPoolCacheEntry::is_vfinal_shift)); |
3020 __ jcc(Assembler::zero, notFinal); | 3051 __ jcc(Assembler::zero, notFinal); |
3021 | 3052 |
3022 const Register method = index; // method must be rbx | 3053 const Register method = index; // method must be rbx |
3023 assert(method == rbx, | 3054 assert(method == rbx, |
3024 "methodOop must be rbx for interpreter calling convention"); | 3055 "methodOop must be rbx for interpreter calling convention"); |
3025 | 3056 |
3026 // do the call - the index is actually the method to call | 3057 // do the call - the index is actually the method to call |
3058 // that is, f2 is a vtable index if !is_vfinal, else f2 is a methodOop | |
3027 __ verify_oop(method); | 3059 __ verify_oop(method); |
3028 | 3060 |
3029 // It's final, need a null check here! | 3061 // It's final, need a null check here! |
3030 __ null_check(recv); | 3062 __ null_check(recv); |
3031 | 3063 |
3037 __ bind(notFinal); | 3069 __ bind(notFinal); |
3038 | 3070 |
3039 // get receiver klass | 3071 // get receiver klass |
3040 __ null_check(recv, oopDesc::klass_offset_in_bytes()); | 3072 __ null_check(recv, oopDesc::klass_offset_in_bytes()); |
3041 __ load_klass(rax, recv); | 3073 __ load_klass(rax, recv); |
3042 | |
3043 __ verify_oop(rax); | 3074 __ verify_oop(rax); |
3044 | 3075 |
3045 // profile this call | 3076 // profile this call |
3046 __ profile_virtual_call(rax, r14, rdx); | 3077 __ profile_virtual_call(rax, r14, rdx); |
3047 | 3078 |
3048 // get target methodOop & entry point | 3079 // get target methodOop & entry point |
3049 const int base = instanceKlass::vtable_start_offset() * wordSize; | 3080 __ lookup_virtual_method(rax, index, method); |
3050 assert(vtableEntry::size() * wordSize == 8, | |
3051 "adjust the scaling in the code below"); | |
3052 __ movptr(method, Address(rax, index, | |
3053 Address::times_8, | |
3054 base + vtableEntry::method_offset_in_bytes())); | |
3055 __ movptr(rdx, Address(method, methodOopDesc::interpreter_entry_offset())); | |
3056 __ jump_from_interpreted(method, rdx); | 3081 __ jump_from_interpreted(method, rdx); |
3057 } | 3082 } |
3058 | 3083 |
3059 | 3084 |
3060 void TemplateTable::invokevirtual(int byte_no) { | 3085 void TemplateTable::invokevirtual(int byte_no) { |
3061 transition(vtos, vtos); | 3086 transition(vtos, vtos); |
3062 assert(byte_no == f2_byte, "use this argument"); | 3087 assert(byte_no == f2_byte, "use this argument"); |
3063 prepare_invoke(rbx, noreg, byte_no); | 3088 prepare_invoke(byte_no, |
3089 rbx, // method or vtable index | |
3090 noreg, // unused itable index | |
3091 rcx, rdx); // recv, flags | |
3064 | 3092 |
3065 // rbx: index | 3093 // rbx: index |
3066 // rcx: receiver | 3094 // rcx: receiver |
3067 // rdx: flags | 3095 // rdx: flags |
3068 | 3096 |
3071 | 3099 |
3072 | 3100 |
3073 void TemplateTable::invokespecial(int byte_no) { | 3101 void TemplateTable::invokespecial(int byte_no) { |
3074 transition(vtos, vtos); | 3102 transition(vtos, vtos); |
3075 assert(byte_no == f1_byte, "use this argument"); | 3103 assert(byte_no == f1_byte, "use this argument"); |
3076 prepare_invoke(rbx, noreg, byte_no); | 3104 prepare_invoke(byte_no, rbx, noreg, // get f1 methodOop |
3105 rcx); // get receiver also for null check | |
3106 __ verify_oop(rcx); | |
3107 __ null_check(rcx); | |
3077 // do the call | 3108 // do the call |
3078 __ verify_oop(rbx); | 3109 __ verify_oop(rbx); |
3079 __ profile_call(rax); | 3110 __ profile_call(rax); |
3080 __ jump_from_interpreted(rbx, rax); | 3111 __ jump_from_interpreted(rbx, rax); |
3081 } | 3112 } |
3082 | 3113 |
3083 | 3114 |
3084 void TemplateTable::invokestatic(int byte_no) { | 3115 void TemplateTable::invokestatic(int byte_no) { |
3085 transition(vtos, vtos); | 3116 transition(vtos, vtos); |
3086 assert(byte_no == f1_byte, "use this argument"); | 3117 assert(byte_no == f1_byte, "use this argument"); |
3087 prepare_invoke(rbx, noreg, byte_no); | 3118 prepare_invoke(byte_no, rbx); // get f1 methodOop |
3088 // do the call | 3119 // do the call |
3089 __ verify_oop(rbx); | 3120 __ verify_oop(rbx); |
3090 __ profile_call(rax); | 3121 __ profile_call(rax); |
3091 __ jump_from_interpreted(rbx, rax); | 3122 __ jump_from_interpreted(rbx, rax); |
3092 } | 3123 } |
3098 } | 3129 } |
3099 | 3130 |
3100 void TemplateTable::invokeinterface(int byte_no) { | 3131 void TemplateTable::invokeinterface(int byte_no) { |
3101 transition(vtos, vtos); | 3132 transition(vtos, vtos); |
3102 assert(byte_no == f1_byte, "use this argument"); | 3133 assert(byte_no == f1_byte, "use this argument"); |
3103 prepare_invoke(rax, rbx, byte_no); | 3134 prepare_invoke(byte_no, rax, rbx, // get f1 klassOop, f2 itable index |
3104 | 3135 rcx, rdx); // recv, flags |
3105 // rax: Interface | 3136 |
3106 // rbx: index | 3137 // rax: interface klass (from f1) |
3138 // rbx: itable index (from f2) | |
3107 // rcx: receiver | 3139 // rcx: receiver |
3108 // rdx: flags | 3140 // rdx: flags |
3109 | 3141 |
3110 // Special case of invokeinterface called for virtual method of | 3142 // Special case of invokeinterface called for virtual method of |
3111 // java.lang.Object. See cpCacheOop.cpp for details. | 3143 // java.lang.Object. See cpCacheOop.cpp for details. |
3112 // This code isn't produced by javac, but could be produced by | 3144 // This code isn't produced by javac, but could be produced by |
3113 // another compliant java compiler. | 3145 // another compliant java compiler. |
3114 Label notMethod; | 3146 Label notMethod; |
3115 __ movl(r14, rdx); | 3147 __ movl(r14, rdx); |
3116 __ andl(r14, (1 << ConstantPoolCacheEntry::methodInterface)); | 3148 __ andl(r14, (1 << ConstantPoolCacheEntry::is_forced_virtual_shift)); |
3117 __ jcc(Assembler::zero, notMethod); | 3149 __ jcc(Assembler::zero, notMethod); |
3118 | 3150 |
3119 invokevirtual_helper(rbx, rcx, rdx); | 3151 invokevirtual_helper(rbx, rcx, rdx); |
3120 __ bind(notMethod); | 3152 __ bind(notMethod); |
3121 | 3153 |
3122 // Get receiver klass into rdx - also a null check | 3154 // Get receiver klass into rdx - also a null check |
3123 __ restore_locals(); // restore r14 | 3155 __ restore_locals(); // restore r14 |
3156 __ null_check(rcx, oopDesc::klass_offset_in_bytes()); | |
3124 __ load_klass(rdx, rcx); | 3157 __ load_klass(rdx, rcx); |
3125 __ verify_oop(rdx); | 3158 __ verify_oop(rdx); |
3126 | 3159 |
3127 // profile this call | 3160 // profile this call |
3128 __ profile_virtual_call(rdx, r13, r14); | 3161 __ profile_virtual_call(rdx, r13, r14); |
3133 rdx, rax, rbx, | 3166 rdx, rax, rbx, |
3134 // outputs: method, scan temp. reg | 3167 // outputs: method, scan temp. reg |
3135 rbx, r13, | 3168 rbx, r13, |
3136 no_such_interface); | 3169 no_such_interface); |
3137 | 3170 |
3138 // rbx,: methodOop to call | 3171 // rbx: methodOop to call |
3139 // rcx: receiver | 3172 // rcx: receiver |
3140 // Check for abstract method error | 3173 // Check for abstract method error |
3141 // Note: This should be done more efficiently via a throw_abstract_method_error | 3174 // Note: This should be done more efficiently via a throw_abstract_method_error |
3142 // interpreter entry point and a conditional jump to it in case of a null | 3175 // interpreter entry point and a conditional jump to it in case of a null |
3143 // method. | 3176 // method. |
3170 __ restore_locals(); // make sure locals pointer is correct as well (was destroyed) | 3203 __ restore_locals(); // make sure locals pointer is correct as well (was destroyed) |
3171 __ call_VM(noreg, CAST_FROM_FN_PTR(address, | 3204 __ call_VM(noreg, CAST_FROM_FN_PTR(address, |
3172 InterpreterRuntime::throw_IncompatibleClassChangeError)); | 3205 InterpreterRuntime::throw_IncompatibleClassChangeError)); |
3173 // the call_VM checks for exception, so we should never return here. | 3206 // the call_VM checks for exception, so we should never return here. |
3174 __ should_not_reach_here(); | 3207 __ should_not_reach_here(); |
3175 return; | 3208 } |
3176 } | 3209 |
3210 | |
3211 void TemplateTable::invokehandle(int byte_no) { | |
3212 transition(vtos, vtos); | |
3213 assert(byte_no == f12_oop, "use this argument"); | |
3214 const Register rbx_method = rbx; // f2 | |
3215 const Register rax_mtype = rax; // f1 | |
3216 const Register rcx_recv = rcx; | |
3217 const Register rdx_flags = rdx; | |
3218 | |
3219 if (!EnableInvokeDynamic) { | |
3220 // rewriter does not generate this bytecode | |
3221 __ should_not_reach_here(); | |
3222 return; | |
3223 } | |
3224 | |
3225 prepare_invoke(byte_no, | |
3226 rbx_method, rax_mtype, // get f2 methodOop, f1 MethodType | |
3227 rcx_recv); | |
3228 __ verify_oop(rbx_method); | |
3229 __ verify_oop(rcx_recv); | |
3230 __ null_check(rcx_recv); | |
3231 | |
3232 // Note: rax_mtype is already pushed (if necessary) by prepare_invoke | |
3233 | |
3234 // FIXME: profile the LambdaForm also | |
3235 __ profile_final_call(rax); | |
3236 | |
3237 __ jump_from_interpreted(rbx_method, rdx); | |
3238 } | |
3239 | |
3177 | 3240 |
3178 void TemplateTable::invokedynamic(int byte_no) { | 3241 void TemplateTable::invokedynamic(int byte_no) { |
3179 transition(vtos, vtos); | 3242 transition(vtos, vtos); |
3180 assert(byte_no == f1_oop, "use this argument"); | 3243 assert(byte_no == f12_oop, "use this argument"); |
3181 | 3244 |
3182 if (!EnableInvokeDynamic) { | 3245 if (!EnableInvokeDynamic) { |
3183 // We should not encounter this bytecode if !EnableInvokeDynamic. | 3246 // We should not encounter this bytecode if !EnableInvokeDynamic. |
3184 // The verifier will stop it. However, if we get past the verifier, | 3247 // The verifier will stop it. However, if we get past the verifier, |
3185 // this will stop the thread in a reasonable way, without crashing the JVM. | 3248 // this will stop the thread in a reasonable way, without crashing the JVM. |
3188 // the call_VM checks for exception, so we should never return here. | 3251 // the call_VM checks for exception, so we should never return here. |
3189 __ should_not_reach_here(); | 3252 __ should_not_reach_here(); |
3190 return; | 3253 return; |
3191 } | 3254 } |
3192 | 3255 |
3193 prepare_invoke(rax, rbx, byte_no); | 3256 const Register rbx_method = rbx; |
3194 | 3257 const Register rax_callsite = rax; |
3195 // rax: CallSite object (f1) | 3258 |
3196 // rbx: unused (f2) | 3259 prepare_invoke(byte_no, rbx_method, rax_callsite); |
3197 // rcx: receiver address | 3260 |
3198 // rdx: flags (unused) | 3261 // rax: CallSite object (from f1) |
3199 | 3262 // rbx: MH.linkToCallSite method (from f2) |
3200 Register rax_callsite = rax; | 3263 |
3201 Register rcx_method_handle = rcx; | 3264 // Note: rax_callsite is already pushed by prepare_invoke |
3202 | 3265 |
3203 // %%% should make a type profile for any invokedynamic that takes a ref argument | 3266 // %%% should make a type profile for any invokedynamic that takes a ref argument |
3204 // profile this call | 3267 // profile this call |
3205 __ profile_call(r13); | 3268 __ profile_call(r13); |
3206 | 3269 |
3207 __ verify_oop(rax_callsite); | 3270 __ verify_oop(rax_callsite); |
3208 __ load_heap_oop(rcx_method_handle, Address(rax_callsite, __ delayed_value(java_lang_invoke_CallSite::target_offset_in_bytes, rdx))); | 3271 |
3209 __ null_check(rcx_method_handle); | 3272 __ jump_from_interpreted(rbx_method, rdx); |
3210 __ verify_oop(rcx_method_handle); | |
3211 __ prepare_to_jump_from_interpreted(); | |
3212 __ jump_to_method_handle_entry(rcx_method_handle, rdx); | |
3213 } | 3273 } |
3214 | 3274 |
3215 | 3275 |
3216 //----------------------------------------------------------------------------- | 3276 //----------------------------------------------------------------------------- |
3217 // Allocation | 3277 // Allocation |