comparison src/cpu/sparc/vm/methodHandles_sparc.cpp @ 3808:341a57af9b0a

6990212: JSR 292 JVMTI MethodEnter hook is not called for JSR 292 bootstrap and target methods Summary: check for single stepping when dispatching invokes from method handles Reviewed-by: coleenp, twisti, kvn, dsamersoff
author never
date Fri, 15 Jul 2011 15:35:50 -0700
parents d83ac25d0304
children 3d42f82cd811
comparison
equal deleted inserted replaced
3807:3fbb609d9e96 3808:341a57af9b0a
522 __ BIND(L_ok); 522 __ BIND(L_ok);
523 BLOCK_COMMENT("} verify_klass"); 523 BLOCK_COMMENT("} verify_klass");
524 } 524 }
525 #endif // ASSERT 525 #endif // ASSERT
526 526
527
528 void MethodHandles::jump_from_method_handle(MacroAssembler* _masm, Register method, Register target, Register temp) {
529 assert(method == G5_method, "interpreter calling convention");
530 __ verify_oop(method);
531 __ ld_ptr(G5_method, in_bytes(methodOopDesc::from_interpreted_offset()), target);
532 if (JvmtiExport::can_post_interpreter_events()) {
533 // JVMTI events, such as single-stepping, are implemented partly by avoiding running
534 // compiled code in threads for which the event is enabled. Check here for
535 // interp_only_mode if these events CAN be enabled.
536 __ verify_thread();
537 Label skip_compiled_code;
538
539 const Address interp_only(G2_thread, JavaThread::interp_only_mode_offset());
540 __ ld(interp_only, temp);
541 __ tst(temp);
542 __ br(Assembler::notZero, true, Assembler::pn, skip_compiled_code);
543 __ delayed()->ld_ptr(G5_method, in_bytes(methodOopDesc::interpreter_entry_offset()), target);
544 __ bind(skip_compiled_code);
545 }
546 __ jmp(target, 0);
547 __ delayed()->nop();
548 }
549
550
527 // Code generation 551 // Code generation
528 address MethodHandles::generate_method_handle_interpreter_entry(MacroAssembler* _masm) { 552 address MethodHandles::generate_method_handle_interpreter_entry(MacroAssembler* _masm) {
529 // I5_savedSP/O5_savedSP: sender SP (must preserve) 553 // I5_savedSP/O5_savedSP: sender SP (must preserve)
530 // G4 (Gargs): incoming argument list (must preserve) 554 // G4 (Gargs): incoming argument list (must preserve)
531 // G5_method: invoke methodOop 555 // G5_method: invoke methodOop
1103 const Register O2_required = O2; 1127 const Register O2_required = O2;
1104 1128
1105 guarantee(java_lang_invoke_MethodHandle::vmentry_offset_in_bytes() != 0, "must have offsets"); 1129 guarantee(java_lang_invoke_MethodHandle::vmentry_offset_in_bytes() != 0, "must have offsets");
1106 1130
1107 // Some handy addresses: 1131 // Some handy addresses:
1108 Address G5_method_fie( G5_method, in_bytes(methodOopDesc::from_interpreted_offset()));
1109 Address G5_method_fce( G5_method, in_bytes(methodOopDesc::from_compiled_offset()));
1110
1111 Address G3_mh_vmtarget( G3_method_handle, java_lang_invoke_MethodHandle::vmtarget_offset_in_bytes()); 1132 Address G3_mh_vmtarget( G3_method_handle, java_lang_invoke_MethodHandle::vmtarget_offset_in_bytes());
1112 1133
1113 Address G3_dmh_vmindex( G3_method_handle, java_lang_invoke_DirectMethodHandle::vmindex_offset_in_bytes()); 1134 Address G3_dmh_vmindex( G3_method_handle, java_lang_invoke_DirectMethodHandle::vmindex_offset_in_bytes());
1114 1135
1115 Address G3_bmh_vmargslot( G3_method_handle, java_lang_invoke_BoundMethodHandle::vmargslot_offset_in_bytes()); 1136 Address G3_bmh_vmargslot( G3_method_handle, java_lang_invoke_BoundMethodHandle::vmargslot_offset_in_bytes());
1134 1155
1135 switch ((int) ek) { 1156 switch ((int) ek) {
1136 case _raise_exception: 1157 case _raise_exception:
1137 { 1158 {
1138 // Not a real MH entry, but rather shared code for raising an 1159 // Not a real MH entry, but rather shared code for raising an
1139 // exception. Since we use the compiled entry, arguments are 1160 // exception. For sharing purposes the arguments are passed into registers
1140 // expected in compiler argument registers. 1161 // and then placed in the intepreter calling convention here.
1141 assert(raise_exception_method(), "must be set"); 1162 assert(raise_exception_method(), "must be set");
1142 assert(raise_exception_method()->from_compiled_entry(), "method must be linked"); 1163 assert(raise_exception_method()->from_compiled_entry(), "method must be linked");
1143 1164
1144 __ mov(O5_savedSP, SP); // Cut the stack back to where the caller started.
1145
1146 Label L_no_method;
1147 // FIXME: fill in _raise_exception_method with a suitable java.lang.invoke method
1148 __ set(AddressLiteral((address) &_raise_exception_method), G5_method); 1165 __ set(AddressLiteral((address) &_raise_exception_method), G5_method);
1149 __ ld_ptr(Address(G5_method, 0), G5_method); 1166 __ ld_ptr(Address(G5_method, 0), G5_method);
1150 1167
1151 const int jobject_oop_offset = 0; 1168 const int jobject_oop_offset = 0;
1152 __ ld_ptr(Address(G5_method, jobject_oop_offset), G5_method); 1169 __ ld_ptr(Address(G5_method, jobject_oop_offset), G5_method);
1153 1170
1154 __ verify_oop(G5_method); 1171 adjust_SP_and_Gargs_down_by_slots(_masm, 3, noreg, noreg);
1155 __ jump_indirect_to(G5_method_fce, O3_scratch); // jump to compiled entry 1172
1156 __ delayed()->nop(); 1173 __ st_ptr(O0_code, __ argument_address(constant(2), noreg, 0));
1174 __ st_ptr(O1_actual, __ argument_address(constant(1), noreg, 0));
1175 __ st_ptr(O2_required, __ argument_address(constant(0), noreg, 0));
1176 jump_from_method_handle(_masm, G5_method, O1_scratch, O2_scratch);
1157 } 1177 }
1158 break; 1178 break;
1159 1179
1160 case _invokestatic_mh: 1180 case _invokestatic_mh:
1161 case _invokespecial_mh: 1181 case _invokespecial_mh:
1162 { 1182 {
1163 __ load_heap_oop(G3_mh_vmtarget, G5_method); // target is a methodOop 1183 __ load_heap_oop(G3_mh_vmtarget, G5_method); // target is a methodOop
1164 __ verify_oop(G5_method);
1165 // Same as TemplateTable::invokestatic or invokespecial, 1184 // Same as TemplateTable::invokestatic or invokespecial,
1166 // minus the CP setup and profiling: 1185 // minus the CP setup and profiling:
1167 if (ek == _invokespecial_mh) { 1186 if (ek == _invokespecial_mh) {
1168 // Must load & check the first argument before entering the target method. 1187 // Must load & check the first argument before entering the target method.
1169 __ load_method_handle_vmslots(O0_argslot, G3_method_handle, O1_scratch); 1188 __ load_method_handle_vmslots(O0_argslot, G3_method_handle, O1_scratch);
1170 __ ld_ptr(__ argument_address(O0_argslot, O0_argslot, -1), G3_method_handle); 1189 __ ld_ptr(__ argument_address(O0_argslot, O0_argslot, -1), G3_method_handle);
1171 __ null_check(G3_method_handle); 1190 __ null_check(G3_method_handle);
1172 __ verify_oop(G3_method_handle); 1191 __ verify_oop(G3_method_handle);
1173 } 1192 }
1174 __ jump_indirect_to(G5_method_fie, O1_scratch); 1193 jump_from_method_handle(_masm, G5_method, O1_scratch, O2_scratch);
1175 __ delayed()->nop();
1176 } 1194 }
1177 break; 1195 break;
1178 1196
1179 case _invokevirtual_mh: 1197 case _invokevirtual_mh:
1180 { 1198 {
1202 __ sll_ptr(O2_index, LogBytesPerWord, O2_index); 1220 __ sll_ptr(O2_index, LogBytesPerWord, O2_index);
1203 __ add(O0_klass, O2_index, O0_klass); 1221 __ add(O0_klass, O2_index, O0_klass);
1204 Address vtable_entry_addr(O0_klass, base + vtableEntry::method_offset_in_bytes()); 1222 Address vtable_entry_addr(O0_klass, base + vtableEntry::method_offset_in_bytes());
1205 __ ld_ptr(vtable_entry_addr, G5_method); 1223 __ ld_ptr(vtable_entry_addr, G5_method);
1206 1224
1207 __ verify_oop(G5_method); 1225 jump_from_method_handle(_masm, G5_method, O1_scratch, O2_scratch);
1208 __ jump_indirect_to(G5_method_fie, O1_scratch);
1209 __ delayed()->nop();
1210 } 1226 }
1211 break; 1227 break;
1212 1228
1213 case _invokeinterface_mh: 1229 case _invokeinterface_mh:
1214 { 1230 {
1235 G5_index, G5_method, 1251 G5_index, G5_method,
1236 O2_scratch, 1252 O2_scratch,
1237 O3_scratch, 1253 O3_scratch,
1238 no_such_interface); 1254 no_such_interface);
1239 1255
1240 __ verify_oop(G5_method); 1256 jump_from_method_handle(_masm, G5_method, O1_scratch, O2_scratch);
1241 __ jump_indirect_to(G5_method_fie, O1_scratch);
1242 __ delayed()->nop();
1243 1257
1244 __ bind(no_such_interface); 1258 __ bind(no_such_interface);
1245 // Throw an exception. 1259 // Throw an exception.
1246 // For historical reasons, it will be IncompatibleClassChangeError. 1260 // For historical reasons, it will be IncompatibleClassChangeError.
1247 __ unimplemented("not tested yet"); 1261 __ unimplemented("not tested yet");
1281 O2_scratch); // must be an even register for !_LP64 long moves (uses O2/O3) 1295 O2_scratch); // must be an even register for !_LP64 long moves (uses O2/O3)
1282 } 1296 }
1283 1297
1284 if (direct_to_method) { 1298 if (direct_to_method) {
1285 __ load_heap_oop(G3_mh_vmtarget, G5_method); // target is a methodOop 1299 __ load_heap_oop(G3_mh_vmtarget, G5_method); // target is a methodOop
1286 __ verify_oop(G5_method); 1300 jump_from_method_handle(_masm, G5_method, O1_scratch, O2_scratch);
1287 __ jump_indirect_to(G5_method_fie, O1_scratch);
1288 __ delayed()->nop();
1289 } else { 1301 } else {
1290 __ load_heap_oop(G3_mh_vmtarget, G3_method_handle); // target is a methodOop 1302 __ load_heap_oop(G3_mh_vmtarget, G3_method_handle); // target is a methodOop
1291 __ verify_oop(G3_method_handle); 1303 __ verify_oop(G3_method_handle);
1292 __ jump_to_method_handle_entry(G3_method_handle, O1_scratch); 1304 __ jump_to_method_handle_entry(G3_method_handle, O1_scratch);
1293 } 1305 }