< prev index next >

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

Print this page

     271   bool inline_reference_get();
     272   bool inline_Class_cast();
     273   bool inline_aescrypt_Block(vmIntrinsics::ID id);
     274   bool inline_cipherBlockChaining_AESCrypt(vmIntrinsics::ID id);
     275   Node* inline_cipherBlockChaining_AESCrypt_predicate(bool decrypting);
     276   Node* get_key_start_from_aescrypt_object(Node* aescrypt_object);
     277   Node* get_original_key_start_from_aescrypt_object(Node* aescrypt_object);
     278   bool inline_sha_implCompress(vmIntrinsics::ID id);
     279   bool inline_digestBase_implCompressMB(int predicate);
     280   bool inline_sha_implCompressMB(Node* digestBaseObj, ciInstanceKlass* instklass_SHA,
     281                                  bool long_state, address stubAddr, const char *stubName,
     282                                  Node* src_start, Node* ofs, Node* limit);
     283   Node* get_state_from_sha_object(Node *sha_object);
     284   Node* get_state_from_sha5_object(Node *sha_object);
     285   Node* inline_digestBase_implCompressMB_predicate(int predicate);
     286   bool inline_encodeISOArray();
     287   bool inline_updateCRC32();
     288   bool inline_updateBytesCRC32();
     289   bool inline_updateByteBufferCRC32();
     290   bool inline_multiplyToLen();

     291
     292   bool inline_profileBoolean();
     293 };
     294
     295
     296 //---------------------------make_vm_intrinsic----------------------------
     297 CallGenerator* Compile::make_vm_intrinsic(ciMethod* m, bool is_virtual) {
     298   vmIntrinsics::ID id = m->intrinsic_id();
     299   assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
     300
     301   ccstr disable_intr = NULL;
     302
     303   if ((DisableIntrinsic[0] != '\0'
     304        && strstr(DisableIntrinsic, vmIntrinsics::name_at(id)) != NULL) ||
     305       (method_has_option_value("DisableIntrinsic", disable_intr)
     306        && strstr(disable_intr, vmIntrinsics::name_at(id)) != NULL)) {
     307     // disabled by a user request on the command line:
     308     // example: -XX:DisableIntrinsic=_hashCode,_getClass
     309     return NULL;
     310   }
     473
     474   case vmIntrinsics::_getAndSetObject:
     475 #ifdef _LP64
     476     if (!UseCompressedOops && !Matcher::match_rule_supported(Op_GetAndSetP)) return NULL;
     477     if (UseCompressedOops && !Matcher::match_rule_supported(Op_GetAndSetN)) return NULL;
     478     break;
     479 #else
     480     if (!Matcher::match_rule_supported(Op_GetAndSetP)) return NULL;
     481     break;
     482 #endif
     483
     484   case vmIntrinsics::_aescrypt_encryptBlock:
     485   case vmIntrinsics::_aescrypt_decryptBlock:
     486     if (!UseAESIntrinsics) return NULL;
     487     break;
     488
     489   case vmIntrinsics::_multiplyToLen:
     490     if (!UseMultiplyToLenIntrinsic) return NULL;
     491     break;
     492

     493   case vmIntrinsics::_cipherBlockChaining_encryptAESCrypt:
     494   case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt:
     495     if (!UseAESIntrinsics) return NULL;
     496     // these two require the predicated logic
     497     predicates = 1;
     498     break;
     499
     500   case vmIntrinsics::_sha_implCompress:
     501     if (!UseSHA1Intrinsics) return NULL;
     502     break;
     503
     504   case vmIntrinsics::_sha2_implCompress:
     505     if (!UseSHA256Intrinsics) return NULL;
     506     break;
     507
     508   case vmIntrinsics::_sha5_implCompress:
     509     if (!UseSHA512Intrinsics) return NULL;
     510     break;
     511
     512   case vmIntrinsics::_digestBase_implCompressMB:
     871   case vmIntrinsics::_Class_cast:               return inline_Class_cast();
     872
     873   case vmIntrinsics::_aescrypt_encryptBlock:
     874   case vmIntrinsics::_aescrypt_decryptBlock:    return inline_aescrypt_Block(intrinsic_id());
     875
     876   case vmIntrinsics::_cipherBlockChaining_encryptAESCrypt:
     877   case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt:
     878     return inline_cipherBlockChaining_AESCrypt(intrinsic_id());
     879
     880   case vmIntrinsics::_sha_implCompress:
     881   case vmIntrinsics::_sha2_implCompress:
     882   case vmIntrinsics::_sha5_implCompress:
     883     return inline_sha_implCompress(intrinsic_id());
     884
     885   case vmIntrinsics::_digestBase_implCompressMB:
     886     return inline_digestBase_implCompressMB(predicate);
     887
     888   case vmIntrinsics::_multiplyToLen:
     889     return inline_multiplyToLen();
     890

     891   case vmIntrinsics::_encodeISOArray:
     892     return inline_encodeISOArray();
     893
     894   case vmIntrinsics::_updateCRC32:
     895     return inline_updateCRC32();
     896   case vmIntrinsics::_updateBytesCRC32:
     897     return inline_updateBytesCRC32();
     898   case vmIntrinsics::_updateByteBufferCRC32:
     899     return inline_updateByteBufferCRC32();
     900
     901   case vmIntrinsics::_profileBoolean:
     902     return inline_profileBoolean();
     903
     904   default:
     905     // If you get here, it may be that someone has added a new intrinsic
     906     // to the list in vmSymbols.hpp without implementing it here.
     907 #ifndef PRODUCT
     908     if ((PrintMiscellaneous && (Verbose || WizardMode)) || PrintOpto) {
     909       tty->print_cr("*** Warning: Unimplemented intrinsic %s(%d)",
     910                     vmIntrinsics::name_at(intrinsic_id()), intrinsic_id());
    5128      } __ end_if();
    5129
    5130      sync_kit(ideal);
    5131      z = __ value(z_alloc);
    5132      // Can't use TypeAryPtr::INTS which uses Bottom offset.
    5133      _gvn.set_type(z, TypeOopPtr::make_from_klass(klass));
    5134      // Final sync IdealKit and GraphKit.
    5135      final_sync(ideal);
    5136 #undef __
    5137
    5138     Node* z_start = array_element_address(z, intcon(0), T_INT);
    5139
    5140     Node* call = make_runtime_call(RC_LEAF|RC_NO_FP,
    5141                                    OptoRuntime::multiplyToLen_Type(),
    5142                                    stubAddr, stubName, TypePtr::BOTTOM,
    5143                                    x_start, xlen, y_start, ylen, z_start, zlen);
    5144   } // original reexecute is set back here
    5145
    5146   C->set_has_split_ifs(true); // Has chance for split-if optimization
    5147   set_result(z);

    5148   return true;
    5149 }
    5150
    5151
    5152 /**
    5153  * Calculate CRC32 for byte.
    5154  * int java.util.zip.CRC32.update(int crc, int b)
    5155  */
    5156 bool LibraryCallKit::inline_updateCRC32() {
    5157   assert(UseCRC32Intrinsics, "need AVX and LCMUL instructions support");
    5158   assert(callee()->signature()->size() == 2, "update has 2 parameters");
    5159   // no receiver since it is static method
    5160   Node* crc  = argument(0); // type: int
    5161   Node* b    = argument(1); // type: int
    5162
    5163   /*
    5164    *    int c = ~ crc;
    5165    *    b = timesXtoThe32[(b ^ c) & 0xFF];
    5166    *    b = b ^ (c >>> 8);
    5167    *    crc = ~b;
     271   bool inline_reference_get();
     272   bool inline_Class_cast();
     273   bool inline_aescrypt_Block(vmIntrinsics::ID id);
     274   bool inline_cipherBlockChaining_AESCrypt(vmIntrinsics::ID id);
     275   Node* inline_cipherBlockChaining_AESCrypt_predicate(bool decrypting);
     276   Node* get_key_start_from_aescrypt_object(Node* aescrypt_object);
     277   Node* get_original_key_start_from_aescrypt_object(Node* aescrypt_object);
     278   bool inline_sha_implCompress(vmIntrinsics::ID id);
     279   bool inline_digestBase_implCompressMB(int predicate);
     280   bool inline_sha_implCompressMB(Node* digestBaseObj, ciInstanceKlass* instklass_SHA,
     281                                  bool long_state, address stubAddr, const char *stubName,
     282                                  Node* src_start, Node* ofs, Node* limit);
     283   Node* get_state_from_sha_object(Node *sha_object);
     284   Node* get_state_from_sha5_object(Node *sha_object);
     285   Node* inline_digestBase_implCompressMB_predicate(int predicate);
     286   bool inline_encodeISOArray();
     287   bool inline_updateCRC32();
     288   bool inline_updateBytesCRC32();
     289   bool inline_updateByteBufferCRC32();
     290   bool inline_multiplyToLen();
     291   bool inline_squareToLen();
     292   bool inline_mulAdd();
     293
     294   bool inline_profileBoolean();
     295 };
     296
     297
     298 //---------------------------make_vm_intrinsic----------------------------
     299 CallGenerator* Compile::make_vm_intrinsic(ciMethod* m, bool is_virtual) {
     300   vmIntrinsics::ID id = m->intrinsic_id();
     301   assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
     302
     303   ccstr disable_intr = NULL;
     304
     305   if ((DisableIntrinsic[0] != '\0'
     306        && strstr(DisableIntrinsic, vmIntrinsics::name_at(id)) != NULL) ||
     307       (method_has_option_value("DisableIntrinsic", disable_intr)
     308        && strstr(disable_intr, vmIntrinsics::name_at(id)) != NULL)) {
     309     // disabled by a user request on the command line:
     310     // example: -XX:DisableIntrinsic=_hashCode,_getClass
     311     return NULL;
     312   }
     475
     476   case vmIntrinsics::_getAndSetObject:
     477 #ifdef _LP64
     478     if (!UseCompressedOops && !Matcher::match_rule_supported(Op_GetAndSetP)) return NULL;
     479     if (UseCompressedOops && !Matcher::match_rule_supported(Op_GetAndSetN)) return NULL;
     480     break;
     481 #else
     482     if (!Matcher::match_rule_supported(Op_GetAndSetP)) return NULL;
     483     break;
     484 #endif
     485
     486   case vmIntrinsics::_aescrypt_encryptBlock:
     487   case vmIntrinsics::_aescrypt_decryptBlock:
     488     if (!UseAESIntrinsics) return NULL;
     489     break;
     490
     491   case vmIntrinsics::_multiplyToLen:
     492     if (!UseMultiplyToLenIntrinsic) return NULL;
     493     break;
     494
     495   case vmIntrinsics::_squareToLen:
     496     if (!UseSquareToLenIntrinsic) return NULL;
     497     break;
     498
     499   case vmIntrinsics::_mulAdd:
     500     if (!UseMulAddIntrinsic) return NULL;
     501     break;
     502
     503   case vmIntrinsics::_cipherBlockChaining_encryptAESCrypt:
     504   case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt:
     505     if (!UseAESIntrinsics) return NULL;
     506     // these two require the predicated logic
     507     predicates = 1;
     508     break;
     509
     510   case vmIntrinsics::_sha_implCompress:
     511     if (!UseSHA1Intrinsics) return NULL;
     512     break;
     513
     514   case vmIntrinsics::_sha2_implCompress:
     515     if (!UseSHA256Intrinsics) return NULL;
     516     break;
     517
     518   case vmIntrinsics::_sha5_implCompress:
     519     if (!UseSHA512Intrinsics) return NULL;
     520     break;
     521
     522   case vmIntrinsics::_digestBase_implCompressMB:
     881   case vmIntrinsics::_Class_cast:               return inline_Class_cast();
     882
     883   case vmIntrinsics::_aescrypt_encryptBlock:
     884   case vmIntrinsics::_aescrypt_decryptBlock:    return inline_aescrypt_Block(intrinsic_id());
     885
     886   case vmIntrinsics::_cipherBlockChaining_encryptAESCrypt:
     887   case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt:
     888     return inline_cipherBlockChaining_AESCrypt(intrinsic_id());
     889
     890   case vmIntrinsics::_sha_implCompress:
     891   case vmIntrinsics::_sha2_implCompress:
     892   case vmIntrinsics::_sha5_implCompress:
     893     return inline_sha_implCompress(intrinsic_id());
     894
     895   case vmIntrinsics::_digestBase_implCompressMB:
     896     return inline_digestBase_implCompressMB(predicate);
     897
     898   case vmIntrinsics::_multiplyToLen:
     899     return inline_multiplyToLen();
     900
     901   case vmIntrinsics::_squareToLen:
     902     return inline_squareToLen();
     903
     904   case vmIntrinsics::_mulAdd:
     905     return inline_mulAdd();
     906
     907   case vmIntrinsics::_encodeISOArray:
     908     return inline_encodeISOArray();
     909
     910   case vmIntrinsics::_updateCRC32:
     911     return inline_updateCRC32();
     912   case vmIntrinsics::_updateBytesCRC32:
     913     return inline_updateBytesCRC32();
     914   case vmIntrinsics::_updateByteBufferCRC32:
     915     return inline_updateByteBufferCRC32();
     916
     917   case vmIntrinsics::_profileBoolean:
     918     return inline_profileBoolean();
     919
     920   default:
     921     // If you get here, it may be that someone has added a new intrinsic
     922     // to the list in vmSymbols.hpp without implementing it here.
     923 #ifndef PRODUCT
     924     if ((PrintMiscellaneous && (Verbose || WizardMode)) || PrintOpto) {
     925       tty->print_cr("*** Warning: Unimplemented intrinsic %s(%d)",
     926                     vmIntrinsics::name_at(intrinsic_id()), intrinsic_id());
    5144      } __ end_if();
    5145
    5146      sync_kit(ideal);
    5147      z = __ value(z_alloc);
    5148      // Can't use TypeAryPtr::INTS which uses Bottom offset.
    5149      _gvn.set_type(z, TypeOopPtr::make_from_klass(klass));
    5150      // Final sync IdealKit and GraphKit.
    5151      final_sync(ideal);
    5152 #undef __
    5153
    5154     Node* z_start = array_element_address(z, intcon(0), T_INT);
    5155
    5156     Node* call = make_runtime_call(RC_LEAF|RC_NO_FP,
    5157                                    OptoRuntime::multiplyToLen_Type(),
    5158                                    stubAddr, stubName, TypePtr::BOTTOM,
    5159                                    x_start, xlen, y_start, ylen, z_start, zlen);
    5160   } // original reexecute is set back here
    5161
    5162   C->set_has_split_ifs(true); // Has chance for split-if optimization
    5163   set_result(z);
    5164   return true;
    5165 }
    5166
    5167 //-------------inline_squareToLen------------------------------------
    5168 bool LibraryCallKit::inline_squareToLen() {
    5169   assert(UseSquareToLenIntrinsic, "not implementated on this platform");
    5170
    5171   address stubAddr = StubRoutines::squareToLen();
    5172   if (stubAddr == NULL) {
    5173     return false; // Intrinsic's stub is not implemented on this platform
    5174   }
    5175   const char* stubName = "squareToLen";
    5176
    5177   assert(callee()->signature()->size() == 3, "squareToLen has 3 parameters");
    5178
    5179   Node* x   = argument(0);
    5180   Node* len = argument(1);
    5181   Node* z   = argument(2);
    5182
    5183   const Type* x_type = x->Value(&_gvn);
    5184   const TypeAryPtr* top_x = x_type->isa_aryptr();
    5185   if (top_x  == NULL || top_x->klass()  == NULL) {
    5186     // failed array check
    5187     return false;
    5188   }
    5189
    5190   BasicType x_elem = x_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
    5191   if (x_elem != T_INT) {
    5192     return false;
    5193   }
    5194
    5195   // Set the original stack and the reexecute bit for the interpreter to reexecute
    5196   // the bytecode that invokes BigInteger.squareToLen() if deoptimization happens
    5197   // on the return from z array allocation in runtime.
    5198   { PreserveReexecuteState preexecs(this);
    5199     jvms()->set_should_reexecute(true);
    5200
    5201     Node* x_start = array_element_address(x, intcon(0), x_elem);
    5202     // 'x_start' points to x array + scaled len
    5203
    5204     // Allocate the result array
    5205     Node* zlen = _gvn.transform(new AddINode(len, len));
    5206     ciKlass* klass = ciTypeArrayKlass::make(T_INT);
    5207     Node* klass_node = makecon(TypeKlassPtr::make(klass));
    5208
    5209     IdealKit ideal(this);
    5210
    5211 #define __ ideal.
    5212      Node* one = __ ConI(1);
    5213      Node* zero = __ ConI(0);
    5214      IdealVariable need_alloc(ideal), z_alloc(ideal);  __ declarations_done();
    5215      __ set(need_alloc, zero);
    5216      __ set(z_alloc, z);
    5217      __ if_then(z, BoolTest::eq, null()); {
    5218        __ increment (need_alloc, one);
    5219      } __ else_(); {
    5220        // Update graphKit memory and control from IdealKit.
    5221        sync_kit(ideal);
    5222        Node* zlen_arg = load_array_length(z);
    5223        // Update IdealKit memory and control from graphKit.
    5224        __ sync_kit(this);
    5225        __ if_then(zlen_arg, BoolTest::lt, zlen); {
    5226          __ increment (need_alloc, one);
    5227        } __ end_if();
    5228      } __ end_if();
    5229
    5230      __ if_then(__ value(need_alloc), BoolTest::ne, zero); {
    5231        // Update graphKit memory and control from IdealKit.
    5232        sync_kit(ideal);
    5233        Node * narr = new_array(klass_node, zlen, 1);
    5234        // Update IdealKit memory and control from graphKit.
    5235        __ sync_kit(this);
    5236        __ set(z_alloc, narr);
    5237      } __ end_if();
    5238
    5239      sync_kit(ideal);
    5240      z = __ value(z_alloc);
    5241      // Can't use TypeAryPtr::INTS which uses Bottom offset.
    5242      _gvn.set_type(z, TypeOopPtr::make_from_klass(klass));
    5243      // Final sync IdealKit and GraphKit.
    5244      final_sync(ideal);
    5245 #undef __
    5246
    5247     Node* z_start = array_element_address(z, intcon(0), T_INT);
    5248
    5249     Node*  call = make_runtime_call(RC_LEAF|RC_NO_FP,
    5250                                  OptoRuntime::squareToLen_Type(),
    5251                                  stubAddr, stubName, TypePtr::BOTTOM,
    5252                                  x_start, len, z_start, zlen);
    5253   } // original reexecute is set back here
    5254
    5255   C->set_has_split_ifs(true); // Has chance for split-if optimization
    5256   set_result(z);
    5257   return true;
    5258 }
    5259
    5260 //-------------inline_mulAdd------------------------------------------
    5261 bool LibraryCallKit::inline_mulAdd() {
    5262   assert(UseMulAddIntrinsic, "not implementated on this platform");
    5263
    5264   address stubAddr = StubRoutines::mulAdd();
    5265   if (stubAddr == NULL) {
    5266     return false; // Intrinsic's stub is not implemented on this platform
    5267   }
    5268   const char* stubName = "mulAdd";
    5269
    5270   assert(callee()->signature()->size() == 5, "mulAdd has 5 parameters");
    5271
    5272   Node* out      = argument(0);
    5273   Node* in       = argument(1);
    5274   Node* offset   = argument(2);
    5275   Node* len      = argument(3);
    5276   Node* k        = argument(4);
    5277
    5278   const Type* out_type = out->Value(&_gvn);
    5279   const Type* in_type = in->Value(&_gvn);
    5280   const TypeAryPtr* top_out = out_type->isa_aryptr();
    5281   const TypeAryPtr* top_in = in_type->isa_aryptr();
    5282   if (top_out  == NULL || top_out->klass()  == NULL ||
    5283       top_in == NULL || top_in->klass() == NULL) {
    5284     // failed array check
    5285     return false;
    5286   }
    5287
    5288   BasicType out_elem = out_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
    5289   BasicType in_elem = in_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
    5290   if (out_elem != T_INT || in_elem != T_INT) {
    5291     return false;
    5292   }
    5293
    5294    Node* outlen = load_array_length(out);
    5295    Node* new_offset = _gvn.transform(new SubINode(outlen, offset));
    5296    Node* out_start = array_element_address(out, intcon(0), out_elem);
    5297    // 'out_start' points to out array + scaled len
    5298    Node* in_start = array_element_address(in, intcon(0), in_elem);
    5299    // 'in_start' points to in array + scaled len
    5300
    5301    Node*  call = make_runtime_call(RC_LEAF|RC_NO_FP,
    5302                                    OptoRuntime::mulAdd_Type(),
    5303                                    stubAddr, stubName, TypePtr::BOTTOM,
    5304                                    out_start,in_start, new_offset, len, k);
    5305   Node* result = _gvn.transform(new ProjNode(call, TypeFunc::Parms));
    5306   set_result(result);
    5307   return true;
    5308 }
    5309
    5310
    5311 /**
    5312  * Calculate CRC32 for byte.
    5313  * int java.util.zip.CRC32.update(int crc, int b)
    5314  */
    5315 bool LibraryCallKit::inline_updateCRC32() {
    5316   assert(UseCRC32Intrinsics, "need AVX and LCMUL instructions support");
    5317   assert(callee()->signature()->size() == 2, "update has 2 parameters");
    5318   // no receiver since it is static method
    5319   Node* crc  = argument(0); // type: int
    5320   Node* b    = argument(1); // type: int
    5321
    5322   /*
    5323    *    int c = ~ crc;
    5324    *    b = timesXtoThe32[(b ^ c) & 0xFF];
    5325    *    b = b ^ (c >>> 8);
    5326    *    crc = ~b;

< prev index next >