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