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

src/share/vm/opto/library_call.cpp

Print this page




 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   Node* pop_math_arg();
 140   bool runtime_math(const TypeFunc* call_type, address funcAddr, const char* funcName);
 141   bool inline_math_native(vmIntrinsics::ID id);
 142   bool inline_trig(vmIntrinsics::ID id);
 143   bool inline_trans(vmIntrinsics::ID id);
 144   bool inline_abs(vmIntrinsics::ID id);
 145   bool inline_sqrt(vmIntrinsics::ID id);
 146   bool inline_pow(vmIntrinsics::ID id);
 147   bool inline_exp(vmIntrinsics::ID id);
 148   bool inline_min_max(vmIntrinsics::ID id);
 149   Node* generate_min_max(vmIntrinsics::ID id, Node* x, Node* y);
 150   // This returns Type::AnyPtr, RawPtr, or OopPtr.
 151   int classify_unsafe_addr(Node* &base, Node* &offset);
 152   Node* make_unsafe_address(Node* base, Node* offset);
 153   bool inline_unsafe_access(bool is_native_ptr, bool is_store, BasicType type, bool is_volatile);
 154   bool inline_unsafe_prefetch(bool is_native_ptr, bool is_store, bool is_static);
 155   bool inline_unsafe_allocate();
 156   bool inline_unsafe_copyMemory();
 157   bool inline_native_currentThread();
 158   bool inline_native_time_funcs(bool isNano);


 243   }
 244 
 245   // Only a few intrinsics implement a virtual dispatch.
 246   // They are expensive calls which are also frequently overridden.
 247   if (is_virtual) {
 248     switch (id) {
 249     case vmIntrinsics::_hashCode:
 250     case vmIntrinsics::_clone:
 251       // OK, Object.hashCode and Object.clone intrinsics come in both flavors
 252       break;
 253     default:
 254       return NULL;
 255     }
 256   }
 257 
 258   // -XX:-InlineNatives disables nearly all intrinsics:
 259   if (!InlineNatives) {
 260     switch (id) {
 261     case vmIntrinsics::_indexOf:
 262     case vmIntrinsics::_compareTo:

 263     case vmIntrinsics::_equalsC:
 264       break;  // InlineNatives does not control String.compareTo
 265     default:
 266       return NULL;
 267     }
 268   }
 269 
 270   switch (id) {
 271   case vmIntrinsics::_compareTo:
 272     if (!SpecialStringCompareTo)  return NULL;
 273     break;
 274   case vmIntrinsics::_indexOf:
 275     if (!SpecialStringIndexOf)  return NULL;
 276     break;



 277   case vmIntrinsics::_equalsC:
 278     if (!SpecialArraysEquals)  return NULL;
 279     break;
 280   case vmIntrinsics::_arraycopy:
 281     if (!InlineArrayCopy)  return NULL;
 282     break;
 283   case vmIntrinsics::_copyMemory:
 284     if (StubRoutines::unsafe_arraycopy() == NULL)  return NULL;
 285     if (!InlineArrayCopy)  return NULL;
 286     break;
 287   case vmIntrinsics::_hashCode:
 288     if (!InlineObjectHash)  return NULL;
 289     break;
 290   case vmIntrinsics::_clone:
 291   case vmIntrinsics::_copyOf:
 292   case vmIntrinsics::_copyOfRange:
 293     if (!InlineObjectCopy)  return NULL;
 294     // These also use the arraycopy intrinsic mechanism:
 295     if (!InlineArrayCopy)  return NULL;
 296     break;


 419   case vmIntrinsics::_dabs:
 420   case vmIntrinsics::_datan2:
 421   case vmIntrinsics::_dsqrt:
 422   case vmIntrinsics::_dexp:
 423   case vmIntrinsics::_dlog:
 424   case vmIntrinsics::_dlog10:
 425   case vmIntrinsics::_dpow:
 426     return inline_math_native(intrinsic_id());
 427 
 428   case vmIntrinsics::_min:
 429   case vmIntrinsics::_max:
 430     return inline_min_max(intrinsic_id());
 431 
 432   case vmIntrinsics::_arraycopy:
 433     return inline_arraycopy();
 434 
 435   case vmIntrinsics::_compareTo:
 436     return inline_string_compareTo();
 437   case vmIntrinsics::_indexOf:
 438     return inline_string_indexOf();


 439 
 440   case vmIntrinsics::_getObject:
 441     return inline_unsafe_access(!is_native_ptr, !is_store, T_OBJECT, false);
 442   case vmIntrinsics::_getBoolean:
 443     return inline_unsafe_access(!is_native_ptr, !is_store, T_BOOLEAN, false);
 444   case vmIntrinsics::_getByte:
 445     return inline_unsafe_access(!is_native_ptr, !is_store, T_BYTE, false);
 446   case vmIntrinsics::_getShort:
 447     return inline_unsafe_access(!is_native_ptr, !is_store, T_SHORT, false);
 448   case vmIntrinsics::_getChar:
 449     return inline_unsafe_access(!is_native_ptr, !is_store, T_CHAR, false);
 450   case vmIntrinsics::_getInt:
 451     return inline_unsafe_access(!is_native_ptr, !is_store, T_INT, false);
 452   case vmIntrinsics::_getLong:
 453     return inline_unsafe_access(!is_native_ptr, !is_store, T_LONG, false);
 454   case vmIntrinsics::_getFloat:
 455     return inline_unsafe_access(!is_native_ptr, !is_store, T_FLOAT, false);
 456   case vmIntrinsics::_getDouble:
 457     return inline_unsafe_access(!is_native_ptr, !is_store, T_DOUBLE, false);
 458 


 803     return true;
 804   }
 805 
 806   ciInstanceKlass* klass = env()->String_klass();
 807   const TypeInstPtr* string_type =
 808     TypeInstPtr::make(TypePtr::BotPTR, klass, false, NULL, 0);
 809 
 810   Node* compare =
 811     _gvn.transform(new (C, 7) StrCompNode(
 812                         control(),
 813                         memory(TypeAryPtr::CHARS),
 814                         memory(string_type->add_offset(value_offset)),
 815                         memory(string_type->add_offset(count_offset)),
 816                         memory(string_type->add_offset(offset_offset)),
 817                         receiver,
 818                         argument));
 819   push(compare);
 820   return true;
 821 }
 822 












































































 823 //------------------------------inline_array_equals----------------------------
 824 bool LibraryCallKit::inline_array_equals() {
 825 
 826   if (!Matcher::has_match_rule(Op_AryEq)) return false;
 827 
 828   _sp += 2;
 829   Node *argument2 = pop();
 830   Node *argument1 = pop();
 831 
 832   Node* equals =
 833     _gvn.transform(new (C, 3) AryEqNode(control(),
 834                                         argument1,
 835                                         argument2)
 836                    );
 837   push(equals);
 838   return true;
 839 }
 840 
 841 // Java version of String.indexOf(constant string)
 842 // class StringDecl {


 967          }__ end_loop(); __ dead(j);
 968          __ set(rtn, __ SubI(__ value(i), sourceOffset)); __ dead(i);
 969          __ goto_(return_);
 970        }__ end_if();
 971        __ if_then(__ AndI(cache, __ LShiftI(one, src)), BoolTest::eq, zero, likely); {
 972          __ increment(i, targetCountLess1);
 973        }__ end_if();
 974        __ increment(i, one);
 975        __ bind(outer_loop);
 976   }__ end_loop(); __ dead(i);
 977   __ bind(return_);
 978   __ drain_delay_transform();
 979 
 980   set_control(__ ctrl());
 981   Node* result = __ value(rtn);
 982 #undef __
 983   C->set_has_loops(true);
 984   return result;
 985 }
 986 
 987 
 988 //------------------------------inline_string_indexOf------------------------
 989 bool LibraryCallKit::inline_string_indexOf() {
 990 
 991   _sp += 2;
 992   Node *argument = pop();  // pop non-receiver first:  it was pushed second
 993   Node *receiver = pop();
 994 
 995   // don't intrinsify is argument isn't a constant string.
 996   if (!argument->is_Con()) {
 997     return false;
 998   }
 999   const TypeOopPtr* str_type = _gvn.type(argument)->isa_oopptr();
1000   if (str_type == NULL) {
1001     return false;
1002   }
1003   ciInstanceKlass* klass = env()->String_klass();
1004   ciObject* str_const = str_type->const_oop();
1005   if (str_const == NULL || str_const->klass() != klass) {
1006     return false;
1007   }


1024   }
1025 
1026   // Null check on self without removing any arguments.  The argument
1027   // null check technically happens in the wrong place, which can lead to
1028   // invalid stack traces when string compare is inlined into a method
1029   // which handles NullPointerExceptions.
1030   _sp += 2;
1031   receiver = do_null_check(receiver, T_OBJECT);
1032   // No null check on the argument is needed since it's a constant String oop.
1033   _sp -= 2;
1034   if (stopped()) {
1035     return true;
1036   }
1037 
1038   // The null string as a pattern always returns 0 (match at beginning of string)
1039   if (c == 0) {
1040     push(intcon(0));
1041     return true;
1042   }
1043 



















