Mercurial > hg > truffle
comparison src/cpu/x86/vm/methodHandles_x86.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 | a19c671188cb |
comparison
equal
deleted
inserted
replaced
3807:3fbb609d9e96 | 3808:341a57af9b0a |
---|---|
544 __ pop(temp); | 544 __ pop(temp); |
545 BLOCK_COMMENT("} verify_klass"); | 545 BLOCK_COMMENT("} verify_klass"); |
546 } | 546 } |
547 #endif //ASSERT | 547 #endif //ASSERT |
548 | 548 |
549 void MethodHandles::jump_from_method_handle(MacroAssembler* _masm, Register method, Register temp) { | |
550 if (JvmtiExport::can_post_interpreter_events()) { | |
551 Label run_compiled_code; | |
552 // JVMTI events, such as single-stepping, are implemented partly by avoiding running | |
553 // compiled code in threads for which the event is enabled. Check here for | |
554 // interp_only_mode if these events CAN be enabled. | |
555 #ifdef _LP64 | |
556 Register rthread = r15_thread; | |
557 #else | |
558 Register rthread = temp; | |
559 __ get_thread(rthread); | |
560 #endif | |
561 // interp_only is an int, on little endian it is sufficient to test the byte only | |
562 // Is a cmpl faster? | |
563 __ cmpb(Address(rthread, JavaThread::interp_only_mode_offset()), 0); | |
564 __ jccb(Assembler::zero, run_compiled_code); | |
565 __ jmp(Address(method, methodOopDesc::interpreter_entry_offset())); | |
566 __ bind(run_compiled_code); | |
567 } | |
568 __ jmp(Address(method, methodOopDesc::from_interpreted_offset())); | |
569 } | |
570 | |
549 // Code generation | 571 // Code generation |
550 address MethodHandles::generate_method_handle_interpreter_entry(MacroAssembler* _masm) { | 572 address MethodHandles::generate_method_handle_interpreter_entry(MacroAssembler* _masm) { |
551 // rbx: methodOop | 573 // rbx: methodOop |
552 // rcx: receiver method handle (must load from sp[MethodTypeForm.vmslots]) | 574 // rcx: receiver method handle (must load from sp[MethodTypeForm.vmslots]) |
553 // rsi/r13: sender SP (must preserve; see prepare_to_jump_from_interpreted) | 575 // rsi/r13: sender SP (must preserve; see prepare_to_jump_from_interpreted) |
1118 assert_different_registers(rarg0_code, rarg1_actual, rarg2_required, saved_last_sp); | 1140 assert_different_registers(rarg0_code, rarg1_actual, rarg2_required, saved_last_sp); |
1119 | 1141 |
1120 guarantee(java_lang_invoke_MethodHandle::vmentry_offset_in_bytes() != 0, "must have offsets"); | 1142 guarantee(java_lang_invoke_MethodHandle::vmentry_offset_in_bytes() != 0, "must have offsets"); |
1121 | 1143 |
1122 // some handy addresses | 1144 // some handy addresses |
1123 Address rbx_method_fie( rbx, methodOopDesc::from_interpreted_offset() ); | |
1124 Address rbx_method_fce( rbx, methodOopDesc::from_compiled_offset() ); | |
1125 | |
1126 Address rcx_mh_vmtarget( rcx_recv, java_lang_invoke_MethodHandle::vmtarget_offset_in_bytes() ); | 1145 Address rcx_mh_vmtarget( rcx_recv, java_lang_invoke_MethodHandle::vmtarget_offset_in_bytes() ); |
1127 Address rcx_dmh_vmindex( rcx_recv, java_lang_invoke_DirectMethodHandle::vmindex_offset_in_bytes() ); | 1146 Address rcx_dmh_vmindex( rcx_recv, java_lang_invoke_DirectMethodHandle::vmindex_offset_in_bytes() ); |
1128 | 1147 |
1129 Address rcx_bmh_vmargslot( rcx_recv, java_lang_invoke_BoundMethodHandle::vmargslot_offset_in_bytes() ); | 1148 Address rcx_bmh_vmargslot( rcx_recv, java_lang_invoke_BoundMethodHandle::vmargslot_offset_in_bytes() ); |
1130 Address rcx_bmh_argument( rcx_recv, java_lang_invoke_BoundMethodHandle::argument_offset_in_bytes() ); | 1149 Address rcx_bmh_argument( rcx_recv, java_lang_invoke_BoundMethodHandle::argument_offset_in_bytes() ); |
1161 // exception. Since we use the compiled entry, arguments are | 1180 // exception. Since we use the compiled entry, arguments are |
1162 // expected in compiler argument registers. | 1181 // expected in compiler argument registers. |
1163 assert(raise_exception_method(), "must be set"); | 1182 assert(raise_exception_method(), "must be set"); |
1164 assert(raise_exception_method()->from_compiled_entry(), "method must be linked"); | 1183 assert(raise_exception_method()->from_compiled_entry(), "method must be linked"); |
1165 | 1184 |
1166 const Register rdi_pc = rax; | 1185 const Register rax_pc = rax; |
1167 __ pop(rdi_pc); // caller PC | 1186 __ pop(rax_pc); // caller PC |
1168 __ mov(rsp, saved_last_sp); // cut the stack back to where the caller started | 1187 __ mov(rsp, saved_last_sp); // cut the stack back to where the caller started |
1169 | 1188 |
1170 Register rbx_method = rbx_temp; | 1189 Register rbx_method = rbx_temp; |
1171 __ movptr(rbx_method, ExternalAddress((address) &_raise_exception_method)); | 1190 __ movptr(rbx_method, ExternalAddress((address) &_raise_exception_method)); |
1172 | 1191 |
1173 const int jobject_oop_offset = 0; | 1192 const int jobject_oop_offset = 0; |
1174 __ movptr(rbx_method, Address(rbx_method, jobject_oop_offset)); // dereference the jobject | 1193 __ movptr(rbx_method, Address(rbx_method, jobject_oop_offset)); // dereference the jobject |
1175 __ verify_oop(rbx_method); | 1194 |
1176 | 1195 __ movptr(rsi, rsp); |
1177 NOT_LP64(__ push(rarg2_required)); | 1196 __ subptr(rsp, 3 * wordSize); |
1178 __ push(rdi_pc); // restore caller PC | 1197 __ push(rax_pc); // restore caller PC |
1179 __ jmp(rbx_method_fce); // jump to compiled entry | 1198 |
1199 __ movptr(__ argument_address(constant(2)), rarg0_code); | |
1200 __ movptr(__ argument_address(constant(1)), rarg1_actual); | |
1201 __ movptr(__ argument_address(constant(0)), rarg2_required); | |
1202 jump_from_method_handle(_masm, rbx_method, rax); | |
1180 } | 1203 } |
1181 break; | 1204 break; |
1182 | 1205 |
1183 case _invokestatic_mh: | 1206 case _invokestatic_mh: |
1184 case _invokespecial_mh: | 1207 case _invokespecial_mh: |
1193 __ load_method_handle_vmslots(rax_argslot, rcx_recv, rdx_temp); | 1216 __ load_method_handle_vmslots(rax_argslot, rcx_recv, rdx_temp); |
1194 __ movptr(rcx_recv, __ argument_address(rax_argslot, -1)); | 1217 __ movptr(rcx_recv, __ argument_address(rax_argslot, -1)); |
1195 __ null_check(rcx_recv); | 1218 __ null_check(rcx_recv); |
1196 __ verify_oop(rcx_recv); | 1219 __ verify_oop(rcx_recv); |
1197 } | 1220 } |
1198 __ jmp(rbx_method_fie); | 1221 jump_from_method_handle(_masm, rbx_method, rax); |
1199 } | 1222 } |
1200 break; | 1223 break; |
1201 | 1224 |
1202 case _invokevirtual_mh: | 1225 case _invokevirtual_mh: |
1203 { | 1226 { |
1226 base + vtableEntry::method_offset_in_bytes()); | 1249 base + vtableEntry::method_offset_in_bytes()); |
1227 Register rbx_method = rbx_temp; | 1250 Register rbx_method = rbx_temp; |
1228 __ movptr(rbx_method, vtable_entry_addr); | 1251 __ movptr(rbx_method, vtable_entry_addr); |
1229 | 1252 |
1230 __ verify_oop(rbx_method); | 1253 __ verify_oop(rbx_method); |
1231 __ jmp(rbx_method_fie); | 1254 jump_from_method_handle(_masm, rbx_method, rax); |
1232 } | 1255 } |
1233 break; | 1256 break; |
1234 | 1257 |
1235 case _invokeinterface_mh: | 1258 case _invokeinterface_mh: |
1236 { | 1259 { |
1261 rbx_index, rbx_method, | 1284 rbx_index, rbx_method, |
1262 rdi_temp, | 1285 rdi_temp, |
1263 no_such_interface); | 1286 no_such_interface); |
1264 | 1287 |
1265 __ verify_oop(rbx_method); | 1288 __ verify_oop(rbx_method); |
1266 __ jmp(rbx_method_fie); | 1289 jump_from_method_handle(_masm, rbx_method, rax); |
1267 __ hlt(); | 1290 __ hlt(); |
1268 | 1291 |
1269 __ bind(no_such_interface); | 1292 __ bind(no_such_interface); |
1270 // Throw an exception. | 1293 // Throw an exception. |
1271 // For historical reasons, it will be IncompatibleClassChangeError. | 1294 // For historical reasons, it will be IncompatibleClassChangeError. |
1309 | 1332 |
1310 if (direct_to_method) { | 1333 if (direct_to_method) { |
1311 Register rbx_method = rbx_temp; | 1334 Register rbx_method = rbx_temp; |
1312 __ load_heap_oop(rbx_method, rcx_mh_vmtarget); | 1335 __ load_heap_oop(rbx_method, rcx_mh_vmtarget); |
1313 __ verify_oop(rbx_method); | 1336 __ verify_oop(rbx_method); |
1314 __ jmp(rbx_method_fie); | 1337 jump_from_method_handle(_masm, rbx_method, rax); |
1315 } else { | 1338 } else { |
1316 __ load_heap_oop(rcx_recv, rcx_mh_vmtarget); | 1339 __ load_heap_oop(rcx_recv, rcx_mh_vmtarget); |
1317 __ verify_oop(rcx_recv); | 1340 __ verify_oop(rcx_recv); |
1318 __ jump_to_method_handle_entry(rcx_recv, rdx_temp); | 1341 __ jump_to_method_handle_entry(rcx_recv, rdx_temp); |
1319 } | 1342 } |