< prev index next >

src/hotspot/share/opto/library_call.cpp

Print this page

6483   if (top_src  == NULL || top_src->klass()  == NULL) {
6484     // failed array check
6485     return false;
6486   }
6487   // Figure out the size and type of the elements we will be copying.
6488   BasicType src_elem = src_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
6489   if (src_elem != T_BYTE) {
6490     return false;
6491   }
6492   // 'src_start' points to src array + offset
6493   src = must_be_not_null(src, true);
6494   Node* src_start = array_element_address(src, ofs, src_elem);
6495   Node* state = NULL;
6496   Node* digest_length = NULL;
6497   address stubAddr;
6498   const char *stubName;
6499 
6500   switch(id) {
6501   case vmIntrinsics::_md5_implCompress:
6502     assert(UseMD5Intrinsics, "need MD5 instruction support");
6503     state = get_state_from_digest_object(digestBase_obj, "[I");
6504     stubAddr = StubRoutines::md5_implCompress();
6505     stubName = "md5_implCompress";
6506     break;
6507   case vmIntrinsics::_sha_implCompress:
6508     assert(UseSHA1Intrinsics, "need SHA1 instruction support");
6509     state = get_state_from_digest_object(digestBase_obj, "[I");
6510     stubAddr = StubRoutines::sha1_implCompress();
6511     stubName = "sha1_implCompress";
6512     break;
6513   case vmIntrinsics::_sha2_implCompress:
6514     assert(UseSHA256Intrinsics, "need SHA256 instruction support");
6515     state = get_state_from_digest_object(digestBase_obj, "[I");
6516     stubAddr = StubRoutines::sha256_implCompress();
6517     stubName = "sha256_implCompress";
6518     break;
6519   case vmIntrinsics::_sha5_implCompress:
6520     assert(UseSHA512Intrinsics, "need SHA512 instruction support");
6521     state = get_state_from_digest_object(digestBase_obj, "[J");
6522     stubAddr = StubRoutines::sha512_implCompress();
6523     stubName = "sha512_implCompress";
6524     break;
6525   case vmIntrinsics::_sha3_implCompress:
6526     assert(UseSHA3Intrinsics, "need SHA3 instruction support");
6527     state = get_state_from_digest_object(digestBase_obj, "[B");
6528     stubAddr = StubRoutines::sha3_implCompress();
6529     stubName = "sha3_implCompress";
6530     digest_length = get_digest_length_from_digest_object(digestBase_obj);
6531     if (digest_length == NULL) return false;
6532     break;
6533   default:
6534     fatal_unexpected_iid(id);
6535     return false;
6536   }
6537   if (state == NULL) return false;
6538 
6539   assert(stubAddr != NULL, "Stub is generated");
6540   if (stubAddr == NULL) return false;
6541 
6542   // Call the stub.
6543   Node* call;
6544   if (digest_length == NULL) {
6545     call = make_runtime_call(RC_LEAF|RC_NO_FP, OptoRuntime::digestBase_implCompress_Type(false),
6546                              stubAddr, stubName, TypePtr::BOTTOM,
6547                              src_start, state);

6571   Node* limit          = argument(3); // type int
6572 
6573   const Type* src_type = src->Value(&_gvn);
6574   const TypeAryPtr* top_src = src_type->isa_aryptr();
6575   if (top_src  == NULL || top_src->klass()  == NULL) {
6576     // failed array check
6577     return false;
6578   }
6579   // Figure out the size and type of the elements we will be copying.
6580   BasicType src_elem = src_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
6581   if (src_elem != T_BYTE) {
6582     return false;
6583   }
6584   // 'src_start' points to src array + offset
6585   src = must_be_not_null(src, false);
6586   Node* src_start = array_element_address(src, ofs, src_elem);
6587 
6588   const char* klass_digestBase_name = NULL;
6589   const char* stub_name = NULL;
6590   address     stub_addr = NULL;
6591   const char* state_type = "[I";
6592 
6593   switch (predicate) {
6594   case 0:
6595     if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_md5_implCompress)) {
6596       klass_digestBase_name = "sun/security/provider/MD5";
6597       stub_name = "md5_implCompressMB";
6598       stub_addr = StubRoutines::md5_implCompressMB();
6599     }
6600     break;
6601   case 1:
6602     if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_sha_implCompress)) {
6603       klass_digestBase_name = "sun/security/provider/SHA";
6604       stub_name = "sha1_implCompressMB";
6605       stub_addr = StubRoutines::sha1_implCompressMB();
6606     }
6607     break;
6608   case 2:
6609     if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_sha2_implCompress)) {
6610       klass_digestBase_name = "sun/security/provider/SHA2";
6611       stub_name = "sha256_implCompressMB";
6612       stub_addr = StubRoutines::sha256_implCompressMB();
6613     }
6614     break;
6615   case 3:
6616     if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_sha5_implCompress)) {
6617       klass_digestBase_name = "sun/security/provider/SHA5";
6618       stub_name = "sha512_implCompressMB";
6619       stub_addr = StubRoutines::sha512_implCompressMB();
6620       state_type = "[J";
6621     }
6622     break;
6623   case 4:
6624     if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_sha3_implCompress)) {
6625       klass_digestBase_name = "sun/security/provider/SHA3";
6626       stub_name = "sha3_implCompressMB";
6627       stub_addr = StubRoutines::sha3_implCompressMB();
6628       state_type = "[B";
6629     }
6630     break;
6631   default:
6632     fatal("unknown DigestBase intrinsic predicate: %d", predicate);
6633   }
6634   if (klass_digestBase_name != NULL) {
6635     assert(stub_addr != NULL, "Stub is generated");
6636     if (stub_addr == NULL) return false;
6637 
6638     // get DigestBase klass to lookup for SHA klass
6639     const TypeInstPtr* tinst = _gvn.type(digestBase_obj)->isa_instptr();
6640     assert(tinst != NULL, "digestBase_obj is not instance???");
6641     assert(tinst->klass()->is_loaded(), "DigestBase is not loaded");
6642 
6643     ciKlass* klass_digestBase = tinst->klass()->as_instance_klass()->find_klass(ciSymbol::make(klass_digestBase_name));
6644     assert(klass_digestBase->is_loaded(), "predicate checks that this class is loaded");
6645     ciInstanceKlass* instklass_digestBase = klass_digestBase->as_instance_klass();
6646     return inline_digestBase_implCompressMB(digestBase_obj, instklass_digestBase, state_type, stub_addr, stub_name, src_start, ofs, limit);
6647   }
6648   return false;
6649 }
6650 
6651 //------------------------------inline_digestBase_implCompressMB-----------------------
6652 bool LibraryCallKit::inline_digestBase_implCompressMB(Node* digestBase_obj, ciInstanceKlass* instklass_digestBase,
6653                                                       const char* state_type, address stubAddr, const char *stubName,
6654                                                       Node* src_start, Node* ofs, Node* limit) {
6655   const TypeKlassPtr* aklass = TypeKlassPtr::make(instklass_digestBase);
6656   const TypeOopPtr* xtype = aklass->as_instance_type();
6657   Node* digest_obj = new CheckCastPPNode(control(), digestBase_obj, xtype);
6658   digest_obj = _gvn.transform(digest_obj);
6659 
6660   Node* state = get_state_from_digest_object(digest_obj, state_type);
6661   if (state == NULL) return false;
6662 
6663   Node* digest_length = NULL;
6664   if (strcmp("sha3_implCompressMB", stubName) == 0) {
6665     digest_length = get_digest_length_from_digest_object(digest_obj);
6666     if (digest_length == NULL) return false;
6667   }
6668 
6669   // Call the stub.
6670   Node* call;
6671   if (digest_length == NULL) {
6672     call = make_runtime_call(RC_LEAF|RC_NO_FP,
6673                              OptoRuntime::digestBase_implCompressMB_Type(false),
6674                              stubAddr, stubName, TypePtr::BOTTOM,
6675                              src_start, state, ofs, limit);
6676   } else {
6677      call = make_runtime_call(RC_LEAF|RC_NO_FP,
6678                              OptoRuntime::digestBase_implCompressMB_Type(true),
6679                              stubAddr, stubName, TypePtr::BOTTOM,
6680                              src_start, state, digest_length, ofs, limit);
6681   }
6682 
6683   // return ofs (int)
6684   Node* result = _gvn.transform(new ProjNode(call, TypeFunc::Parms));
6685   set_result(result);
6686 
6687   return true;
6688 }
6689 
6690 //------------------------------get_state_from_digest_object-----------------------
6691 Node * LibraryCallKit::get_state_from_digest_object(Node *digest_object, const char *state_type) {







6692   Node* digest_state = load_field_from_object(digest_object, "state", state_type);
6693   assert (digest_state != NULL, "wrong version of sun.security.provider.MD5/SHA/SHA2/SHA5/SHA3");
6694   if (digest_state == NULL) return (Node *) NULL;
6695 
6696   // now have the array, need to get the start address of the state array
6697   Node* state = array_element_address(digest_state, intcon(0), T_INT);
6698   return state;
6699 }
6700 
6701 //------------------------------get_digest_length_from_sha3_object----------------------------------
6702 Node * LibraryCallKit::get_digest_length_from_digest_object(Node *digest_object) {
6703   Node* digest_length = load_field_from_object(digest_object, "digestLength", "I");
6704   assert (digest_length != NULL, "sanity");
6705   return digest_length;
6706 }
6707 
6708 //----------------------------inline_digestBase_implCompressMB_predicate----------------------------
6709 // Return node representing slow path of predicate check.
6710 // the pseudo code we want to emulate with this predicate is:
6711 //    if (digestBaseObj instanceof MD5/SHA/SHA2/SHA5/SHA3) do_intrinsic, else do_javapath
6712 //
6713 Node* LibraryCallKit::inline_digestBase_implCompressMB_predicate(int predicate) {
6714   assert(UseMD5Intrinsics || UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics || UseSHA3Intrinsics,
6715          "need MD5/SHA1/SHA256/SHA512/SHA3 instruction support");
6716   assert((uint)predicate < 5, "sanity");
6717 

6483   if (top_src  == NULL || top_src->klass()  == NULL) {
6484     // failed array check
6485     return false;
6486   }
6487   // Figure out the size and type of the elements we will be copying.
6488   BasicType src_elem = src_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
6489   if (src_elem != T_BYTE) {
6490     return false;
6491   }
6492   // 'src_start' points to src array + offset
6493   src = must_be_not_null(src, true);
6494   Node* src_start = array_element_address(src, ofs, src_elem);
6495   Node* state = NULL;
6496   Node* digest_length = NULL;
6497   address stubAddr;
6498   const char *stubName;
6499 
6500   switch(id) {
6501   case vmIntrinsics::_md5_implCompress:
6502     assert(UseMD5Intrinsics, "need MD5 instruction support");
6503     state = get_state_from_digest_object(digestBase_obj, T_INT);
6504     stubAddr = StubRoutines::md5_implCompress();
6505     stubName = "md5_implCompress";
6506     break;
6507   case vmIntrinsics::_sha_implCompress:
6508     assert(UseSHA1Intrinsics, "need SHA1 instruction support");
6509     state = get_state_from_digest_object(digestBase_obj, T_INT);
6510     stubAddr = StubRoutines::sha1_implCompress();
6511     stubName = "sha1_implCompress";
6512     break;
6513   case vmIntrinsics::_sha2_implCompress:
6514     assert(UseSHA256Intrinsics, "need SHA256 instruction support");
6515     state = get_state_from_digest_object(digestBase_obj, T_INT);
6516     stubAddr = StubRoutines::sha256_implCompress();
6517     stubName = "sha256_implCompress";
6518     break;
6519   case vmIntrinsics::_sha5_implCompress:
6520     assert(UseSHA512Intrinsics, "need SHA512 instruction support");
6521     state = get_state_from_digest_object(digestBase_obj, T_LONG);
6522     stubAddr = StubRoutines::sha512_implCompress();
6523     stubName = "sha512_implCompress";
6524     break;
6525   case vmIntrinsics::_sha3_implCompress:
6526     assert(UseSHA3Intrinsics, "need SHA3 instruction support");
6527     state = get_state_from_digest_object(digestBase_obj, T_BYTE);
6528     stubAddr = StubRoutines::sha3_implCompress();
6529     stubName = "sha3_implCompress";
6530     digest_length = get_digest_length_from_digest_object(digestBase_obj);
6531     if (digest_length == NULL) return false;
6532     break;
6533   default:
6534     fatal_unexpected_iid(id);
6535     return false;
6536   }
6537   if (state == NULL) return false;
6538 
6539   assert(stubAddr != NULL, "Stub is generated");
6540   if (stubAddr == NULL) return false;
6541 
6542   // Call the stub.
6543   Node* call;
6544   if (digest_length == NULL) {
6545     call = make_runtime_call(RC_LEAF|RC_NO_FP, OptoRuntime::digestBase_implCompress_Type(false),
6546                              stubAddr, stubName, TypePtr::BOTTOM,
6547                              src_start, state);

6571   Node* limit          = argument(3); // type int
6572 
6573   const Type* src_type = src->Value(&_gvn);
6574   const TypeAryPtr* top_src = src_type->isa_aryptr();
6575   if (top_src  == NULL || top_src->klass()  == NULL) {
6576     // failed array check
6577     return false;
6578   }
6579   // Figure out the size and type of the elements we will be copying.
6580   BasicType src_elem = src_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
6581   if (src_elem != T_BYTE) {
6582     return false;
6583   }
6584   // 'src_start' points to src array + offset
6585   src = must_be_not_null(src, false);
6586   Node* src_start = array_element_address(src, ofs, src_elem);
6587 
6588   const char* klass_digestBase_name = NULL;
6589   const char* stub_name = NULL;
6590   address     stub_addr = NULL;
6591   BasicType elem_type = T_INT;
6592 
6593   switch (predicate) {
6594   case 0:
6595     if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_md5_implCompress)) {
6596       klass_digestBase_name = "sun/security/provider/MD5";
6597       stub_name = "md5_implCompressMB";
6598       stub_addr = StubRoutines::md5_implCompressMB();
6599     }
6600     break;
6601   case 1:
6602     if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_sha_implCompress)) {
6603       klass_digestBase_name = "sun/security/provider/SHA";
6604       stub_name = "sha1_implCompressMB";
6605       stub_addr = StubRoutines::sha1_implCompressMB();
6606     }
6607     break;
6608   case 2:
6609     if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_sha2_implCompress)) {
6610       klass_digestBase_name = "sun/security/provider/SHA2";
6611       stub_name = "sha256_implCompressMB";
6612       stub_addr = StubRoutines::sha256_implCompressMB();
6613     }
6614     break;
6615   case 3:
6616     if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_sha5_implCompress)) {
6617       klass_digestBase_name = "sun/security/provider/SHA5";
6618       stub_name = "sha512_implCompressMB";
6619       stub_addr = StubRoutines::sha512_implCompressMB();
6620       elem_type = T_LONG;
6621     }
6622     break;
6623   case 4:
6624     if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_sha3_implCompress)) {
6625       klass_digestBase_name = "sun/security/provider/SHA3";
6626       stub_name = "sha3_implCompressMB";
6627       stub_addr = StubRoutines::sha3_implCompressMB();
6628       elem_type = T_BYTE;
6629     }
6630     break;
6631   default:
6632     fatal("unknown DigestBase intrinsic predicate: %d", predicate);
6633   }
6634   if (klass_digestBase_name != NULL) {
6635     assert(stub_addr != NULL, "Stub is generated");
6636     if (stub_addr == NULL) return false;
6637 
6638     // get DigestBase klass to lookup for SHA klass
6639     const TypeInstPtr* tinst = _gvn.type(digestBase_obj)->isa_instptr();
6640     assert(tinst != NULL, "digestBase_obj is not instance???");
6641     assert(tinst->klass()->is_loaded(), "DigestBase is not loaded");
6642 
6643     ciKlass* klass_digestBase = tinst->klass()->as_instance_klass()->find_klass(ciSymbol::make(klass_digestBase_name));
6644     assert(klass_digestBase->is_loaded(), "predicate checks that this class is loaded");
6645     ciInstanceKlass* instklass_digestBase = klass_digestBase->as_instance_klass();
6646     return inline_digestBase_implCompressMB(digestBase_obj, instklass_digestBase, elem_type, stub_addr, stub_name, src_start, ofs, limit);
6647   }
6648   return false;
6649 }
6650 
6651 //------------------------------inline_digestBase_implCompressMB-----------------------
6652 bool LibraryCallKit::inline_digestBase_implCompressMB(Node* digestBase_obj, ciInstanceKlass* instklass_digestBase,
6653                                                       BasicType elem_type, address stubAddr, const char *stubName,
6654                                                       Node* src_start, Node* ofs, Node* limit) {
6655   const TypeKlassPtr* aklass = TypeKlassPtr::make(instklass_digestBase);
6656   const TypeOopPtr* xtype = aklass->as_instance_type();
6657   Node* digest_obj = new CheckCastPPNode(control(), digestBase_obj, xtype);
6658   digest_obj = _gvn.transform(digest_obj);
6659 
6660   Node* state = get_state_from_digest_object(digest_obj, elem_type);
6661   if (state == NULL) return false;
6662 
6663   Node* digest_length = NULL;
6664   if (strcmp("sha3_implCompressMB", stubName) == 0) {
6665     digest_length = get_digest_length_from_digest_object(digest_obj);
6666     if (digest_length == NULL) return false;
6667   }
6668 
6669   // Call the stub.
6670   Node* call;
6671   if (digest_length == NULL) {
6672     call = make_runtime_call(RC_LEAF|RC_NO_FP,
6673                              OptoRuntime::digestBase_implCompressMB_Type(false),
6674                              stubAddr, stubName, TypePtr::BOTTOM,
6675                              src_start, state, ofs, limit);
6676   } else {
6677      call = make_runtime_call(RC_LEAF|RC_NO_FP,
6678                              OptoRuntime::digestBase_implCompressMB_Type(true),
6679                              stubAddr, stubName, TypePtr::BOTTOM,
6680                              src_start, state, digest_length, ofs, limit);
6681   }
6682 
6683   // return ofs (int)
6684   Node* result = _gvn.transform(new ProjNode(call, TypeFunc::Parms));
6685   set_result(result);
6686 
6687   return true;
6688 }
6689 
6690 //------------------------------get_state_from_digest_object-----------------------
6691 Node * LibraryCallKit::get_state_from_digest_object(Node *digest_object, BasicType elem_type) {
6692   const char* state_type;
6693   switch (elem_type) {
6694     case T_BYTE: state_type = "[B"; break;
6695     case T_INT:  state_type = "[I"; break;
6696     case T_LONG: state_type = "[J"; break;
6697     default: ShouldNotReachHere();
6698   }
6699   Node* digest_state = load_field_from_object(digest_object, "state", state_type);
6700   assert (digest_state != NULL, "wrong version of sun.security.provider.MD5/SHA/SHA2/SHA5/SHA3");
6701   if (digest_state == NULL) return (Node *) NULL;
6702 
6703   // now have the array, need to get the start address of the state array
6704   Node* state = array_element_address(digest_state, intcon(0), elem_type);
6705   return state;
6706 }
6707 
6708 //------------------------------get_digest_length_from_sha3_object----------------------------------
6709 Node * LibraryCallKit::get_digest_length_from_digest_object(Node *digest_object) {
6710   Node* digest_length = load_field_from_object(digest_object, "digestLength", "I");
6711   assert (digest_length != NULL, "sanity");
6712   return digest_length;
6713 }
6714 
6715 //----------------------------inline_digestBase_implCompressMB_predicate----------------------------
6716 // Return node representing slow path of predicate check.
6717 // the pseudo code we want to emulate with this predicate is:
6718 //    if (digestBaseObj instanceof MD5/SHA/SHA2/SHA5/SHA3) do_intrinsic, else do_javapath
6719 //
6720 Node* LibraryCallKit::inline_digestBase_implCompressMB_predicate(int predicate) {
6721   assert(UseMD5Intrinsics || UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics || UseSHA3Intrinsics,
6722          "need MD5/SHA1/SHA256/SHA512/SHA3 instruction support");
6723   assert((uint)predicate < 5, "sanity");
6724 
< prev index next >