annotate src/share/vm/opto/stringopts.cpp @ 4710:41406797186b

7113012: G1: rename not-fully-young GCs as "mixed" Summary: Renamed partially-young GCs as mixed and fully-young GCs as young. Change all external output that includes those terms (GC log and GC ergo log) as well as any comments, fields, methods, etc. The changeset also includes very minor code tidying up (added some curly brackets). Reviewed-by: johnc, brutisso
author tonyp
date Fri, 16 Dec 2011 02:14:27 -0500
parents 2b27ef5c2173
children df3d4a91f7f6
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1 /*
2426
1d1603768966 7010070: Update all 2010 Oracle-changed OpenJDK files to have the proper copyright dates - second pass
trims
parents: 2385
diff changeset
2 * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
4 *
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
7 * published by the Free Software Foundation.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
8 *
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
13 * accompanied this code).
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
14 *
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
18 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1250
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1250
diff changeset
20 * or visit www.oracle.com if you need additional information or have any
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1250
diff changeset
21 * questions.
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
22 *
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
23 */
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
24
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1817
diff changeset
25 #include "precompiled.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1817
diff changeset
26 #include "compiler/compileLog.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1817
diff changeset
27 #include "opto/addnode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1817
diff changeset
28 #include "opto/callGenerator.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1817
diff changeset
29 #include "opto/callnode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1817
diff changeset
30 #include "opto/divnode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1817
diff changeset
31 #include "opto/graphKit.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1817
diff changeset
32 #include "opto/idealKit.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1817
diff changeset
33 #include "opto/rootnode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1817
diff changeset
34 #include "opto/runtime.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1817
diff changeset
35 #include "opto/stringopts.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1817
diff changeset
36 #include "opto/subnode.hpp"
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
37
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
38 #define __ kit.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
39
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
40 class StringConcat : public ResourceObj {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
41 private:
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
42 PhaseStringOpts* _stringopts;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
43 Node* _string_alloc;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
44 AllocateNode* _begin; // The allocation the begins the pattern
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
45 CallStaticJavaNode* _end; // The final call of the pattern. Will either be
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
46 // SB.toString or or String.<init>(SB.toString)
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
47 bool _multiple; // indicates this is a fusion of two or more
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
48 // separate StringBuilders
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
49
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
50 Node* _arguments; // The list of arguments to be concatenated
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
51 GrowableArray<int> _mode; // into a String along with a mode flag
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
52 // indicating how to treat the value.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
53
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
54 Node_List _control; // List of control nodes that will be deleted
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
55 Node_List _uncommon_traps; // Uncommon traps that needs to be rewritten
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
56 // to restart at the initial JVMState.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
57 public:
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
58 // Mode for converting arguments to Strings
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
59 enum {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
60 StringMode,
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
61 IntMode,
2090
2ddb2fab82cb 7009359: HS with -XX:+AggressiveOpts optimize new StringBuffer(null) so it does not throw NPE as expected
kvn
parents: 1972
diff changeset
62 CharMode,
2ddb2fab82cb 7009359: HS with -XX:+AggressiveOpts optimize new StringBuffer(null) so it does not throw NPE as expected
kvn
parents: 1972
diff changeset
63 StringNullCheckMode
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
64 };
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
65
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
66 StringConcat(PhaseStringOpts* stringopts, CallStaticJavaNode* end):
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
67 _end(end),
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
68 _begin(NULL),
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
69 _multiple(false),
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
70 _string_alloc(NULL),
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
71 _stringopts(stringopts) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
72 _arguments = new (_stringopts->C, 1) Node(1);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
73 _arguments->del_req(0);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
74 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
75
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
76 bool validate_control_flow();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
77
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
78 void merge_add() {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
79 #if 0
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
80 // XXX This is place holder code for reusing an existing String
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
81 // allocation but the logic for checking the state safety is
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
82 // probably inadequate at the moment.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
83 CallProjections endprojs;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
84 sc->end()->extract_projections(&endprojs, false);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
85 if (endprojs.resproj != NULL) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
86 for (SimpleDUIterator i(endprojs.resproj); i.has_next(); i.next()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
87 CallStaticJavaNode *use = i.get()->isa_CallStaticJava();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
88 if (use != NULL && use->method() != NULL &&
1817
c40600e85311 6986028: assert(_base == Int) failed: Not an Int in CmpINode::sub
never
parents: 1748
diff changeset
89 use->method()->intrinsic_id() == vmIntrinsics::_String_String &&
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
90 use->in(TypeFunc::Parms + 1) == endprojs.resproj) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
91 // Found useless new String(sb.toString()) so reuse the newly allocated String
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
92 // when creating the result instead of allocating a new one.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
93 sc->set_string_alloc(use->in(TypeFunc::Parms));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
94 sc->set_end(use);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
95 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
96 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
97 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
98 #endif
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
99 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
100
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
101 StringConcat* merge(StringConcat* other, Node* arg);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
102
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
103 void set_allocation(AllocateNode* alloc) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
104 _begin = alloc;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
105 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
106
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
107 void append(Node* value, int mode) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
108 _arguments->add_req(value);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
109 _mode.append(mode);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
110 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
111 void push(Node* value, int mode) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
112 _arguments->ins_req(0, value);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
113 _mode.insert_before(0, mode);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
114 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
115 void push_string(Node* value) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
116 push(value, StringMode);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
117 }
2090
2ddb2fab82cb 7009359: HS with -XX:+AggressiveOpts optimize new StringBuffer(null) so it does not throw NPE as expected
kvn
parents: 1972
diff changeset
118 void push_string_null_check(Node* value) {
2ddb2fab82cb 7009359: HS with -XX:+AggressiveOpts optimize new StringBuffer(null) so it does not throw NPE as expected
kvn
parents: 1972
diff changeset
119 push(value, StringNullCheckMode);
2ddb2fab82cb 7009359: HS with -XX:+AggressiveOpts optimize new StringBuffer(null) so it does not throw NPE as expected
kvn
parents: 1972
diff changeset
120 }
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
121 void push_int(Node* value) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
122 push(value, IntMode);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
123 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
124 void push_char(Node* value) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
125 push(value, CharMode);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
126 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
127
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
128 Node* argument(int i) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
129 return _arguments->in(i);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
130 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
131 void set_argument(int i, Node* value) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
132 _arguments->set_req(i, value);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
133 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
134 int num_arguments() {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
135 return _mode.length();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
136 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
137 int mode(int i) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
138 return _mode.at(i);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
139 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
140 void add_control(Node* ctrl) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
141 assert(!_control.contains(ctrl), "only push once");
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
142 _control.push(ctrl);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
143 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
144 CallStaticJavaNode* end() { return _end; }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
145 AllocateNode* begin() { return _begin; }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
146 Node* string_alloc() { return _string_alloc; }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
147
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
148 void eliminate_unneeded_control();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
149 void eliminate_initialize(InitializeNode* init);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
150 void eliminate_call(CallNode* call);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
151
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
152 void maybe_log_transform() {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
153 CompileLog* log = _stringopts->C->log();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
154 if (log != NULL) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
155 log->head("replace_string_concat arguments='%d' string_alloc='%d' multiple='%d'",
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
156 num_arguments(),
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
157 _string_alloc != NULL,
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
158 _multiple);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
159 JVMState* p = _begin->jvms();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
160 while (p != NULL) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
161 log->elem("jvms bci='%d' method='%d'", p->bci(), log->identify(p->method()));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
162 p = p->caller();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
163 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
164 log->tail("replace_string_concat");
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
165 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
166 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
167
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
168 void convert_uncommon_traps(GraphKit& kit, const JVMState* jvms) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
169 for (uint u = 0; u < _uncommon_traps.size(); u++) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
170 Node* uct = _uncommon_traps.at(u);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
171
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
172 // Build a new call using the jvms state of the allocate
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1552
diff changeset
173 address call_addr = SharedRuntime::uncommon_trap_blob()->entry_point();
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
174 const TypeFunc* call_type = OptoRuntime::uncommon_trap_Type();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
175 int size = call_type->domain()->cnt();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
176 const TypePtr* no_memory_effects = NULL;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
177 Compile* C = _stringopts->C;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
178 CallStaticJavaNode* call = new (C, size) CallStaticJavaNode(call_type, call_addr, "uncommon_trap",
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
179 jvms->bci(), no_memory_effects);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
180 for (int e = 0; e < TypeFunc::Parms; e++) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
181 call->init_req(e, uct->in(e));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
182 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
183 // Set the trap request to record intrinsic failure if this trap
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
184 // is taken too many times. Ideally we would handle then traps by
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
185 // doing the original bookkeeping in the MDO so that if it caused
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
186 // the code to be thrown out we could still recompile and use the
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
187 // optimization. Failing the uncommon traps doesn't really mean
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
188 // that the optimization is a bad idea but there's no other way to
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
189 // do the MDO updates currently.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
190 int trap_request = Deoptimization::make_trap_request(Deoptimization::Reason_intrinsic,
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
191 Deoptimization::Action_make_not_entrant);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
192 call->init_req(TypeFunc::Parms, __ intcon(trap_request));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
193 kit.add_safepoint_edges(call);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
194
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
195 _stringopts->gvn()->transform(call);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
196 C->gvn_replace_by(uct, call);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
197 uct->disconnect_inputs(NULL);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
198 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
199 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
200
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
201 void cleanup() {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
202 // disconnect the hook node
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
203 _arguments->disconnect_inputs(NULL);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
204 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
205 };
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
206
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
207
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
208 void StringConcat::eliminate_unneeded_control() {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
209 eliminate_initialize(begin()->initialization());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
210 for (uint i = 0; i < _control.size(); i++) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
211 Node* n = _control.at(i);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
212 if (n->is_Call()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
213 if (n != _end) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
214 eliminate_call(n->as_Call());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
215 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
216 } else if (n->is_IfTrue()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
217 Compile* C = _stringopts->C;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
218 C->gvn_replace_by(n, n->in(0)->in(0));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
219 C->gvn_replace_by(n->in(0), C->top());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
220 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
221 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
222 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
223
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
224
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
225 StringConcat* StringConcat::merge(StringConcat* other, Node* arg) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
226 StringConcat* result = new StringConcat(_stringopts, _end);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
227 for (uint x = 0; x < _control.size(); x++) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
228 Node* n = _control.at(x);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
229 if (n->is_Call()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
230 result->_control.push(n);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
231 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
232 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
233 for (uint x = 0; x < other->_control.size(); x++) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
234 Node* n = other->_control.at(x);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
235 if (n->is_Call()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
236 result->_control.push(n);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
237 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
238 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
239 assert(result->_control.contains(other->_end), "what?");
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
240 assert(result->_control.contains(_begin), "what?");
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
241 for (int x = 0; x < num_arguments(); x++) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
242 if (argument(x) == arg) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
243 // replace the toString result with the all the arguments that
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
244 // made up the other StringConcat
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
245 for (int y = 0; y < other->num_arguments(); y++) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
246 result->append(other->argument(y), other->mode(y));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
247 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
248 } else {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
249 result->append(argument(x), mode(x));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
250 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
251 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
252 result->set_allocation(other->_begin);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
253 result->_multiple = true;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
254 return result;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
255 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
256
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
257
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
258 void StringConcat::eliminate_call(CallNode* call) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
259 Compile* C = _stringopts->C;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
260 CallProjections projs;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
261 call->extract_projections(&projs, false);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
262 if (projs.fallthrough_catchproj != NULL) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
263 C->gvn_replace_by(projs.fallthrough_catchproj, call->in(TypeFunc::Control));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
264 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
265 if (projs.fallthrough_memproj != NULL) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
266 C->gvn_replace_by(projs.fallthrough_memproj, call->in(TypeFunc::Memory));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
267 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
268 if (projs.catchall_memproj != NULL) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
269 C->gvn_replace_by(projs.catchall_memproj, C->top());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
270 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
271 if (projs.fallthrough_ioproj != NULL) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
272 C->gvn_replace_by(projs.fallthrough_ioproj, call->in(TypeFunc::I_O));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
273 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
274 if (projs.catchall_ioproj != NULL) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
275 C->gvn_replace_by(projs.catchall_ioproj, C->top());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
276 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
277 if (projs.catchall_catchproj != NULL) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
278 // EA can't cope with the partially collapsed graph this
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
279 // creates so put it on the worklist to be collapsed later.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
280 for (SimpleDUIterator i(projs.catchall_catchproj); i.has_next(); i.next()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
281 Node *use = i.get();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
282 int opc = use->Opcode();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
283 if (opc == Op_CreateEx || opc == Op_Region) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
284 _stringopts->record_dead_node(use);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
285 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
286 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
287 C->gvn_replace_by(projs.catchall_catchproj, C->top());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
288 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
289 if (projs.resproj != NULL) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
290 C->gvn_replace_by(projs.resproj, C->top());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
291 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
292 C->gvn_replace_by(call, C->top());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
293 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
294
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
295 void StringConcat::eliminate_initialize(InitializeNode* init) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
296 Compile* C = _stringopts->C;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
297
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
298 // Eliminate Initialize node.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
299 assert(init->outcnt() <= 2, "only a control and memory projection expected");
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
300 assert(init->req() <= InitializeNode::RawStores, "no pending inits");
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
301 Node *ctrl_proj = init->proj_out(TypeFunc::Control);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
302 if (ctrl_proj != NULL) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
303 C->gvn_replace_by(ctrl_proj, init->in(TypeFunc::Control));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
304 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
305 Node *mem_proj = init->proj_out(TypeFunc::Memory);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
306 if (mem_proj != NULL) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
307 Node *mem = init->in(TypeFunc::Memory);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
308 C->gvn_replace_by(mem_proj, mem);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
309 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
310 C->gvn_replace_by(init, C->top());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
311 init->disconnect_inputs(NULL);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
312 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
313
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
314 Node_List PhaseStringOpts::collect_toString_calls() {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
315 Node_List string_calls;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
316 Node_List worklist;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
317
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
318 _visited.Clear();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
319
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
320 // Prime the worklist
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
321 for (uint i = 1; i < C->root()->len(); i++) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
322 Node* n = C->root()->in(i);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
323 if (n != NULL && !_visited.test_set(n->_idx)) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
324 worklist.push(n);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
325 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
326 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
327
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
328 while (worklist.size() > 0) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
329 Node* ctrl = worklist.pop();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
330 if (ctrl->is_CallStaticJava()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
331 CallStaticJavaNode* csj = ctrl->as_CallStaticJava();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
332 ciMethod* m = csj->method();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
333 if (m != NULL &&
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
334 (m->intrinsic_id() == vmIntrinsics::_StringBuffer_toString ||
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
335 m->intrinsic_id() == vmIntrinsics::_StringBuilder_toString)) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
336 string_calls.push(csj);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
337 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
338 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
339 if (ctrl->in(0) != NULL && !_visited.test_set(ctrl->in(0)->_idx)) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
340 worklist.push(ctrl->in(0));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
341 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
342 if (ctrl->is_Region()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
343 for (uint i = 1; i < ctrl->len(); i++) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
344 if (ctrl->in(i) != NULL && !_visited.test_set(ctrl->in(i)->_idx)) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
345 worklist.push(ctrl->in(i));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
346 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
347 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
348 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
349 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
350 return string_calls;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
351 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
352
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
353
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
354 StringConcat* PhaseStringOpts::build_candidate(CallStaticJavaNode* call) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
355 ciMethod* m = call->method();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
356 ciSymbol* string_sig;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
357 ciSymbol* int_sig;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
358 ciSymbol* char_sig;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
359 if (m->holder() == C->env()->StringBuilder_klass()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
360 string_sig = ciSymbol::String_StringBuilder_signature();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
361 int_sig = ciSymbol::int_StringBuilder_signature();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
362 char_sig = ciSymbol::char_StringBuilder_signature();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
363 } else if (m->holder() == C->env()->StringBuffer_klass()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
364 string_sig = ciSymbol::String_StringBuffer_signature();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
365 int_sig = ciSymbol::int_StringBuffer_signature();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
366 char_sig = ciSymbol::char_StringBuffer_signature();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
367 } else {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
368 return NULL;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
369 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
370 #ifndef PRODUCT
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
371 if (PrintOptimizeStringConcat) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
372 tty->print("considering toString call in ");
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
373 call->jvms()->dump_spec(tty); tty->cr();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
374 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
375 #endif
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
376
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
377 StringConcat* sc = new StringConcat(this, call);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
378
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
379 AllocateNode* alloc = NULL;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
380 InitializeNode* init = NULL;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
381
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
382 // possible opportunity for StringBuilder fusion
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
383 CallStaticJavaNode* cnode = call;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
384 while (cnode) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
385 Node* recv = cnode->in(TypeFunc::Parms)->uncast();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
386 if (recv->is_Proj()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
387 recv = recv->in(0);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
388 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
389 cnode = recv->isa_CallStaticJava();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
390 if (cnode == NULL) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
391 alloc = recv->isa_Allocate();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
392 if (alloc == NULL) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
393 break;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
394 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
395 // Find the constructor call
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
396 Node* result = alloc->result_cast();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
397 if (result == NULL || !result->is_CheckCastPP()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
398 // strange looking allocation
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
399 #ifndef PRODUCT
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
400 if (PrintOptimizeStringConcat) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
401 tty->print("giving up because allocation looks strange ");
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
402 alloc->jvms()->dump_spec(tty); tty->cr();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
403 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
404 #endif
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
405 break;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
406 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
407 Node* constructor = NULL;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
408 for (SimpleDUIterator i(result); i.has_next(); i.next()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
409 CallStaticJavaNode *use = i.get()->isa_CallStaticJava();
1817
c40600e85311 6986028: assert(_base == Int) failed: Not an Int in CmpINode::sub
never
parents: 1748
diff changeset
410 if (use != NULL &&
c40600e85311 6986028: assert(_base == Int) failed: Not an Int in CmpINode::sub
never
parents: 1748
diff changeset
411 use->method() != NULL &&
c40600e85311 6986028: assert(_base == Int) failed: Not an Int in CmpINode::sub
never
parents: 1748
diff changeset
412 !use->method()->is_static() &&
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
413 use->method()->name() == ciSymbol::object_initializer_name() &&
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
414 use->method()->holder() == m->holder()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
415 // Matched the constructor.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
416 ciSymbol* sig = use->method()->signature()->as_symbol();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
417 if (sig == ciSymbol::void_method_signature() ||
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
418 sig == ciSymbol::int_void_signature() ||
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
419 sig == ciSymbol::string_void_signature()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
420 if (sig == ciSymbol::string_void_signature()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
421 // StringBuilder(String) so pick this up as the first argument
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
422 assert(use->in(TypeFunc::Parms + 1) != NULL, "what?");
2090
2ddb2fab82cb 7009359: HS with -XX:+AggressiveOpts optimize new StringBuffer(null) so it does not throw NPE as expected
kvn
parents: 1972
diff changeset
423 const Type* type = _gvn->type(use->in(TypeFunc::Parms + 1));
2ddb2fab82cb 7009359: HS with -XX:+AggressiveOpts optimize new StringBuffer(null) so it does not throw NPE as expected
kvn
parents: 1972
diff changeset
424 if (type == TypePtr::NULL_PTR) {
2ddb2fab82cb 7009359: HS with -XX:+AggressiveOpts optimize new StringBuffer(null) so it does not throw NPE as expected
kvn
parents: 1972
diff changeset
425 // StringBuilder(null) throws exception.
2ddb2fab82cb 7009359: HS with -XX:+AggressiveOpts optimize new StringBuffer(null) so it does not throw NPE as expected
kvn
parents: 1972
diff changeset
426 #ifndef PRODUCT
2ddb2fab82cb 7009359: HS with -XX:+AggressiveOpts optimize new StringBuffer(null) so it does not throw NPE as expected
kvn
parents: 1972
diff changeset
427 if (PrintOptimizeStringConcat) {
2ddb2fab82cb 7009359: HS with -XX:+AggressiveOpts optimize new StringBuffer(null) so it does not throw NPE as expected
kvn
parents: 1972
diff changeset
428 tty->print("giving up because StringBuilder(null) throws exception");
2ddb2fab82cb 7009359: HS with -XX:+AggressiveOpts optimize new StringBuffer(null) so it does not throw NPE as expected
kvn
parents: 1972
diff changeset
429 alloc->jvms()->dump_spec(tty); tty->cr();
2ddb2fab82cb 7009359: HS with -XX:+AggressiveOpts optimize new StringBuffer(null) so it does not throw NPE as expected
kvn
parents: 1972
diff changeset
430 }
2ddb2fab82cb 7009359: HS with -XX:+AggressiveOpts optimize new StringBuffer(null) so it does not throw NPE as expected
kvn
parents: 1972
diff changeset
431 #endif
2ddb2fab82cb 7009359: HS with -XX:+AggressiveOpts optimize new StringBuffer(null) so it does not throw NPE as expected
kvn
parents: 1972
diff changeset
432 return NULL;
2ddb2fab82cb 7009359: HS with -XX:+AggressiveOpts optimize new StringBuffer(null) so it does not throw NPE as expected
kvn
parents: 1972
diff changeset
433 }
2ddb2fab82cb 7009359: HS with -XX:+AggressiveOpts optimize new StringBuffer(null) so it does not throw NPE as expected
kvn
parents: 1972
diff changeset
434 // StringBuilder(str) argument needs null check.
2ddb2fab82cb 7009359: HS with -XX:+AggressiveOpts optimize new StringBuffer(null) so it does not throw NPE as expected
kvn
parents: 1972
diff changeset
435 sc->push_string_null_check(use->in(TypeFunc::Parms + 1));
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
436 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
437 // The int variant takes an initial size for the backing
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
438 // array so just treat it like the void version.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
439 constructor = use;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
440 } else {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
441 #ifndef PRODUCT
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
442 if (PrintOptimizeStringConcat) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
443 tty->print("unexpected constructor signature: %s", sig->as_utf8());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
444 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
445 #endif
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
446 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
447 break;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
448 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
449 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
450 if (constructor == NULL) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
451 // couldn't find constructor
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
452 #ifndef PRODUCT
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
453 if (PrintOptimizeStringConcat) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
454 tty->print("giving up because couldn't find constructor ");
2090
2ddb2fab82cb 7009359: HS with -XX:+AggressiveOpts optimize new StringBuffer(null) so it does not throw NPE as expected
kvn
parents: 1972
diff changeset
455 alloc->jvms()->dump_spec(tty); tty->cr();
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
456 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
457 #endif
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
458 break;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
459 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
460
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
461 // Walked all the way back and found the constructor call so see
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
462 // if this call converted into a direct string concatenation.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
463 sc->add_control(call);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
464 sc->add_control(constructor);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
465 sc->add_control(alloc);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
466 sc->set_allocation(alloc);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
467 if (sc->validate_control_flow()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
468 return sc;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
469 } else {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
470 return NULL;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
471 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
472 } else if (cnode->method() == NULL) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
473 break;
1817
c40600e85311 6986028: assert(_base == Int) failed: Not an Int in CmpINode::sub
never
parents: 1748
diff changeset
474 } else if (!cnode->method()->is_static() &&
c40600e85311 6986028: assert(_base == Int) failed: Not an Int in CmpINode::sub
never
parents: 1748
diff changeset
475 cnode->method()->holder() == m->holder() &&
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
476 cnode->method()->name() == ciSymbol::append_name() &&
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
477 (cnode->method()->signature()->as_symbol() == string_sig ||
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
478 cnode->method()->signature()->as_symbol() == char_sig ||
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
479 cnode->method()->signature()->as_symbol() == int_sig)) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
480 sc->add_control(cnode);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
481 Node* arg = cnode->in(TypeFunc::Parms + 1);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
482 if (cnode->method()->signature()->as_symbol() == int_sig) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
483 sc->push_int(arg);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
484 } else if (cnode->method()->signature()->as_symbol() == char_sig) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
485 sc->push_char(arg);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
486 } else {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
487 if (arg->is_Proj() && arg->in(0)->is_CallStaticJava()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
488 CallStaticJavaNode* csj = arg->in(0)->as_CallStaticJava();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
489 if (csj->method() != NULL &&
1817
c40600e85311 6986028: assert(_base == Int) failed: Not an Int in CmpINode::sub
never
parents: 1748
diff changeset
490 csj->method()->intrinsic_id() == vmIntrinsics::_Integer_toString) {
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
491 sc->add_control(csj);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
492 sc->push_int(csj->in(TypeFunc::Parms));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
493 continue;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
494 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
495 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
496 sc->push_string(arg);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
497 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
498 continue;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
499 } else {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
500 // some unhandled signature
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
501 #ifndef PRODUCT
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
502 if (PrintOptimizeStringConcat) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
503 tty->print("giving up because encountered unexpected signature ");
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
504 cnode->tf()->dump(); tty->cr();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
505 cnode->in(TypeFunc::Parms + 1)->dump();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
506 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
507 #endif
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
508 break;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
509 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
510 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
511 return NULL;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
512 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
513
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
514
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
515 PhaseStringOpts::PhaseStringOpts(PhaseGVN* gvn, Unique_Node_List*):
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
516 Phase(StringOpts),
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
517 _gvn(gvn),
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
518 _visited(Thread::current()->resource_area()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
519
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
520 assert(OptimizeStringConcat, "shouldn't be here");
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
521
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
522 size_table_field = C->env()->Integer_klass()->get_field_by_name(ciSymbol::make("sizeTable"),
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
523 ciSymbol::make("[I"), true);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
524 if (size_table_field == NULL) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
525 // Something wrong so give up.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
526 assert(false, "why can't we find Integer.sizeTable?");
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
527 return;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
528 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
529
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
530 // Collect the types needed to talk about the various slices of memory
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
531 const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(),
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
532 false, NULL, 0);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
533
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
534 const TypePtr* value_field_type = string_type->add_offset(java_lang_String::value_offset_in_bytes());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
535 const TypePtr* offset_field_type = string_type->add_offset(java_lang_String::offset_offset_in_bytes());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
536 const TypePtr* count_field_type = string_type->add_offset(java_lang_String::count_offset_in_bytes());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
537
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
538 value_field_idx = C->get_alias_index(value_field_type);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
539 count_field_idx = C->get_alias_index(count_field_type);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
540 offset_field_idx = C->get_alias_index(offset_field_type);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
541 char_adr_idx = C->get_alias_index(TypeAryPtr::CHARS);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
542
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
543 // For each locally allocated StringBuffer see if the usages can be
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
544 // collapsed into a single String construction.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
545
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
546 // Run through the list of allocation looking for SB.toString to see
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
547 // if it's possible to fuse the usage of the SB into a single String
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
548 // construction.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
549 GrowableArray<StringConcat*> concats;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
550 Node_List toStrings = collect_toString_calls();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
551 while (toStrings.size() > 0) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
552 StringConcat* sc = build_candidate(toStrings.pop()->as_CallStaticJava());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
553 if (sc != NULL) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
554 concats.push(sc);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
555 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
556 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
557
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
558 // try to coalesce separate concats
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
559 restart:
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
560 for (int c = 0; c < concats.length(); c++) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
561 StringConcat* sc = concats.at(c);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
562 for (int i = 0; i < sc->num_arguments(); i++) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
563 Node* arg = sc->argument(i);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
564 if (arg->is_Proj() && arg->in(0)->is_CallStaticJava()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
565 CallStaticJavaNode* csj = arg->in(0)->as_CallStaticJava();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
566 if (csj->method() != NULL &&
1817
c40600e85311 6986028: assert(_base == Int) failed: Not an Int in CmpINode::sub
never
parents: 1748
diff changeset
567 (csj->method()->intrinsic_id() == vmIntrinsics::_StringBuilder_toString ||
c40600e85311 6986028: assert(_base == Int) failed: Not an Int in CmpINode::sub
never
parents: 1748
diff changeset
568 csj->method()->intrinsic_id() == vmIntrinsics::_StringBuffer_toString)) {
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
569 for (int o = 0; o < concats.length(); o++) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
570 if (c == o) continue;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
571 StringConcat* other = concats.at(o);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
572 if (other->end() == csj) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
573 #ifndef PRODUCT
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
574 if (PrintOptimizeStringConcat) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
575 tty->print_cr("considering stacked concats");
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
576 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
577 #endif
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
578
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
579 StringConcat* merged = sc->merge(other, arg);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
580 if (merged->validate_control_flow()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
581 #ifndef PRODUCT
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
582 if (PrintOptimizeStringConcat) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
583 tty->print_cr("stacking would succeed");
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
584 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
585 #endif
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
586 if (c < o) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
587 concats.remove_at(o);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
588 concats.at_put(c, merged);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
589 } else {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
590 concats.remove_at(c);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
591 concats.at_put(o, merged);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
592 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
593 goto restart;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
594 } else {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
595 #ifndef PRODUCT
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
596 if (PrintOptimizeStringConcat) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
597 tty->print_cr("stacking would fail");
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
598 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
599 #endif
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
600 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
601 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
602 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
603 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
604 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
605 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
606 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
607
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
608
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
609 for (int c = 0; c < concats.length(); c++) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
610 StringConcat* sc = concats.at(c);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
611 replace_string_concat(sc);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
612 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
613
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
614 remove_dead_nodes();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
615 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
616
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
617 void PhaseStringOpts::record_dead_node(Node* dead) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
618 dead_worklist.push(dead);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
619 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
620
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
621 void PhaseStringOpts::remove_dead_nodes() {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
622 // Delete any dead nodes to make things clean enough that escape
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
623 // analysis doesn't get unhappy.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
624 while (dead_worklist.size() > 0) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
625 Node* use = dead_worklist.pop();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
626 int opc = use->Opcode();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
627 switch (opc) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
628 case Op_Region: {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
629 uint i = 1;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
630 for (i = 1; i < use->req(); i++) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
631 if (use->in(i) != C->top()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
632 break;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
633 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
634 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
635 if (i >= use->req()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
636 for (SimpleDUIterator i(use); i.has_next(); i.next()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
637 Node* m = i.get();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
638 if (m->is_Phi()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
639 dead_worklist.push(m);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
640 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
641 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
642 C->gvn_replace_by(use, C->top());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
643 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
644 break;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
645 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
646 case Op_AddP:
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
647 case Op_CreateEx: {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
648 // Recurisvely clean up references to CreateEx so EA doesn't
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
649 // get unhappy about the partially collapsed graph.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
650 for (SimpleDUIterator i(use); i.has_next(); i.next()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
651 Node* m = i.get();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
652 if (m->is_AddP()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
653 dead_worklist.push(m);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
654 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
655 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
656 C->gvn_replace_by(use, C->top());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
657 break;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
658 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
659 case Op_Phi:
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
660 if (use->in(0) == C->top()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
661 C->gvn_replace_by(use, C->top());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
662 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
663 break;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
664 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
665 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
666 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
667
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
668
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
669 bool StringConcat::validate_control_flow() {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
670 // We found all the calls and arguments now lets see if it's
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
671 // safe to transform the graph as we would expect.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
672
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
673 // Check to see if this resulted in too many uncommon traps previously
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
674 if (Compile::current()->too_many_traps(_begin->jvms()->method(), _begin->jvms()->bci(),
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
675 Deoptimization::Reason_intrinsic)) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
676 return false;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
677 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
678
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
679 // Walk backwards over the control flow from toString to the
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
680 // allocation and make sure all the control flow is ok. This
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
681 // means it's either going to be eliminated once the calls are
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
682 // removed or it can safely be transformed into an uncommon
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
683 // trap.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
684
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
685 int null_check_count = 0;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
686 Unique_Node_List ctrl_path;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
687
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
688 assert(_control.contains(_begin), "missing");
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
689 assert(_control.contains(_end), "missing");
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
690
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
691 // Collect the nodes that we know about and will eliminate into ctrl_path
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
692 for (uint i = 0; i < _control.size(); i++) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
693 // Push the call and it's control projection
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
694 Node* n = _control.at(i);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
695 if (n->is_Allocate()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
696 AllocateNode* an = n->as_Allocate();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
697 InitializeNode* init = an->initialization();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
698 ctrl_path.push(init);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
699 ctrl_path.push(init->as_Multi()->proj_out(0));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
700 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
701 if (n->is_Call()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
702 CallNode* cn = n->as_Call();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
703 ctrl_path.push(cn);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
704 ctrl_path.push(cn->proj_out(0));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
705 ctrl_path.push(cn->proj_out(0)->unique_out());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
706 ctrl_path.push(cn->proj_out(0)->unique_out()->as_Catch()->proj_out(0));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
707 } else {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
708 ShouldNotReachHere();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
709 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
710 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
711
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
712 // Skip backwards through the control checking for unexpected contro flow
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
713 Node* ptr = _end;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
714 bool fail = false;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
715 while (ptr != _begin) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
716 if (ptr->is_Call() && ctrl_path.member(ptr)) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
717 ptr = ptr->in(0);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
718 } else if (ptr->is_CatchProj() && ctrl_path.member(ptr)) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
719 ptr = ptr->in(0)->in(0)->in(0);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
720 assert(ctrl_path.member(ptr), "should be a known piece of control");
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
721 } else if (ptr->is_IfTrue()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
722 IfNode* iff = ptr->in(0)->as_If();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
723 BoolNode* b = iff->in(1)->isa_Bool();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
724 Node* cmp = b->in(1);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
725 Node* v1 = cmp->in(1);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
726 Node* v2 = cmp->in(2);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
727 Node* otherproj = iff->proj_out(1 - ptr->as_Proj()->_con);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
728
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
729 // Null check of the return of append which can simply be eliminated
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
730 if (b->_test._test == BoolTest::ne &&
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
731 v2->bottom_type() == TypePtr::NULL_PTR &&
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
732 v1->is_Proj() && ctrl_path.member(v1->in(0))) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
733 // NULL check of the return value of the append
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
734 null_check_count++;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
735 if (otherproj->outcnt() == 1) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
736 CallStaticJavaNode* call = otherproj->unique_out()->isa_CallStaticJava();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
737 if (call != NULL && call->_name != NULL && strcmp(call->_name, "uncommon_trap") == 0) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
738 ctrl_path.push(call);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
739 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
740 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
741 _control.push(ptr);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
742 ptr = ptr->in(0)->in(0);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
743 continue;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
744 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
745
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
746 // A test which leads to an uncommon trap which should be safe.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
747 // Later this trap will be converted into a trap that restarts
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
748 // at the beginning.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
749 if (otherproj->outcnt() == 1) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
750 CallStaticJavaNode* call = otherproj->unique_out()->isa_CallStaticJava();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
751 if (call != NULL && call->_name != NULL && strcmp(call->_name, "uncommon_trap") == 0) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
752 // control flow leads to uct so should be ok
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
753 _uncommon_traps.push(call);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
754 ctrl_path.push(call);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
755 ptr = ptr->in(0)->in(0);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
756 continue;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
757 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
758 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
759
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
760 #ifndef PRODUCT
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
761 // Some unexpected control flow we don't know how to handle.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
762 if (PrintOptimizeStringConcat) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
763 tty->print_cr("failing with unknown test");
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
764 b->dump();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
765 cmp->dump();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
766 v1->dump();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
767 v2->dump();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
768 tty->cr();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
769 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
770 #endif
3396
2b27ef5c2173 7046096: SEGV IN C2 WITH 6U25
kvn
parents: 3283
diff changeset
771 fail = true;
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
772 break;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
773 } else if (ptr->is_Proj() && ptr->in(0)->is_Initialize()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
774 ptr = ptr->in(0)->in(0);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
775 } else if (ptr->is_Region()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
776 Node* copy = ptr->as_Region()->is_copy();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
777 if (copy != NULL) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
778 ptr = copy;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
779 continue;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
780 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
781 if (ptr->req() == 3 &&
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
782 ptr->in(1) != NULL && ptr->in(1)->is_Proj() &&
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
783 ptr->in(2) != NULL && ptr->in(2)->is_Proj() &&
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
784 ptr->in(1)->in(0) == ptr->in(2)->in(0) &&
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
785 ptr->in(1)->in(0) != NULL && ptr->in(1)->in(0)->is_If()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
786 // Simple diamond.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
787 // XXX should check for possibly merging stores. simple data merges are ok.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
788 ptr = ptr->in(1)->in(0)->in(0);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
789 continue;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
790 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
791 #ifndef PRODUCT
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
792 if (PrintOptimizeStringConcat) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
793 tty->print_cr("fusion would fail for region");
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
794 _begin->dump();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
795 ptr->dump(2);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
796 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
797 #endif
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
798 fail = true;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
799 break;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
800 } else {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
801 // other unknown control
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
802 if (!fail) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
803 #ifndef PRODUCT
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
804 if (PrintOptimizeStringConcat) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
805 tty->print_cr("fusion would fail for");
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
806 _begin->dump();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
807 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
808 #endif
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
809 fail = true;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
810 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
811 #ifndef PRODUCT
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
812 if (PrintOptimizeStringConcat) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
813 ptr->dump();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
814 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
815 #endif
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
816 ptr = ptr->in(0);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
817 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
818 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
819 #ifndef PRODUCT
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
820 if (PrintOptimizeStringConcat && fail) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
821 tty->cr();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
822 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
823 #endif
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
824 if (fail) return !fail;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
825
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
826 // Validate that all these results produced are contained within
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
827 // this cluster of objects. First collect all the results produced
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
828 // by calls in the region.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
829 _stringopts->_visited.Clear();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
830 Node_List worklist;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
831 Node* final_result = _end->proj_out(TypeFunc::Parms);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
832 for (uint i = 0; i < _control.size(); i++) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
833 CallNode* cnode = _control.at(i)->isa_Call();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
834 if (cnode != NULL) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
835 _stringopts->_visited.test_set(cnode->_idx);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
836 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
837 Node* result = cnode != NULL ? cnode->proj_out(TypeFunc::Parms) : NULL;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
838 if (result != NULL && result != final_result) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
839 worklist.push(result);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
840 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
841 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
842
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
843 Node* last_result = NULL;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
844 while (worklist.size() > 0) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
845 Node* result = worklist.pop();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
846 if (_stringopts->_visited.test_set(result->_idx))
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
847 continue;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
848 for (SimpleDUIterator i(result); i.has_next(); i.next()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
849 Node *use = i.get();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
850 if (ctrl_path.member(use)) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
851 // already checked this
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
852 continue;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
853 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
854 int opc = use->Opcode();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
855 if (opc == Op_CmpP || opc == Op_Node) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
856 ctrl_path.push(use);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
857 continue;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
858 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
859 if (opc == Op_CastPP || opc == Op_CheckCastPP) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
860 for (SimpleDUIterator j(use); j.has_next(); j.next()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
861 worklist.push(j.get());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
862 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
863 worklist.push(use->in(1));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
864 ctrl_path.push(use);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
865 continue;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
866 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
867 #ifndef PRODUCT
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
868 if (PrintOptimizeStringConcat) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
869 if (result != last_result) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
870 last_result = result;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
871 tty->print_cr("extra uses for result:");
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
872 last_result->dump();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
873 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
874 use->dump();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
875 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
876 #endif
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
877 fail = true;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
878 break;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
879 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
880 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
881
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
882 #ifndef PRODUCT
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
883 if (PrintOptimizeStringConcat && !fail) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
884 ttyLocker ttyl;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
885 tty->cr();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
886 tty->print("fusion would succeed (%d %d) for ", null_check_count, _uncommon_traps.size());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
887 _begin->jvms()->dump_spec(tty); tty->cr();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
888 for (int i = 0; i < num_arguments(); i++) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
889 argument(i)->dump();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
890 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
891 _control.dump();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
892 tty->cr();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
893 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
894 #endif
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
895
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
896 return !fail;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
897 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
898
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
899 Node* PhaseStringOpts::fetch_static_field(GraphKit& kit, ciField* field) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
900 const TypeKlassPtr* klass_type = TypeKlassPtr::make(field->holder());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
901 Node* klass_node = __ makecon(klass_type);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
902 BasicType bt = field->layout_type();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
903 ciType* field_klass = field->type();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
904
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
905 const Type *type;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
906 if( bt == T_OBJECT ) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
907 if (!field->type()->is_loaded()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
908 type = TypeInstPtr::BOTTOM;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
909 } else if (field->is_constant()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
910 // This can happen if the constant oop is non-perm.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
911 ciObject* con = field->constant_value().as_object();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
912 // Do not "join" in the previous type; it doesn't add value,
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
913 // and may yield a vacuous result if the field is of interface type.
2379
b099aaf51bf8 6962931: move interned strings out of the perm gen
jcoomes
parents: 2090
diff changeset
914 type = TypeOopPtr::make_from_constant(con, true)->isa_oopptr();
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
915 assert(type != NULL, "field singleton type must be consistent");
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
916 } else {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
917 type = TypeOopPtr::make_from_klass(field_klass->as_klass());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
918 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
919 } else {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
920 type = Type::get_const_basic_type(bt);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
921 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
922
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
923 return kit.make_load(NULL, kit.basic_plus_adr(klass_node, field->offset_in_bytes()),
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
924 type, T_OBJECT,
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
925 C->get_alias_index(klass_type->add_offset(field->offset_in_bytes())));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
926 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
927
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
928 Node* PhaseStringOpts::int_stringSize(GraphKit& kit, Node* arg) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
929 RegionNode *final_merge = new (C, 3) RegionNode(3);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
930 kit.gvn().set_type(final_merge, Type::CONTROL);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
931 Node* final_size = new (C, 3) PhiNode(final_merge, TypeInt::INT);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
932 kit.gvn().set_type(final_size, TypeInt::INT);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
933
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
934 IfNode* iff = kit.create_and_map_if(kit.control(),
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
935 __ Bool(__ CmpI(arg, __ intcon(0x80000000)), BoolTest::ne),
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
936 PROB_FAIR, COUNT_UNKNOWN);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
937 Node* is_min = __ IfFalse(iff);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
938 final_merge->init_req(1, is_min);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
939 final_size->init_req(1, __ intcon(11));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
940
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
941 kit.set_control(__ IfTrue(iff));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
942 if (kit.stopped()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
943 final_merge->init_req(2, C->top());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
944 final_size->init_req(2, C->top());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
945 } else {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
946
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
947 // int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
948 RegionNode *r = new (C, 3) RegionNode(3);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
949 kit.gvn().set_type(r, Type::CONTROL);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
950 Node *phi = new (C, 3) PhiNode(r, TypeInt::INT);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
951 kit.gvn().set_type(phi, TypeInt::INT);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
952 Node *size = new (C, 3) PhiNode(r, TypeInt::INT);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
953 kit.gvn().set_type(size, TypeInt::INT);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
954 Node* chk = __ CmpI(arg, __ intcon(0));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
955 Node* p = __ Bool(chk, BoolTest::lt);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
956 IfNode* iff = kit.create_and_map_if(kit.control(), p, PROB_FAIR, COUNT_UNKNOWN);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
957 Node* lessthan = __ IfTrue(iff);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
958 Node* greaterequal = __ IfFalse(iff);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
959 r->init_req(1, lessthan);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
960 phi->init_req(1, __ SubI(__ intcon(0), arg));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
961 size->init_req(1, __ intcon(1));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
962 r->init_req(2, greaterequal);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
963 phi->init_req(2, arg);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
964 size->init_req(2, __ intcon(0));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
965 kit.set_control(r);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
966 C->record_for_igvn(r);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
967 C->record_for_igvn(phi);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
968 C->record_for_igvn(size);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
969
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
970 // for (int i=0; ; i++)
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
971 // if (x <= sizeTable[i])
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
972 // return i+1;
2383
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2090
diff changeset
973
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2090
diff changeset
974 // Add loop predicate first.
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2090
diff changeset
975 kit.add_predicate();
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2090
diff changeset
976
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
977 RegionNode *loop = new (C, 3) RegionNode(3);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
978 loop->init_req(1, kit.control());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
979 kit.gvn().set_type(loop, Type::CONTROL);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
980
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
981 Node *index = new (C, 3) PhiNode(loop, TypeInt::INT);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
982 index->init_req(1, __ intcon(0));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
983 kit.gvn().set_type(index, TypeInt::INT);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
984 kit.set_control(loop);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
985 Node* sizeTable = fetch_static_field(kit, size_table_field);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
986
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
987 Node* value = kit.load_array_element(NULL, sizeTable, index, TypeAryPtr::INTS);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
988 C->record_for_igvn(value);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
989 Node* limit = __ CmpI(phi, value);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
990 Node* limitb = __ Bool(limit, BoolTest::le);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
991 IfNode* iff2 = kit.create_and_map_if(kit.control(), limitb, PROB_MIN, COUNT_UNKNOWN);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
992 Node* lessEqual = __ IfTrue(iff2);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
993 Node* greater = __ IfFalse(iff2);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
994
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
995 loop->init_req(2, greater);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
996 index->init_req(2, __ AddI(index, __ intcon(1)));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
997
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
998 kit.set_control(lessEqual);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
999 C->record_for_igvn(loop);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1000 C->record_for_igvn(index);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1001
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1002 final_merge->init_req(2, kit.control());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1003 final_size->init_req(2, __ AddI(__ AddI(index, size), __ intcon(1)));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1004 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1005
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1006 kit.set_control(final_merge);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1007 C->record_for_igvn(final_merge);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1008 C->record_for_igvn(final_size);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1009
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1010 return final_size;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1011 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1012
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1013 void PhaseStringOpts::int_getChars(GraphKit& kit, Node* arg, Node* char_array, Node* start, Node* end) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1014 RegionNode *final_merge = new (C, 4) RegionNode(4);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1015 kit.gvn().set_type(final_merge, Type::CONTROL);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1016 Node *final_mem = PhiNode::make(final_merge, kit.memory(char_adr_idx), Type::MEMORY, TypeAryPtr::CHARS);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1017 kit.gvn().set_type(final_mem, Type::MEMORY);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1018
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1019 // need to handle Integer.MIN_VALUE specially because negating doesn't make it positive
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1020 {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1021 // i == MIN_VALUE
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1022 IfNode* iff = kit.create_and_map_if(kit.control(),
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1023 __ Bool(__ CmpI(arg, __ intcon(0x80000000)), BoolTest::ne),
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1024 PROB_FAIR, COUNT_UNKNOWN);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1025
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1026 Node* old_mem = kit.memory(char_adr_idx);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1027
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1028 kit.set_control(__ IfFalse(iff));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1029 if (kit.stopped()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1030 // Statically not equal to MIN_VALUE so this path is dead
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1031 final_merge->init_req(3, kit.control());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1032 } else {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1033 copy_string(kit, __ makecon(TypeInstPtr::make(C->env()->the_min_jint_string())),
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1034 char_array, start);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1035 final_merge->init_req(3, kit.control());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1036 final_mem->init_req(3, kit.memory(char_adr_idx));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1037 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1038
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1039 kit.set_control(__ IfTrue(iff));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1040 kit.set_memory(old_mem, char_adr_idx);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1041 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1042
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1043
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1044 // Simplified version of Integer.getChars
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1045
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1046 // int q, r;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1047 // int charPos = index;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1048 Node* charPos = end;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1049
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1050 // char sign = 0;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1051
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1052 Node* i = arg;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1053 Node* sign = __ intcon(0);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1054
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1055 // if (i < 0) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1056 // sign = '-';
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1057 // i = -i;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1058 // }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1059 {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1060 IfNode* iff = kit.create_and_map_if(kit.control(),
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1061 __ Bool(__ CmpI(arg, __ intcon(0)), BoolTest::lt),
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1062 PROB_FAIR, COUNT_UNKNOWN);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1063
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1064 RegionNode *merge = new (C, 3) RegionNode(3);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1065 kit.gvn().set_type(merge, Type::CONTROL);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1066 i = new (C, 3) PhiNode(merge, TypeInt::INT);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1067 kit.gvn().set_type(i, TypeInt::INT);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1068 sign = new (C, 3) PhiNode(merge, TypeInt::INT);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1069 kit.gvn().set_type(sign, TypeInt::INT);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1070
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1071 merge->init_req(1, __ IfTrue(iff));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1072 i->init_req(1, __ SubI(__ intcon(0), arg));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1073 sign->init_req(1, __ intcon('-'));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1074 merge->init_req(2, __ IfFalse(iff));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1075 i->init_req(2, arg);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1076 sign->init_req(2, __ intcon(0));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1077
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1078 kit.set_control(merge);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1079
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1080 C->record_for_igvn(merge);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1081 C->record_for_igvn(i);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1082 C->record_for_igvn(sign);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1083 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1084
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1085 // for (;;) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1086 // q = i / 10;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1087 // r = i - ((q << 3) + (q << 1)); // r = i-(q*10) ...
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1088 // buf [--charPos] = digits [r];
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1089 // i = q;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1090 // if (i == 0) break;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1091 // }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1092
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1093 {
2383
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2090
diff changeset
1094 // Add loop predicate first.
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2090
diff changeset
1095 kit.add_predicate();
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2090
diff changeset
1096
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1097 RegionNode *head = new (C, 3) RegionNode(3);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1098 head->init_req(1, kit.control());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1099 kit.gvn().set_type(head, Type::CONTROL);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1100 Node *i_phi = new (C, 3) PhiNode(head, TypeInt::INT);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1101 i_phi->init_req(1, i);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1102 kit.gvn().set_type(i_phi, TypeInt::INT);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1103 charPos = PhiNode::make(head, charPos);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1104 kit.gvn().set_type(charPos, TypeInt::INT);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1105 Node *mem = PhiNode::make(head, kit.memory(char_adr_idx), Type::MEMORY, TypeAryPtr::CHARS);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1106 kit.gvn().set_type(mem, Type::MEMORY);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1107 kit.set_control(head);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1108 kit.set_memory(mem, char_adr_idx);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1109
1250
3f5b7efb9642 6920293: OptimizeStringConcat causing core dumps
never
parents: 1080
diff changeset
1110 Node* q = __ DivI(NULL, i_phi, __ intcon(10));
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1111 Node* r = __ SubI(i_phi, __ AddI(__ LShiftI(q, __ intcon(3)),
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1112 __ LShiftI(q, __ intcon(1))));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1113 Node* m1 = __ SubI(charPos, __ intcon(1));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1114 Node* ch = __ AddI(r, __ intcon('0'));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1115
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1116 Node* st = __ store_to_memory(kit.control(), kit.array_element_address(char_array, m1, T_CHAR),
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1117 ch, T_CHAR, char_adr_idx);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1118
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1119
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1120 IfNode* iff = kit.create_and_map_if(head, __ Bool(__ CmpI(q, __ intcon(0)), BoolTest::ne),
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1121 PROB_FAIR, COUNT_UNKNOWN);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1122 Node* ne = __ IfTrue(iff);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1123 Node* eq = __ IfFalse(iff);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1124
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1125 head->init_req(2, ne);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1126 mem->init_req(2, st);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1127 i_phi->init_req(2, q);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1128 charPos->init_req(2, m1);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1129
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1130 charPos = m1;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1131
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1132 kit.set_control(eq);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1133 kit.set_memory(st, char_adr_idx);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1134
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1135 C->record_for_igvn(head);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1136 C->record_for_igvn(mem);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1137 C->record_for_igvn(i_phi);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1138 C->record_for_igvn(charPos);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1139 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1140
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1141 {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1142 // if (sign != 0) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1143 // buf [--charPos] = sign;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1144 // }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1145 IfNode* iff = kit.create_and_map_if(kit.control(),
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1146 __ Bool(__ CmpI(sign, __ intcon(0)), BoolTest::ne),
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1147 PROB_FAIR, COUNT_UNKNOWN);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1148
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1149 final_merge->init_req(2, __ IfFalse(iff));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1150 final_mem->init_req(2, kit.memory(char_adr_idx));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1151
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1152 kit.set_control(__ IfTrue(iff));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1153 if (kit.stopped()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1154 final_merge->init_req(1, C->top());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1155 final_mem->init_req(1, C->top());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1156 } else {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1157 Node* m1 = __ SubI(charPos, __ intcon(1));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1158 Node* st = __ store_to_memory(kit.control(), kit.array_element_address(char_array, m1, T_CHAR),
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1159 sign, T_CHAR, char_adr_idx);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1160
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1161 final_merge->init_req(1, kit.control());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1162 final_mem->init_req(1, st);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1163 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1164
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1165 kit.set_control(final_merge);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1166 kit.set_memory(final_mem, char_adr_idx);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1167
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1168 C->record_for_igvn(final_merge);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1169 C->record_for_igvn(final_mem);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1170 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1171 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1172
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1173
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1174 Node* PhaseStringOpts::copy_string(GraphKit& kit, Node* str, Node* char_array, Node* start) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1175 Node* string = str;
3283
01fd6090fdd8 7032162: assert(flat != TypePtr::BOTTOM) failed: cannot alias-analyze an untyped ptr
never
parents: 2426
diff changeset
1176 Node* offset = kit.make_load(kit.control(),
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1177 kit.basic_plus_adr(string, string, java_lang_String::offset_offset_in_bytes()),
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1178 TypeInt::INT, T_INT, offset_field_idx);
3283
01fd6090fdd8 7032162: assert(flat != TypePtr::BOTTOM) failed: cannot alias-analyze an untyped ptr
never
parents: 2426
diff changeset
1179 Node* count = kit.make_load(kit.control(),
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1180 kit.basic_plus_adr(string, string, java_lang_String::count_offset_in_bytes()),
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1181 TypeInt::INT, T_INT, count_field_idx);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1182 const TypeAryPtr* value_type = TypeAryPtr::make(TypePtr::NotNull,
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1183 TypeAry::make(TypeInt::CHAR,TypeInt::POS),
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1184 ciTypeArrayKlass::make(T_CHAR), true, 0);
3283
01fd6090fdd8 7032162: assert(flat != TypePtr::BOTTOM) failed: cannot alias-analyze an untyped ptr
never
parents: 2426
diff changeset
1185 Node* value = kit.make_load(kit.control(),
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1186 kit.basic_plus_adr(string, string, java_lang_String::value_offset_in_bytes()),
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1187 value_type, T_OBJECT, value_field_idx);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1188
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1189 // copy the contents
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1190 if (offset->is_Con() && count->is_Con() && value->is_Con() && count->get_int() < unroll_string_copy_length) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1191 // For small constant strings just emit individual stores.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1192 // A length of 6 seems like a good space/speed tradeof.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1193 int c = count->get_int();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1194 int o = offset->get_int();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1195 const TypeOopPtr* t = kit.gvn().type(value)->isa_oopptr();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1196 ciTypeArray* value_array = t->const_oop()->as_type_array();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1197 for (int e = 0; e < c; e++) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1198 __ store_to_memory(kit.control(), kit.array_element_address(char_array, start, T_CHAR),
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1199 __ intcon(value_array->char_at(o + e)), T_CHAR, char_adr_idx);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1200 start = __ AddI(start, __ intcon(1));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1201 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1202 } else {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1203 Node* src_ptr = kit.array_element_address(value, offset, T_CHAR);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1204 Node* dst_ptr = kit.array_element_address(char_array, start, T_CHAR);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1205 Node* c = count;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1206 Node* extra = NULL;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1207 #ifdef _LP64
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1208 c = __ ConvI2L(c);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1209 extra = C->top();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1210 #endif
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1211 Node* call = kit.make_runtime_call(GraphKit::RC_LEAF|GraphKit::RC_NO_FP,
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1212 OptoRuntime::fast_arraycopy_Type(),
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1213 CAST_FROM_FN_PTR(address, StubRoutines::jshort_disjoint_arraycopy()),
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1214 "jshort_disjoint_arraycopy", TypeAryPtr::CHARS,
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1215 src_ptr, dst_ptr, c, extra);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1216 start = __ AddI(start, count);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1217 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1218 return start;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1219 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1220
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1221
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1222 void PhaseStringOpts::replace_string_concat(StringConcat* sc) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1223 // Log a little info about the transformation
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1224 sc->maybe_log_transform();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1225
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1226 // pull the JVMState of the allocation into a SafePointNode to serve as
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1227 // as a shim for the insertion of the new code.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1228 JVMState* jvms = sc->begin()->jvms()->clone_shallow(C);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1229 uint size = sc->begin()->req();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1230 SafePointNode* map = new (C, size) SafePointNode(size, jvms);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1231
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1232 // copy the control and memory state from the final call into our
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1233 // new starting state. This allows any preceeding tests to feed
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1234 // into the new section of code.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1235 for (uint i1 = 0; i1 < TypeFunc::Parms; i1++) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1236 map->init_req(i1, sc->end()->in(i1));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1237 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1238 // blow away old allocation arguments
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1239 for (uint i1 = TypeFunc::Parms; i1 < jvms->debug_start(); i1++) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1240 map->init_req(i1, C->top());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1241 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1242 // Copy the rest of the inputs for the JVMState
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1243 for (uint i1 = jvms->debug_start(); i1 < sc->begin()->req(); i1++) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1244 map->init_req(i1, sc->begin()->in(i1));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1245 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1246 // Make sure the memory state is a MergeMem for parsing.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1247 if (!map->in(TypeFunc::Memory)->is_MergeMem()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1248 map->set_req(TypeFunc::Memory, MergeMemNode::make(C, map->in(TypeFunc::Memory)));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1249 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1250
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1251 jvms->set_map(map);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1252 map->ensure_stack(jvms, jvms->method()->max_stack());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1253
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1254
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1255 // disconnect all the old StringBuilder calls from the graph
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1256 sc->eliminate_unneeded_control();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1257
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1258 // At this point all the old work has been completely removed from
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1259 // the graph and the saved JVMState exists at the point where the
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1260 // final toString call used to be.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1261 GraphKit kit(jvms);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1262
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1263 // There may be uncommon traps which are still using the
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1264 // intermediate states and these need to be rewritten to point at
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1265 // the JVMState at the beginning of the transformation.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1266 sc->convert_uncommon_traps(kit, jvms);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1267
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1268 // Now insert the logic to compute the size of the string followed
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1269 // by all the logic to construct array and resulting string.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1270
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1271 Node* null_string = __ makecon(TypeInstPtr::make(C->env()->the_null_string()));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1272
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1273 // Create a region for the overflow checks to merge into.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1274 int args = MAX2(sc->num_arguments(), 1);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1275 RegionNode* overflow = new (C, args) RegionNode(args);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1276 kit.gvn().set_type(overflow, Type::CONTROL);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1277
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1278 // Create a hook node to hold onto the individual sizes since they
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1279 // are need for the copying phase.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1280 Node* string_sizes = new (C, args) Node(args);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1281
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1282 Node* length = __ intcon(0);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1283 for (int argi = 0; argi < sc->num_arguments(); argi++) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1284 Node* arg = sc->argument(argi);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1285 switch (sc->mode(argi)) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1286 case StringConcat::IntMode: {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1287 Node* string_size = int_stringSize(kit, arg);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1288
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1289 // accumulate total
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1290 length = __ AddI(length, string_size);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1291
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1292 // Cache this value for the use by int_toString
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1293 string_sizes->init_req(argi, string_size);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1294 break;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1295 }
2090
2ddb2fab82cb 7009359: HS with -XX:+AggressiveOpts optimize new StringBuffer(null) so it does not throw NPE as expected
kvn
parents: 1972
diff changeset
1296 case StringConcat::StringNullCheckMode: {
2ddb2fab82cb 7009359: HS with -XX:+AggressiveOpts optimize new StringBuffer(null) so it does not throw NPE as expected
kvn
parents: 1972
diff changeset
1297 const Type* type = kit.gvn().type(arg);
2ddb2fab82cb 7009359: HS with -XX:+AggressiveOpts optimize new StringBuffer(null) so it does not throw NPE as expected
kvn
parents: 1972
diff changeset
1298 assert(type != TypePtr::NULL_PTR, "missing check");
2ddb2fab82cb 7009359: HS with -XX:+AggressiveOpts optimize new StringBuffer(null) so it does not throw NPE as expected
kvn
parents: 1972
diff changeset
1299 if (!type->higher_equal(TypeInstPtr::NOTNULL)) {
2ddb2fab82cb 7009359: HS with -XX:+AggressiveOpts optimize new StringBuffer(null) so it does not throw NPE as expected
kvn
parents: 1972
diff changeset
1300 // Null check with uncommont trap since
2ddb2fab82cb 7009359: HS with -XX:+AggressiveOpts optimize new StringBuffer(null) so it does not throw NPE as expected
kvn
parents: 1972
diff changeset
1301 // StringBuilder(null) throws exception.
2ddb2fab82cb 7009359: HS with -XX:+AggressiveOpts optimize new StringBuffer(null) so it does not throw NPE as expected
kvn
parents: 1972
diff changeset
1302 // Use special uncommon trap instead of
2ddb2fab82cb 7009359: HS with -XX:+AggressiveOpts optimize new StringBuffer(null) so it does not throw NPE as expected
kvn
parents: 1972
diff changeset
1303 // calling normal do_null_check().
2ddb2fab82cb 7009359: HS with -XX:+AggressiveOpts optimize new StringBuffer(null) so it does not throw NPE as expected
kvn
parents: 1972
diff changeset
1304 Node* p = __ Bool(__ CmpP(arg, kit.null()), BoolTest::ne);
2ddb2fab82cb 7009359: HS with -XX:+AggressiveOpts optimize new StringBuffer(null) so it does not throw NPE as expected
kvn
parents: 1972
diff changeset
1305 IfNode* iff = kit.create_and_map_if(kit.control(), p, PROB_MIN, COUNT_UNKNOWN);
2ddb2fab82cb 7009359: HS with -XX:+AggressiveOpts optimize new StringBuffer(null) so it does not throw NPE as expected
kvn
parents: 1972
diff changeset
1306 overflow->add_req(__ IfFalse(iff));
2ddb2fab82cb 7009359: HS with -XX:+AggressiveOpts optimize new StringBuffer(null) so it does not throw NPE as expected
kvn
parents: 1972
diff changeset
1307 Node* notnull = __ IfTrue(iff);
2ddb2fab82cb 7009359: HS with -XX:+AggressiveOpts optimize new StringBuffer(null) so it does not throw NPE as expected
kvn
parents: 1972
diff changeset
1308 kit.set_control(notnull); // set control for the cast_not_null
2ddb2fab82cb 7009359: HS with -XX:+AggressiveOpts optimize new StringBuffer(null) so it does not throw NPE as expected
kvn
parents: 1972
diff changeset
1309 arg = kit.cast_not_null(arg, false);
2ddb2fab82cb 7009359: HS with -XX:+AggressiveOpts optimize new StringBuffer(null) so it does not throw NPE as expected
kvn
parents: 1972
diff changeset
1310 sc->set_argument(argi, arg);
2ddb2fab82cb 7009359: HS with -XX:+AggressiveOpts optimize new StringBuffer(null) so it does not throw NPE as expected
kvn
parents: 1972
diff changeset
1311 }
2ddb2fab82cb 7009359: HS with -XX:+AggressiveOpts optimize new StringBuffer(null) so it does not throw NPE as expected
kvn
parents: 1972
diff changeset
1312 assert(kit.gvn().type(arg)->higher_equal(TypeInstPtr::NOTNULL), "sanity");
2ddb2fab82cb 7009359: HS with -XX:+AggressiveOpts optimize new StringBuffer(null) so it does not throw NPE as expected
kvn
parents: 1972
diff changeset
1313 // Fallthrough to add string length.
2ddb2fab82cb 7009359: HS with -XX:+AggressiveOpts optimize new StringBuffer(null) so it does not throw NPE as expected
kvn
parents: 1972
diff changeset
1314 }
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1315 case StringConcat::StringMode: {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1316 const Type* type = kit.gvn().type(arg);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1317 if (type == TypePtr::NULL_PTR) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1318 // replace the argument with the null checked version
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1319 arg = null_string;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1320 sc->set_argument(argi, arg);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1321 } else if (!type->higher_equal(TypeInstPtr::NOTNULL)) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1322 // s = s != null ? s : "null";
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1323 // length = length + (s.count - s.offset);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1324 RegionNode *r = new (C, 3) RegionNode(3);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1325 kit.gvn().set_type(r, Type::CONTROL);
1250
3f5b7efb9642 6920293: OptimizeStringConcat causing core dumps
never
parents: 1080
diff changeset
1326 Node *phi = new (C, 3) PhiNode(r, type);
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1327 kit.gvn().set_type(phi, phi->bottom_type());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1328 Node* p = __ Bool(__ CmpP(arg, kit.null()), BoolTest::ne);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1329 IfNode* iff = kit.create_and_map_if(kit.control(), p, PROB_MIN, COUNT_UNKNOWN);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1330 Node* notnull = __ IfTrue(iff);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1331 Node* isnull = __ IfFalse(iff);
1250
3f5b7efb9642 6920293: OptimizeStringConcat causing core dumps
never
parents: 1080
diff changeset
1332 kit.set_control(notnull); // set control for the cast_not_null
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1333 r->init_req(1, notnull);
1250
3f5b7efb9642 6920293: OptimizeStringConcat causing core dumps
never
parents: 1080
diff changeset
1334 phi->init_req(1, kit.cast_not_null(arg, false));
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1335 r->init_req(2, isnull);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1336 phi->init_req(2, null_string);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1337 kit.set_control(r);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1338 C->record_for_igvn(r);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1339 C->record_for_igvn(phi);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1340 // replace the argument with the null checked version
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1341 arg = phi;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1342 sc->set_argument(argi, arg);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1343 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1344 // Node* offset = kit.make_load(NULL, kit.basic_plus_adr(arg, arg, offset_offset),
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1345 // TypeInt::INT, T_INT, offset_field_idx);
3283
01fd6090fdd8 7032162: assert(flat != TypePtr::BOTTOM) failed: cannot alias-analyze an untyped ptr
never
parents: 2426
diff changeset
1346 Node* count = kit.make_load(kit.control(), kit.basic_plus_adr(arg, arg, java_lang_String::count_offset_in_bytes()),
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1347 TypeInt::INT, T_INT, count_field_idx);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1348 length = __ AddI(length, count);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1349 string_sizes->init_req(argi, NULL);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1350 break;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1351 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1352 case StringConcat::CharMode: {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1353 // one character only
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1354 length = __ AddI(length, __ intcon(1));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1355 break;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1356 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1357 default:
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1358 ShouldNotReachHere();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1359 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1360 if (argi > 0) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1361 // Check that the sum hasn't overflowed
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1362 IfNode* iff = kit.create_and_map_if(kit.control(),
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1363 __ Bool(__ CmpI(length, __ intcon(0)), BoolTest::lt),
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1364 PROB_MIN, COUNT_UNKNOWN);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1365 kit.set_control(__ IfFalse(iff));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1366 overflow->set_req(argi, __ IfTrue(iff));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1367 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1368 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1369
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1370 {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1371 // Hook
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1372 PreserveJVMState pjvms(&kit);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1373 kit.set_control(overflow);
2090
2ddb2fab82cb 7009359: HS with -XX:+AggressiveOpts optimize new StringBuffer(null) so it does not throw NPE as expected
kvn
parents: 1972
diff changeset
1374 C->record_for_igvn(overflow);
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1375 kit.uncommon_trap(Deoptimization::Reason_intrinsic,
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1376 Deoptimization::Action_make_not_entrant);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1377 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1378
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1379 // length now contains the number of characters needed for the
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1380 // char[] so create a new AllocateArray for the char[]
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1381 Node* char_array = NULL;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1382 {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1383 PreserveReexecuteState preexecs(&kit);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1384 // The original jvms is for an allocation of either a String or
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1385 // StringBuffer so no stack adjustment is necessary for proper
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1386 // reexecution. If we deoptimize in the slow path the bytecode
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1387 // will be reexecuted and the char[] allocation will be thrown away.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1388 kit.jvms()->set_should_reexecute(true);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1389 char_array = kit.new_array(__ makecon(TypeKlassPtr::make(ciTypeArrayKlass::make(T_CHAR))),
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1390 length, 1);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1391 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1392
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1393 // Mark the allocation so that zeroing is skipped since the code
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1394 // below will overwrite the entire array
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1395 AllocateArrayNode* char_alloc = AllocateArrayNode::Ideal_array_allocation(char_array, _gvn);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1396 char_alloc->maybe_set_complete(_gvn);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1397
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1398 // Now copy the string representations into the final char[]
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1399 Node* start = __ intcon(0);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1400 for (int argi = 0; argi < sc->num_arguments(); argi++) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1401 Node* arg = sc->argument(argi);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1402 switch (sc->mode(argi)) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1403 case StringConcat::IntMode: {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1404 Node* end = __ AddI(start, string_sizes->in(argi));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1405 // getChars words backwards so pass the ending point as well as the start
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1406 int_getChars(kit, arg, char_array, start, end);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1407 start = end;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1408 break;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1409 }
2090
2ddb2fab82cb 7009359: HS with -XX:+AggressiveOpts optimize new StringBuffer(null) so it does not throw NPE as expected
kvn
parents: 1972
diff changeset
1410 case StringConcat::StringNullCheckMode:
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1411 case StringConcat::StringMode: {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1412 start = copy_string(kit, arg, char_array, start);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1413 break;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1414 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1415 case StringConcat::CharMode: {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1416 __ store_to_memory(kit.control(), kit.array_element_address(char_array, start, T_CHAR),
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1417 arg, T_CHAR, char_adr_idx);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1418 start = __ AddI(start, __ intcon(1));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1419 break;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1420 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1421 default:
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1422 ShouldNotReachHere();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1423 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1424 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1425
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1426 // If we're not reusing an existing String allocation then allocate one here.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1427 Node* result = sc->string_alloc();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1428 if (result == NULL) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1429 PreserveReexecuteState preexecs(&kit);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1430 // The original jvms is for an allocation of either a String or
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1431 // StringBuffer so no stack adjustment is necessary for proper
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1432 // reexecution.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1433 kit.jvms()->set_should_reexecute(true);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1434 result = kit.new_instance(__ makecon(TypeKlassPtr::make(C->env()->String_klass())));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1435 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1436
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1437 // Intialize the string
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1438 kit.store_to_memory(kit.control(), kit.basic_plus_adr(result, java_lang_String::offset_offset_in_bytes()),
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1439 __ intcon(0), T_INT, offset_field_idx);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1440 kit.store_to_memory(kit.control(), kit.basic_plus_adr(result, java_lang_String::count_offset_in_bytes()),
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1441 length, T_INT, count_field_idx);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1442 kit.store_to_memory(kit.control(), kit.basic_plus_adr(result, java_lang_String::value_offset_in_bytes()),
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1443 char_array, T_OBJECT, value_field_idx);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1444
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1445 // hook up the outgoing control and result
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1446 kit.replace_call(sc->end(), result);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1447
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1448 // Unhook any hook nodes
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1449 string_sizes->disconnect_inputs(NULL);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1450 sc->cleanup();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1451 }