Mercurial > hg > graal-jvmci-8
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 } |