annotate src/share/vm/opto/stringopts.cpp @ 10185:d50cc62e94ff

8012715: G1: GraphKit accesses PtrQueue::_index as int but is size_t Summary: In graphKit INT operations were generated to access PtrQueue::_index which has type size_t. This is 64 bit on 64-bit machines. No problems occur on little endian machines as long as the index fits into 32 bit, but on big endian machines the upper part is read, which is zero. This leads to unnecessary branches to the slow path in the runtime. Reviewed-by: twisti, johnc Contributed-by: Martin Doerr <martin.doerr@sap.com>
author johnc
date Wed, 24 Apr 2013 14:48:43 -0700
parents d092d1b31229
children 90abdd727e64
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 /*
6057
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6043
diff changeset
2 * Copyright (c) 2009, 2012, 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) {
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6223
diff changeset
72 _arguments = new (_stringopts->C) Node(1);
1080
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 }
6186
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
115
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
116 void push_string(Node* value) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
117 push(value, StringMode);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
118 }
2090
2ddb2fab82cb 7009359: HS with -XX:+AggressiveOpts optimize new StringBuffer(null) so it does not throw NPE as expected
kvn
parents: 1972
diff changeset
119 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
120 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
121 }
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
122 void push_int(Node* value) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
123 push(value, IntMode);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
124 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
125 void push_char(Node* value) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
126 push(value, CharMode);
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
6186
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
129 static bool is_SB_toString(Node* call) {
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
130 if (call->is_CallStaticJava()) {
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
131 CallStaticJavaNode* csj = call->as_CallStaticJava();
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
132 ciMethod* m = csj->method();
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
133 if (m != NULL &&
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
134 (m->intrinsic_id() == vmIntrinsics::_StringBuilder_toString ||
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
135 m->intrinsic_id() == vmIntrinsics::_StringBuffer_toString)) {
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
136 return true;
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
137 }
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
138 }
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
139 return false;
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
140 }
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
141
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
142 static Node* skip_string_null_check(Node* value) {
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
143 // Look for a diamond shaped Null check of toString() result
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
144 // (could be code from String.valueOf()):
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
145 // (Proj == NULL) ? "null":"CastPP(Proj)#NotNULL
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
146 if (value->is_Phi()) {
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
147 int true_path = value->as_Phi()->is_diamond_phi();
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
148 if (true_path != 0) {
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
149 // phi->region->if_proj->ifnode->bool
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
150 BoolNode* b = value->in(0)->in(1)->in(0)->in(1)->as_Bool();
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
151 Node* cmp = b->in(1);
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
152 Node* v1 = cmp->in(1);
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
153 Node* v2 = cmp->in(2);
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
154 // Null check of the return of toString which can simply be skipped.
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
155 if (b->_test._test == BoolTest::ne &&
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
156 v2->bottom_type() == TypePtr::NULL_PTR &&
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
157 value->in(true_path)->Opcode() == Op_CastPP &&
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
158 value->in(true_path)->in(1) == v1 &&
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
159 v1->is_Proj() && is_SB_toString(v1->in(0))) {
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
160 return v1;
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
161 }
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
162 }
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
163 }
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
164 return value;
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
165 }
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
166
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
167 Node* argument(int i) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
168 return _arguments->in(i);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
169 }
6186
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
170 Node* argument_uncast(int i) {
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
171 Node* arg = argument(i);
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
172 int amode = mode(i);
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
173 if (amode == StringConcat::StringMode ||
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
174 amode == StringConcat::StringNullCheckMode) {
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
175 arg = skip_string_null_check(arg);
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
176 }
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
177 return arg;
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
178 }
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
179 void set_argument(int i, Node* value) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
180 _arguments->set_req(i, value);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
181 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
182 int num_arguments() {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
183 return _mode.length();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
184 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
185 int mode(int i) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
186 return _mode.at(i);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
187 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
188 void add_control(Node* ctrl) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
189 assert(!_control.contains(ctrl), "only push once");
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
190 _control.push(ctrl);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
191 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
192 CallStaticJavaNode* end() { return _end; }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
193 AllocateNode* begin() { return _begin; }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
194 Node* string_alloc() { return _string_alloc; }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
195
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
196 void eliminate_unneeded_control();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
197 void eliminate_initialize(InitializeNode* init);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
198 void eliminate_call(CallNode* call);
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 void maybe_log_transform() {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
201 CompileLog* log = _stringopts->C->log();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
202 if (log != NULL) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
203 log->head("replace_string_concat arguments='%d' string_alloc='%d' multiple='%d'",
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
204 num_arguments(),
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
205 _string_alloc != NULL,
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
206 _multiple);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
207 JVMState* p = _begin->jvms();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
208 while (p != NULL) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
209 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
210 p = p->caller();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
211 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
212 log->tail("replace_string_concat");
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
213 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
214 }
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 void convert_uncommon_traps(GraphKit& kit, const JVMState* jvms) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
217 for (uint u = 0; u < _uncommon_traps.size(); u++) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
218 Node* uct = _uncommon_traps.at(u);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
219
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
220 // Build a new call using the jvms state of the allocate
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1552
diff changeset
221 address call_addr = SharedRuntime::uncommon_trap_blob()->entry_point();
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
222 const TypeFunc* call_type = OptoRuntime::uncommon_trap_Type();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
223 const TypePtr* no_memory_effects = NULL;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
224 Compile* C = _stringopts->C;
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6223
diff changeset
225 CallStaticJavaNode* call = new (C) CallStaticJavaNode(call_type, call_addr, "uncommon_trap",
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6223
diff changeset
226 jvms->bci(), no_memory_effects);
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
227 for (int e = 0; e < TypeFunc::Parms; e++) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
228 call->init_req(e, uct->in(e));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
229 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
230 // Set the trap request to record intrinsic failure if this trap
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
231 // is taken too many times. Ideally we would handle then traps by
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
232 // doing the original bookkeeping in the MDO so that if it caused
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
233 // 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
234 // optimization. Failing the uncommon traps doesn't really mean
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
235 // 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
236 // do the MDO updates currently.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
237 int trap_request = Deoptimization::make_trap_request(Deoptimization::Reason_intrinsic,
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
238 Deoptimization::Action_make_not_entrant);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
239 call->init_req(TypeFunc::Parms, __ intcon(trap_request));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
240 kit.add_safepoint_edges(call);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
241
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
242 _stringopts->gvn()->transform(call);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
243 C->gvn_replace_by(uct, call);
7196
2aff40cb4703 7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents: 6804
diff changeset
244 uct->disconnect_inputs(NULL, C);
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
245 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
246 }
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 void cleanup() {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
249 // disconnect the hook node
7196
2aff40cb4703 7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents: 6804
diff changeset
250 _arguments->disconnect_inputs(NULL, _stringopts->C);
1080
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 };
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
253
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
254
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
255 void StringConcat::eliminate_unneeded_control() {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
256 for (uint i = 0; i < _control.size(); i++) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
257 Node* n = _control.at(i);
6186
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
258 if (n->is_Allocate()) {
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
259 eliminate_initialize(n->as_Allocate()->initialization());
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
260 }
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
261 if (n->is_Call()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
262 if (n != _end) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
263 eliminate_call(n->as_Call());
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 } else if (n->is_IfTrue()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
266 Compile* C = _stringopts->C;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
267 C->gvn_replace_by(n, n->in(0)->in(0));
7473
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
268 // get rid of the other projection
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
269 C->gvn_replace_by(n->in(0)->as_If()->proj_out(false), C->top());
1080
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 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
272 }
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
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
275 StringConcat* StringConcat::merge(StringConcat* other, Node* arg) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
276 StringConcat* result = new StringConcat(_stringopts, _end);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
277 for (uint x = 0; x < _control.size(); x++) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
278 Node* n = _control.at(x);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
279 if (n->is_Call()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
280 result->_control.push(n);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
281 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
282 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
283 for (uint x = 0; x < other->_control.size(); x++) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
284 Node* n = other->_control.at(x);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
285 if (n->is_Call()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
286 result->_control.push(n);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
287 }
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 assert(result->_control.contains(other->_end), "what?");
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
290 assert(result->_control.contains(_begin), "what?");
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
291 for (int x = 0; x < num_arguments(); x++) {
6186
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
292 Node* argx = argument_uncast(x);
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
293 if (argx == arg) {
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
294 // replace the toString result with the all the arguments that
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
295 // made up the other StringConcat
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
296 for (int y = 0; y < other->num_arguments(); y++) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
297 result->append(other->argument(y), other->mode(y));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
298 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
299 } else {
6186
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
300 result->append(argx, mode(x));
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
301 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
302 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
303 result->set_allocation(other->_begin);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
304 result->_multiple = true;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
305 return result;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
306 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
307
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
308
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
309 void StringConcat::eliminate_call(CallNode* call) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
310 Compile* C = _stringopts->C;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
311 CallProjections projs;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
312 call->extract_projections(&projs, false);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
313 if (projs.fallthrough_catchproj != NULL) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
314 C->gvn_replace_by(projs.fallthrough_catchproj, call->in(TypeFunc::Control));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
315 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
316 if (projs.fallthrough_memproj != NULL) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
317 C->gvn_replace_by(projs.fallthrough_memproj, call->in(TypeFunc::Memory));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
318 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
319 if (projs.catchall_memproj != NULL) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
320 C->gvn_replace_by(projs.catchall_memproj, C->top());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
321 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
322 if (projs.fallthrough_ioproj != NULL) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
323 C->gvn_replace_by(projs.fallthrough_ioproj, call->in(TypeFunc::I_O));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
324 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
325 if (projs.catchall_ioproj != NULL) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
326 C->gvn_replace_by(projs.catchall_ioproj, C->top());
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 if (projs.catchall_catchproj != NULL) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
329 // EA can't cope with the partially collapsed graph this
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
330 // creates so put it on the worklist to be collapsed later.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
331 for (SimpleDUIterator i(projs.catchall_catchproj); i.has_next(); i.next()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
332 Node *use = i.get();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
333 int opc = use->Opcode();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
334 if (opc == Op_CreateEx || opc == Op_Region) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
335 _stringopts->record_dead_node(use);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
336 }
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 C->gvn_replace_by(projs.catchall_catchproj, C->top());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
339 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
340 if (projs.resproj != NULL) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
341 C->gvn_replace_by(projs.resproj, C->top());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
342 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
343 C->gvn_replace_by(call, C->top());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
344 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
345
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
346 void StringConcat::eliminate_initialize(InitializeNode* init) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
347 Compile* C = _stringopts->C;
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 // Eliminate Initialize node.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
350 assert(init->outcnt() <= 2, "only a control and memory projection expected");
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
351 assert(init->req() <= InitializeNode::RawStores, "no pending inits");
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
352 Node *ctrl_proj = init->proj_out(TypeFunc::Control);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
353 if (ctrl_proj != NULL) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
354 C->gvn_replace_by(ctrl_proj, init->in(TypeFunc::Control));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
355 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
356 Node *mem_proj = init->proj_out(TypeFunc::Memory);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
357 if (mem_proj != NULL) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
358 Node *mem = init->in(TypeFunc::Memory);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
359 C->gvn_replace_by(mem_proj, mem);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
360 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
361 C->gvn_replace_by(init, C->top());
7196
2aff40cb4703 7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents: 6804
diff changeset
362 init->disconnect_inputs(NULL, C);
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
363 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
364
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
365 Node_List PhaseStringOpts::collect_toString_calls() {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
366 Node_List string_calls;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
367 Node_List worklist;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
368
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
369 _visited.Clear();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
370
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
371 // Prime the worklist
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
372 for (uint i = 1; i < C->root()->len(); i++) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
373 Node* n = C->root()->in(i);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
374 if (n != NULL && !_visited.test_set(n->_idx)) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
375 worklist.push(n);
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 }
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 while (worklist.size() > 0) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
380 Node* ctrl = worklist.pop();
6186
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
381 if (StringConcat::is_SB_toString(ctrl)) {
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
382 CallStaticJavaNode* csj = ctrl->as_CallStaticJava();
6186
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
383 string_calls.push(csj);
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
384 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
385 if (ctrl->in(0) != NULL && !_visited.test_set(ctrl->in(0)->_idx)) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
386 worklist.push(ctrl->in(0));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
387 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
388 if (ctrl->is_Region()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
389 for (uint i = 1; i < ctrl->len(); i++) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
390 if (ctrl->in(i) != NULL && !_visited.test_set(ctrl->in(i)->_idx)) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
391 worklist.push(ctrl->in(i));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
392 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
393 }
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 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
396 return string_calls;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
397 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
398
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
399
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
400 StringConcat* PhaseStringOpts::build_candidate(CallStaticJavaNode* call) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
401 ciMethod* m = call->method();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
402 ciSymbol* string_sig;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
403 ciSymbol* int_sig;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
404 ciSymbol* char_sig;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
405 if (m->holder() == C->env()->StringBuilder_klass()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
406 string_sig = ciSymbol::String_StringBuilder_signature();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
407 int_sig = ciSymbol::int_StringBuilder_signature();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
408 char_sig = ciSymbol::char_StringBuilder_signature();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
409 } else if (m->holder() == C->env()->StringBuffer_klass()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
410 string_sig = ciSymbol::String_StringBuffer_signature();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
411 int_sig = ciSymbol::int_StringBuffer_signature();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
412 char_sig = ciSymbol::char_StringBuffer_signature();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
413 } else {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
414 return NULL;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
415 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
416 #ifndef PRODUCT
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
417 if (PrintOptimizeStringConcat) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
418 tty->print("considering toString call in ");
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
419 call->jvms()->dump_spec(tty); tty->cr();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
420 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
421 #endif
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
422
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
423 StringConcat* sc = new StringConcat(this, call);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
424
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
425 AllocateNode* alloc = NULL;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
426 InitializeNode* init = NULL;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
427
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
428 // possible opportunity for StringBuilder fusion
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
429 CallStaticJavaNode* cnode = call;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
430 while (cnode) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
431 Node* recv = cnode->in(TypeFunc::Parms)->uncast();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
432 if (recv->is_Proj()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
433 recv = recv->in(0);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
434 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
435 cnode = recv->isa_CallStaticJava();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
436 if (cnode == NULL) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
437 alloc = recv->isa_Allocate();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
438 if (alloc == NULL) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
439 break;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
440 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
441 // Find the constructor call
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
442 Node* result = alloc->result_cast();
7473
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
443 if (result == NULL || !result->is_CheckCastPP() || alloc->in(TypeFunc::Memory)->is_top()) {
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
444 // strange looking allocation
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
445 #ifndef PRODUCT
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
446 if (PrintOptimizeStringConcat) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
447 tty->print("giving up because allocation looks strange ");
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
448 alloc->jvms()->dump_spec(tty); tty->cr();
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 #endif
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
451 break;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
452 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
453 Node* constructor = NULL;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
454 for (SimpleDUIterator i(result); i.has_next(); i.next()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
455 CallStaticJavaNode *use = i.get()->isa_CallStaticJava();
1817
c40600e85311 6986028: assert(_base == Int) failed: Not an Int in CmpINode::sub
never
parents: 1748
diff changeset
456 if (use != NULL &&
c40600e85311 6986028: assert(_base == Int) failed: Not an Int in CmpINode::sub
never
parents: 1748
diff changeset
457 use->method() != NULL &&
c40600e85311 6986028: assert(_base == Int) failed: Not an Int in CmpINode::sub
never
parents: 1748
diff changeset
458 !use->method()->is_static() &&
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
459 use->method()->name() == ciSymbol::object_initializer_name() &&
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
460 use->method()->holder() == m->holder()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
461 // Matched the constructor.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
462 ciSymbol* sig = use->method()->signature()->as_symbol();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
463 if (sig == ciSymbol::void_method_signature() ||
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
464 sig == ciSymbol::int_void_signature() ||
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
465 sig == ciSymbol::string_void_signature()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
466 if (sig == ciSymbol::string_void_signature()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
467 // StringBuilder(String) so pick this up as the first argument
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
468 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
469 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
470 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
471 // 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
472 #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
473 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
474 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
475 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
476 }
2ddb2fab82cb 7009359: HS with -XX:+AggressiveOpts optimize new StringBuffer(null) so it does not throw NPE as expected
kvn
parents: 1972
diff changeset
477 #endif
2ddb2fab82cb 7009359: HS with -XX:+AggressiveOpts optimize new StringBuffer(null) so it does not throw NPE as expected
kvn
parents: 1972
diff changeset
478 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
479 }
2ddb2fab82cb 7009359: HS with -XX:+AggressiveOpts optimize new StringBuffer(null) so it does not throw NPE as expected
kvn
parents: 1972
diff changeset
480 // 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
481 sc->push_string_null_check(use->in(TypeFunc::Parms + 1));
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
482 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
483 // The int variant takes an initial size for the backing
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
484 // array so just treat it like the void version.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
485 constructor = use;
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 #ifndef PRODUCT
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
488 if (PrintOptimizeStringConcat) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
489 tty->print("unexpected constructor signature: %s", sig->as_utf8());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
490 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
491 #endif
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
492 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
493 break;
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 if (constructor == NULL) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
497 // couldn't find constructor
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
498 #ifndef PRODUCT
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
499 if (PrintOptimizeStringConcat) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
500 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
501 alloc->jvms()->dump_spec(tty); tty->cr();
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
502 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
503 #endif
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
504 break;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
505 }
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 // Walked all the way back and found the constructor call so see
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
508 // if this call converted into a direct string concatenation.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
509 sc->add_control(call);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
510 sc->add_control(constructor);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
511 sc->add_control(alloc);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
512 sc->set_allocation(alloc);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
513 if (sc->validate_control_flow()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
514 return sc;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
515 } else {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
516 return NULL;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
517 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
518 } else if (cnode->method() == NULL) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
519 break;
1817
c40600e85311 6986028: assert(_base == Int) failed: Not an Int in CmpINode::sub
never
parents: 1748
diff changeset
520 } else if (!cnode->method()->is_static() &&
c40600e85311 6986028: assert(_base == Int) failed: Not an Int in CmpINode::sub
never
parents: 1748
diff changeset
521 cnode->method()->holder() == m->holder() &&
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
522 cnode->method()->name() == ciSymbol::append_name() &&
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
523 (cnode->method()->signature()->as_symbol() == string_sig ||
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
524 cnode->method()->signature()->as_symbol() == char_sig ||
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
525 cnode->method()->signature()->as_symbol() == int_sig)) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
526 sc->add_control(cnode);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
527 Node* arg = cnode->in(TypeFunc::Parms + 1);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
528 if (cnode->method()->signature()->as_symbol() == int_sig) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
529 sc->push_int(arg);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
530 } else if (cnode->method()->signature()->as_symbol() == char_sig) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
531 sc->push_char(arg);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
532 } else {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
533 if (arg->is_Proj() && arg->in(0)->is_CallStaticJava()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
534 CallStaticJavaNode* csj = arg->in(0)->as_CallStaticJava();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
535 if (csj->method() != NULL &&
6223
ed21db7b3fda 7123926: Some CTW test crash: !_control.contains(ctrl)
kvn
parents: 6186
diff changeset
536 csj->method()->intrinsic_id() == vmIntrinsics::_Integer_toString &&
ed21db7b3fda 7123926: Some CTW test crash: !_control.contains(ctrl)
kvn
parents: 6186
diff changeset
537 arg->outcnt() == 1) {
ed21db7b3fda 7123926: Some CTW test crash: !_control.contains(ctrl)
kvn
parents: 6186
diff changeset
538 // _control is the list of StringBuilder calls nodes which
ed21db7b3fda 7123926: Some CTW test crash: !_control.contains(ctrl)
kvn
parents: 6186
diff changeset
539 // will be replaced by new String code after this optimization.
ed21db7b3fda 7123926: Some CTW test crash: !_control.contains(ctrl)
kvn
parents: 6186
diff changeset
540 // Integer::toString() call is not part of StringBuilder calls
ed21db7b3fda 7123926: Some CTW test crash: !_control.contains(ctrl)
kvn
parents: 6186
diff changeset
541 // chain. It could be eliminated only if its result is used
ed21db7b3fda 7123926: Some CTW test crash: !_control.contains(ctrl)
kvn
parents: 6186
diff changeset
542 // only by this SB calls chain.
ed21db7b3fda 7123926: Some CTW test crash: !_control.contains(ctrl)
kvn
parents: 6186
diff changeset
543 // Another limitation: it should be used only once because
ed21db7b3fda 7123926: Some CTW test crash: !_control.contains(ctrl)
kvn
parents: 6186
diff changeset
544 // it is unknown that it is used only by this SB calls chain
ed21db7b3fda 7123926: Some CTW test crash: !_control.contains(ctrl)
kvn
parents: 6186
diff changeset
545 // until all related SB calls nodes are collected.
ed21db7b3fda 7123926: Some CTW test crash: !_control.contains(ctrl)
kvn
parents: 6186
diff changeset
546 assert(arg->unique_out() == cnode, "sanity");
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
547 sc->add_control(csj);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
548 sc->push_int(csj->in(TypeFunc::Parms));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
549 continue;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
550 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
551 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
552 sc->push_string(arg);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
553 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
554 continue;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
555 } else {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
556 // some unhandled signature
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
557 #ifndef PRODUCT
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
558 if (PrintOptimizeStringConcat) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
559 tty->print("giving up because encountered unexpected signature ");
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
560 cnode->tf()->dump(); tty->cr();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
561 cnode->in(TypeFunc::Parms + 1)->dump();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
562 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
563 #endif
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
564 break;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
565 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
566 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
567 return NULL;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
568 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
569
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
570
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
571 PhaseStringOpts::PhaseStringOpts(PhaseGVN* gvn, Unique_Node_List*):
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
572 Phase(StringOpts),
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
573 _gvn(gvn),
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
574 _visited(Thread::current()->resource_area()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
575
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
576 assert(OptimizeStringConcat, "shouldn't be here");
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
577
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
578 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
579 ciSymbol::make("[I"), true);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
580 if (size_table_field == NULL) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
581 // Something wrong so give up.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
582 assert(false, "why can't we find Integer.sizeTable?");
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
583 return;
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
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
586 // Collect the types needed to talk about the various slices of memory
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
587 char_adr_idx = C->get_alias_index(TypeAryPtr::CHARS);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
588
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
589 // For each locally allocated StringBuffer see if the usages can be
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
590 // collapsed into a single String construction.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
591
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
592 // Run through the list of allocation looking for SB.toString to see
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
593 // 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
594 // construction.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
595 GrowableArray<StringConcat*> concats;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
596 Node_List toStrings = collect_toString_calls();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
597 while (toStrings.size() > 0) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
598 StringConcat* sc = build_candidate(toStrings.pop()->as_CallStaticJava());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
599 if (sc != NULL) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
600 concats.push(sc);
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 // try to coalesce separate concats
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
605 restart:
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
606 for (int c = 0; c < concats.length(); c++) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
607 StringConcat* sc = concats.at(c);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
608 for (int i = 0; i < sc->num_arguments(); i++) {
6186
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
609 Node* arg = sc->argument_uncast(i);
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
610 if (arg->is_Proj() && StringConcat::is_SB_toString(arg->in(0))) {
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
611 CallStaticJavaNode* csj = arg->in(0)->as_CallStaticJava();
6186
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
612 for (int o = 0; o < concats.length(); o++) {
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
613 if (c == o) continue;
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
614 StringConcat* other = concats.at(o);
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
615 if (other->end() == csj) {
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
616 #ifndef PRODUCT
6186
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
617 if (PrintOptimizeStringConcat) {
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
618 tty->print_cr("considering stacked concats");
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
619 }
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
620 #endif
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
621
6186
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
622 StringConcat* merged = sc->merge(other, arg);
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
623 if (merged->validate_control_flow()) {
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
624 #ifndef PRODUCT
6186
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
625 if (PrintOptimizeStringConcat) {
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
626 tty->print_cr("stacking would succeed");
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
627 }
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
628 #endif
6186
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
629 if (c < o) {
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
630 concats.remove_at(o);
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
631 concats.at_put(c, merged);
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
632 } else {
6186
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
633 concats.remove_at(c);
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
634 concats.at_put(o, merged);
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
635 }
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
636 goto restart;
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
637 } else {
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
638 #ifndef PRODUCT
6186
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
639 if (PrintOptimizeStringConcat) {
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
640 tty->print_cr("stacking would fail");
751bd303aa45 7179138: Incorrect result with String concatenation optimization
kvn
parents: 6057
diff changeset
641 }
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
642 #endif
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 }
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 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
647 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
648 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
649
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
650
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
651 for (int c = 0; c < concats.length(); c++) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
652 StringConcat* sc = concats.at(c);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
653 replace_string_concat(sc);
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 remove_dead_nodes();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
657 }
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 void PhaseStringOpts::record_dead_node(Node* dead) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
660 dead_worklist.push(dead);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
661 }
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 void PhaseStringOpts::remove_dead_nodes() {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
664 // Delete any dead nodes to make things clean enough that escape
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
665 // analysis doesn't get unhappy.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
666 while (dead_worklist.size() > 0) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
667 Node* use = dead_worklist.pop();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
668 int opc = use->Opcode();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
669 switch (opc) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
670 case Op_Region: {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
671 uint i = 1;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
672 for (i = 1; i < use->req(); i++) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
673 if (use->in(i) != C->top()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
674 break;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
675 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
676 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
677 if (i >= use->req()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
678 for (SimpleDUIterator i(use); i.has_next(); i.next()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
679 Node* m = i.get();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
680 if (m->is_Phi()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
681 dead_worklist.push(m);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
682 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
683 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
684 C->gvn_replace_by(use, C->top());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
685 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
686 break;
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 case Op_AddP:
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
689 case Op_CreateEx: {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
690 // Recurisvely clean up references to CreateEx so EA doesn't
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
691 // get unhappy about the partially collapsed graph.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
692 for (SimpleDUIterator i(use); i.has_next(); i.next()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
693 Node* m = i.get();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
694 if (m->is_AddP()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
695 dead_worklist.push(m);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
696 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
697 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
698 C->gvn_replace_by(use, C->top());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
699 break;
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 case Op_Phi:
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
702 if (use->in(0) == C->top()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
703 C->gvn_replace_by(use, C->top());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
704 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
705 break;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
706 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
707 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
708 }
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 bool StringConcat::validate_control_flow() {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
712 // 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
713 // safe to transform the graph as we would expect.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
714
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
715 // Check to see if this resulted in too many uncommon traps previously
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
716 if (Compile::current()->too_many_traps(_begin->jvms()->method(), _begin->jvms()->bci(),
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
717 Deoptimization::Reason_intrinsic)) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
718 return false;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
719 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
720
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
721 // Walk backwards over the control flow from toString to the
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
722 // allocation and make sure all the control flow is ok. This
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
723 // means it's either going to be eliminated once the calls are
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
724 // removed or it can safely be transformed into an uncommon
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
725 // trap.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
726
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
727 int null_check_count = 0;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
728 Unique_Node_List ctrl_path;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
729
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
730 assert(_control.contains(_begin), "missing");
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
731 assert(_control.contains(_end), "missing");
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
732
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
733 // 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
734 for (uint i = 0; i < _control.size(); i++) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
735 // Push the call and it's control projection
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
736 Node* n = _control.at(i);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
737 if (n->is_Allocate()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
738 AllocateNode* an = n->as_Allocate();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
739 InitializeNode* init = an->initialization();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
740 ctrl_path.push(init);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
741 ctrl_path.push(init->as_Multi()->proj_out(0));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
742 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
743 if (n->is_Call()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
744 CallNode* cn = n->as_Call();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
745 ctrl_path.push(cn);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
746 ctrl_path.push(cn->proj_out(0));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
747 ctrl_path.push(cn->proj_out(0)->unique_out());
7421
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
748 if (cn->proj_out(0)->unique_out()->as_Catch()->proj_out(0) != NULL) {
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
749 ctrl_path.push(cn->proj_out(0)->unique_out()->as_Catch()->proj_out(0));
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
750 }
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
751 } else {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
752 ShouldNotReachHere();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
753 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
754 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
755
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
756 // Skip backwards through the control checking for unexpected contro flow
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
757 Node* ptr = _end;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
758 bool fail = false;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
759 while (ptr != _begin) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
760 if (ptr->is_Call() && ctrl_path.member(ptr)) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
761 ptr = ptr->in(0);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
762 } else if (ptr->is_CatchProj() && ctrl_path.member(ptr)) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
763 ptr = ptr->in(0)->in(0)->in(0);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
764 assert(ctrl_path.member(ptr), "should be a known piece of control");
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
765 } else if (ptr->is_IfTrue()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
766 IfNode* iff = ptr->in(0)->as_If();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
767 BoolNode* b = iff->in(1)->isa_Bool();
7421
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
768
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
769 if (b == NULL) {
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
770 fail = true;
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
771 break;
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
772 }
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
773
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
774 Node* cmp = b->in(1);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
775 Node* v1 = cmp->in(1);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
776 Node* v2 = cmp->in(2);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
777 Node* otherproj = iff->proj_out(1 - ptr->as_Proj()->_con);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
778
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
779 // Null check of the return of append which can simply be eliminated
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
780 if (b->_test._test == BoolTest::ne &&
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
781 v2->bottom_type() == TypePtr::NULL_PTR &&
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
782 v1->is_Proj() && ctrl_path.member(v1->in(0))) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
783 // NULL check of the return value of the append
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
784 null_check_count++;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
785 if (otherproj->outcnt() == 1) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
786 CallStaticJavaNode* call = otherproj->unique_out()->isa_CallStaticJava();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
787 if (call != NULL && call->_name != NULL && strcmp(call->_name, "uncommon_trap") == 0) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
788 ctrl_path.push(call);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
789 }
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 _control.push(ptr);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
792 ptr = ptr->in(0)->in(0);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
793 continue;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
794 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
795
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
796 // A test which leads to an uncommon trap which should be safe.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
797 // Later this trap will be converted into a trap that restarts
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
798 // at the beginning.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
799 if (otherproj->outcnt() == 1) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
800 CallStaticJavaNode* call = otherproj->unique_out()->isa_CallStaticJava();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
801 if (call != NULL && call->_name != NULL && strcmp(call->_name, "uncommon_trap") == 0) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
802 // control flow leads to uct so should be ok
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
803 _uncommon_traps.push(call);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
804 ctrl_path.push(call);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
805 ptr = ptr->in(0)->in(0);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
806 continue;
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 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
809
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
810 #ifndef PRODUCT
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
811 // Some unexpected control flow we don't know how to handle.
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 tty->print_cr("failing with unknown test");
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
814 b->dump();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
815 cmp->dump();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
816 v1->dump();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
817 v2->dump();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
818 tty->cr();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
819 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
820 #endif
3396
2b27ef5c2173 7046096: SEGV IN C2 WITH 6U25
kvn
parents: 3283
diff changeset
821 fail = true;
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
822 break;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
823 } else if (ptr->is_Proj() && ptr->in(0)->is_Initialize()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
824 ptr = ptr->in(0)->in(0);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
825 } else if (ptr->is_Region()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
826 Node* copy = ptr->as_Region()->is_copy();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
827 if (copy != NULL) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
828 ptr = copy;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
829 continue;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
830 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
831 if (ptr->req() == 3 &&
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
832 ptr->in(1) != NULL && ptr->in(1)->is_Proj() &&
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
833 ptr->in(2) != NULL && ptr->in(2)->is_Proj() &&
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
834 ptr->in(1)->in(0) == ptr->in(2)->in(0) &&
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
835 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
836 // Simple diamond.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
837 // XXX should check for possibly merging stores. simple data merges are ok.
7473
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
838 // The IGVN will make this simple diamond go away when it
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
839 // transforms the Region. Make sure it sees it.
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
840 Compile::current()->record_for_igvn(ptr);
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
841 ptr = ptr->in(1)->in(0)->in(0);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
842 continue;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
843 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
844 #ifndef PRODUCT
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
845 if (PrintOptimizeStringConcat) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
846 tty->print_cr("fusion would fail for region");
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
847 _begin->dump();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
848 ptr->dump(2);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
849 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
850 #endif
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
851 fail = true;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
852 break;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
853 } else {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
854 // other unknown control
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
855 if (!fail) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
856 #ifndef PRODUCT
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
857 if (PrintOptimizeStringConcat) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
858 tty->print_cr("fusion would fail for");
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
859 _begin->dump();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
860 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
861 #endif
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
862 fail = true;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
863 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
864 #ifndef PRODUCT
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
865 if (PrintOptimizeStringConcat) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
866 ptr->dump();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
867 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
868 #endif
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
869 ptr = ptr->in(0);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
870 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
871 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
872 #ifndef PRODUCT
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
873 if (PrintOptimizeStringConcat && fail) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
874 tty->cr();
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 if (fail) return !fail;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
878
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
879 // Validate that all these results produced are contained within
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
880 // this cluster of objects. First collect all the results produced
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
881 // by calls in the region.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
882 _stringopts->_visited.Clear();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
883 Node_List worklist;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
884 Node* final_result = _end->proj_out(TypeFunc::Parms);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
885 for (uint i = 0; i < _control.size(); i++) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
886 CallNode* cnode = _control.at(i)->isa_Call();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
887 if (cnode != NULL) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
888 _stringopts->_visited.test_set(cnode->_idx);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
889 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
890 Node* result = cnode != NULL ? cnode->proj_out(TypeFunc::Parms) : NULL;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
891 if (result != NULL && result != final_result) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
892 worklist.push(result);
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 }
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 Node* last_result = NULL;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
897 while (worklist.size() > 0) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
898 Node* result = worklist.pop();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
899 if (_stringopts->_visited.test_set(result->_idx))
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
900 continue;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
901 for (SimpleDUIterator i(result); i.has_next(); i.next()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
902 Node *use = i.get();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
903 if (ctrl_path.member(use)) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
904 // already checked this
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
905 continue;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
906 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
907 int opc = use->Opcode();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
908 if (opc == Op_CmpP || opc == Op_Node) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
909 ctrl_path.push(use);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
910 continue;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
911 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
912 if (opc == Op_CastPP || opc == Op_CheckCastPP) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
913 for (SimpleDUIterator j(use); j.has_next(); j.next()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
914 worklist.push(j.get());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
915 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
916 worklist.push(use->in(1));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
917 ctrl_path.push(use);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
918 continue;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
919 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
920 #ifndef PRODUCT
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
921 if (PrintOptimizeStringConcat) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
922 if (result != last_result) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
923 last_result = result;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
924 tty->print_cr("extra uses for result:");
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
925 last_result->dump();
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 use->dump();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
928 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
929 #endif
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
930 fail = true;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
931 break;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
932 }
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
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
935 #ifndef PRODUCT
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
936 if (PrintOptimizeStringConcat && !fail) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
937 ttyLocker ttyl;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
938 tty->cr();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
939 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
940 _begin->jvms()->dump_spec(tty); tty->cr();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
941 for (int i = 0; i < num_arguments(); i++) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
942 argument(i)->dump();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
943 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
944 _control.dump();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
945 tty->cr();
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 #endif
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
948
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
949 return !fail;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
950 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
951
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
952 Node* PhaseStringOpts::fetch_static_field(GraphKit& kit, ciField* field) {
6043
df3d4a91f7f6 7161796: PhaseStringOpts::fetch_static_field tries to fetch field from the Klass instead of the mirror
never
parents: 3396
diff changeset
953 const TypeInstPtr* mirror_type = TypeInstPtr::make(field->holder()->java_mirror());
df3d4a91f7f6 7161796: PhaseStringOpts::fetch_static_field tries to fetch field from the Klass instead of the mirror
never
parents: 3396
diff changeset
954 Node* klass_node = __ makecon(mirror_type);
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
955 BasicType bt = field->layout_type();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
956 ciType* field_klass = field->type();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
957
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
958 const Type *type;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
959 if( bt == T_OBJECT ) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
960 if (!field->type()->is_loaded()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
961 type = TypeInstPtr::BOTTOM;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
962 } else if (field->is_constant()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
963 // This can happen if the constant oop is non-perm.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
964 ciObject* con = field->constant_value().as_object();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
965 // Do not "join" in the previous type; it doesn't add value,
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
966 // 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
967 type = TypeOopPtr::make_from_constant(con, true)->isa_oopptr();
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
968 assert(type != NULL, "field singleton type must be consistent");
6043
df3d4a91f7f6 7161796: PhaseStringOpts::fetch_static_field tries to fetch field from the Klass instead of the mirror
never
parents: 3396
diff changeset
969 return __ makecon(type);
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
970 } else {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
971 type = TypeOopPtr::make_from_klass(field_klass->as_klass());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
972 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
973 } else {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
974 type = Type::get_const_basic_type(bt);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
975 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
976
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
977 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
978 type, T_OBJECT,
6043
df3d4a91f7f6 7161796: PhaseStringOpts::fetch_static_field tries to fetch field from the Klass instead of the mirror
never
parents: 3396
diff changeset
979 C->get_alias_index(mirror_type->add_offset(field->offset_in_bytes())));
1080
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
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
982 Node* PhaseStringOpts::int_stringSize(GraphKit& kit, Node* arg) {
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6223
diff changeset
983 RegionNode *final_merge = new (C) RegionNode(3);
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
984 kit.gvn().set_type(final_merge, Type::CONTROL);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6223
diff changeset
985 Node* final_size = new (C) PhiNode(final_merge, TypeInt::INT);
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
986 kit.gvn().set_type(final_size, TypeInt::INT);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
987
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
988 IfNode* iff = kit.create_and_map_if(kit.control(),
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
989 __ Bool(__ CmpI(arg, __ intcon(0x80000000)), BoolTest::ne),
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
990 PROB_FAIR, COUNT_UNKNOWN);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
991 Node* is_min = __ IfFalse(iff);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
992 final_merge->init_req(1, is_min);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
993 final_size->init_req(1, __ intcon(11));
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 kit.set_control(__ IfTrue(iff));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
996 if (kit.stopped()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
997 final_merge->init_req(2, C->top());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
998 final_size->init_req(2, C->top());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
999 } else {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1000
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1001 // int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6223
diff changeset
1002 RegionNode *r = new (C) RegionNode(3);
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1003 kit.gvn().set_type(r, Type::CONTROL);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6223
diff changeset
1004 Node *phi = new (C) PhiNode(r, TypeInt::INT);
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1005 kit.gvn().set_type(phi, TypeInt::INT);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6223
diff changeset
1006 Node *size = new (C) PhiNode(r, TypeInt::INT);
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1007 kit.gvn().set_type(size, TypeInt::INT);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1008 Node* chk = __ CmpI(arg, __ intcon(0));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1009 Node* p = __ Bool(chk, BoolTest::lt);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1010 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
1011 Node* lessthan = __ IfTrue(iff);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1012 Node* greaterequal = __ IfFalse(iff);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1013 r->init_req(1, lessthan);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1014 phi->init_req(1, __ SubI(__ intcon(0), arg));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1015 size->init_req(1, __ intcon(1));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1016 r->init_req(2, greaterequal);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1017 phi->init_req(2, arg);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1018 size->init_req(2, __ intcon(0));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1019 kit.set_control(r);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1020 C->record_for_igvn(r);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1021 C->record_for_igvn(phi);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1022 C->record_for_igvn(size);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1023
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1024 // for (int i=0; ; i++)
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1025 // if (x <= sizeTable[i])
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1026 // return i+1;
2383
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2090
diff changeset
1027
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2090
diff changeset
1028 // Add loop predicate first.
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2090
diff changeset
1029 kit.add_predicate();
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2090
diff changeset
1030
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6223
diff changeset
1031 RegionNode *loop = new (C) RegionNode(3);
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1032 loop->init_req(1, kit.control());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1033 kit.gvn().set_type(loop, Type::CONTROL);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1034
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6223
diff changeset
1035 Node *index = new (C) PhiNode(loop, TypeInt::INT);
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1036 index->init_req(1, __ intcon(0));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1037 kit.gvn().set_type(index, TypeInt::INT);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1038 kit.set_control(loop);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1039 Node* sizeTable = fetch_static_field(kit, size_table_field);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1040
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1041 Node* value = kit.load_array_element(NULL, sizeTable, index, TypeAryPtr::INTS);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1042 C->record_for_igvn(value);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1043 Node* limit = __ CmpI(phi, value);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1044 Node* limitb = __ Bool(limit, BoolTest::le);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1045 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
1046 Node* lessEqual = __ IfTrue(iff2);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1047 Node* greater = __ IfFalse(iff2);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1048
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1049 loop->init_req(2, greater);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1050 index->init_req(2, __ AddI(index, __ intcon(1)));
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 kit.set_control(lessEqual);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1053 C->record_for_igvn(loop);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1054 C->record_for_igvn(index);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1055
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1056 final_merge->init_req(2, kit.control());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1057 final_size->init_req(2, __ AddI(__ AddI(index, size), __ intcon(1)));
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 kit.set_control(final_merge);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1061 C->record_for_igvn(final_merge);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1062 C->record_for_igvn(final_size);
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 return final_size;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1065 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1066
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1067 void PhaseStringOpts::int_getChars(GraphKit& kit, Node* arg, Node* char_array, Node* start, Node* end) {
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6223
diff changeset
1068 RegionNode *final_merge = new (C) RegionNode(4);
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1069 kit.gvn().set_type(final_merge, Type::CONTROL);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1070 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
1071 kit.gvn().set_type(final_mem, Type::MEMORY);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1072
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1073 // 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
1074 {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1075 // i == MIN_VALUE
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1076 IfNode* iff = kit.create_and_map_if(kit.control(),
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1077 __ Bool(__ CmpI(arg, __ intcon(0x80000000)), BoolTest::ne),
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1078 PROB_FAIR, COUNT_UNKNOWN);
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 Node* old_mem = kit.memory(char_adr_idx);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1081
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1082 kit.set_control(__ IfFalse(iff));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1083 if (kit.stopped()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1084 // Statically not equal to MIN_VALUE so this path is dead
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1085 final_merge->init_req(3, kit.control());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1086 } else {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1087 copy_string(kit, __ makecon(TypeInstPtr::make(C->env()->the_min_jint_string())),
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1088 char_array, start);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1089 final_merge->init_req(3, kit.control());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1090 final_mem->init_req(3, kit.memory(char_adr_idx));
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 kit.set_control(__ IfTrue(iff));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1094 kit.set_memory(old_mem, char_adr_idx);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1095 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1096
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1097
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1098 // Simplified version of Integer.getChars
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1099
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1100 // int q, r;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1101 // int charPos = index;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1102 Node* charPos = end;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1103
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1104 // char sign = 0;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1105
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1106 Node* i = arg;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1107 Node* sign = __ intcon(0);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1108
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1109 // if (i < 0) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1110 // sign = '-';
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1111 // i = -i;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1112 // }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1113 {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1114 IfNode* iff = kit.create_and_map_if(kit.control(),
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1115 __ Bool(__ CmpI(arg, __ intcon(0)), BoolTest::lt),
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1116 PROB_FAIR, COUNT_UNKNOWN);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1117
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6223
diff changeset
1118 RegionNode *merge = new (C) RegionNode(3);
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1119 kit.gvn().set_type(merge, Type::CONTROL);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6223
diff changeset
1120 i = new (C) PhiNode(merge, TypeInt::INT);
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1121 kit.gvn().set_type(i, TypeInt::INT);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6223
diff changeset
1122 sign = new (C) PhiNode(merge, TypeInt::INT);
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1123 kit.gvn().set_type(sign, TypeInt::INT);
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 merge->init_req(1, __ IfTrue(iff));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1126 i->init_req(1, __ SubI(__ intcon(0), arg));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1127 sign->init_req(1, __ intcon('-'));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1128 merge->init_req(2, __ IfFalse(iff));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1129 i->init_req(2, arg);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1130 sign->init_req(2, __ intcon(0));
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(merge);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1133
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1134 C->record_for_igvn(merge);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1135 C->record_for_igvn(i);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1136 C->record_for_igvn(sign);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1137 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1138
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1139 // for (;;) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1140 // q = i / 10;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1141 // r = i - ((q << 3) + (q << 1)); // r = i-(q*10) ...
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1142 // buf [--charPos] = digits [r];
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1143 // i = q;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1144 // if (i == 0) break;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1145 // }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1146
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1147 {
2383
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2090
diff changeset
1148 // Add loop predicate first.
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2090
diff changeset
1149 kit.add_predicate();
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2090
diff changeset
1150
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6223
diff changeset
1151 RegionNode *head = new (C) RegionNode(3);
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1152 head->init_req(1, kit.control());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1153 kit.gvn().set_type(head, Type::CONTROL);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6223
diff changeset
1154 Node *i_phi = new (C) PhiNode(head, TypeInt::INT);
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1155 i_phi->init_req(1, i);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1156 kit.gvn().set_type(i_phi, TypeInt::INT);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1157 charPos = PhiNode::make(head, charPos);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1158 kit.gvn().set_type(charPos, TypeInt::INT);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1159 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
1160 kit.gvn().set_type(mem, Type::MEMORY);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1161 kit.set_control(head);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1162 kit.set_memory(mem, char_adr_idx);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1163
1250
3f5b7efb9642 6920293: OptimizeStringConcat causing core dumps
never
parents: 1080
diff changeset
1164 Node* q = __ DivI(NULL, i_phi, __ intcon(10));
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1165 Node* r = __ SubI(i_phi, __ AddI(__ LShiftI(q, __ intcon(3)),
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1166 __ LShiftI(q, __ intcon(1))));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1167 Node* m1 = __ SubI(charPos, __ intcon(1));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1168 Node* ch = __ AddI(r, __ intcon('0'));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1169
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1170 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
1171 ch, T_CHAR, char_adr_idx);
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 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
1175 PROB_FAIR, COUNT_UNKNOWN);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1176 Node* ne = __ IfTrue(iff);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1177 Node* eq = __ IfFalse(iff);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1178
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1179 head->init_req(2, ne);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1180 mem->init_req(2, st);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1181 i_phi->init_req(2, q);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1182 charPos->init_req(2, m1);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1183
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1184 charPos = m1;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1185
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1186 kit.set_control(eq);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1187 kit.set_memory(st, char_adr_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 C->record_for_igvn(head);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1190 C->record_for_igvn(mem);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1191 C->record_for_igvn(i_phi);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1192 C->record_for_igvn(charPos);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1193 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1194
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1195 {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1196 // if (sign != 0) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1197 // buf [--charPos] = sign;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1198 // }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1199 IfNode* iff = kit.create_and_map_if(kit.control(),
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1200 __ Bool(__ CmpI(sign, __ intcon(0)), BoolTest::ne),
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1201 PROB_FAIR, COUNT_UNKNOWN);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1202
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1203 final_merge->init_req(2, __ IfFalse(iff));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1204 final_mem->init_req(2, kit.memory(char_adr_idx));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1205
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1206 kit.set_control(__ IfTrue(iff));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1207 if (kit.stopped()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1208 final_merge->init_req(1, C->top());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1209 final_mem->init_req(1, C->top());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1210 } else {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1211 Node* m1 = __ SubI(charPos, __ intcon(1));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1212 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
1213 sign, T_CHAR, char_adr_idx);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1214
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1215 final_merge->init_req(1, kit.control());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1216 final_mem->init_req(1, st);
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
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1219 kit.set_control(final_merge);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1220 kit.set_memory(final_mem, char_adr_idx);
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 C->record_for_igvn(final_merge);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1223 C->record_for_igvn(final_mem);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1224 }
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
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1227
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1228 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
1229 Node* string = str;
6057
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6043
diff changeset
1230 Node* offset = kit.load_String_offset(kit.control(), string);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6043
diff changeset
1231 Node* count = kit.load_String_length(kit.control(), string);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6043
diff changeset
1232 Node* value = kit.load_String_value (kit.control(), string);
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1233
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1234 // copy the contents
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1235 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
1236 // For small constant strings just emit individual stores.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1237 // A length of 6 seems like a good space/speed tradeof.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1238 int c = count->get_int();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1239 int o = offset->get_int();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1240 const TypeOopPtr* t = kit.gvn().type(value)->isa_oopptr();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1241 ciTypeArray* value_array = t->const_oop()->as_type_array();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1242 for (int e = 0; e < c; e++) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1243 __ 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
1244 __ intcon(value_array->char_at(o + e)), T_CHAR, char_adr_idx);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1245 start = __ AddI(start, __ intcon(1));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1246 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1247 } else {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1248 Node* src_ptr = kit.array_element_address(value, offset, T_CHAR);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1249 Node* dst_ptr = kit.array_element_address(char_array, start, T_CHAR);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1250 Node* c = count;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1251 Node* extra = NULL;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1252 #ifdef _LP64
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1253 c = __ ConvI2L(c);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1254 extra = C->top();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1255 #endif
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1256 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
1257 OptoRuntime::fast_arraycopy_Type(),
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1258 CAST_FROM_FN_PTR(address, StubRoutines::jshort_disjoint_arraycopy()),
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1259 "jshort_disjoint_arraycopy", TypeAryPtr::CHARS,
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1260 src_ptr, dst_ptr, c, extra);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1261 start = __ AddI(start, count);
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 return start;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1264 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1265
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1266
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1267 void PhaseStringOpts::replace_string_concat(StringConcat* sc) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1268 // Log a little info about the transformation
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1269 sc->maybe_log_transform();
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 // pull the JVMState of the allocation into a SafePointNode to serve as
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1272 // as a shim for the insertion of the new code.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1273 JVMState* jvms = sc->begin()->jvms()->clone_shallow(C);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1274 uint size = sc->begin()->req();
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6223
diff changeset
1275 SafePointNode* map = new (C) SafePointNode(size, jvms);
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1276
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1277 // copy the control and memory state from the final call into our
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1278 // new starting state. This allows any preceeding tests to feed
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1279 // into the new section of code.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1280 for (uint i1 = 0; i1 < TypeFunc::Parms; i1++) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1281 map->init_req(i1, sc->end()->in(i1));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1282 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1283 // blow away old allocation arguments
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1284 for (uint i1 = TypeFunc::Parms; i1 < jvms->debug_start(); i1++) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1285 map->init_req(i1, C->top());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1286 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1287 // Copy the rest of the inputs for the JVMState
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1288 for (uint i1 = jvms->debug_start(); i1 < sc->begin()->req(); i1++) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1289 map->init_req(i1, sc->begin()->in(i1));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1290 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1291 // Make sure the memory state is a MergeMem for parsing.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1292 if (!map->in(TypeFunc::Memory)->is_MergeMem()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1293 map->set_req(TypeFunc::Memory, MergeMemNode::make(C, map->in(TypeFunc::Memory)));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1294 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1295
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1296 jvms->set_map(map);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1297 map->ensure_stack(jvms, jvms->method()->max_stack());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1298
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1299
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1300 // disconnect all the old StringBuilder calls from the graph
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1301 sc->eliminate_unneeded_control();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1302
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1303 // At this point all the old work has been completely removed from
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1304 // the graph and the saved JVMState exists at the point where the
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1305 // final toString call used to be.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1306 GraphKit kit(jvms);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1307
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1308 // There may be uncommon traps which are still using the
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1309 // intermediate states and these need to be rewritten to point at
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1310 // the JVMState at the beginning of the transformation.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1311 sc->convert_uncommon_traps(kit, jvms);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1312
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1313 // Now insert the logic to compute the size of the string followed
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1314 // by all the logic to construct array and resulting string.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1315
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1316 Node* null_string = __ makecon(TypeInstPtr::make(C->env()->the_null_string()));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1317
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1318 // Create a region for the overflow checks to merge into.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1319 int args = MAX2(sc->num_arguments(), 1);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6223
diff changeset
1320 RegionNode* overflow = new (C) RegionNode(args);
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1321 kit.gvn().set_type(overflow, Type::CONTROL);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1322
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1323 // Create a hook node to hold onto the individual sizes since they
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1324 // are need for the copying phase.
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6223
diff changeset
1325 Node* string_sizes = new (C) Node(args);
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1326
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1327 Node* length = __ intcon(0);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1328 for (int argi = 0; argi < sc->num_arguments(); argi++) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1329 Node* arg = sc->argument(argi);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1330 switch (sc->mode(argi)) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1331 case StringConcat::IntMode: {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1332 Node* string_size = int_stringSize(kit, arg);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1333
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1334 // accumulate total
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1335 length = __ AddI(length, string_size);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1336
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1337 // Cache this value for the use by int_toString
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1338 string_sizes->init_req(argi, string_size);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1339 break;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1340 }
2090
2ddb2fab82cb 7009359: HS with -XX:+AggressiveOpts optimize new StringBuffer(null) so it does not throw NPE as expected
kvn
parents: 1972
diff changeset
1341 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
1342 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
1343 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
1344 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
1345 // 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
1346 // 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
1347 // 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
1348 // 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
1349 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
1350 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
1351 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
1352 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
1353 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
1354 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
1355 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
1356 }
2ddb2fab82cb 7009359: HS with -XX:+AggressiveOpts optimize new StringBuffer(null) so it does not throw NPE as expected
kvn
parents: 1972
diff changeset
1357 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
1358 // 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
1359 }
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1360 case StringConcat::StringMode: {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1361 const Type* type = kit.gvn().type(arg);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1362 if (type == TypePtr::NULL_PTR) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1363 // replace the argument with the null checked version
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1364 arg = null_string;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1365 sc->set_argument(argi, arg);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1366 } else if (!type->higher_equal(TypeInstPtr::NOTNULL)) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1367 // s = s != null ? s : "null";
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1368 // length = length + (s.count - s.offset);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6223
diff changeset
1369 RegionNode *r = new (C) RegionNode(3);
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1370 kit.gvn().set_type(r, Type::CONTROL);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6223
diff changeset
1371 Node *phi = new (C) PhiNode(r, type);
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1372 kit.gvn().set_type(phi, phi->bottom_type());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1373 Node* p = __ Bool(__ CmpP(arg, kit.null()), BoolTest::ne);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1374 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
1375 Node* notnull = __ IfTrue(iff);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1376 Node* isnull = __ IfFalse(iff);
1250
3f5b7efb9642 6920293: OptimizeStringConcat causing core dumps
never
parents: 1080
diff changeset
1377 kit.set_control(notnull); // set control for the cast_not_null
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1378 r->init_req(1, notnull);
1250
3f5b7efb9642 6920293: OptimizeStringConcat causing core dumps
never
parents: 1080
diff changeset
1379 phi->init_req(1, kit.cast_not_null(arg, false));
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1380 r->init_req(2, isnull);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1381 phi->init_req(2, null_string);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1382 kit.set_control(r);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1383 C->record_for_igvn(r);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1384 C->record_for_igvn(phi);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1385 // replace the argument with the null checked version
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1386 arg = phi;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1387 sc->set_argument(argi, arg);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1388 }
6057
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6043
diff changeset
1389
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6043
diff changeset
1390 Node* count = kit.load_String_length(kit.control(), arg);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 6043
diff changeset
1391
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1392 length = __ AddI(length, count);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1393 string_sizes->init_req(argi, NULL);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1394 break;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1395 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1396 case StringConcat::CharMode: {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1397 // one character only
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1398 length = __ AddI(length, __ intcon(1));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1399 break;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1400 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1401 default:
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1402 ShouldNotReachHere();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1403 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1404 if (argi > 0) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1405 // Check that the sum hasn't overflowed
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1406 IfNode* iff = kit.create_and_map_if(kit.control(),
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1407 __ Bool(__ CmpI(length, __ intcon(0)), BoolTest::lt),
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1408 PROB_MIN, COUNT_UNKNOWN);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1409 kit.set_control(__ IfFalse(iff));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1410 overflow->set_req(argi, __ IfTrue(iff));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1411 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1412 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1413
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 // Hook
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1416 PreserveJVMState pjvms(&kit);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1417 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
1418 C->record_for_igvn(overflow);
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1419 kit.uncommon_trap(Deoptimization::Reason_intrinsic,
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1420 Deoptimization::Action_make_not_entrant);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1421 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1422
7421
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1423 Node* result;
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1424 if (!kit.stopped()) {
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1425
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1426 // length now contains the number of characters needed for the
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1427 // char[] so create a new AllocateArray for the char[]
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1428 Node* char_array = NULL;
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1429 {
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1430 PreserveReexecuteState preexecs(&kit);
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1431 // The original jvms is for an allocation of either a String or
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1432 // StringBuffer so no stack adjustment is necessary for proper
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1433 // reexecution. If we deoptimize in the slow path the bytecode
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1434 // will be reexecuted and the char[] allocation will be thrown away.
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1435 kit.jvms()->set_should_reexecute(true);
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1436 char_array = kit.new_array(__ makecon(TypeKlassPtr::make(ciTypeArrayKlass::make(T_CHAR))),
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1437 length, 1);
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1438 }
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1439
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1440 // Mark the allocation so that zeroing is skipped since the code
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1441 // below will overwrite the entire array
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1442 AllocateArrayNode* char_alloc = AllocateArrayNode::Ideal_array_allocation(char_array, _gvn);
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1443 char_alloc->maybe_set_complete(_gvn);
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1444
7421
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1445 // Now copy the string representations into the final char[]
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1446 Node* start = __ intcon(0);
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1447 for (int argi = 0; argi < sc->num_arguments(); argi++) {
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1448 Node* arg = sc->argument(argi);
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1449 switch (sc->mode(argi)) {
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1450 case StringConcat::IntMode: {
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1451 Node* end = __ AddI(start, string_sizes->in(argi));
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1452 // getChars words backwards so pass the ending point as well as the start
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1453 int_getChars(kit, arg, char_array, start, end);
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1454 start = end;
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1455 break;
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1456 }
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1457 case StringConcat::StringNullCheckMode:
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1458 case StringConcat::StringMode: {
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1459 start = copy_string(kit, arg, char_array, start);
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1460 break;
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1461 }
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1462 case StringConcat::CharMode: {
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1463 __ store_to_memory(kit.control(), kit.array_element_address(char_array, start, T_CHAR),
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1464 arg, T_CHAR, char_adr_idx);
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1465 start = __ AddI(start, __ intcon(1));
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1466 break;
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1467 }
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1468 default:
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1469 ShouldNotReachHere();
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1470 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1471 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1472
7421
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1473 // If we're not reusing an existing String allocation then allocate one here.
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1474 result = sc->string_alloc();
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1475 if (result == NULL) {
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1476 PreserveReexecuteState preexecs(&kit);
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1477 // The original jvms is for an allocation of either a String or
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1478 // StringBuffer so no stack adjustment is necessary for proper
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1479 // reexecution.
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1480 kit.jvms()->set_should_reexecute(true);
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1481 result = kit.new_instance(__ makecon(TypeKlassPtr::make(C->env()->String_klass())));
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1482 }
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1483
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1484 // Intialize the string
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1485 if (java_lang_String::has_offset_field()) {
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1486 kit.store_String_offset(kit.control(), result, __ intcon(0));
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1487 kit.store_String_length(kit.control(), result, length);
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1488 }
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1489 kit.store_String_value(kit.control(), result, char_array);
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1490 } else {
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1491 result = C->top();
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1492 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1493 // hook up the outgoing control and result
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1494 kit.replace_call(sc->end(), result);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1495
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1496 // Unhook any hook nodes
7196
2aff40cb4703 7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents: 6804
diff changeset
1497 string_sizes->disconnect_inputs(NULL, C);
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1498 sc->cleanup();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents:
diff changeset
1499 }