src/share/vm/opto/stringopts.cpp

changeset 2413
2ddb2fab82cb
parent 2314
f95d63e2154a
child 2661
b099aaf51bf8
child 2665
9dc311b8473e
     1.1 --- a/src/share/vm/opto/stringopts.cpp	Mon Dec 27 21:51:31 2010 -0800
     1.2 +++ b/src/share/vm/opto/stringopts.cpp	Tue Dec 28 17:34:02 2010 -0800
     1.3 @@ -59,7 +59,8 @@
     1.4    enum {
     1.5      StringMode,
     1.6      IntMode,
     1.7 -    CharMode
     1.8 +    CharMode,
     1.9 +    StringNullCheckMode
    1.10    };
    1.11  
    1.12    StringConcat(PhaseStringOpts* stringopts, CallStaticJavaNode* end):
    1.13 @@ -114,6 +115,9 @@
    1.14    void push_string(Node* value) {
    1.15      push(value, StringMode);
    1.16    }
    1.17 +  void push_string_null_check(Node* value) {
    1.18 +    push(value, StringNullCheckMode);
    1.19 +  }
    1.20    void push_int(Node* value) {
    1.21      push(value, IntMode);
    1.22    }
    1.23 @@ -416,7 +420,19 @@
    1.24              if (sig == ciSymbol::string_void_signature()) {
    1.25                // StringBuilder(String) so pick this up as the first argument
    1.26                assert(use->in(TypeFunc::Parms + 1) != NULL, "what?");
    1.27 -              sc->push_string(use->in(TypeFunc::Parms + 1));
    1.28 +              const Type* type = _gvn->type(use->in(TypeFunc::Parms + 1));
    1.29 +              if (type == TypePtr::NULL_PTR) {
    1.30 +                // StringBuilder(null) throws exception.
    1.31 +#ifndef PRODUCT
    1.32 +                if (PrintOptimizeStringConcat) {
    1.33 +                  tty->print("giving up because StringBuilder(null) throws exception");
    1.34 +                  alloc->jvms()->dump_spec(tty); tty->cr();
    1.35 +                }
    1.36 +#endif
    1.37 +                return NULL;
    1.38 +              }
    1.39 +              // StringBuilder(str) argument needs null check.
    1.40 +              sc->push_string_null_check(use->in(TypeFunc::Parms + 1));
    1.41              }
    1.42              // The int variant takes an initial size for the backing
    1.43              // array so just treat it like the void version.
    1.44 @@ -436,7 +452,7 @@
    1.45  #ifndef PRODUCT
    1.46          if (PrintOptimizeStringConcat) {
    1.47            tty->print("giving up because couldn't find constructor ");
    1.48 -          alloc->jvms()->dump_spec(tty);
    1.49 +          alloc->jvms()->dump_spec(tty); tty->cr();
    1.50          }
    1.51  #endif
    1.52          break;
    1.53 @@ -1269,6 +1285,25 @@
    1.54          string_sizes->init_req(argi, string_size);
    1.55          break;
    1.56        }
    1.57 +      case StringConcat::StringNullCheckMode: {
    1.58 +        const Type* type = kit.gvn().type(arg);
    1.59 +        assert(type != TypePtr::NULL_PTR, "missing check");
    1.60 +        if (!type->higher_equal(TypeInstPtr::NOTNULL)) {
    1.61 +          // Null check with uncommont trap since
    1.62 +          // StringBuilder(null) throws exception.
    1.63 +          // Use special uncommon trap instead of
    1.64 +          // calling normal do_null_check().
    1.65 +          Node* p = __ Bool(__ CmpP(arg, kit.null()), BoolTest::ne);
    1.66 +          IfNode* iff = kit.create_and_map_if(kit.control(), p, PROB_MIN, COUNT_UNKNOWN);
    1.67 +          overflow->add_req(__ IfFalse(iff));
    1.68 +          Node* notnull = __ IfTrue(iff);
    1.69 +          kit.set_control(notnull); // set control for the cast_not_null
    1.70 +          arg = kit.cast_not_null(arg, false);
    1.71 +          sc->set_argument(argi, arg);
    1.72 +        }
    1.73 +        assert(kit.gvn().type(arg)->higher_equal(TypeInstPtr::NOTNULL), "sanity");
    1.74 +        // Fallthrough to add string length.
    1.75 +      }
    1.76        case StringConcat::StringMode: {
    1.77          const Type* type = kit.gvn().type(arg);
    1.78          if (type == TypePtr::NULL_PTR) {
    1.79 @@ -1328,6 +1363,7 @@
    1.80      // Hook
    1.81      PreserveJVMState pjvms(&kit);
    1.82      kit.set_control(overflow);
    1.83 +    C->record_for_igvn(overflow);
    1.84      kit.uncommon_trap(Deoptimization::Reason_intrinsic,
    1.85                        Deoptimization::Action_make_not_entrant);
    1.86    }
    1.87 @@ -1363,6 +1399,7 @@
    1.88          start = end;
    1.89          break;
    1.90        }
    1.91 +      case StringConcat::StringNullCheckMode:
    1.92        case StringConcat::StringMode: {
    1.93          start = copy_string(kit, arg, char_array, start);
    1.94          break;

mercurial