src/share/vm/opto/stringopts.cpp

changeset 3889
751bd303aa45
parent 3760
8f972594effc
child 3927
ed21db7b3fda
     1.1 --- a/src/share/vm/opto/stringopts.cpp	Fri Jun 22 10:40:48 2012 -0700
     1.2 +++ b/src/share/vm/opto/stringopts.cpp	Tue Jun 26 09:06:16 2012 -0700
     1.3 @@ -112,6 +112,7 @@
     1.4      _arguments->ins_req(0, value);
     1.5      _mode.insert_before(0, mode);
     1.6    }
     1.7 +
     1.8    void push_string(Node* value) {
     1.9      push(value, StringMode);
    1.10    }
    1.11 @@ -125,9 +126,56 @@
    1.12      push(value, CharMode);
    1.13    }
    1.14  
    1.15 +  static bool is_SB_toString(Node* call) {
    1.16 +    if (call->is_CallStaticJava()) {
    1.17 +      CallStaticJavaNode* csj = call->as_CallStaticJava();
    1.18 +      ciMethod* m = csj->method();
    1.19 +      if (m != NULL &&
    1.20 +          (m->intrinsic_id() == vmIntrinsics::_StringBuilder_toString ||
    1.21 +           m->intrinsic_id() == vmIntrinsics::_StringBuffer_toString)) {
    1.22 +        return true;
    1.23 +      }
    1.24 +    }
    1.25 +    return false;
    1.26 +  }
    1.27 +
    1.28 +  static Node* skip_string_null_check(Node* value) {
    1.29 +    // Look for a diamond shaped Null check of toString() result
    1.30 +    // (could be code from String.valueOf()):
    1.31 +    // (Proj == NULL) ? "null":"CastPP(Proj)#NotNULL
    1.32 +    if (value->is_Phi()) {
    1.33 +      int true_path = value->as_Phi()->is_diamond_phi();
    1.34 +      if (true_path != 0) {
    1.35 +        // phi->region->if_proj->ifnode->bool
    1.36 +        BoolNode* b = value->in(0)->in(1)->in(0)->in(1)->as_Bool();
    1.37 +        Node* cmp = b->in(1);
    1.38 +        Node* v1 = cmp->in(1);
    1.39 +        Node* v2 = cmp->in(2);
    1.40 +        // Null check of the return of toString which can simply be skipped.
    1.41 +        if (b->_test._test == BoolTest::ne &&
    1.42 +            v2->bottom_type() == TypePtr::NULL_PTR &&
    1.43 +            value->in(true_path)->Opcode() == Op_CastPP &&
    1.44 +            value->in(true_path)->in(1) == v1 &&
    1.45 +            v1->is_Proj() && is_SB_toString(v1->in(0))) {
    1.46 +          return v1;
    1.47 +        }
    1.48 +      }
    1.49 +    }
    1.50 +    return value;
    1.51 +  }
    1.52 +
    1.53    Node* argument(int i) {
    1.54      return _arguments->in(i);
    1.55    }
    1.56 +  Node* argument_uncast(int i) {
    1.57 +    Node* arg = argument(i);
    1.58 +    int amode = mode(i);
    1.59 +    if (amode == StringConcat::StringMode ||
    1.60 +        amode == StringConcat::StringNullCheckMode) {
    1.61 +      arg = skip_string_null_check(arg);
    1.62 +    }
    1.63 +    return arg;
    1.64 +  }
    1.65    void set_argument(int i, Node* value) {
    1.66      _arguments->set_req(i, value);
    1.67    }
    1.68 @@ -206,9 +254,11 @@
    1.69  
    1.70  
    1.71  void StringConcat::eliminate_unneeded_control() {
    1.72 -  eliminate_initialize(begin()->initialization());
    1.73    for (uint i = 0; i < _control.size(); i++) {
    1.74      Node* n = _control.at(i);
    1.75 +    if (n->is_Allocate()) {
    1.76 +      eliminate_initialize(n->as_Allocate()->initialization());
    1.77 +    }
    1.78      if (n->is_Call()) {
    1.79        if (n != _end) {
    1.80          eliminate_call(n->as_Call());
    1.81 @@ -239,14 +289,15 @@
    1.82    assert(result->_control.contains(other->_end), "what?");
    1.83    assert(result->_control.contains(_begin), "what?");
    1.84    for (int x = 0; x < num_arguments(); x++) {
    1.85 -    if (argument(x) == arg) {
    1.86 +    Node* argx = argument_uncast(x);
    1.87 +    if (argx == arg) {
    1.88        // replace the toString result with the all the arguments that
    1.89        // made up the other StringConcat
    1.90        for (int y = 0; y < other->num_arguments(); y++) {
    1.91          result->append(other->argument(y), other->mode(y));
    1.92        }
    1.93      } else {
    1.94 -      result->append(argument(x), mode(x));
    1.95 +      result->append(argx, mode(x));
    1.96      }
    1.97    }
    1.98    result->set_allocation(other->_begin);
    1.99 @@ -327,14 +378,9 @@
   1.100  
   1.101    while (worklist.size() > 0) {
   1.102      Node* ctrl = worklist.pop();
   1.103 -    if (ctrl->is_CallStaticJava()) {
   1.104 +    if (StringConcat::is_SB_toString(ctrl)) {
   1.105        CallStaticJavaNode* csj = ctrl->as_CallStaticJava();
   1.106 -      ciMethod* m = csj->method();
   1.107 -      if (m != NULL &&
   1.108 -          (m->intrinsic_id() == vmIntrinsics::_StringBuffer_toString ||
   1.109 -           m->intrinsic_id() == vmIntrinsics::_StringBuilder_toString)) {
   1.110 -        string_calls.push(csj);
   1.111 -      }
   1.112 +      string_calls.push(csj);
   1.113      }
   1.114      if (ctrl->in(0) != NULL && !_visited.test_set(ctrl->in(0)->_idx)) {
   1.115        worklist.push(ctrl->in(0));
   1.116 @@ -550,44 +596,40 @@
   1.117    for (int c = 0; c < concats.length(); c++) {
   1.118      StringConcat* sc = concats.at(c);
   1.119      for (int i = 0; i < sc->num_arguments(); i++) {
   1.120 -      Node* arg = sc->argument(i);
   1.121 -      if (arg->is_Proj() && arg->in(0)->is_CallStaticJava()) {
   1.122 +      Node* arg = sc->argument_uncast(i);
   1.123 +      if (arg->is_Proj() && StringConcat::is_SB_toString(arg->in(0))) {
   1.124          CallStaticJavaNode* csj = arg->in(0)->as_CallStaticJava();
   1.125 -        if (csj->method() != NULL &&
   1.126 -            (csj->method()->intrinsic_id() == vmIntrinsics::_StringBuilder_toString ||
   1.127 -             csj->method()->intrinsic_id() == vmIntrinsics::_StringBuffer_toString)) {
   1.128 -          for (int o = 0; o < concats.length(); o++) {
   1.129 -            if (c == o) continue;
   1.130 -            StringConcat* other = concats.at(o);
   1.131 -            if (other->end() == csj) {
   1.132 +        for (int o = 0; o < concats.length(); o++) {
   1.133 +          if (c == o) continue;
   1.134 +          StringConcat* other = concats.at(o);
   1.135 +          if (other->end() == csj) {
   1.136 +#ifndef PRODUCT
   1.137 +            if (PrintOptimizeStringConcat) {
   1.138 +              tty->print_cr("considering stacked concats");
   1.139 +            }
   1.140 +#endif
   1.141 +
   1.142 +            StringConcat* merged = sc->merge(other, arg);
   1.143 +            if (merged->validate_control_flow()) {
   1.144  #ifndef PRODUCT
   1.145                if (PrintOptimizeStringConcat) {
   1.146 -                tty->print_cr("considering stacked concats");
   1.147 +                tty->print_cr("stacking would succeed");
   1.148                }
   1.149  #endif
   1.150 -
   1.151 -              StringConcat* merged = sc->merge(other, arg);
   1.152 -              if (merged->validate_control_flow()) {
   1.153 +              if (c < o) {
   1.154 +                concats.remove_at(o);
   1.155 +                concats.at_put(c, merged);
   1.156 +              } else {
   1.157 +                concats.remove_at(c);
   1.158 +                concats.at_put(o, merged);
   1.159 +              }
   1.160 +              goto restart;
   1.161 +            } else {
   1.162  #ifndef PRODUCT
   1.163 -                if (PrintOptimizeStringConcat) {
   1.164 -                  tty->print_cr("stacking would succeed");
   1.165 -                }
   1.166 +              if (PrintOptimizeStringConcat) {
   1.167 +                tty->print_cr("stacking would fail");
   1.168 +              }
   1.169  #endif
   1.170 -                if (c < o) {
   1.171 -                  concats.remove_at(o);
   1.172 -                  concats.at_put(c, merged);
   1.173 -                } else {
   1.174 -                  concats.remove_at(c);
   1.175 -                  concats.at_put(o, merged);
   1.176 -                }
   1.177 -                goto restart;
   1.178 -              } else {
   1.179 -#ifndef PRODUCT
   1.180 -                if (PrintOptimizeStringConcat) {
   1.181 -                  tty->print_cr("stacking would fail");
   1.182 -                }
   1.183 -#endif
   1.184 -              }
   1.185              }
   1.186            }
   1.187          }

mercurial