< prev index next >

src/cpu/ppc/vm/sharedRuntime_ppc.cpp

Print this page
rev 8611 : 8086069: Adapt runtime calls to recent intrinsics to pass ints as long
Summary: Remove CCallingConventionRequiresIntsAsLongs from shared code and push functionality to native wrapper. Less optimal but more flexible.

@@ -729,27 +729,12 @@
     case T_CHAR:
     case T_BYTE:
     case T_SHORT:
     case T_INT:
       // We must cast ints to longs and use full 64 bit stack slots
-      // here. We do the cast in GraphKit::gen_stub() and just guard
-      // here against loosing that change.
-      assert(CCallingConventionRequiresIntsAsLongs,
-             "argument of type int should be promoted to type long");
-      guarantee(i > 0 && sig_bt[i-1] == T_LONG,
-                "argument of type (bt) should have been promoted to type (T_LONG,bt) for bt in "
-                "{T_BOOLEAN, T_CHAR, T_BYTE, T_SHORT, T_INT}");
-      // Do not count halves.
-      regs[i].set_bad();
-      --arg;
-      break;
+      // here.  Thus fall through, handle as long.
     case T_LONG:
-      guarantee(sig_bt[i+1] == T_VOID    ||
-                sig_bt[i+1] == T_BOOLEAN || sig_bt[i+1] == T_CHAR  ||
-                sig_bt[i+1] == T_BYTE    || sig_bt[i+1] == T_SHORT ||
-                sig_bt[i+1] == T_INT,
-                "expecting type (T_LONG,half) or type (T_LONG,bt) with bt in {T_BOOLEAN, T_CHAR, T_BYTE, T_SHORT, T_INT}");
     case T_OBJECT:
     case T_ARRAY:
     case T_ADDRESS:
     case T_METADATA:
       // Oops are already boxed if required (JNI).