1044   jchar lastChar = pat->char_at(o + (c - 1));
1045   int cache = 0;
1046   int i;
1047   for (i = 0; i < c - 1; i++) {
1048     assert(i < pat->length(), "out of range");
1049     cache |= (1 << (pat->char_at(o + i) & (sizeof(cache) * BitsPerByte - 1)));
1050   }
1051 
1052   int md2 = c;
1053   for (i = 0; i < c - 1; i++) {
1054     assert(i < pat->length(), "out of range");
1055     if (pat->char_at(o + i) == lastChar) {
1056       md2 = (c - 1) - i;
1057     }
1058   }
1059 
1060   Node* result = string_indexOf(receiver, pat, o, cache, md2);

1061   push(result);
1062   return true;
1063 }
1064 
1065 //--------------------------pop_math_arg--------------------------------
1066 // Pop a double argument to a math function from the stack
1067 // rounding it if necessary.
1068 Node * LibraryCallKit::pop_math_arg() {
1069   Node *arg = pop_pair();
1070   if( Matcher::strict_fp_requires_explicit_rounding && UseSSE<=1 )
1071     arg = _gvn.transform( new (C, 2) RoundDoubleNode(0, arg) );
1072   return arg;
1073 }
1074 
1075 //------------------------------inline_trig----------------------------------
1076 // Inline sin/cos/tan instructions, if possible.  If rounding is required, do
1077 // argument reduction which will turn into a fast/slow diamond.
1078 bool LibraryCallKit::inline_trig(vmIntrinsics::ID id) {
1079   _sp += arg_size();            // restore stack pointer
1080   Node* arg = pop_math_arg();




 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);
 156   bool inline_unsafe_allocate();
 157   bool inline_unsafe_copyMemory();
 158   bool inline_native_currentThread();
 159   bool inline_native_time_funcs(bool isNano);


 244   }
 245 
 246   // Only a few intrinsics implement a virtual dispatch.
 247   // They are expensive calls which are also frequently overridden.
 248   if (is_virtual) {
 249     switch (id) {
 250     case vmIntrinsics::_hashCode:
 251     case vmIntrinsics::_clone:
 252       // OK, Object.hashCode and Object.clone intrinsics come in both flavors
 253       break;
 254     default:
 255       return NULL;
 256     }
 257   }
 258 
 259   // -XX:-InlineNatives disables nearly all intrinsics:
 260   if (!InlineNatives) {
 261     switch (id) {
 262     case vmIntrinsics::_indexOf:
 263     case vmIntrinsics::_compareTo:
 264     case vmIntrinsics::_equals:
 265     case vmIntrinsics::_equalsC:
 266       break;  // InlineNatives does not control String.compareTo
 267     default:
 268       return NULL;
 269     }
 270   }
 271 
 272   switch (id) {
 273   case vmIntrinsics::_compareTo:
 274     if (!SpecialStringCompareTo)  return NULL;
 275     break;
 276   case vmIntrinsics::_indexOf:
 277     if (!SpecialStringIndexOf)  return NULL;
 278     break;
 279   case vmIntrinsics::_equals:
 280     if (!SpecialStringEquals)  return NULL;
 281     break;
 282   case vmIntrinsics::_equalsC:
 283     if (!SpecialArraysEquals)  return NULL;
 284     break;
 285   case vmIntrinsics::_arraycopy:
 286     if (!InlineArrayCopy)  return NULL;
 287     break;
 288   case vmIntrinsics::_copyMemory:
 289     if (StubRoutines::unsafe_arraycopy() == NULL)  return NULL;
 290     if (!InlineArrayCopy)  return NULL;
 291     break;
 292   case vmIntrinsics::_hashCode:
 293     if (!InlineObjectHash)  return NULL;
 294     break;
 295   case vmIntrinsics::_clone:
 296   case vmIntrinsics::_copyOf:
 297   case vmIntrinsics::_copyOfRange:
 298     if (!InlineObjectCopy)  return NULL;
 299     // These also use the arraycopy intrinsic mechanism:
 300     if (!InlineArrayCopy)  return NULL;
 301     break;


 424   case vmIntrinsics::_dabs:
 425   case vmIntrinsics::_datan2:
 426   case vmIntrinsics::_dsqrt:
 427   case vmIntrinsics::_dexp:
 428   case vmIntrinsics::_dlog:
 429   case vmIntrinsics::_dlog10:
 430   case vmIntrinsics::_dpow:
 431     return inline_math_native(intrinsic_id());
 432 
 433   case vmIntrinsics::_min:
 434   case vmIntrinsics::_max:
 435     return inline_min_max(intrinsic_id());
 436 
 437   case vmIntrinsics::_arraycopy:
 438     return inline_arraycopy();
 439 
 440   case vmIntrinsics::_compareTo:
 441     return inline_string_compareTo();
 442   case vmIntrinsics::_indexOf:
 443     return inline_string_indexOf();
 444   case vmIntrinsics::_equals:
 445     return inline_string_equals();
 446 
 447   case vmIntrinsics::_getObject:
 448     return inline_unsafe_access(!is_native_ptr, !is_store, T_OBJECT, false);
 449   case vmIntrinsics::_getBoolean:
 450     return inline_unsafe_access(!is_native_ptr, !is_store, T_BOOLEAN, false);
 451   case vmIntrinsics::_getByte:
 452     return inline_unsafe_access(!is_native_ptr, !is_store, T_BYTE, false);
 453   case vmIntrinsics::_getShort:
 454     return inline_unsafe_access(!is_native_ptr, !is_store, T_SHORT, false);
 455   case vmIntrinsics::_getChar:
 456     return inline_unsafe_access(!is_native_ptr, !is_store, T_CHAR, false);
 457   case vmIntrinsics::_getInt:
 458     return inline_unsafe_access(!is_native_ptr, !is_store, T_INT, false);
 459   case vmIntrinsics::_getLong:
 460     return inline_unsafe_access(!is_native_ptr, !is_store, T_LONG, false);
 461   case vmIntrinsics::_getFloat:
 462     return inline_unsafe_access(!is_native_ptr, !is_store, T_FLOAT, false);
 463   case vmIntrinsics::_getDouble:
 464     return inline_unsafe_access(!is_native_ptr, !is_store, T_DOUBLE, false);
 465 


 810     return true;
 811   }
 812 
 813   ciInstanceKlass* klass = env()->String_klass();
 814   const TypeInstPtr* string_type =
 815     TypeInstPtr::make(TypePtr::BotPTR, klass, false, NULL, 0);
 816 
 817   Node* compare =
 818     _gvn.transform(new (C, 7) StrCompNode(
 819                         control(),
 820                         memory(TypeAryPtr::CHARS),
 821                         memory(string_type->add_offset(value_offset)),
 822                         memory(string_type->add_offset(count_offset)),
 823                         memory(string_type->add_offset(offset_offset)),
 824                         receiver,
 825                         argument));
 826   push(compare);
 827   return true;
 828 }
 829 
 830 //------------------------------inline_string_equals------------------------
 831 bool LibraryCallKit::inline_string_equals() {
 832 
 833   if (!Matcher::has_match_rule(Op_StrEquals)) return false;
 834 
 835   const int value_offset = java_lang_String::value_offset_in_bytes();
 836   const int count_offset = java_lang_String::count_offset_in_bytes();
 837   const int offset_offset = java_lang_String::offset_offset_in_bytes();
 838 
 839   _sp += 2;
 840   Node* argument = pop();  // pop non-receiver first:  it was pushed second
 841   Node* receiver = pop();
 842  
 843   
 844   // Null check on self without removing any arguments.  The argument
 845   // null check technically happens in the wrong place, which can lead to
 846   // invalid stack traces when string compare is inlined into a method
 847   // which handles NullPointerExceptions.
 848   _sp += 2;
 849   receiver = do_null_check(receiver, T_OBJECT);
 850   //should not do null check for argument for String.equals(), because spec 
 851   //allows to specify NULL as argument. 
 852   _sp -= 2;
 853   if (stopped()) {
 854     return true;
 855   }
 856 
 857   // get String klass for instanceOf
 858   ciInstanceKlass* klass = env()->String_klass();
 859 
 860   // two paths (plus control) merge
 861   RegionNode* region = new (C, 3) RegionNode(3);
 862   Node* phi = new (C, 3) PhiNode(region, TypeInt::BOOL);
 863 
 864   Node* inst = gen_instanceof(argument, makecon(TypeKlassPtr::make(klass)));
 865   Node* cmp = _gvn.transform(new (C, 3) CmpINode(inst, intcon(1)));
 866   Node* bol  = _gvn.transform(new (C, 2) BoolNode(cmp, BoolTest::eq));
 867 
 868   IfNode* iff = create_and_map_if(control(), bol, PROB_MAX, COUNT_UNKNOWN);
 869 
 870   Node* if_true  = _gvn.transform(new (C, 1) IfTrueNode(iff));
 871   set_control(if_true);
 872 
 873   const TypeInstPtr* string_type =
 874     TypeInstPtr::make(TypePtr::BotPTR, klass, false, NULL, 0);
 875 
 876 // instanceOf == true
 877   Node* equals =    
 878     _gvn.transform(new (C, 7) StrEqualsNode(
 879                         control(),
 880                         memory(TypeAryPtr::CHARS),
 881                         memory(string_type->add_offset(value_offset)),
 882                         memory(string_type->add_offset(count_offset)),
 883                         memory(string_type->add_offset(offset_offset)),
 884                         receiver,

 885                         argument));
 886 
 887   phi->init_req(1, _gvn.transform(equals));
 888   region->init_req(1, if_true);
 889 
 890   //instanceOf == false, fallthrough
 891   Node* if_false = _gvn.transform(new (C, 1) IfFalseNode(iff));
 892   set_control(if_false);
 893 
 894   phi->init_req(2, _gvn.transform(intcon(0)));
 895   region->init_req(2, if_false);
 896 
 897   // post merge
 898   set_control(_gvn.transform(region));
 899   record_for_igvn(region);
 900 
 901   push(_gvn.transform(phi));
 902 
 903   return true;
 904 }
 905 
 906 //------------------------------inline_array_equals----------------------------
 907 bool LibraryCallKit::inline_array_equals() {
 908 
 909   if (!Matcher::has_match_rule(Op_AryEq)) return false;
 910 
 911   _sp += 2;
 912   Node *argument2 = pop();
 913   Node *argument1 = pop();
 914 
 915   Node* equals =
 916     _gvn.transform(new (C, 3) AryEqNode(control(),
 917                                         argument1,
 918                                         argument2)
 919                    );
 920   push(equals);
 921   return true;
 922 }
 923 
 924 // Java version of String.indexOf(constant string)
 925 // class StringDecl {


