src/share/vm/opto/library_call.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File 6827605 Sdiff src/share/vm/opto

src/share/vm/opto/library_call.cpp

Print this page




 116     return generate_array_guard_common(kls, region, false, true);
 117   }
 118   Node* generate_objArray_guard(Node* kls, RegionNode* region) {
 119     return generate_array_guard_common(kls, region, true, false);
 120   }
 121   Node* generate_non_objArray_guard(Node* kls, RegionNode* region) {
 122     return generate_array_guard_common(kls, region, true, true);
 123   }
 124   Node* generate_array_guard_common(Node* kls, RegionNode* region,
 125                                     bool obj_array, bool not_array);
 126   Node* generate_virtual_guard(Node* obj_klass, RegionNode* slow_region);
 127   CallJavaNode* generate_method_call(vmIntrinsics::ID method_id,
 128                                      bool is_virtual = false, bool is_static = false);
 129   CallJavaNode* generate_method_call_static(vmIntrinsics::ID method_id) {
 130     return generate_method_call(method_id, false, true);
 131   }
 132   CallJavaNode* generate_method_call_virtual(vmIntrinsics::ID method_id) {
 133     return generate_method_call(method_id, true, false);
 134   }
 135 

 136   bool inline_string_compareTo();
 137   bool inline_string_indexOf();
 138   Node* string_indexOf(Node* string_object, ciTypeArray* target_array, jint offset, jint cache_i, jint md2_i);
 139   bool inline_string_equals();
 140   Node* pop_math_arg();
 141   bool runtime_math(const TypeFunc* call_type, address funcAddr, const char* funcName);
 142   bool inline_math_native(vmIntrinsics::ID id);
 143   bool inline_trig(vmIntrinsics::ID id);
 144   bool inline_trans(vmIntrinsics::ID id);
 145   bool inline_abs(vmIntrinsics::ID id);
 146   bool inline_sqrt(vmIntrinsics::ID id);
 147   bool inline_pow(vmIntrinsics::ID id);
 148   bool inline_exp(vmIntrinsics::ID id);
 149   bool inline_min_max(vmIntrinsics::ID id);
 150   Node* generate_min_max(vmIntrinsics::ID id, Node* x, Node* y);
 151   // This returns Type::AnyPtr, RawPtr, or OopPtr.
 152   int classify_unsafe_addr(Node* &base, Node* &offset);
 153   Node* make_unsafe_address(Node* base, Node* offset);
 154   bool inline_unsafe_access(bool is_native_ptr, bool is_store, BasicType type, bool is_volatile);
 155   bool inline_unsafe_prefetch(bool is_native_ptr, bool is_store, bool is_static);


 779     last = _gvn.transform( new (C, 3) AddINode(last, offset));
 780   Node* cmp_lt = _gvn.transform( new (C, 3) CmpUNode(array_length, last) );
 781   Node* bol_lt = _gvn.transform( new (C, 2) BoolNode(cmp_lt, BoolTest::lt) );
 782   Node* is_over = generate_guard(bol_lt, region, PROB_MIN);
 783   return is_over;
 784 }
 785 
 786 
 787 //--------------------------generate_current_thread--------------------
 788 Node* LibraryCallKit::generate_current_thread(Node* &tls_output) {
 789   ciKlass*    thread_klass = env()->Thread_klass();
 790   const Type* thread_type  = TypeOopPtr::make_from_klass(thread_klass)->cast_to_ptr_type(TypePtr::NotNull);
 791   Node* thread = _gvn.transform(new (C, 1) ThreadLocalNode());
 792   Node* p = basic_plus_adr(top()/*!oop*/, thread, in_bytes(JavaThread::threadObj_offset()));
 793   Node* threadObj = make_load(NULL, p, thread_type, T_OBJECT);
 794   tls_output = thread;
 795   return threadObj;
 796 }
 797 
 798 


























































 799 //------------------------------inline_string_compareTo------------------------
 800 bool LibraryCallKit::inline_string_compareTo() {
 801 
 802   if (!Matcher::has_match_rule(Op_StrComp)) return false;
 803 
 804   const int value_offset = java_lang_String::value_offset_in_bytes();
 805   const int count_offset = java_lang_String::count_offset_in_bytes();
 806   const int offset_offset = java_lang_String::offset_offset_in_bytes();
 807 
 808   _sp += 2;
 809   Node *argument = pop();  // pop non-receiver first:  it was pushed second
 810   Node *receiver = pop();
 811 
 812   // Null check on self without removing any arguments.  The argument
 813   // null check technically happens in the wrong place, which can lead to
 814   // invalid stack traces when string compare is inlined into a method
 815   // which handles NullPointerExceptions.
 816   _sp += 2;
 817   receiver = do_null_check(receiver, T_OBJECT);
 818   argument = do_null_check(argument, T_OBJECT);
 819   _sp -= 2;
 820   if (stopped()) {
 821     return true;
 822   }
 823 
 824   ciInstanceKlass* klass = env()->String_klass();
 825   const TypeInstPtr* string_type =
 826     TypeInstPtr::make(TypePtr::BotPTR, klass, false, NULL, 0);

 827 
 828   Node* compare =
 829     _gvn.transform(new (C, 7) StrCompNode(
 830                         control(),
 831                         memory(TypeAryPtr::CHARS),
 832                         memory(string_type->add_offset(value_offset)),
 833                         memory(string_type->add_offset(count_offset)),
 834                         memory(string_type->add_offset(offset_offset)),
 835                         receiver,
 836                         argument));
 837   push(compare);
 838   return true;
 839 }
 840 
 841 //------------------------------inline_string_equals------------------------
 842 bool LibraryCallKit::inline_string_equals() {
 843 
 844   if (!Matcher::has_match_rule(Op_StrEquals)) return false;
 845 
 846   const int value_offset = java_lang_String::value_offset_in_bytes();
 847   const int count_offset = java_lang_String::count_offset_in_bytes();
 848   const int offset_offset = java_lang_String::offset_offset_in_bytes();
 849 
 850   _sp += 2;
 851   Node* argument = pop();  // pop non-receiver first:  it was pushed second
 852   Node* receiver = pop();
 853 
 854   // Null check on self without removing any arguments.  The argument
 855   // null check technically happens in the wrong place, which can lead to
 856   // invalid stack traces when string compare is inlined into a method
 857   // which handles NullPointerExceptions.
 858   _sp += 2;
 859   receiver = do_null_check(receiver, T_OBJECT);
 860   //should not do null check for argument for String.equals(), because spec
 861   //allows to specify NULL as argument.
 862   _sp -= 2;
 863 
 864   if (stopped()) {
 865     return true;
 866   }
 867 















 868   // get String klass for instanceOf
 869   ciInstanceKlass* klass = env()->String_klass();
 870 
 871   // two paths (plus control) merge
 872   RegionNode* region = new (C, 3) RegionNode(3);
 873   Node* phi = new (C, 3) PhiNode(region, TypeInt::BOOL);
 874 
 875   Node* inst = gen_instanceof(argument, makecon(TypeKlassPtr::make(klass)));
 876   Node* cmp  = _gvn.transform(new (C, 3) CmpINode(inst, intcon(1)));
 877   Node* bol  = _gvn.transform(new (C, 2) BoolNode(cmp, BoolTest::eq));
 878 
 879   IfNode* iff = create_and_map_if(control(), bol, PROB_MAX, COUNT_UNKNOWN);

 880 
 881   Node* if_true  = _gvn.transform(new (C, 1) IfTrueNode(iff));
 882   set_control(if_true);



 883 
 884   const TypeInstPtr* string_type =
 885     TypeInstPtr::make(TypePtr::BotPTR, klass, false, NULL, 0);
 886 
 887   // instanceOf == true
 888   Node* equals =
 889     _gvn.transform(new (C, 7) StrEqualsNode(
 890                         control(),
 891                         memory(TypeAryPtr::CHARS),
 892                         memory(string_type->add_offset(value_offset)),
 893                         memory(string_type->add_offset(count_offset)),
 894                         memory(string_type->add_offset(offset_offset)),
 895                         receiver,
 896                         argument));
 897 
 898   phi->init_req(1, _gvn.transform(equals));
 899   region->init_req(1, if_true);


 900 
 901   //instanceOf == false, fallthrough
 902   Node* if_false = _gvn.transform(new (C, 1) IfFalseNode(iff));
 903   set_control(if_false);
 904 
 905   phi->init_req(2, _gvn.transform(intcon(0)));
 906   region->init_req(2, if_false);







 907 








 908   // post merge
 909   set_control(_gvn.transform(region));
 910   record_for_igvn(region);
 911 
 912   push(_gvn.transform(phi));
 913 
 914   return true;
 915 }
 916 
 917 //------------------------------inline_array_equals----------------------------
 918 bool LibraryCallKit::inline_array_equals() {
 919 
 920   if (!Matcher::has_match_rule(Op_AryEq)) return false;
 921 
 922   _sp += 2;
 923   Node *argument2 = pop();
 924   Node *argument1 = pop();
 925 
 926   Node* equals =
 927     _gvn.transform(new (C, 3) AryEqNode(control(),
 928                                         argument1,
 929                                         argument2)
 930                    );
 931   push(equals);
 932   return true;
 933 }
 934 
 935 // Java version of String.indexOf(constant string)
 936 // class StringDecl {
 937 //   StringDecl(char[] ca) {
 938 //     offset = 0;
 939 //     count = ca.length;
 940 //     value = ca;
 941 //   }
 942 //   int offset;
 943 //   int count;
 944 //   char[] value;
 945 // }
 946 //
 947 // static int string_indexOf_J(StringDecl string_object, char[] target_object,
 948 //                             int targetOffset, int cache_i, int md2) {
 949 //   int cache = cache_i;
 950 //   int sourceOffset = string_object.offset;