@@ -1271,11 +1256,11 @@
 }
 
 static void int_move(MacroAssembler*masm,
                      VMRegPair src, VMRegPair dst,
                      Register r_caller_sp, Register r_temp) {
-  assert(src.first()->is_valid() && src.second() == src.first()->next(), "incoming must be long-int");
+  assert(src.first()->is_valid(), "incoming must be int");
   assert(dst.first()->is_valid() && dst.second() == dst.first()->next(), "outgoing must be long");
 
   if (src.first()->is_stack()) {
     if (dst.first()->is_stack()) {
       // stack to stack

@@ -1760,34 +1745,27 @@
   // We have received a description of where all the java args are located
   // on entry to the wrapper. We need to convert these args to where
   // the jni function will expect them. To figure out where they go
   // we convert the java signature to a C signature by inserting
   // the hidden arguments as arg[0] and possibly arg[1] (static method)
-  //
-  // Additionally, on ppc64 we must convert integers to longs in the C
-  // signature. We do this in advance in order to have no trouble with
-  // indexes into the bt-arrays.
-  // So convert the signature and registers now, and adjust the total number
-  // of in-arguments accordingly.
-  int i2l_argcnt = convert_ints_to_longints_argcnt(total_in_args, in_sig_bt); // PPC64: pass ints as longs.
 
   // Calculate the total number of C arguments and create arrays for the
   // signature and the outgoing registers.
   // On ppc64, we have two arrays for the outgoing registers, because
   // some floating-point arguments must be passed in registers _and_
   // in stack locations.
   bool method_is_static = method->is_static();
-  int  total_c_args     = i2l_argcnt;
+  int  total_c_args     = total_in_args;
 
   if (!is_critical_native) {
     int n_hidden_args = method_is_static ? 2 : 1;
     total_c_args += n_hidden_args;
   } else {
     // No JNIEnv*, no this*, but unpacked arrays (base+length).
     for (int i = 0; i < total_in_args; i++) {
       if (in_sig_bt[i] == T_ARRAY) {
-        total_c_args += 2; // PPC64: T_LONG, T_INT, T_ADDRESS (see convert_ints_to_longints and c_calling_convention)
+        total_c_args++;
       }
     }
   }
 
   BasicType *out_sig_bt = NEW_RESOURCE_ARRAY(BasicType, total_c_args);

@@ -1801,23 +1779,21 @@
   //   3) copy the rest of the incoming signature (shifted by the number of
   //      hidden arguments).
 
   int argc = 0;
   if (!is_critical_native) {
-    convert_ints_to_longints(i2l_argcnt, total_in_args, in_sig_bt, in_regs); // PPC64: pass ints as longs.
-
     out_sig_bt[argc++] = T_ADDRESS;
     if (method->is_static()) {
       out_sig_bt[argc++] = T_OBJECT;
     }
 
     for (int i = 0; i < total_in_args ; i++ ) {
       out_sig_bt[argc++] = in_sig_bt[i];
     }
   } else {
     Thread* THREAD = Thread::current();
-    in_elem_bt = NEW_RESOURCE_ARRAY(BasicType, i2l_argcnt);
+    in_elem_bt = NEW_RESOURCE_ARRAY(BasicType, total_c_args);
     SignatureStream ss(method->signature());
     int o = 0;
     for (int i = 0; i < total_in_args ; i++, o++) {
       if (in_sig_bt[i] == T_ARRAY) {
         // Arrays are passed as int, elem* pair

@@ -1837,32 +1813,20 @@
             default: ShouldNotReachHere();
           }
         }
       } else {
         in_elem_bt[o] = T_VOID;
-        switch(in_sig_bt[i]) { // PPC64: pass ints as longs.
-          case T_BOOLEAN:
-          case T_CHAR:
-          case T_BYTE:
-          case T_SHORT:
-          case T_INT: in_elem_bt[++o] = T_VOID; break;
-          default: break;
-        }
       }
       if (in_sig_bt[i] != T_VOID) {
         assert(in_sig_bt[i] == ss.type(), "must match");
         ss.next();
       }
     }
-    assert(i2l_argcnt==o, "must match");
-
-    convert_ints_to_longints(i2l_argcnt, total_in_args, in_sig_bt, in_regs); // PPC64: pass ints as longs.
 
     for (int i = 0; i < total_in_args ; i++ ) {
       if (in_sig_bt[i] == T_ARRAY) {
         // Arrays are passed as int, elem* pair.
-        out_sig_bt[argc++] = T_LONG; // PPC64: pass ints as longs.
         out_sig_bt[argc++] = T_INT;
         out_sig_bt[argc++] = T_ADDRESS;
       } else {
         out_sig_bt[argc++] = in_sig_bt[i];
       }

@@ -1919,11 +1883,12 @@
         switch (in_sig_bt[i]) {
           case T_BOOLEAN:
           case T_BYTE:
           case T_SHORT:
           case T_CHAR:
-          case T_INT:  /*single_slots++;*/ break; // PPC64: pass ints as longs.
+          case T_INT:
+          // Fall through.
           case T_ARRAY:
           case T_LONG: double_slots++; break;
           default:  ShouldNotReachHere();
         }
       } else if (in_regs[i].first()->is_FloatRegister()) {

@@ -2096,28 +2061,20 @@
       case T_BOOLEAN:
       case T_CHAR:
       case T_BYTE:
       case T_SHORT:
       case T_INT:
-        guarantee(in > 0 && in_sig_bt[in-1] == T_LONG,
-                  "expecting type (T_LONG,bt) for bt in {T_BOOLEAN, T_CHAR, T_BYTE, T_SHORT, T_INT}");
+        // Move int and do sign extension.
+        int_move(masm, in_regs[in], out_regs[out], r_callers_sp, r_temp_1);
         break;
       case T_LONG:
-        if (in_sig_bt[in+1] == T_VOID) {
           long_move(masm, in_regs[in], out_regs[out], r_callers_sp, r_temp_1);
-        } else {
-          guarantee(in_sig_bt[in+1] == T_BOOLEAN || in_sig_bt[in+1] == T_CHAR  ||
-                    in_sig_bt[in+1] == T_BYTE    || in_sig_bt[in+1] == T_SHORT ||
-                    in_sig_bt[in+1] == T_INT,
-                 "expecting type (T_LONG,bt) for bt in {T_BOOLEAN, T_CHAR, T_BYTE, T_SHORT, T_INT}");
-          int_move(masm, in_regs[in], out_regs[out], r_callers_sp, r_temp_1);
-        }
         break;
       case T_ARRAY:
         if (is_critical_native) {
           int body_arg = out;
-          out -= 2; // Point to length arg. PPC64: pass ints as longs.
+          out -= 1; // Point to length arg.
           unpack_array_argument(masm, in_regs[in], in_elem_bt[in], out_regs[body_arg], out_regs[out],
                                 r_callers_sp, r_temp_1, r_temp_2);
           break;
         }
       case T_OBJECT:

@@ -2185,11 +2142,10 @@
   // to native.
 
   // Make sure that thread is non-volatile; it crosses a bunch of VM calls below.
   assert(R16_thread->is_nonvolatile(), "thread must be in non-volatile register");
 
-
 # if 0
   // DTrace method entry
 # endif
 
   // Lock a synchronized method.
< prev index next >