hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp
changeset 13881 a326d528f3e1
parent 13742 9180987e305d
child 13883 6979b9850feb
equal deleted inserted replaced
13751:7fd047780d47 13881:a326d528f3e1
  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
  1504   // on entry to the wrapper. We need to convert these args to where
  1497   // on entry to the wrapper. We need to convert these args to where
  1505   // the jni function will expect them. To figure out where they go
  1498   // the jni function will expect them. To figure out where they go
  1506   // we convert the java signature to a C signature by inserting
  1499   // we convert the java signature to a C signature by inserting
  1507   // the hidden arguments as arg[0] and possibly arg[1] (static method)
  1500   // the hidden arguments as arg[0] and possibly arg[1] (static method)
  1508 
  1501 
       
  1502   const int total_in_args = method->size_of_parameters();
  1509   int total_c_args = total_in_args;
  1503   int total_c_args = total_in_args;
  1510   if (!is_critical_native) {
  1504   if (!is_critical_native) {
  1511     total_c_args += 1;
  1505     total_c_args += 1;
  1512     if (method->is_static()) {
  1506     if (method->is_static()) {
  1513       total_c_args++;
  1507       total_c_args++;