src/share/vm/opto/library_call.cpp

changeset 7152
166d744df0de
parent 7134
d8847542f83a
child 7155
4874332f9799
     1.1 --- a/src/share/vm/opto/library_call.cpp	Tue Sep 09 19:18:13 2014 +0000
     1.2 +++ b/src/share/vm/opto/library_call.cpp	Tue Sep 02 12:48:45 2014 -0700
     1.3 @@ -322,6 +322,7 @@
     1.4    bool inline_updateCRC32();
     1.5    bool inline_updateBytesCRC32();
     1.6    bool inline_updateByteBufferCRC32();
     1.7 +  bool inline_multiplyToLen();
     1.8  };
     1.9  
    1.10  
    1.11 @@ -330,8 +331,12 @@
    1.12    vmIntrinsics::ID id = m->intrinsic_id();
    1.13    assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
    1.14  
    1.15 -  if (DisableIntrinsic[0] != '\0'
    1.16 -      && strstr(DisableIntrinsic, vmIntrinsics::name_at(id)) != NULL) {
    1.17 +  ccstr disable_intr = NULL;
    1.18 +
    1.19 +  if ((DisableIntrinsic[0] != '\0'
    1.20 +       && strstr(DisableIntrinsic, vmIntrinsics::name_at(id)) != NULL) ||
    1.21 +      (method_has_option_value("DisableIntrinsic", disable_intr)
    1.22 +       && strstr(disable_intr, vmIntrinsics::name_at(id)) != NULL)) {
    1.23      // disabled by a user request on the command line:
    1.24      // example: -XX:DisableIntrinsic=_hashCode,_getClass
    1.25      return NULL;
    1.26 @@ -515,6 +520,10 @@
    1.27      if (!UseAESIntrinsics) return NULL;
    1.28      break;
    1.29  
    1.30 +  case vmIntrinsics::_multiplyToLen:
    1.31 +    if (!UseMultiplyToLenIntrinsic) return NULL;
    1.32 +    break;
    1.33 +
    1.34    case vmIntrinsics::_cipherBlockChaining_encryptAESCrypt:
    1.35    case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt:
    1.36      if (!UseAESIntrinsics) return NULL;
    1.37 @@ -912,6 +921,9 @@
    1.38    case vmIntrinsics::_digestBase_implCompressMB:
    1.39      return inline_digestBase_implCompressMB(predicate);
    1.40  
    1.41 +  case vmIntrinsics::_multiplyToLen:
    1.42 +    return inline_multiplyToLen();
    1.43 +
    1.44    case vmIntrinsics::_encodeISOArray:
    1.45      return inline_encodeISOArray();
    1.46  
    1.47 @@ -5735,6 +5747,106 @@
    1.48    return true;
    1.49  }
    1.50  
    1.51 +//-------------inline_multiplyToLen-----------------------------------
    1.52 +bool LibraryCallKit::inline_multiplyToLen() {
    1.53 +  assert(UseMultiplyToLenIntrinsic, "not implementated on this platform");
    1.54 +
    1.55 +  address stubAddr = StubRoutines::multiplyToLen();
    1.56 +  if (stubAddr == NULL) {
    1.57 +    return false; // Intrinsic's stub is not implemented on this platform
    1.58 +  }
    1.59 +  const char* stubName = "multiplyToLen";
    1.60 +
    1.61 +  assert(callee()->signature()->size() == 5, "multiplyToLen has 5 parameters");
    1.62 +
    1.63 +  Node* x    = argument(1);
    1.64 +  Node* xlen = argument(2);
    1.65 +  Node* y    = argument(3);
    1.66 +  Node* ylen = argument(4);
    1.67 +  Node* z    = argument(5);
    1.68 +
    1.69 +  const Type* x_type = x->Value(&_gvn);
    1.70 +  const Type* y_type = y->Value(&_gvn);
    1.71 +  const TypeAryPtr* top_x = x_type->isa_aryptr();
    1.72 +  const TypeAryPtr* top_y = y_type->isa_aryptr();
    1.73 +  if (top_x  == NULL || top_x->klass()  == NULL ||
    1.74 +      top_y == NULL || top_y->klass() == NULL) {
    1.75 +    // failed array check
    1.76 +    return false;
    1.77 +  }
    1.78 +
    1.79 +  BasicType x_elem = x_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
    1.80 +  BasicType y_elem = y_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
    1.81 +  if (x_elem != T_INT || y_elem != T_INT) {
    1.82 +    return false;
    1.83 +  }
    1.84 +
    1.85 +  // Set the original stack and the reexecute bit for the interpreter to reexecute
    1.86 +  // the bytecode that invokes BigInteger.multiplyToLen() if deoptimization happens
    1.87 +  // on the return from z array allocation in runtime.
    1.88 +  { PreserveReexecuteState preexecs(this);
    1.89 +    jvms()->set_should_reexecute(true);
    1.90 +
    1.91 +    Node* x_start = array_element_address(x, intcon(0), x_elem);
    1.92 +    Node* y_start = array_element_address(y, intcon(0), y_elem);
    1.93 +    // 'x_start' points to x array + scaled xlen
    1.94 +    // 'y_start' points to y array + scaled ylen
    1.95 +
    1.96 +    // Allocate the result array
    1.97 +    Node* zlen = _gvn.transform(new(C) AddINode(xlen, ylen));
    1.98 +    Node* klass_node = makecon(TypeKlassPtr::make(ciTypeArrayKlass::make(T_INT)));
    1.99 +
   1.100 +    IdealKit ideal(this);
   1.101 +
   1.102 +#define __ ideal.
   1.103 +     Node* one = __ ConI(1);
   1.104 +     Node* zero = __ ConI(0);
   1.105 +     IdealVariable need_alloc(ideal), z_alloc(ideal);  __ declarations_done();
   1.106 +     __ set(need_alloc, zero);
   1.107 +     __ set(z_alloc, z);
   1.108 +     __ if_then(z, BoolTest::eq, null()); {
   1.109 +       __ increment (need_alloc, one);
   1.110 +     } __ else_(); {
   1.111 +       // Update graphKit memory and control from IdealKit.
   1.112 +       sync_kit(ideal);
   1.113 +       Node* zlen_arg = load_array_length(z);
   1.114 +       // Update IdealKit memory and control from graphKit.
   1.115 +       __ sync_kit(this);
   1.116 +       __ if_then(zlen_arg, BoolTest::lt, zlen); {
   1.117 +         __ increment (need_alloc, one);
   1.118 +       } __ end_if();
   1.119 +     } __ end_if();
   1.120 +
   1.121 +     __ if_then(__ value(need_alloc), BoolTest::ne, zero); {
   1.122 +       // Update graphKit memory and control from IdealKit.
   1.123 +       sync_kit(ideal);
   1.124 +       Node * narr = new_array(klass_node, zlen, 1);
   1.125 +       // Update IdealKit memory and control from graphKit.
   1.126 +       __ sync_kit(this);
   1.127 +       __ set(z_alloc, narr);
   1.128 +     } __ end_if();
   1.129 +
   1.130 +     sync_kit(ideal);
   1.131 +     z = __ value(z_alloc);
   1.132 +     _gvn.set_type(z, TypeAryPtr::INTS);
   1.133 +     // Final sync IdealKit and GraphKit.
   1.134 +     final_sync(ideal);
   1.135 +#undef __
   1.136 +
   1.137 +    Node* z_start = array_element_address(z, intcon(0), T_INT);
   1.138 +
   1.139 +    Node* call = make_runtime_call(RC_LEAF|RC_NO_FP,
   1.140 +                                   OptoRuntime::multiplyToLen_Type(),
   1.141 +                                   stubAddr, stubName, TypePtr::BOTTOM,
   1.142 +                                   x_start, xlen, y_start, ylen, z_start, zlen);
   1.143 +  } // original reexecute is set back here
   1.144 +
   1.145 +  C->set_has_split_ifs(true); // Has chance for split-if optimization
   1.146 +  set_result(z);
   1.147 +  return true;
   1.148 +}
   1.149 +
   1.150 +
   1.151  /**
   1.152   * Calculate CRC32 for byte.
   1.153   * int java.util.zip.CRC32.update(int crc, int b)

mercurial