279 bool inline_cipherBlockChaining_AESCrypt(vmIntrinsics::ID id); 280 Node* inline_cipherBlockChaining_AESCrypt_predicate(bool decrypting); 281 Node* get_key_start_from_aescrypt_object(Node* aescrypt_object); 282 Node* get_original_key_start_from_aescrypt_object(Node* aescrypt_object); 283 bool inline_ghash_processBlocks(); 284 bool inline_sha_implCompress(vmIntrinsics::ID id); 285 bool inline_digestBase_implCompressMB(int predicate); 286 bool inline_sha_implCompressMB(Node* digestBaseObj, ciInstanceKlass* instklass_SHA, 287 bool long_state, address stubAddr, const char *stubName, 288 Node* src_start, Node* ofs, Node* limit); 289 Node* get_state_from_sha_object(Node *sha_object); 290 Node* get_state_from_sha5_object(Node *sha_object); 291 Node* inline_digestBase_implCompressMB_predicate(int predicate); 292 bool inline_encodeISOArray(); 293 bool inline_updateCRC32(); 294 bool inline_updateBytesCRC32(); 295 bool inline_updateByteBufferCRC32(); 296 Node* get_table_from_crc32c_class(ciInstanceKlass *crc32c_class); 297 bool inline_updateBytesCRC32C(); 298 bool inline_updateDirectByteBufferCRC32C(); 299 bool inline_multiplyToLen(); 300 bool inline_squareToLen(); 301 bool inline_mulAdd(); 302 bool inline_montgomeryMultiply(); 303 bool inline_montgomerySquare(); 304 305 bool inline_profileBoolean(); 306 bool inline_isCompileConstant(); 307 }; 308 309 //---------------------------make_vm_intrinsic---------------------------- 310 CallGenerator* Compile::make_vm_intrinsic(ciMethod* m, bool is_virtual) { 311 vmIntrinsics::ID id = m->intrinsic_id(); 312 assert(id != vmIntrinsics::_none, "must be a VM intrinsic"); 313 314 if (!m->is_loaded()) { 315 // Do not attempt to inline unloaded methods. 316 return NULL; 317 } 318 682 return inline_montgomerySquare(); 683 684 case vmIntrinsics::_ghash_processBlocks: 685 return inline_ghash_processBlocks(); 686 687 case vmIntrinsics::_encodeISOArray: 688 return inline_encodeISOArray(); 689 690 case vmIntrinsics::_updateCRC32: 691 return inline_updateCRC32(); 692 case vmIntrinsics::_updateBytesCRC32: 693 return inline_updateBytesCRC32(); 694 case vmIntrinsics::_updateByteBufferCRC32: 695 return inline_updateByteBufferCRC32(); 696 697 case vmIntrinsics::_updateBytesCRC32C: 698 return inline_updateBytesCRC32C(); 699 case vmIntrinsics::_updateDirectByteBufferCRC32C: 700 return inline_updateDirectByteBufferCRC32C(); 701 702 case vmIntrinsics::_profileBoolean: 703 return inline_profileBoolean(); 704 case vmIntrinsics::_isCompileConstant: 705 return inline_isCompileConstant(); 706 707 default: 708 // If you get here, it may be that someone has added a new intrinsic 709 // to the list in vmSymbols.hpp without implementing it here. 710 #ifndef PRODUCT 711 if ((PrintMiscellaneous && (Verbose || WizardMode)) || PrintOpto) { 712 tty->print_cr("*** Warning: Unimplemented intrinsic %s(%d)", 713 vmIntrinsics::name_at(intrinsic_id()), intrinsic_id()); 714 } 715 #endif 716 return false; 717 } 718 } 719 720 Node* LibraryCallKit::try_to_predicate(int predicate) { 721 if (!jvms()->has_method()) { 5530 5531 // 'src_start' points to src array + scaled offset 5532 Node* src_start = basic_plus_adr(top(), base, offset); 5533 5534 // static final int[] byteTable in class CRC32C 5535 Node* table = get_table_from_crc32c_class(callee()->holder()); 5536 Node* table_start = array_element_address(table, intcon(0), T_INT); 5537 5538 // Call the stub. 5539 address stubAddr = StubRoutines::updateBytesCRC32C(); 5540 const char *stubName = "updateBytesCRC32C"; 5541 5542 Node* call = make_runtime_call(RC_LEAF, OptoRuntime::updateBytesCRC32C_Type(), 5543 stubAddr, stubName, TypePtr::BOTTOM, 5544 crc, src_start, length, table_start); 5545 Node* result = _gvn.transform(new ProjNode(call, TypeFunc::Parms)); 5546 set_result(result); 5547 return true; 5548 } 5549 5550 //----------------------------inline_reference_get---------------------------- 5551 // public T java.lang.ref.Reference.get(); 5552 bool LibraryCallKit::inline_reference_get() { 5553 const int referent_offset = java_lang_ref_Reference::referent_offset; 5554 guarantee(referent_offset > 0, "should have already been set"); 5555 5556 // Get the argument: 5557 Node* reference_obj = null_check_receiver(); 5558 if (stopped()) return true; 5559 5560 Node* adr = basic_plus_adr(reference_obj, reference_obj, referent_offset); 5561 5562 ciInstanceKlass* klass = env()->Object_klass(); 5563 const TypeOopPtr* object_type = TypeOopPtr::make_from_klass(klass); 5564 5565 Node* no_ctrl = NULL; 5566 Node* result = make_load(no_ctrl, adr, object_type, T_OBJECT, MemNode::unordered); 5567 5568 // Use the pre-barrier to record the value in the referent field 5569 pre_barrier(false /* do_load */, | 279 bool inline_cipherBlockChaining_AESCrypt(vmIntrinsics::ID id); 280 Node* inline_cipherBlockChaining_AESCrypt_predicate(bool decrypting); 281 Node* get_key_start_from_aescrypt_object(Node* aescrypt_object); 282 Node* get_original_key_start_from_aescrypt_object(Node* aescrypt_object); 283 bool inline_ghash_processBlocks(); 284 bool inline_sha_implCompress(vmIntrinsics::ID id); 285 bool inline_digestBase_implCompressMB(int predicate); 286 bool inline_sha_implCompressMB(Node* digestBaseObj, ciInstanceKlass* instklass_SHA, 287 bool long_state, address stubAddr, const char *stubName, 288 Node* src_start, Node* ofs, Node* limit); 289 Node* get_state_from_sha_object(Node *sha_object); 290 Node* get_state_from_sha5_object(Node *sha_object); 291 Node* inline_digestBase_implCompressMB_predicate(int predicate); 292 bool inline_encodeISOArray(); 293 bool inline_updateCRC32(); 294 bool inline_updateBytesCRC32(); 295 bool inline_updateByteBufferCRC32(); 296 Node* get_table_from_crc32c_class(ciInstanceKlass *crc32c_class); 297 bool inline_updateBytesCRC32C(); 298 bool inline_updateDirectByteBufferCRC32C(); 299 bool inline_updateBytesAdler32(); 300 bool inline_updateByteBufferAdler32(); 301 bool inline_multiplyToLen(); 302 bool inline_squareToLen(); 303 bool inline_mulAdd(); 304 bool inline_montgomeryMultiply(); 305 bool inline_montgomerySquare(); 306 307 bool inline_profileBoolean(); 308 bool inline_isCompileConstant(); 309 }; 310 311 //---------------------------make_vm_intrinsic---------------------------- 312 CallGenerator* Compile::make_vm_intrinsic(ciMethod* m, bool is_virtual) { 313 vmIntrinsics::ID id = m->intrinsic_id(); 314 assert(id != vmIntrinsics::_none, "must be a VM intrinsic"); 315 316 if (!m->is_loaded()) { 317 // Do not attempt to inline unloaded methods. 318 return NULL; 319 } 320 684 return inline_montgomerySquare(); 685 686 case vmIntrinsics::_ghash_processBlocks: 687 return inline_ghash_processBlocks(); 688 689 case vmIntrinsics::_encodeISOArray: 690 return inline_encodeISOArray(); 691 692 case vmIntrinsics::_updateCRC32: 693 return inline_updateCRC32(); 694 case vmIntrinsics::_updateBytesCRC32: 695 return inline_updateBytesCRC32(); 696 case vmIntrinsics::_updateByteBufferCRC32: 697 return inline_updateByteBufferCRC32(); 698 699 case vmIntrinsics::_updateBytesCRC32C: 700 return inline_updateBytesCRC32C(); 701 case vmIntrinsics::_updateDirectByteBufferCRC32C: 702 return inline_updateDirectByteBufferCRC32C(); 703 704 case vmIntrinsics::_updateBytesAdler32: 705 return inline_updateBytesAdler32(); 706 case vmIntrinsics::_updateByteBufferAdler32: 707 return inline_updateByteBufferAdler32(); 708 709 case vmIntrinsics::_profileBoolean: 710 return inline_profileBoolean(); 711 case vmIntrinsics::_isCompileConstant: 712 return inline_isCompileConstant(); 713 714 default: 715 // If you get here, it may be that someone has added a new intrinsic 716 // to the list in vmSymbols.hpp without implementing it here. 717 #ifndef PRODUCT 718 if ((PrintMiscellaneous && (Verbose || WizardMode)) || PrintOpto) { 719 tty->print_cr("*** Warning: Unimplemented intrinsic %s(%d)", 720 vmIntrinsics::name_at(intrinsic_id()), intrinsic_id()); 721 } 722 #endif 723 return false; 724 } 725 } 726 727 Node* LibraryCallKit::try_to_predicate(int predicate) { 728 if (!jvms()->has_method()) { 5537 5538 // 'src_start' points to src array + scaled offset 5539 Node* src_start = basic_plus_adr(top(), base, offset); 5540 5541 // static final int[] byteTable in class CRC32C 5542 Node* table = get_table_from_crc32c_class(callee()->holder()); 5543 Node* table_start = array_element_address(table, intcon(0), T_INT); 5544 5545 // Call the stub. 5546 address stubAddr = StubRoutines::updateBytesCRC32C(); 5547 const char *stubName = "updateBytesCRC32C"; 5548 5549 Node* call = make_runtime_call(RC_LEAF, OptoRuntime::updateBytesCRC32C_Type(), 5550 stubAddr, stubName, TypePtr::BOTTOM, 5551 crc, src_start, length, table_start); 5552 Node* result = _gvn.transform(new ProjNode(call, TypeFunc::Parms)); 5553 set_result(result); 5554 return true; 5555 } 5556 5557 //------------------------------inline_updateBytesAdler32---------------------- 5558 // 5559 // Calculate Adler32 checksum for byte[] array. 5560 // int java.util.zip.Adler32.updateBytes(int crc, byte[] buf, int off, int len) 5561 // 5562 bool LibraryCallKit::inline_updateBytesAdler32() { 5563 assert(UseAdler32Intrinsics, "Adler32 Instrinsic support need"); // check if we actually need to check this flag or check a different one 5564 assert(callee()->signature()->size() == 4, "updateBytes has 4 parameters"); 5565 assert(callee()->holder()->is_loaded(), "Adler32 class must be loaded"); 5566 // no receiver since it is static method 5567 Node* crc = argument(0); // type: int 5568 Node* src = argument(1); // type: oop 5569 Node* offset = argument(2); // type: int 5570 Node* length = argument(3); // type: int 5571 5572 const Type* src_type = src->Value(&_gvn); 5573 const TypeAryPtr* top_src = src_type->isa_aryptr(); 5574 if (top_src == NULL || top_src->klass() == NULL) { 5575 // failed array check 5576 return false; 5577 } 5578 5579 // Figure out the size and type of the elements we will be copying. 5580 BasicType src_elem = src_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type(); 5581 if (src_elem != T_BYTE) { 5582 return false; 5583 } 5584 5585 // 'src_start' points to src array + scaled offset 5586 Node* src_start = array_element_address(src, offset, src_elem); 5587 5588 // We assume that range check is done by caller. 5589 // TODO: generate range check (offset+length < src.length) in debug VM. 5590 5591 // Call the stub. 5592 address stubAddr = StubRoutines::updateBytesAdler32(); 5593 const char *stubName = "updateBytesAdler32"; 5594 5595 Node* call = make_runtime_call(RC_LEAF, OptoRuntime::updateBytesAdler32_Type(), 5596 stubAddr, stubName, TypePtr::BOTTOM, 5597 crc, src_start, length); 5598 Node* result = _gvn.transform(new ProjNode(call, TypeFunc::Parms)); 5599 set_result(result); 5600 return true; 5601 } 5602 5603 //------------------------------inline_updateByteBufferAdler32--------------- 5604 // 5605 // Calculate Adler32 checksum for DirectByteBuffer. 5606 // int java.util.zip.Adler32.updateByteBuffer(int crc, long buf, int off, int len) 5607 // 5608 bool LibraryCallKit::inline_updateByteBufferAdler32() { 5609 assert(UseAdler32Intrinsics, "Adler32 Instrinsic support need"); // check if we actually need to check this flag or check a different one 5610 assert(callee()->signature()->size() == 5, "updateByteBuffer has 4 parameters and one is long"); 5611 assert(callee()->holder()->is_loaded(), "Adler32 class must be loaded"); 5612 // no receiver since it is static method 5613 Node* crc = argument(0); // type: int 5614 Node* src = argument(1); // type: long 5615 Node* offset = argument(3); // type: int 5616 Node* length = argument(4); // type: int 5617 5618 src = ConvL2X(src); // adjust Java long to machine word 5619 Node* base = _gvn.transform(new CastX2PNode(src)); 5620 offset = ConvI2X(offset); 5621 5622 // 'src_start' points to src array + scaled offset 5623 Node* src_start = basic_plus_adr(top(), base, offset); 5624 5625 // Call the stub. 5626 address stubAddr = StubRoutines::updateBytesAdler32(); 5627 const char *stubName = "updateBytesAdler32"; 5628 5629 Node* call = make_runtime_call(RC_LEAF, OptoRuntime::updateBytesAdler32_Type(), 5630 stubAddr, stubName, TypePtr::BOTTOM, 5631 crc, src_start, length); 5632 5633 Node* result = _gvn.transform(new ProjNode(call, TypeFunc::Parms)); 5634 set_result(result); 5635 return true; 5636 } 5637 5638 //----------------------------inline_reference_get---------------------------- 5639 // public T java.lang.ref.Reference.get(); 5640 bool LibraryCallKit::inline_reference_get() { 5641 const int referent_offset = java_lang_ref_Reference::referent_offset; 5642 guarantee(referent_offset > 0, "should have already been set"); 5643 5644 // Get the argument: 5645 Node* reference_obj = null_check_receiver(); 5646 if (stopped()) return true; 5647 5648 Node* adr = basic_plus_adr(reference_obj, reference_obj, referent_offset); 5649 5650 ciInstanceKlass* klass = env()->Object_klass(); 5651 const TypeOopPtr* object_type = TypeOopPtr::make_from_klass(klass); 5652 5653 Node* no_ctrl = NULL; 5654 Node* result = make_load(no_ctrl, adr, object_type, T_OBJECT, MemNode::unordered); 5655 5656 // Use the pre-barrier to record the value in the referent field 5657 pre_barrier(false /* do_load */, |