1091 
1092   Node* result;
1093   if (Matcher::has_match_rule(Op_StrIndexOf) &&
1094       UseSSE42Intrinsics) {
1095     // Generate SSE4.2 version of indexOf
1096     // We currently only have match rules that use SSE4.2
1097 
1098     // Null check on self without removing any arguments.  The argument
1099     // null check technically happens in the wrong place, which can lead to
1100     // invalid stack traces when string compare is inlined into a method
1101     // which handles NullPointerExceptions.
1102     _sp += 2;
1103     receiver = do_null_check(receiver, T_OBJECT);
1104     argument = do_null_check(argument, T_OBJECT);
1105     _sp -= 2;
1106 
1107     if (stopped()) {
1108       return true;
1109     }
1110 





1111     ciInstanceKlass* klass = env()->String_klass();
1112     const TypeInstPtr* string_type =
1113       TypeInstPtr::make(TypePtr::BotPTR, klass, false, NULL, 0);
1114 
1115     result =
1116       _gvn.transform(new (C, 7)
1117                      StrIndexOfNode(control(),
1118                                     memory(TypeAryPtr::CHARS),
1119                                     memory(string_type->add_offset(value_offset)),
1120                                     memory(string_type->add_offset(count_offset)),
1121                                     memory(string_type->add_offset(offset_offset)),
1122                                     receiver,
1123                                     argument));
















1124   } else { //Use LibraryCallKit::string_indexOf
1125     // don't intrinsify is argument isn't a constant string.
1126     if (!argument->is_Con()) {
1127      return false;
1128     }
1129     const TypeOopPtr* str_type = _gvn.type(argument)->isa_oopptr();
1130     if (str_type == NULL) {
1131       return false;
1132     }
1133     ciInstanceKlass* klass = env()->String_klass();
1134     ciObject* str_const = str_type->const_oop();
1135     if (str_const == NULL || str_const->klass() != klass) {
1136       return false;
1137     }
1138     ciInstance* str = str_const->as_instance();
1139     assert(str != NULL, "must be instance");
1140 
1141     ciObject* v = str->field_value_by_offset(value_offset).as_object();
1142     int       o = str->field_value_by_offset(offset_offset).as_int();
1143     int       c = str->field_value_by_offset(count_offset).as_int();




 116     return generate_array_guard_common(kls, region, false, true);
 117   }
 118   Node* generate_objArray_guard(Node* kls, RegionNode* region) {
 119     return generate_array_guard_common(kls, region, true, false);
 120   }
 121   Node* generate_non_objArray_guard(Node* kls, RegionNode* region) {
 122     return generate_array_guard_common(kls, region, true, true);
 123   }
 124   Node* generate_array_guard_common(Node* kls, RegionNode* region,
 125                                     bool obj_array, bool not_array);
 126   Node* generate_virtual_guard(Node* obj_klass, RegionNode* slow_region);
 127   CallJavaNode* generate_method_call(vmIntrinsics::ID method_id,
 128                                      bool is_virtual = false, bool is_static = false);
 129   CallJavaNode* generate_method_call_static(vmIntrinsics::ID method_id) {
 130     return generate_method_call(method_id, false, true);
 131   }
 132   CallJavaNode* generate_method_call_virtual(vmIntrinsics::ID method_id) {
 133     return generate_method_call(method_id, true, false);
 134   }
 135 
 136   Node* make_string_method_node(int opcode, Node* str1, Node* cnt1, Node* str2, Node* cnt2);
 137   bool inline_string_compareTo();
 138   bool inline_string_indexOf();
 139   Node* string_indexOf(Node* string_object, ciTypeArray* target_array, jint offset, jint cache_i, jint md2_i);
 140   bool inline_string_equals();
 141   Node* pop_math_arg();
 142   bool runtime_math(const TypeFunc* call_type, address funcAddr, const char* funcName);
 143   bool inline_math_native(vmIntrinsics::ID id);
 144   bool inline_trig(vmIntrinsics::ID id);
 145   bool inline_trans(vmIntrinsics::ID id);
 146   bool inline_abs(vmIntrinsics::ID id);
 147   bool inline_sqrt(vmIntrinsics::ID id);
 148   bool inline_pow(vmIntrinsics::ID id);
 149   bool inline_exp(vmIntrinsics::ID id);
 150   bool inline_min_max(vmIntrinsics::ID id);
 151   Node* generate_min_max(vmIntrinsics::ID id, Node* x, Node* y);
 152   // This returns Type::AnyPtr, RawPtr, or OopPtr.
 153   int classify_unsafe_addr(Node* &base, Node* &offset);
 154   Node* make_unsafe_address(Node* base, Node* offset);
 155   bool inline_unsafe_access(bool is_native_ptr, bool is_store, BasicType type, bool is_volatile);
 156   bool inline_unsafe_prefetch(bool is_native_ptr, bool is_store, bool is_static);


 780     last = _gvn.transform( new (C, 3) AddINode(last, offset));
 781   Node* cmp_lt = _gvn.transform( new (C, 3) CmpUNode(array_length, last) );
 782   Node* bol_lt = _gvn.transform( new (C, 2) BoolNode(cmp_lt, BoolTest::lt) );
 783   Node* is_over = generate_guard(bol_lt, region, PROB_MIN);
 784   return is_over;
 785 }
 786 
 787 
 788 //--------------------------generate_current_thread--------------------
 789 Node* LibraryCallKit::generate_current_thread(Node* &tls_output) {
 790   ciKlass*    thread_klass = env()->Thread_klass();
 791   const Type* thread_type  = TypeOopPtr::make_from_klass(thread_klass)->cast_to_ptr_type(TypePtr::NotNull);
 792   Node* thread = _gvn.transform(new (C, 1) ThreadLocalNode());
 793   Node* p = basic_plus_adr(top()/*!oop*/, thread, in_bytes(JavaThread::threadObj_offset()));
 794   Node* threadObj = make_load(NULL, p, thread_type, T_OBJECT);
 795   tls_output = thread;
 796   return threadObj;
 797 }
 798 
 799 
 800 //------------------------------make_string_method_node------------------------
 801 // Helper method for String intrinsic finctions.
 802 Node* LibraryCallKit::make_string_method_node(int opcode, Node* str1, Node* cnt1, Node* str2, Node* cnt2) {
 803   const int value_offset  = java_lang_String::value_offset_in_bytes();
 804   const int count_offset  = java_lang_String::count_offset_in_bytes();
 805   const int offset_offset = java_lang_String::offset_offset_in_bytes();
 806 
 807   Node* no_ctrl = NULL;
 808 
 809   ciInstanceKlass* klass = env()->String_klass();
 810   const TypeInstPtr* string_type =
 811         TypeInstPtr::make(TypePtr::BotPTR, klass, false, NULL, 0);
 812 
 813   const TypeAryPtr* value_type = 
 814         TypeAryPtr::make(TypePtr::NotNull,
 815                          TypeAry::make(TypeInt::CHAR,TypeInt::POS),
 816                          ciTypeArrayKlass::make(T_CHAR), true, 0);
 817 
 818   // Get start addr of string and substring
 819   Node* str1_valuea  = basic_plus_adr(str1, str1, value_offset);
 820   Node* str1_value   = make_load(no_ctrl, str1_valuea, value_type, T_OBJECT, string_type->add_offset(value_offset));
 821   Node* str1_offseta = basic_plus_adr(str1, str1, offset_offset);
 822   Node* str1_offset  = make_load(no_ctrl, str1_offseta, TypeInt::INT, T_INT, string_type->add_offset(offset_offset));
 823   Node* str1_start   = array_element_address(str1_value, str1_offset, T_CHAR);
 824 
 825   // Pin loads from String::equals() argument since it could be NULL.
 826   Node* str2_ctrl = (opcode == Op_StrEquals) ? control() : no_ctrl;
 827   Node* str2_valuea  = basic_plus_adr(str2, str2, value_offset);
 828   Node* str2_value   = make_load(str2_ctrl, str2_valuea, value_type, T_OBJECT, string_type->add_offset(value_offset));
 829   Node* str2_offseta = basic_plus_adr(str2, str2, offset_offset);
 830   Node* str2_offset  = make_load(str2_ctrl, str2_offseta, TypeInt::INT, T_INT, string_type->add_offset(offset_offset));
 831   Node* str2_start   = array_element_address(str2_value, str2_offset, T_CHAR);
 832 
 833   Node* result = NULL;
 834   switch (opcode) {
 835   case Op_StrIndexOf:
 836     result = new (C, 6) StrIndexOfNode(control(), memory(TypeAryPtr::CHARS),
 837                                        str1_start, cnt1, str2_start, cnt2);
 838     break;
 839   case Op_StrComp:
 840     result = new (C, 6) StrCompNode(control(), memory(TypeAryPtr::CHARS),
 841                                     str1_start, cnt1, str2_start, cnt2);
 842     break;
 843   case Op_StrEquals:
 844     result = new (C, 5) StrEqualsNode(control(), memory(TypeAryPtr::CHARS),
 845                                       str1_start, str2_start, cnt1);
 846     break;
 847   default:
 848     ShouldNotReachHere();
 849     return NULL;
 850   }
 851 
 852   // All these intrinsics have checks.
 853   C->set_has_split_ifs(true); // Has chance for split-if optimization
 854 
 855   return _gvn.transform(result);
 856 }
 857 
 858 //------------------------------inline_string_compareTo------------------------
 859 bool LibraryCallKit::inline_string_compareTo() {
 860 
 861   if (!Matcher::has_match_rule(Op_StrComp)) return false;
 862 
 863   const int value_offset = java_lang_String::value_offset_in_bytes();
 864   const int count_offset = java_lang_String::count_offset_in_bytes();
 865   const int offset_offset = java_lang_String::offset_offset_in_bytes();
 866 
 867   _sp += 2;
 868   Node *argument = pop();  // pop non-receiver first:  it was pushed second
 869   Node *receiver = pop();
 870 
 871   // Null check on self without removing any arguments.  The argument
 872   // null check technically happens in the wrong place, which can lead to
 873   // invalid stack traces when string compare is inlined into a method
 874   // which handles NullPointerExceptions.
 875   _sp += 2;
 876   receiver = do_null_check(receiver, T_OBJECT);
 877   argument = do_null_check(argument, T_OBJECT);
 878   _sp -= 2;
 879   if (stopped()) {
 880     return true;
 881   }
 882 
 883   ciInstanceKlass* klass = env()->String_klass();
 884   const TypeInstPtr* string_type =
 885     TypeInstPtr::make(TypePtr::BotPTR, klass, false, NULL, 0);
 886   Node* no_ctrl = NULL;
 887 
 888   // Get counts for string and argument
 889   Node* receiver_cnta = basic_plus_adr(receiver, receiver, count_offset);
 890   Node* receiver_cnt  = make_load(no_ctrl, receiver_cnta, TypeInt::INT, T_INT, string_type->add_offset(count_offset));
 891 
 892   Node* argument_cnta = basic_plus_adr(argument, argument, count_offset);
 893   Node* argument_cnt  = make_load(no_ctrl, argument_cnta, TypeInt::INT, T_INT, string_type->add_offset(count_offset));
 894 
 895   Node* compare = make_string_method_node(Op_StrComp, receiver, receiver_cnt, argument, argument_cnt);

 896   push(compare);
 897   return true;
 898 }
 899 
 900 //------------------------------inline_string_equals------------------------
 901 bool LibraryCallKit::inline_string_equals() {
 902 
 903   if (!Matcher::has_match_rule(Op_StrEquals)) return false;
 904 
 905   const int value_offset = java_lang_String::value_offset_in_bytes();
 906   const int count_offset = java_lang_String::count_offset_in_bytes();
 907   const int offset_offset = java_lang_String::offset_offset_in_bytes();
 908 
 909   _sp += 2;
 910   Node* argument = pop();  // pop non-receiver first:  it was pushed second
 911   Node* receiver = pop();
 912 
 913   // Null check on self without removing any arguments.  The argument
 914   // null check technically happens in the wrong place, which can lead to
 915   // invalid stack traces when string compare is inlined into a method
 916   // which handles NullPointerExceptions.
 917   _sp += 2;
 918   receiver = do_null_check(receiver, T_OBJECT);
 919   //should not do null check for argument for String.equals(), because spec
 920   //allows to specify NULL as argument.
 921   _sp -= 2;
 922 
 923   if (stopped()) {
 924     return true;
 925   }
 926 
 927   // paths (plus control) merge
 928   RegionNode* region = new (C, 5) RegionNode(5);
 929   Node* phi = new (C, 5) PhiNode(region, TypeInt::BOOL);
 930 
 931   // does source == target string?
 932   Node* cmp = _gvn.transform(new (C, 3) CmpPNode(receiver, argument));
 933   Node* bol = _gvn.transform(new (C, 2) BoolNode(cmp, BoolTest::eq));
 934 
 935   Node* if_eq = generate_slow_guard(bol, NULL);
 936   if (if_eq != NULL) {
 937     // receiver == argument
 938     phi->init_req(2, intcon(1));
 939     region->init_req(2, if_eq);
 940   }
 941 
 942   // get String klass for instanceOf
 943   ciInstanceKlass* klass = env()->String_klass();
 944 
 945   if (!stopped()) {



 946     Node* inst = gen_instanceof(argument, makecon(TypeKlassPtr::make(klass)));
 947     Node* cmp  = _gvn.transform(new (C, 3) CmpINode(inst, intcon(1)));
 948     Node* bol  = _gvn.transform(new (C, 2) BoolNode(cmp, BoolTest::ne));
 949 
 950     Node* inst_false = generate_guard(bol, NULL, PROB_MIN);
 951     //instanceOf == true, fallthrough
 952 
 953     if (inst_false != NULL) {
 954       phi->init_req(3, intcon(0));
 955       region->init_req(3, inst_false);
 956     }
 957   }
 958 
 959   const TypeInstPtr* string_type =
 960     TypeInstPtr::make(TypePtr::BotPTR, klass, false, NULL, 0);
 961 
 962   Node* no_ctrl = NULL;
 963   Node* receiver_cnt;
 964   Node* argument_cnt;







 965 
 966   if (!stopped()) {
 967     // Get counts for string and argument
 968     Node* receiver_cnta = basic_plus_adr(receiver, receiver, count_offset);
 969     receiver_cnt  = make_load(no_ctrl, receiver_cnta, TypeInt::INT, T_INT, string_type->add_offset(count_offset));
 970 
 971     // Pin load from argument string since it could be NULL.
 972     Node* argument_cnta = basic_plus_adr(argument, argument, count_offset);
 973     argument_cnt  = make_load(control(), argument_cnta, TypeInt::INT, T_INT, string_type->add_offset(count_offset));
 974 
 975     // Check for receiver count != argument count
 976     Node* cmp = _gvn.transform( new(C, 3) CmpINode(receiver_cnt, argument_cnt) );
 977     Node* bol = _gvn.transform( new(C, 2) BoolNode(cmp, BoolTest::ne) );
 978     Node* if_ne = generate_slow_guard(bol, NULL);
 979     if (if_ne != NULL) {
 980       phi->init_req(4, intcon(0));
 981       region->init_req(4, if_ne);
 982     }
 983   }
 984 
 985   // Check for count == 0 is done by mach node StrEquals.
 986 
 987   if (!stopped()) {
 988     Node* equals = make_string_method_node(Op_StrEquals, receiver, receiver_cnt, argument, argument_cnt);
 989     phi->init_req(1, equals);
 990     region->init_req(1, control());
 991   }
 992 
 993   // post merge
 994   set_control(_gvn.transform(region));
 995   record_for_igvn(region);
 996 
 997   push(_gvn.transform(phi));
 998 
 999   return true;
1000 }
1001 
1002 //------------------------------inline_array_equals----------------------------
1003 bool LibraryCallKit::inline_array_equals() {
1004 
1005   if (!Matcher::has_match_rule(Op_AryEq)) return false;
1006 
1007   _sp += 2;
1008   Node *argument2 = pop();
1009   Node *argument1 = pop();
1010 
1011   Node* equals =
1012     _gvn.transform(new (C, 4) AryEqNode(control(), memory(TypeAryPtr::CHARS),
1013                                         argument1, argument2) );


1014   push(equals);
1015   return true;
1016 }
1017 
1018 // Java version of String.indexOf(constant string)
1019 // class StringDecl {
1020 //   StringDecl(char[] ca) {
1021 //     offset = 0;
1022 //     count = ca.length;
1023 //     value = ca;
1024 //   }
1025 //   int offset;
1026 //   int count;
1027 //   char[] value;
1028 // }
1029 //
1030 // static int string_indexOf_J(StringDecl string_object, char[] target_object,
1031 //                             int targetOffset, int cache_i, int md2) {
1032 //   int cache = cache_i;
1033 //   int sourceOffset = string_object.offset;