1050          }__ end_loop(); __ dead(j);
1051          __ set(rtn, __ SubI(__ value(i), sourceOffset)); __ dead(i);
1052          __ goto_(return_);
1053        }__ end_if();
1054        __ if_then(__ AndI(cache, __ LShiftI(one, src)), BoolTest::eq, zero, likely); {
1055          __ increment(i, targetCountLess1);
1056        }__ end_if();
1057        __ increment(i, one);
1058        __ bind(outer_loop);
1059   }__ end_loop(); __ dead(i);
1060   __ bind(return_);
1061   __ drain_delay_transform();
1062 
1063   set_control(__ ctrl());
1064   Node* result = __ value(rtn);
1065 #undef __
1066   C->set_has_loops(true);
1067   return result;
1068 }
1069 

1070 //------------------------------inline_string_indexOf------------------------
1071 bool LibraryCallKit::inline_string_indexOf() {
1072 
1073   _sp += 2;
1074   Node *argument = pop();  // pop non-receiver first:  it was pushed second
1075   Node *receiver = pop();
1076 
1077   // don't intrinsify is argument isn't a constant string.
1078   if (!argument->is_Con()) {
1079     return false;
1080   }
1081   const TypeOopPtr* str_type = _gvn.type(argument)->isa_oopptr();
1082   if (str_type == NULL) {
1083     return false;
1084   }
1085   ciInstanceKlass* klass = env()->String_klass();
1086   ciObject* str_const = str_type->const_oop();
1087   if (str_const == NULL || str_const->klass() != klass) {
1088     return false;
1089   }


1106   }
1107 
1108   // Null check on self without removing any arguments.  The argument
1109   // null check technically happens in the wrong place, which can lead to
1110   // invalid stack traces when string compare is inlined into a method
1111   // which handles NullPointerExceptions.
1112   _sp += 2;
1113   receiver = do_null_check(receiver, T_OBJECT);
1114   // No null check on the argument is needed since it's a constant String oop.
1115   _sp -= 2;
1116   if (stopped()) {
1117     return true;
1118   }
1119 
1120   // The null string as a pattern always returns 0 (match at beginning of string)
1121   if (c == 0) {
1122     push(intcon(0));
1123     return true;
1124   }
1125 
1126   Node* result;
1127   if (Matcher::has_match_rule(Op_StrIndexOf) &&
1128       UseSSE >= 4 && UseSSE42Intrinsics) {
1129     // Generate SSE4.2 version of indexOf
1130     // We currently only have match rules that use SSE4.2
1131     const TypeInstPtr* string_type =
1132       TypeInstPtr::make(TypePtr::BotPTR, klass, false, NULL, 0);
1133 
1134     result =
1135       _gvn.transform(new (C, 7)
1136                      StrIndexOfNode(control(),
1137                                     memory(TypeAryPtr::CHARS),
1138                                     memory(string_type->add_offset(value_offset)),
1139                                     memory(string_type->add_offset(count_offset)),
1140                                     memory(string_type->add_offset(offset_offset)),
1141                                     receiver,
1142                                     argument));
1143   } else {
1144     // Generate default indexOf
1145     jchar lastChar = pat->char_at(o + (c - 1));
1146     int cache = 0;
1147     int i;
1148     for (i = 0; i < c - 1; i++) {
1149       assert(i < pat->length(), "out of range");
1150       cache |= (1 << (pat->char_at(o + i) & (sizeof(cache) * BitsPerByte - 1)));
1151     }
1152 
1153     int md2 = c;
1154     for (i = 0; i < c - 1; i++) {
1155       assert(i < pat->length(), "out of range");
1156       if (pat->char_at(o + i) == lastChar) {
1157         md2 = (c - 1) - i;
1158       }
1159     }
1160 
1161     result = string_indexOf(receiver, pat, o, cache, md2);
1162   }
1163   push(result);
1164   return true;
1165 }
1166 
1167 //--------------------------pop_math_arg--------------------------------
1168 // Pop a double argument to a math function from the stack
1169 // rounding it if necessary.
1170 Node * LibraryCallKit::pop_math_arg() {
1171   Node *arg = pop_pair();
1172   if( Matcher::strict_fp_requires_explicit_rounding && UseSSE<=1 )
1173     arg = _gvn.transform( new (C, 2) RoundDoubleNode(0, arg) );
1174   return arg;
1175 }
1176 
1177 //------------------------------inline_trig----------------------------------
1178 // Inline sin/cos/tan instructions, if possible.  If rounding is required, do
1179 // argument reduction which will turn into a fast/slow diamond.
1180 bool LibraryCallKit::inline_trig(vmIntrinsics::ID id) {
1181   _sp += arg_size();            // restore stack pointer
1182   Node* arg = pop_math_arg();


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