src/share/vm/opto/library_call.cpp

changeset 7026
922c87c9aed4
parent 6733
00c8a1255912
child 7027
b20a35eae442
equal deleted inserted replaced
7025:b1bc1af04c6e 7026:922c87c9aed4
44 class LibraryIntrinsic : public InlineCallGenerator { 44 class LibraryIntrinsic : public InlineCallGenerator {
45 // Extend the set of intrinsics known to the runtime: 45 // Extend the set of intrinsics known to the runtime:
46 public: 46 public:
47 private: 47 private:
48 bool _is_virtual; 48 bool _is_virtual;
49 bool _is_predicted;
50 bool _does_virtual_dispatch; 49 bool _does_virtual_dispatch;
50 int8_t _predicates_count; // Intrinsic is predicated by several conditions
51 int8_t _last_predicate; // Last generated predicate
51 vmIntrinsics::ID _intrinsic_id; 52 vmIntrinsics::ID _intrinsic_id;
52 53
53 public: 54 public:
54 LibraryIntrinsic(ciMethod* m, bool is_virtual, bool is_predicted, bool does_virtual_dispatch, vmIntrinsics::ID id) 55 LibraryIntrinsic(ciMethod* m, bool is_virtual, int predicates_count, bool does_virtual_dispatch, vmIntrinsics::ID id)
55 : InlineCallGenerator(m), 56 : InlineCallGenerator(m),
56 _is_virtual(is_virtual), 57 _is_virtual(is_virtual),
57 _is_predicted(is_predicted),
58 _does_virtual_dispatch(does_virtual_dispatch), 58 _does_virtual_dispatch(does_virtual_dispatch),
59 _predicates_count((int8_t)predicates_count),
60 _last_predicate((int8_t)-1),
59 _intrinsic_id(id) 61 _intrinsic_id(id)
60 { 62 {
61 } 63 }
62 virtual bool is_intrinsic() const { return true; } 64 virtual bool is_intrinsic() const { return true; }
63 virtual bool is_virtual() const { return _is_virtual; } 65 virtual bool is_virtual() const { return _is_virtual; }
64 virtual bool is_predicted() const { return _is_predicted; } 66 virtual bool is_predicated() const { return _predicates_count > 0; }
67 virtual int predicates_count() const { return _predicates_count; }
65 virtual bool does_virtual_dispatch() const { return _does_virtual_dispatch; } 68 virtual bool does_virtual_dispatch() const { return _does_virtual_dispatch; }
66 virtual JVMState* generate(JVMState* jvms, Parse* parent_parser); 69 virtual JVMState* generate(JVMState* jvms, Parse* parent_parser);
67 virtual Node* generate_predicate(JVMState* jvms); 70 virtual Node* generate_predicate(JVMState* jvms, int predicate);
68 vmIntrinsics::ID intrinsic_id() const { return _intrinsic_id; } 71 vmIntrinsics::ID intrinsic_id() const { return _intrinsic_id; }
69 }; 72 };
70 73
71 74
72 // Local helper class for LibraryIntrinsic: 75 // Local helper class for LibraryIntrinsic:
105 int bci() const { return jvms()->bci(); } 108 int bci() const { return jvms()->bci(); }
106 LibraryIntrinsic* intrinsic() const { return _intrinsic; } 109 LibraryIntrinsic* intrinsic() const { return _intrinsic; }
107 vmIntrinsics::ID intrinsic_id() const { return _intrinsic->intrinsic_id(); } 110 vmIntrinsics::ID intrinsic_id() const { return _intrinsic->intrinsic_id(); }
108 ciMethod* callee() const { return _intrinsic->method(); } 111 ciMethod* callee() const { return _intrinsic->method(); }
109 112
110 bool try_to_inline(); 113 bool try_to_inline(int predicate);
111 Node* try_to_predicate(); 114 Node* try_to_predicate(int predicate);
112 115
113 void push_result() { 116 void push_result() {
114 // Push the result onto the stack. 117 // Push the result onto the stack.
115 if (!stopped() && result() != NULL) { 118 if (!stopped() && result() != NULL) {
116 BasicType bt = result()->bottom_type()->basic_type(); 119 BasicType bt = result()->bottom_type()->basic_type();
365 default: 368 default:
366 return NULL; 369 return NULL;
367 } 370 }
368 } 371 }
369 372
370 bool is_predicted = false; 373 int predicates = 0;
371 bool does_virtual_dispatch = false; 374 bool does_virtual_dispatch = false;
372 375
373 switch (id) { 376 switch (id) {
374 case vmIntrinsics::_compareTo: 377 case vmIntrinsics::_compareTo:
375 if (!SpecialStringCompareTo) return NULL; 378 if (!SpecialStringCompareTo) return NULL;
506 509
507 case vmIntrinsics::_cipherBlockChaining_encryptAESCrypt: 510 case vmIntrinsics::_cipherBlockChaining_encryptAESCrypt:
508 case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt: 511 case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt:
509 if (!UseAESIntrinsics) return NULL; 512 if (!UseAESIntrinsics) return NULL;
510 // these two require the predicated logic 513 // these two require the predicated logic
511 is_predicted = true; 514 predicates = 1;
512 break; 515 break;
513 516
514 case vmIntrinsics::_updateCRC32: 517 case vmIntrinsics::_updateCRC32:
515 case vmIntrinsics::_updateBytesCRC32: 518 case vmIntrinsics::_updateBytesCRC32:
516 case vmIntrinsics::_updateByteBufferCRC32: 519 case vmIntrinsics::_updateByteBufferCRC32:
575 // -XX:-InlineUnsafeOps disables natives from the Unsafe class. 578 // -XX:-InlineUnsafeOps disables natives from the Unsafe class.
576 if (m->holder()->name() == ciSymbol::sun_misc_Unsafe()) { 579 if (m->holder()->name() == ciSymbol::sun_misc_Unsafe()) {
577 if (!InlineUnsafeOps) return NULL; 580 if (!InlineUnsafeOps) return NULL;
578 } 581 }
579 582
580 return new LibraryIntrinsic(m, is_virtual, is_predicted, does_virtual_dispatch, (vmIntrinsics::ID) id); 583 return new LibraryIntrinsic(m, is_virtual, predicates, does_virtual_dispatch, (vmIntrinsics::ID) id);
581 } 584 }
582 585
583 //----------------------register_library_intrinsics----------------------- 586 //----------------------register_library_intrinsics-----------------------
584 // Initialize this file's data structures, for each Compile instance. 587 // Initialize this file's data structures, for each Compile instance.
585 void Compile::register_library_intrinsics() { 588 void Compile::register_library_intrinsics() {
599 #endif 602 #endif
600 ciMethod* callee = kit.callee(); 603 ciMethod* callee = kit.callee();
601 const int bci = kit.bci(); 604 const int bci = kit.bci();
602 605
603 // Try to inline the intrinsic. 606 // Try to inline the intrinsic.
604 if (kit.try_to_inline()) { 607 if (kit.try_to_inline(_last_predicate)) {
605 if (C->print_intrinsics() || C->print_inlining()) { 608 if (C->print_intrinsics() || C->print_inlining()) {
606 C->print_inlining(callee, jvms->depth() - 1, bci, is_virtual() ? "(intrinsic, virtual)" : "(intrinsic)"); 609 C->print_inlining(callee, jvms->depth() - 1, bci, is_virtual() ? "(intrinsic, virtual)" : "(intrinsic)");
607 } 610 }
608 C->gather_intrinsic_statistics(intrinsic_id(), is_virtual(), Compile::_intrinsic_worked); 611 C->gather_intrinsic_statistics(intrinsic_id(), is_virtual(), Compile::_intrinsic_worked);
609 if (C->log()) { 612 if (C->log()) {
632 } 635 }
633 C->gather_intrinsic_statistics(intrinsic_id(), is_virtual(), Compile::_intrinsic_failed); 636 C->gather_intrinsic_statistics(intrinsic_id(), is_virtual(), Compile::_intrinsic_failed);
634 return NULL; 637 return NULL;
635 } 638 }
636 639
637 Node* LibraryIntrinsic::generate_predicate(JVMState* jvms) { 640 Node* LibraryIntrinsic::generate_predicate(JVMState* jvms, int predicate) {
638 LibraryCallKit kit(jvms, this); 641 LibraryCallKit kit(jvms, this);
639 Compile* C = kit.C; 642 Compile* C = kit.C;
640 int nodes = C->unique(); 643 int nodes = C->unique();
644 _last_predicate = predicate;
641 #ifndef PRODUCT 645 #ifndef PRODUCT
642 assert(is_predicted(), "sanity"); 646 assert(is_predicated() && predicate < predicates_count(), "sanity");
643 if ((C->print_intrinsics() || C->print_inlining()) && Verbose) { 647 if ((C->print_intrinsics() || C->print_inlining()) && Verbose) {
644 char buf[1000]; 648 char buf[1000];
645 const char* str = vmIntrinsics::short_name_as_C_string(intrinsic_id(), buf, sizeof(buf)); 649 const char* str = vmIntrinsics::short_name_as_C_string(intrinsic_id(), buf, sizeof(buf));
646 tty->print_cr("Predicate for intrinsic %s", str); 650 tty->print_cr("Predicate for intrinsic %s", str);
647 } 651 }
648 #endif 652 #endif
649 ciMethod* callee = kit.callee(); 653 ciMethod* callee = kit.callee();
650 const int bci = kit.bci(); 654 const int bci = kit.bci();
651 655
652 Node* slow_ctl = kit.try_to_predicate(); 656 Node* slow_ctl = kit.try_to_predicate(predicate);
653 if (!kit.failing()) { 657 if (!kit.failing()) {
654 if (C->print_intrinsics() || C->print_inlining()) { 658 if (C->print_intrinsics() || C->print_inlining()) {
655 C->print_inlining(callee, jvms->depth() - 1, bci, is_virtual() ? "(intrinsic, virtual)" : "(intrinsic)"); 659 C->print_inlining(callee, jvms->depth() - 1, bci, is_virtual() ? "(intrinsic, virtual, predicate)" : "(intrinsic, predicate)");
656 } 660 }
657 C->gather_intrinsic_statistics(intrinsic_id(), is_virtual(), Compile::_intrinsic_worked); 661 C->gather_intrinsic_statistics(intrinsic_id(), is_virtual(), Compile::_intrinsic_worked);
658 if (C->log()) { 662 if (C->log()) {
659 C->log()->elem("predicate_intrinsic id='%s'%s nodes='%d'", 663 C->log()->elem("predicate_intrinsic id='%s'%s nodes='%d'",
660 vmIntrinsics::name_at(intrinsic_id()), 664 vmIntrinsics::name_at(intrinsic_id()),
679 } 683 }
680 C->gather_intrinsic_statistics(intrinsic_id(), is_virtual(), Compile::_intrinsic_failed); 684 C->gather_intrinsic_statistics(intrinsic_id(), is_virtual(), Compile::_intrinsic_failed);
681 return NULL; 685 return NULL;
682 } 686 }
683 687
684 bool LibraryCallKit::try_to_inline() { 688 bool LibraryCallKit::try_to_inline(int predicate) {
685 // Handle symbolic names for otherwise undistinguished boolean switches: 689 // Handle symbolic names for otherwise undistinguished boolean switches:
686 const bool is_store = true; 690 const bool is_store = true;
687 const bool is_native_ptr = true; 691 const bool is_native_ptr = true;
688 const bool is_static = true; 692 const bool is_static = true;
689 const bool is_volatile = true; 693 const bool is_volatile = true;
896 #endif 900 #endif
897 return false; 901 return false;
898 } 902 }
899 } 903 }
900 904
901 Node* LibraryCallKit::try_to_predicate() { 905 Node* LibraryCallKit::try_to_predicate(int predicate) {
902 if (!jvms()->has_method()) { 906 if (!jvms()->has_method()) {
903 // Root JVMState has a null method. 907 // Root JVMState has a null method.
904 assert(map()->memory()->Opcode() == Op_Parm, ""); 908 assert(map()->memory()->Opcode() == Op_Parm, "");
905 // Insert the memory aliasing node 909 // Insert the memory aliasing node
906 set_all_memory(reset_memory()); 910 set_all_memory(reset_memory());
5864 const TypePtr* adr_type = C->alias_type(field)->adr_type(); 5868 const TypePtr* adr_type = C->alias_type(field)->adr_type();
5865 Node *adr = basic_plus_adr(fromObj, fromObj, offset); 5869 Node *adr = basic_plus_adr(fromObj, fromObj, offset);
5866 BasicType bt = field->layout_type(); 5870 BasicType bt = field->layout_type();
5867 5871
5868 // Build the resultant type of the load 5872 // Build the resultant type of the load
5869 const Type *type = TypeOopPtr::make_from_klass(field_klass->as_klass()); 5873 const Type *type;
5874 if (bt == T_OBJECT) {
5875 type = TypeOopPtr::make_from_klass(field_klass->as_klass());
5876 } else {
5877 type = Type::get_const_basic_type(bt);
5878 }
5870 5879
5871 // Build the load. 5880 // Build the load.
5872 Node* loadedField = make_load(NULL, adr, type, bt, adr_type, MemNode::unordered, is_vol); 5881 Node* loadedField = make_load(NULL, adr, type, bt, adr_type, MemNode::unordered, is_vol);
5873 return loadedField; 5882 return loadedField;
5874 } 5883 }
5994 // cast it to what we know it will be at runtime 6003 // cast it to what we know it will be at runtime
5995 const TypeInstPtr* tinst = _gvn.type(cipherBlockChaining_object)->isa_instptr(); 6004 const TypeInstPtr* tinst = _gvn.type(cipherBlockChaining_object)->isa_instptr();
5996 assert(tinst != NULL, "CBC obj is null"); 6005 assert(tinst != NULL, "CBC obj is null");
5997 assert(tinst->klass()->is_loaded(), "CBC obj is not loaded"); 6006 assert(tinst->klass()->is_loaded(), "CBC obj is not loaded");
5998 ciKlass* klass_AESCrypt = tinst->klass()->as_instance_klass()->find_klass(ciSymbol::make("com/sun/crypto/provider/AESCrypt")); 6007 ciKlass* klass_AESCrypt = tinst->klass()->as_instance_klass()->find_klass(ciSymbol::make("com/sun/crypto/provider/AESCrypt"));
5999 if (!klass_AESCrypt->is_loaded()) return false; 6008 assert(klass_AESCrypt->is_loaded(), "predicate checks that this class is loaded");
6000 6009
6001 ciInstanceKlass* instklass_AESCrypt = klass_AESCrypt->as_instance_klass(); 6010 ciInstanceKlass* instklass_AESCrypt = klass_AESCrypt->as_instance_klass();
6002 const TypeKlassPtr* aklass = TypeKlassPtr::make(instklass_AESCrypt); 6011 const TypeKlassPtr* aklass = TypeKlassPtr::make(instklass_AESCrypt);
6003 const TypeOopPtr* xtype = aklass->as_instance_type(); 6012 const TypeOopPtr* xtype = aklass->as_instance_type();
6004 Node* aescrypt_object = new(C) CheckCastPPNode(control(), embeddedCipherObj, xtype); 6013 Node* aescrypt_object = new(C) CheckCastPPNode(control(), embeddedCipherObj, xtype);
6069 // for decryption: 6078 // for decryption:
6070 // if ((embeddedCipherObj instanceof AESCrypt) && (cipher!=plain)) do_intrinsic, else do_javapath 6079 // if ((embeddedCipherObj instanceof AESCrypt) && (cipher!=plain)) do_intrinsic, else do_javapath
6071 // note cipher==plain is more conservative than the original java code but that's OK 6080 // note cipher==plain is more conservative than the original java code but that's OK
6072 // 6081 //
6073 Node* LibraryCallKit::inline_cipherBlockChaining_AESCrypt_predicate(bool decrypting) { 6082 Node* LibraryCallKit::inline_cipherBlockChaining_AESCrypt_predicate(bool decrypting) {
6074 // First, check receiver for NULL since it is virtual method. 6083 // The receiver was checked for NULL already.
6075 Node* objCBC = argument(0); 6084 Node* objCBC = argument(0);
6076 objCBC = null_check(objCBC);
6077
6078 if (stopped()) return NULL; // Always NULL
6079 6085
6080 // Load embeddedCipher field of CipherBlockChaining object. 6086 // Load embeddedCipher field of CipherBlockChaining object.
6081 Node* embeddedCipherObj = load_field_from_object(objCBC, "embeddedCipher", "Lcom/sun/crypto/provider/SymmetricCipher;", /*is_exact*/ false); 6087 Node* embeddedCipherObj = load_field_from_object(objCBC, "embeddedCipher", "Lcom/sun/crypto/provider/SymmetricCipher;", /*is_exact*/ false);
6082 6088
6083 // get AESCrypt klass for instanceOf check 6089 // get AESCrypt klass for instanceOf check

mercurial