Mercurial > hg > graal-jvmci-8
comparison src/share/vm/interpreter/bytecodeInterpreter.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 | f08d439fab8c |
children | da91efe96a93 |
comparison
equal
deleted
inserted
replaced
6241:aba91a731143 | 6266:1d7922586cf6 |
---|---|
1772 } | 1772 } |
1773 #endif /* VM_JVMTI */ | 1773 #endif /* VM_JVMTI */ |
1774 | 1774 |
1775 oop obj; | 1775 oop obj; |
1776 if ((Bytecodes::Code)opcode == Bytecodes::_getstatic) { | 1776 if ((Bytecodes::Code)opcode == Bytecodes::_getstatic) { |
1777 obj = (oop) cache->f1(); | 1777 obj = (oop) cache->f1_as_instance(); |
1778 MORE_STACK(1); // Assume single slot push | 1778 MORE_STACK(1); // Assume single slot push |
1779 } else { | 1779 } else { |
1780 obj = (oop) STACK_OBJECT(-1); | 1780 obj = (oop) STACK_OBJECT(-1); |
1781 CHECK_NULL(obj); | 1781 CHECK_NULL(obj); |
1782 } | 1782 } |
1783 | 1783 |
1784 // | 1784 // |
1785 // Now store the result on the stack | 1785 // Now store the result on the stack |
1786 // | 1786 // |
1787 TosState tos_type = cache->flag_state(); | 1787 TosState tos_type = cache->flag_state(); |
1788 int field_offset = cache->f2(); | 1788 int field_offset = cache->f2_as_index(); |
1789 if (cache->is_volatile()) { | 1789 if (cache->is_volatile()) { |
1790 if (tos_type == atos) { | 1790 if (tos_type == atos) { |
1791 VERIFY_OOP(obj->obj_field_acquire(field_offset)); | 1791 VERIFY_OOP(obj->obj_field_acquire(field_offset)); |
1792 SET_STACK_OBJECT(obj->obj_field_acquire(field_offset), -1); | 1792 SET_STACK_OBJECT(obj->obj_field_acquire(field_offset), -1); |
1793 } else if (tos_type == itos) { | 1793 } else if (tos_type == itos) { |
1883 count = -1; | 1883 count = -1; |
1884 if (tos_type == ltos || tos_type == dtos) { | 1884 if (tos_type == ltos || tos_type == dtos) { |
1885 --count; | 1885 --count; |
1886 } | 1886 } |
1887 if ((Bytecodes::Code)opcode == Bytecodes::_putstatic) { | 1887 if ((Bytecodes::Code)opcode == Bytecodes::_putstatic) { |
1888 obj = (oop) cache->f1(); | 1888 obj = (oop) cache->f1_as_instance(); |
1889 } else { | 1889 } else { |
1890 --count; | 1890 --count; |
1891 obj = (oop) STACK_OBJECT(count); | 1891 obj = (oop) STACK_OBJECT(count); |
1892 CHECK_NULL(obj); | 1892 CHECK_NULL(obj); |
1893 } | 1893 } |
1894 | 1894 |
1895 // | 1895 // |
1896 // Now store the result | 1896 // Now store the result |
1897 // | 1897 // |
1898 int field_offset = cache->f2(); | 1898 int field_offset = cache->f2_as_index(); |
1899 if (cache->is_volatile()) { | 1899 if (cache->is_volatile()) { |
1900 if (tos_type == itos) { | 1900 if (tos_type == itos) { |
1901 obj->release_int_field_put(field_offset, STACK_INT(-1)); | 1901 obj->release_int_field_put(field_offset, STACK_INT(-1)); |
1902 } else if (tos_type == atos) { | 1902 } else if (tos_type == atos) { |
1903 VERIFY_OOP(STACK_OBJECT(-1)); | 1903 VERIFY_OOP(STACK_OBJECT(-1)); |
2175 | 2175 |
2176 // We are resolved if the f1 field contains a non-null object (CallSite, etc.) | 2176 // We are resolved if the f1 field contains a non-null object (CallSite, etc.) |
2177 // This kind of CP cache entry does not need to match the flags byte, because | 2177 // This kind of CP cache entry does not need to match the flags byte, because |
2178 // there is a 1-1 relation between bytecode type and CP entry type. | 2178 // there is a 1-1 relation between bytecode type and CP entry type. |
2179 ConstantPoolCacheEntry* cache = cp->entry_at(index); | 2179 ConstantPoolCacheEntry* cache = cp->entry_at(index); |
2180 if (cache->is_f1_null()) { | 2180 oop result = cache->f1_as_instance(); |
2181 if (result == NULL) { | |
2181 CALL_VM(InterpreterRuntime::resolve_ldc(THREAD, (Bytecodes::Code) opcode), | 2182 CALL_VM(InterpreterRuntime::resolve_ldc(THREAD, (Bytecodes::Code) opcode), |
2182 handle_exception); | 2183 handle_exception); |
2184 result = cache->f1_as_instance(); | |
2183 } | 2185 } |
2184 | 2186 |
2185 VERIFY_OOP(cache->f1()); | 2187 VERIFY_OOP(result); |
2186 SET_STACK_OBJECT(cache->f1(), 0); | 2188 SET_STACK_OBJECT(result, 0); |
2187 UPDATE_PC_AND_TOS_AND_CONTINUE(incr, 1); | 2189 UPDATE_PC_AND_TOS_AND_CONTINUE(incr, 1); |
2188 } | 2190 } |
2189 | 2191 |
2190 CASE(_invokedynamic): { | 2192 CASE(_invokedynamic): { |
2191 if (!EnableInvokeDynamic) { | 2193 if (!EnableInvokeDynamic) { |
2202 // We are resolved if the f1 field contains a non-null object (CallSite, etc.) | 2204 // We are resolved if the f1 field contains a non-null object (CallSite, etc.) |
2203 // This kind of CP cache entry does not need to match the flags byte, because | 2205 // This kind of CP cache entry does not need to match the flags byte, because |
2204 // there is a 1-1 relation between bytecode type and CP entry type. | 2206 // there is a 1-1 relation between bytecode type and CP entry type. |
2205 assert(constantPoolCacheOopDesc::is_secondary_index(index), "incorrect format"); | 2207 assert(constantPoolCacheOopDesc::is_secondary_index(index), "incorrect format"); |
2206 ConstantPoolCacheEntry* cache = cp->secondary_entry_at(index); | 2208 ConstantPoolCacheEntry* cache = cp->secondary_entry_at(index); |
2207 if (cache->is_f1_null()) { | 2209 oop result = cache->f1_as_instance(); |
2210 if (result == NULL) { | |
2208 CALL_VM(InterpreterRuntime::resolve_invokedynamic(THREAD), | 2211 CALL_VM(InterpreterRuntime::resolve_invokedynamic(THREAD), |
2209 handle_exception); | 2212 handle_exception); |
2213 result = cache->f1_as_instance(); | |
2210 } | 2214 } |
2211 | 2215 |
2212 VERIFY_OOP(cache->f1()); | 2216 VERIFY_OOP(result); |
2213 oop method_handle = java_lang_invoke_CallSite::target(cache->f1()); | 2217 oop method_handle = java_lang_invoke_CallSite::target(result); |
2214 CHECK_NULL(method_handle); | 2218 CHECK_NULL(method_handle); |
2215 | 2219 |
2216 istate->set_msg(call_method_handle); | 2220 istate->set_msg(call_method_handle); |
2217 istate->set_callee((methodOop) method_handle); | 2221 istate->set_callee((methodOop) method_handle); |
2218 istate->set_bcp_advance(5); | 2222 istate->set_bcp_advance(5); |
2237 | 2241 |
2238 // Special case of invokeinterface called for virtual method of | 2242 // Special case of invokeinterface called for virtual method of |
2239 // java.lang.Object. See cpCacheOop.cpp for details. | 2243 // java.lang.Object. See cpCacheOop.cpp for details. |
2240 // This code isn't produced by javac, but could be produced by | 2244 // This code isn't produced by javac, but could be produced by |
2241 // another compliant java compiler. | 2245 // another compliant java compiler. |
2242 if (cache->is_methodInterface()) { | 2246 if (cache->is_forced_virtual()) { |
2243 methodOop callee; | 2247 methodOop callee; |
2244 CHECK_NULL(STACK_OBJECT(-(cache->parameter_size()))); | 2248 CHECK_NULL(STACK_OBJECT(-(cache->parameter_size()))); |
2245 if (cache->is_vfinal()) { | 2249 if (cache->is_vfinal()) { |
2246 callee = (methodOop) cache->f2(); | 2250 callee = cache->f2_as_vfinal_method(); |
2247 } else { | 2251 } else { |
2248 // get receiver | 2252 // get receiver |
2249 int parms = cache->parameter_size(); | 2253 int parms = cache->parameter_size(); |
2250 // Same comments as invokevirtual apply here | 2254 // Same comments as invokevirtual apply here |
2251 VERIFY_OOP(STACK_OBJECT(-parms)); | 2255 VERIFY_OOP(STACK_OBJECT(-parms)); |
2252 instanceKlass* rcvrKlass = (instanceKlass*) | 2256 instanceKlass* rcvrKlass = (instanceKlass*) |
2253 STACK_OBJECT(-parms)->klass()->klass_part(); | 2257 STACK_OBJECT(-parms)->klass()->klass_part(); |
2254 callee = (methodOop) rcvrKlass->start_of_vtable()[ cache->f2()]; | 2258 callee = (methodOop) rcvrKlass->start_of_vtable()[ cache->f2_as_index()]; |
2255 } | 2259 } |
2256 istate->set_callee(callee); | 2260 istate->set_callee(callee); |
2257 istate->set_callee_entry_point(callee->from_interpreted_entry()); | 2261 istate->set_callee_entry_point(callee->from_interpreted_entry()); |
2258 #ifdef VM_JVMTI | 2262 #ifdef VM_JVMTI |
2259 if (JvmtiExport::can_post_interpreter_events() && THREAD->is_interp_only_mode()) { | 2263 if (JvmtiExport::can_post_interpreter_events() && THREAD->is_interp_only_mode()) { |
2264 UPDATE_PC_AND_RETURN(0); // I'll be back... | 2268 UPDATE_PC_AND_RETURN(0); // I'll be back... |
2265 } | 2269 } |
2266 | 2270 |
2267 // this could definitely be cleaned up QQQ | 2271 // this could definitely be cleaned up QQQ |
2268 methodOop callee; | 2272 methodOop callee; |
2269 klassOop iclass = (klassOop)cache->f1(); | 2273 klassOop iclass = cache->f1_as_klass(); |
2270 // instanceKlass* interface = (instanceKlass*) iclass->klass_part(); | 2274 // instanceKlass* interface = (instanceKlass*) iclass->klass_part(); |
2271 // get receiver | 2275 // get receiver |
2272 int parms = cache->parameter_size(); | 2276 int parms = cache->parameter_size(); |
2273 oop rcvr = STACK_OBJECT(-parms); | 2277 oop rcvr = STACK_OBJECT(-parms); |
2274 CHECK_NULL(rcvr); | 2278 CHECK_NULL(rcvr); |
2282 // interface. The link resolver checks this but only for the first | 2286 // interface. The link resolver checks this but only for the first |
2283 // time this interface is called. | 2287 // time this interface is called. |
2284 if (i == int2->itable_length()) { | 2288 if (i == int2->itable_length()) { |
2285 VM_JAVA_ERROR(vmSymbols::java_lang_IncompatibleClassChangeError(), ""); | 2289 VM_JAVA_ERROR(vmSymbols::java_lang_IncompatibleClassChangeError(), ""); |
2286 } | 2290 } |
2287 int mindex = cache->f2(); | 2291 int mindex = cache->f2_as_index(); |
2288 itableMethodEntry* im = ki->first_method_entry(rcvr->klass()); | 2292 itableMethodEntry* im = ki->first_method_entry(rcvr->klass()); |
2289 callee = im[mindex].method(); | 2293 callee = im[mindex].method(); |
2290 if (callee == NULL) { | 2294 if (callee == NULL) { |
2291 VM_JAVA_ERROR(vmSymbols::java_lang_AbstractMethodError(), ""); | 2295 VM_JAVA_ERROR(vmSymbols::java_lang_AbstractMethodError(), ""); |
2292 } | 2296 } |
2320 istate->set_msg(call_method); | 2324 istate->set_msg(call_method); |
2321 { | 2325 { |
2322 methodOop callee; | 2326 methodOop callee; |
2323 if ((Bytecodes::Code)opcode == Bytecodes::_invokevirtual) { | 2327 if ((Bytecodes::Code)opcode == Bytecodes::_invokevirtual) { |
2324 CHECK_NULL(STACK_OBJECT(-(cache->parameter_size()))); | 2328 CHECK_NULL(STACK_OBJECT(-(cache->parameter_size()))); |
2325 if (cache->is_vfinal()) callee = (methodOop) cache->f2(); | 2329 if (cache->is_vfinal()) callee = cache->f2_as_vfinal_method(); |
2326 else { | 2330 else { |
2327 // get receiver | 2331 // get receiver |
2328 int parms = cache->parameter_size(); | 2332 int parms = cache->parameter_size(); |
2329 // this works but needs a resourcemark and seems to create a vtable on every call: | 2333 // this works but needs a resourcemark and seems to create a vtable on every call: |
2330 // methodOop callee = rcvr->klass()->klass_part()->vtable()->method_at(cache->f2()); | 2334 // methodOop callee = rcvr->klass()->klass_part()->vtable()->method_at(cache->f2_as_index()); |
2331 // | 2335 // |
2332 // this fails with an assert | 2336 // this fails with an assert |
2333 // instanceKlass* rcvrKlass = instanceKlass::cast(STACK_OBJECT(-parms)->klass()); | 2337 // instanceKlass* rcvrKlass = instanceKlass::cast(STACK_OBJECT(-parms)->klass()); |
2334 // but this works | 2338 // but this works |
2335 VERIFY_OOP(STACK_OBJECT(-parms)); | 2339 VERIFY_OOP(STACK_OBJECT(-parms)); |
2348 but using instanceKlass::cast(STACK_OBJECT(-parms)->klass()) causes in assertion failure | 2352 but using instanceKlass::cast(STACK_OBJECT(-parms)->klass()) causes in assertion failure |
2349 because rcvr->klass()->klass_part()->oop_is_instance() == 0 | 2353 because rcvr->klass()->klass_part()->oop_is_instance() == 0 |
2350 However it seems to have a vtable in the right location. Huh? | 2354 However it seems to have a vtable in the right location. Huh? |
2351 | 2355 |
2352 */ | 2356 */ |
2353 callee = (methodOop) rcvrKlass->start_of_vtable()[ cache->f2()]; | 2357 callee = (methodOop) rcvrKlass->start_of_vtable()[ cache->f2_as_index()]; |
2354 } | 2358 } |
2355 } else { | 2359 } else { |
2356 if ((Bytecodes::Code)opcode == Bytecodes::_invokespecial) { | 2360 if ((Bytecodes::Code)opcode == Bytecodes::_invokespecial) { |
2357 CHECK_NULL(STACK_OBJECT(-(cache->parameter_size()))); | 2361 CHECK_NULL(STACK_OBJECT(-(cache->parameter_size()))); |
2358 } | 2362 } |
2359 callee = (methodOop) cache->f1(); | 2363 callee = cache->f1_as_method(); |
2360 } | 2364 } |
2361 | 2365 |
2362 istate->set_callee(callee); | 2366 istate->set_callee(callee); |
2363 istate->set_callee_entry_point(callee->from_interpreted_entry()); | 2367 istate->set_callee_entry_point(callee->from_interpreted_entry()); |
2364 #ifdef VM_JVMTI | 2368 #ifdef VM_JVMTI |