< prev index next >

## src/share/vm/opto/library_call.cpp

Print this page

    *** 286,295 ****
    --- 286,297 ----
        bool inline_encodeISOArray();
        bool inline_updateCRC32();
        bool inline_updateBytesCRC32();
        bool inline_updateByteBufferCRC32();
        bool inline_multiplyToLen();
    +   bool inline_squareToLen();
    +   bool inline_mulAdd();

        bool inline_profileBoolean();
      };

    *** 488,497 ****
    --- 490,507 ----

        case vmIntrinsics::_multiplyToLen:
          if (!UseMultiplyToLenIntrinsic) return NULL;
          break;

    +   case vmIntrinsics::_squareToLen:
    +     if (!UseSquareToLenIntrinsic) return NULL;
    +     break;
    +
    +   case vmIntrinsics::_mulAdd:
    +     if (!UseMulAddIntrinsic) return NULL;
    +     break;
    +
        case vmIntrinsics::_cipherBlockChaining_encryptAESCrypt:
        case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt:
          if (!UseAESIntrinsics) return NULL;
          // these two require the predicated logic
          predicates = 1;
    *** 886,895 ****
    --- 896,911 ----
          return inline_digestBase_implCompressMB(predicate);

        case vmIntrinsics::_multiplyToLen:
          return inline_multiplyToLen();

    +   case vmIntrinsics::_squareToLen:
    +     return inline_squareToLen();
    +
    +   case vmIntrinsics::_mulAdd:
    +     return inline_mulAdd();
    +
        case vmIntrinsics::_encodeISOArray:
          return inline_encodeISOArray();

        case vmIntrinsics::_updateCRC32:
          return inline_updateCRC32();
    *** 5146,5155 ****
    --- 5162,5314 ----
        C->set_has_split_ifs(true); // Has chance for split-if optimization
        set_result(z);
        return true;
      }

    + //-------------inline_squareToLen------------------------------------
    + bool LibraryCallKit::inline_squareToLen() {
    +   assert(UseSquareToLenIntrinsic, "not implementated on this platform");
    +
    +   address stubAddr = StubRoutines::squareToLen();
    +   if (stubAddr == NULL) {
    +     return false; // Intrinsic's stub is not implemented on this platform
    +   }
    +   const char* stubName = "squareToLen";
    +
    +   assert(callee()->signature()->size() == 3, "squareToLen has 3 parameters");
    +
    +   Node* x   = argument(0);
    +   Node* len = argument(1);
    +   Node* z   = argument(2);
    +
    +   const Type* x_type = x->Value(&_gvn);
    +   const TypeAryPtr* top_x = x_type->isa_aryptr();
    +   if (top_x  == NULL || top_x->klass()  == NULL) {
    +     // failed array check
    +     return false;
    +   }
    +
    +   BasicType x_elem = x_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
    +   if (x_elem != T_INT) {
    +     return false;
    +   }
    +
    +   // Set the original stack and the reexecute bit for the interpreter to reexecute
    +   // the bytecode that invokes BigInteger.squareToLen() if deoptimization happens
    +   // on the return from z array allocation in runtime.
    +   { PreserveReexecuteState preexecs(this);
    +     jvms()->set_should_reexecute(true);
    +
    +     Node* x_start = array_element_address(x, intcon(0), x_elem);
    +     // 'x_start' points to x array + scaled len
    +
    +     // Allocate the result array
    +     Node* zlen = _gvn.transform(new AddINode(len, len));
    +     ciKlass* klass = ciTypeArrayKlass::make(T_INT);
    +     Node* klass_node = makecon(TypeKlassPtr::make(klass));
    +
    +     IdealKit ideal(this);
    +
    + #define __ ideal.
    +      Node* one = __ ConI(1);
    +      Node* zero = __ ConI(0);
    +      IdealVariable need_alloc(ideal), z_alloc(ideal);  __ declarations_done();
    +      __ set(need_alloc, zero);
    +      __ set(z_alloc, z);
    +      __ if_then(z, BoolTest::eq, null()); {
    +        __ increment (need_alloc, one);
    +      } __ else_(); {
    +        // Update graphKit memory and control from IdealKit.
    +        sync_kit(ideal);
    +        Node* zlen_arg = load_array_length(z);
    +        // Update IdealKit memory and control from graphKit.
    +        __ sync_kit(this);
    +        __ if_then(zlen_arg, BoolTest::lt, zlen); {
    +          __ increment (need_alloc, one);
    +        } __ end_if();
    +      } __ end_if();
    +
    +      __ if_then(__ value(need_alloc), BoolTest::ne, zero); {
    +        // Update graphKit memory and control from IdealKit.
    +        sync_kit(ideal);
    +        Node * narr = new_array(klass_node, zlen, 1);
    +        // Update IdealKit memory and control from graphKit.
    +        __ sync_kit(this);
    +        __ set(z_alloc, narr);
    +      } __ end_if();
    +
    +      sync_kit(ideal);
    +      z = __ value(z_alloc);
    +      // Can't use TypeAryPtr::INTS which uses Bottom offset.
    +      _gvn.set_type(z, TypeOopPtr::make_from_klass(klass));
    +      // Final sync IdealKit and GraphKit.
    +      final_sync(ideal);
    + #undef __
    +
    +     Node* z_start = array_element_address(z, intcon(0), T_INT);
    +
    +     Node*  call = make_runtime_call(RC_LEAF|RC_NO_FP,
    +                                  OptoRuntime::squareToLen_Type(),
    +                                  stubAddr, stubName, TypePtr::BOTTOM,
    +                                  x_start, len, z_start, zlen);
    +   } // original reexecute is set back here
    +
    +   C->set_has_split_ifs(true); // Has chance for split-if optimization
    +   set_result(z);
    +   return true;
    + }
    +
    + //-------------inline_mulAdd------------------------------------------
    + bool LibraryCallKit::inline_mulAdd() {
    +   assert(UseMulAddIntrinsic, "not implementated on this platform");
    +
    +   address stubAddr = StubRoutines::mulAdd();
    +   if (stubAddr == NULL) {
    +     return false; // Intrinsic's stub is not implemented on this platform
    +   }
    +   const char* stubName = "mulAdd";
    +
    +   assert(callee()->signature()->size() == 5, "mulAdd has 5 parameters");
    +
    +   Node* out      = argument(0);
    +   Node* in       = argument(1);
    +   Node* offset   = argument(2);
    +   Node* len      = argument(3);
    +   Node* k        = argument(4);
    +
    +   const Type* out_type = out->Value(&_gvn);
    +   const Type* in_type = in->Value(&_gvn);
    +   const TypeAryPtr* top_out = out_type->isa_aryptr();
    +   const TypeAryPtr* top_in = in_type->isa_aryptr();
    +   if (top_out  == NULL || top_out->klass()  == NULL ||
    +       top_in == NULL || top_in->klass() == NULL) {
    +     // failed array check
    +     return false;
    +   }
    +
    +   BasicType out_elem = out_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
    +   BasicType in_elem = in_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
    +   if (out_elem != T_INT || in_elem != T_INT) {
    +     return false;
    +   }
    +
    +    Node* outlen = load_array_length(out);
    +    Node* new_offset = _gvn.transform(new SubINode(outlen, offset));
    +    Node* out_start = array_element_address(out, intcon(0), out_elem);
    +    // 'out_start' points to out array + scaled len
    +    Node* in_start = array_element_address(in, intcon(0), in_elem);
    +    // 'in_start' points to in array + scaled len
    +
    +    Node*  call = make_runtime_call(RC_LEAF|RC_NO_FP,
    +                                    OptoRuntime::mulAdd_Type(),
    +                                    stubAddr, stubName, TypePtr::BOTTOM,
    +                                    out_start,in_start, new_offset, len, k);
    +   Node* result = _gvn.transform(new ProjNode(call, TypeFunc::Parms));
    +   set_result(result);
    +   return true;
    + }
    +

      /**
       * Calculate CRC32 for byte.
       * int java.util.zip.CRC32.update(int crc, int b)
       */

< prev index next >