1174 
1175   Node* result;
1176   if (Matcher::has_match_rule(Op_StrIndexOf) &&
1177       UseSSE42Intrinsics) {
1178     // Generate SSE4.2 version of indexOf
1179     // We currently only have match rules that use SSE4.2
1180 
1181     // Null check on self without removing any arguments.  The argument
1182     // null check technically happens in the wrong place, which can lead to
1183     // invalid stack traces when string compare is inlined into a method
1184     // which handles NullPointerExceptions.
1185     _sp += 2;
1186     receiver = do_null_check(receiver, T_OBJECT);
1187     argument = do_null_check(argument, T_OBJECT);
1188     _sp -= 2;
1189 
1190     if (stopped()) {
1191       return true;
1192     }
1193 
1194     // Make the merge point
1195     RegionNode* result_rgn = new (C, 3) RegionNode(3);
1196     Node*       result_phi = new (C, 3) PhiNode(result_rgn, TypeInt::INT);
1197     Node* no_ctrl  = NULL;
1198 
1199     ciInstanceKlass* klass = env()->String_klass();
1200     const TypeInstPtr* string_type =
1201       TypeInstPtr::make(TypePtr::BotPTR, klass, false, NULL, 0);
1202 
1203     // Get counts for string and substr
1204     Node* source_cnta = basic_plus_adr(receiver, receiver, count_offset);
1205     Node* source_cnt  = make_load(no_ctrl, source_cnta, TypeInt::INT, T_INT, string_type->add_offset(count_offset));
1206 
1207     Node* substr_cnta = basic_plus_adr(argument, argument, count_offset);
1208     Node* substr_cnt  = make_load(no_ctrl, substr_cnta, TypeInt::INT, T_INT, string_type->add_offset(count_offset));
1209 
1210     // Check for substr count > string count
1211     Node* cmp = _gvn.transform( new(C, 3) CmpINode(substr_cnt, source_cnt) );
1212     Node* bol = _gvn.transform( new(C, 2) BoolNode(cmp, BoolTest::gt) );
1213     Node* if_gt = generate_slow_guard(bol, NULL);
1214     if (if_gt != NULL) {
1215       result_phi->init_req(2, intcon(-1));
1216       result_rgn->init_req(2, if_gt);
1217     }
1218 
1219     if (!stopped()) {
1220       result = make_string_method_node(Op_StrIndexOf, receiver, source_cnt, argument, substr_cnt);
1221       result_phi->init_req(1, result);
1222       result_rgn->init_req(1, control());
1223     }
1224     set_control(_gvn.transform(result_rgn));
1225     record_for_igvn(result_rgn);
1226     result = _gvn.transform(result_phi);
1227     
1228   } else { //Use LibraryCallKit::string_indexOf
1229     // don't intrinsify is argument isn't a constant string.
1230     if (!argument->is_Con()) {
1231      return false;
1232     }
1233     const TypeOopPtr* str_type = _gvn.type(argument)->isa_oopptr();
1234     if (str_type == NULL) {
1235       return false;
1236     }
1237     ciInstanceKlass* klass = env()->String_klass();
1238     ciObject* str_const = str_type->const_oop();
1239     if (str_const == NULL || str_const->klass() != klass) {
1240       return false;
1241     }
1242     ciInstance* str = str_const->as_instance();
1243     assert(str != NULL, "must be instance");
1244 
1245     ciObject* v = str->field_value_by_offset(value_offset).as_object();
1246     int       o = str->field_value_by_offset(offset_offset).as_int();
1247     int       c = str->field_value_by_offset(count_offset).as_int();


src/share/vm/opto/library_call.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File