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 }