1344 simple_move32(masm, tmp, length_arg); |
1344 simple_move32(masm, tmp, length_arg); |
1345 __ bind(done); |
1345 __ bind(done); |
1346 } |
1346 } |
1347 |
1347 |
1348 static void verify_oop_args(MacroAssembler* masm, |
1348 static void verify_oop_args(MacroAssembler* masm, |
1349 int total_args_passed, |
1349 methodHandle method, |
1350 const BasicType* sig_bt, |
1350 const BasicType* sig_bt, |
1351 const VMRegPair* regs) { |
1351 const VMRegPair* regs) { |
1352 Register temp_reg = rbx; // not part of any compiled calling seq |
1352 Register temp_reg = rbx; // not part of any compiled calling seq |
1353 if (VerifyOops) { |
1353 if (VerifyOops) { |
1354 for (int i = 0; i < total_args_passed; i++) { |
1354 for (int i = 0; i < method->size_of_parameters(); i++) { |
1355 if (sig_bt[i] == T_OBJECT || |
1355 if (sig_bt[i] == T_OBJECT || |
1356 sig_bt[i] == T_ARRAY) { |
1356 sig_bt[i] == T_ARRAY) { |
1357 VMReg r = regs[i].first(); |
1357 VMReg r = regs[i].first(); |
1358 assert(r->is_valid(), "bad oop arg"); |
1358 assert(r->is_valid(), "bad oop arg"); |
1359 if (r->is_stack()) { |
1359 if (r->is_stack()) { |
1366 } |
1366 } |
1367 } |
1367 } |
1368 } |
1368 } |
1369 |
1369 |
1370 static void gen_special_dispatch(MacroAssembler* masm, |
1370 static void gen_special_dispatch(MacroAssembler* masm, |
1371 int total_args_passed, |
1371 methodHandle method, |
1372 int comp_args_on_stack, |
|
1373 vmIntrinsics::ID special_dispatch, |
|
1374 const BasicType* sig_bt, |
1372 const BasicType* sig_bt, |
1375 const VMRegPair* regs) { |
1373 const VMRegPair* regs) { |
1376 verify_oop_args(masm, total_args_passed, sig_bt, regs); |
1374 verify_oop_args(masm, method, sig_bt, regs); |
|
1375 vmIntrinsics::ID iid = method->intrinsic_id(); |
1377 |
1376 |
1378 // Now write the args into the outgoing interpreter space |
1377 // Now write the args into the outgoing interpreter space |
1379 bool has_receiver = false; |
1378 bool has_receiver = false; |
1380 Register receiver_reg = noreg; |
1379 Register receiver_reg = noreg; |
1381 int member_arg_pos = -1; |
1380 int member_arg_pos = -1; |
1382 Register member_reg = noreg; |
1381 Register member_reg = noreg; |
1383 int ref_kind = MethodHandles::signature_polymorphic_intrinsic_ref_kind(special_dispatch); |
1382 int ref_kind = MethodHandles::signature_polymorphic_intrinsic_ref_kind(iid); |
1384 if (ref_kind != 0) { |
1383 if (ref_kind != 0) { |
1385 member_arg_pos = total_args_passed - 1; // trailing MemberName argument |
1384 member_arg_pos = method->size_of_parameters() - 1; // trailing MemberName argument |
1386 member_reg = rbx; // known to be free at this point |
1385 member_reg = rbx; // known to be free at this point |
1387 has_receiver = MethodHandles::ref_kind_has_receiver(ref_kind); |
1386 has_receiver = MethodHandles::ref_kind_has_receiver(ref_kind); |
1388 } else if (special_dispatch == vmIntrinsics::_invokeBasic) { |
1387 } else if (iid == vmIntrinsics::_invokeBasic) { |
1389 has_receiver = true; |
1388 has_receiver = true; |
1390 } else { |
1389 } else { |
1391 guarantee(false, err_msg("special_dispatch=%d", special_dispatch)); |
1390 fatal(err_msg_res("unexpected intrinsic id %d", iid)); |
1392 } |
1391 } |
1393 |
1392 |
1394 if (member_reg != noreg) { |
1393 if (member_reg != noreg) { |
1395 // Load the member_arg into register, if necessary. |
1394 // Load the member_arg into register, if necessary. |
1396 assert(member_arg_pos >= 0 && member_arg_pos < total_args_passed, "oob"); |
1395 SharedRuntime::check_member_name_argument_is_last_argument(method, sig_bt, regs); |
1397 assert(sig_bt[member_arg_pos] == T_OBJECT, "dispatch argument must be an object"); |
|
1398 VMReg r = regs[member_arg_pos].first(); |
1396 VMReg r = regs[member_arg_pos].first(); |
1399 assert(r->is_valid(), "bad member arg"); |
|
1400 if (r->is_stack()) { |
1397 if (r->is_stack()) { |
1401 __ movptr(member_reg, Address(rsp, r->reg2stack() * VMRegImpl::stack_slot_size + wordSize)); |
1398 __ movptr(member_reg, Address(rsp, r->reg2stack() * VMRegImpl::stack_slot_size + wordSize)); |
1402 } else { |
1399 } else { |
1403 // no data motion is needed |
1400 // no data motion is needed |
1404 member_reg = r->as_Register(); |
1401 member_reg = r->as_Register(); |
1405 } |
1402 } |
1406 } |
1403 } |
1407 |
1404 |
1408 if (has_receiver) { |
1405 if (has_receiver) { |
1409 // Make sure the receiver is loaded into a register. |
1406 // Make sure the receiver is loaded into a register. |
1410 assert(total_args_passed > 0, "oob"); |
1407 assert(method->size_of_parameters() > 0, "oob"); |
1411 assert(sig_bt[0] == T_OBJECT, "receiver argument must be an object"); |
1408 assert(sig_bt[0] == T_OBJECT, "receiver argument must be an object"); |
1412 VMReg r = regs[0].first(); |
1409 VMReg r = regs[0].first(); |
1413 assert(r->is_valid(), "bad receiver arg"); |
1410 assert(r->is_valid(), "bad receiver arg"); |
1414 if (r->is_stack()) { |
1411 if (r->is_stack()) { |
1415 // Porting note: This assumes that compiled calling conventions always |
1412 // Porting note: This assumes that compiled calling conventions always |
1416 // pass the receiver oop in a register. If this is not true on some |
1413 // pass the receiver oop in a register. If this is not true on some |
1417 // platform, pick a temp and load the receiver from stack. |
1414 // platform, pick a temp and load the receiver from stack. |
1418 assert(false, "receiver always in a register"); |
1415 fatal("receiver always in a register"); |
1419 receiver_reg = rcx; // known to be free at this point |
1416 receiver_reg = rcx; // known to be free at this point |
1420 __ movptr(receiver_reg, Address(rsp, r->reg2stack() * VMRegImpl::stack_slot_size + wordSize)); |
1417 __ movptr(receiver_reg, Address(rsp, r->reg2stack() * VMRegImpl::stack_slot_size + wordSize)); |
1421 } else { |
1418 } else { |
1422 // no data motion is needed |
1419 // no data motion is needed |
1423 receiver_reg = r->as_Register(); |
1420 receiver_reg = r->as_Register(); |
1424 } |
1421 } |
1425 } |
1422 } |
1426 |
1423 |
1427 // Figure out which address we are really jumping to: |
1424 // Figure out which address we are really jumping to: |
1428 MethodHandles::generate_method_handle_dispatch(masm, special_dispatch, |
1425 MethodHandles::generate_method_handle_dispatch(masm, iid, |
1429 receiver_reg, member_reg, /*for_compiler_entry:*/ true); |
1426 receiver_reg, member_reg, /*for_compiler_entry:*/ true); |
1430 } |
1427 } |
1431 |
1428 |
1432 // --------------------------------------------------------------------------- |
1429 // --------------------------------------------------------------------------- |
1433 // Generate a native wrapper for a given method. The method takes arguments |
1430 // Generate a native wrapper for a given method. The method takes arguments |
1459 // return to caller |
1456 // return to caller |
1460 // |
1457 // |
1461 nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm, |
1458 nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm, |
1462 methodHandle method, |
1459 methodHandle method, |
1463 int compile_id, |
1460 int compile_id, |
1464 int total_in_args, |
|
1465 int comp_args_on_stack, |
|
1466 BasicType* in_sig_bt, |
1461 BasicType* in_sig_bt, |
1467 VMRegPair* in_regs, |
1462 VMRegPair* in_regs, |
1468 BasicType ret_type) { |
1463 BasicType ret_type) { |
1469 if (method->is_method_handle_intrinsic()) { |
1464 if (method->is_method_handle_intrinsic()) { |
1470 vmIntrinsics::ID iid = method->intrinsic_id(); |
1465 vmIntrinsics::ID iid = method->intrinsic_id(); |
1471 intptr_t start = (intptr_t)__ pc(); |
1466 intptr_t start = (intptr_t)__ pc(); |
1472 int vep_offset = ((intptr_t)__ pc()) - start; |
1467 int vep_offset = ((intptr_t)__ pc()) - start; |
1473 gen_special_dispatch(masm, |
1468 gen_special_dispatch(masm, |
1474 total_in_args, |
1469 method, |
1475 comp_args_on_stack, |
|
1476 method->intrinsic_id(), |
|
1477 in_sig_bt, |
1470 in_sig_bt, |
1478 in_regs); |
1471 in_regs); |
1479 int frame_complete = ((intptr_t)__ pc()) - start; // not complete, period |
1472 int frame_complete = ((intptr_t)__ pc()) - start; // not complete, period |
1480 __ flush(); |
1473 __ flush(); |
1481 int stack_slots = SharedRuntime::out_preserve_stack_slots(); // no out slots at all, actually |
1474 int stack_slots = SharedRuntime::out_preserve_stack_slots(); // no out slots at all, actually |