annotate src/share/vm/opto/graphKit.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 30f42e691e70
children 6f3fd5150b67
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
6057
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
2 * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1397
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1397
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: 1397
diff changeset
21 * questions.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1965
diff changeset
25 #include "precompiled.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1965
diff changeset
26 #include "compiler/compileLog.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1965
diff changeset
27 #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1965
diff changeset
28 #include "gc_implementation/g1/heapRegion.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1965
diff changeset
29 #include "gc_interface/collectedHeap.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1965
diff changeset
30 #include "memory/barrierSet.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1965
diff changeset
31 #include "memory/cardTableModRefBS.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1965
diff changeset
32 #include "opto/addnode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1965
diff changeset
33 #include "opto/graphKit.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1965
diff changeset
34 #include "opto/idealKit.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1965
diff changeset
35 #include "opto/locknode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1965
diff changeset
36 #include "opto/machnode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1965
diff changeset
37 #include "opto/parse.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1965
diff changeset
38 #include "opto/rootnode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1965
diff changeset
39 #include "opto/runtime.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1965
diff changeset
40 #include "runtime/deoptimization.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1965
diff changeset
41 #include "runtime/sharedRuntime.hpp"
0
a61af66fc99e Initial load
duke
parents:
diff changeset
42
a61af66fc99e Initial load
duke
parents:
diff changeset
43 //----------------------------GraphKit-----------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
44 // Main utility constructor.
a61af66fc99e Initial load
duke
parents:
diff changeset
45 GraphKit::GraphKit(JVMState* jvms)
a61af66fc99e Initial load
duke
parents:
diff changeset
46 : Phase(Phase::Parser),
a61af66fc99e Initial load
duke
parents:
diff changeset
47 _env(C->env()),
a61af66fc99e Initial load
duke
parents:
diff changeset
48 _gvn(*C->initial_gvn())
a61af66fc99e Initial load
duke
parents:
diff changeset
49 {
a61af66fc99e Initial load
duke
parents:
diff changeset
50 _exceptions = jvms->map()->next_exception();
a61af66fc99e Initial load
duke
parents:
diff changeset
51 if (_exceptions != NULL) jvms->map()->set_next_exception(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
52 set_jvms(jvms);
a61af66fc99e Initial load
duke
parents:
diff changeset
53 }
a61af66fc99e Initial load
duke
parents:
diff changeset
54
a61af66fc99e Initial load
duke
parents:
diff changeset
55 // Private constructor for parser.
a61af66fc99e Initial load
duke
parents:
diff changeset
56 GraphKit::GraphKit()
a61af66fc99e Initial load
duke
parents:
diff changeset
57 : Phase(Phase::Parser),
a61af66fc99e Initial load
duke
parents:
diff changeset
58 _env(C->env()),
a61af66fc99e Initial load
duke
parents:
diff changeset
59 _gvn(*C->initial_gvn())
a61af66fc99e Initial load
duke
parents:
diff changeset
60 {
a61af66fc99e Initial load
duke
parents:
diff changeset
61 _exceptions = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
62 set_map(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
63 debug_only(_sp = -99);
a61af66fc99e Initial load
duke
parents:
diff changeset
64 debug_only(set_bci(-99));
a61af66fc99e Initial load
duke
parents:
diff changeset
65 }
a61af66fc99e Initial load
duke
parents:
diff changeset
66
a61af66fc99e Initial load
duke
parents:
diff changeset
67
a61af66fc99e Initial load
duke
parents:
diff changeset
68
a61af66fc99e Initial load
duke
parents:
diff changeset
69 //---------------------------clean_stack---------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
70 // Clear away rubbish from the stack area of the JVM state.
a61af66fc99e Initial load
duke
parents:
diff changeset
71 // This destroys any arguments that may be waiting on the stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
72 void GraphKit::clean_stack(int from_sp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
73 SafePointNode* map = this->map();
a61af66fc99e Initial load
duke
parents:
diff changeset
74 JVMState* jvms = this->jvms();
a61af66fc99e Initial load
duke
parents:
diff changeset
75 int stk_size = jvms->stk_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
76 int stkoff = jvms->stkoff();
a61af66fc99e Initial load
duke
parents:
diff changeset
77 Node* top = this->top();
a61af66fc99e Initial load
duke
parents:
diff changeset
78 for (int i = from_sp; i < stk_size; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
79 if (map->in(stkoff + i) != top) {
a61af66fc99e Initial load
duke
parents:
diff changeset
80 map->set_req(stkoff + i, top);
a61af66fc99e Initial load
duke
parents:
diff changeset
81 }
a61af66fc99e Initial load
duke
parents:
diff changeset
82 }
a61af66fc99e Initial load
duke
parents:
diff changeset
83 }
a61af66fc99e Initial load
duke
parents:
diff changeset
84
a61af66fc99e Initial load
duke
parents:
diff changeset
85
a61af66fc99e Initial load
duke
parents:
diff changeset
86 //--------------------------------sync_jvms-----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
87 // Make sure our current jvms agrees with our parse state.
a61af66fc99e Initial load
duke
parents:
diff changeset
88 JVMState* GraphKit::sync_jvms() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
89 JVMState* jvms = this->jvms();
a61af66fc99e Initial load
duke
parents:
diff changeset
90 jvms->set_bci(bci()); // Record the new bci in the JVMState
a61af66fc99e Initial load
duke
parents:
diff changeset
91 jvms->set_sp(sp()); // Record the new sp in the JVMState
a61af66fc99e Initial load
duke
parents:
diff changeset
92 assert(jvms_in_sync(), "jvms is now in sync");
a61af66fc99e Initial load
duke
parents:
diff changeset
93 return jvms;
a61af66fc99e Initial load
duke
parents:
diff changeset
94 }
a61af66fc99e Initial load
duke
parents:
diff changeset
95
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
96 //--------------------------------sync_jvms_for_reexecute---------------------
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
97 // Make sure our current jvms agrees with our parse state. This version
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
98 // uses the reexecute_sp for reexecuting bytecodes.
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
99 JVMState* GraphKit::sync_jvms_for_reexecute() {
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
100 JVMState* jvms = this->jvms();
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
101 jvms->set_bci(bci()); // Record the new bci in the JVMState
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
102 jvms->set_sp(reexecute_sp()); // Record the new sp in the JVMState
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
103 return jvms;
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
104 }
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
105
0
a61af66fc99e Initial load
duke
parents:
diff changeset
106 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
107 bool GraphKit::jvms_in_sync() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
108 Parse* parse = is_Parse();
a61af66fc99e Initial load
duke
parents:
diff changeset
109 if (parse == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
110 if (bci() != jvms()->bci()) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
111 if (sp() != (int)jvms()->sp()) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
112 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
113 }
a61af66fc99e Initial load
duke
parents:
diff changeset
114 if (jvms()->method() != parse->method()) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
115 if (jvms()->bci() != parse->bci()) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
116 int jvms_sp = jvms()->sp();
a61af66fc99e Initial load
duke
parents:
diff changeset
117 if (jvms_sp != parse->sp()) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
118 int jvms_depth = jvms()->depth();
a61af66fc99e Initial load
duke
parents:
diff changeset
119 if (jvms_depth != parse->depth()) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
120 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
121 }
a61af66fc99e Initial load
duke
parents:
diff changeset
122
a61af66fc99e Initial load
duke
parents:
diff changeset
123 // Local helper checks for special internal merge points
a61af66fc99e Initial load
duke
parents:
diff changeset
124 // used to accumulate and merge exception states.
a61af66fc99e Initial load
duke
parents:
diff changeset
125 // They are marked by the region's in(0) edge being the map itself.
a61af66fc99e Initial load
duke
parents:
diff changeset
126 // Such merge points must never "escape" into the parser at large,
a61af66fc99e Initial load
duke
parents:
diff changeset
127 // until they have been handed to gvn.transform.
a61af66fc99e Initial load
duke
parents:
diff changeset
128 static bool is_hidden_merge(Node* reg) {
a61af66fc99e Initial load
duke
parents:
diff changeset
129 if (reg == NULL) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
130 if (reg->is_Phi()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
131 reg = reg->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
132 if (reg == NULL) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
133 }
a61af66fc99e Initial load
duke
parents:
diff changeset
134 return reg->is_Region() && reg->in(0) != NULL && reg->in(0)->is_Root();
a61af66fc99e Initial load
duke
parents:
diff changeset
135 }
a61af66fc99e Initial load
duke
parents:
diff changeset
136
a61af66fc99e Initial load
duke
parents:
diff changeset
137 void GraphKit::verify_map() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
138 if (map() == NULL) return; // null map is OK
a61af66fc99e Initial load
duke
parents:
diff changeset
139 assert(map()->req() <= jvms()->endoff(), "no extra garbage on map");
a61af66fc99e Initial load
duke
parents:
diff changeset
140 assert(!map()->has_exceptions(), "call add_exception_states_from 1st");
a61af66fc99e Initial load
duke
parents:
diff changeset
141 assert(!is_hidden_merge(control()), "call use_exception_state, not set_map");
a61af66fc99e Initial load
duke
parents:
diff changeset
142 }
a61af66fc99e Initial load
duke
parents:
diff changeset
143
a61af66fc99e Initial load
duke
parents:
diff changeset
144 void GraphKit::verify_exception_state(SafePointNode* ex_map) {
a61af66fc99e Initial load
duke
parents:
diff changeset
145 assert(ex_map->next_exception() == NULL, "not already part of a chain");
a61af66fc99e Initial load
duke
parents:
diff changeset
146 assert(has_saved_ex_oop(ex_map), "every exception state has an ex_oop");
a61af66fc99e Initial load
duke
parents:
diff changeset
147 }
a61af66fc99e Initial load
duke
parents:
diff changeset
148 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
149
a61af66fc99e Initial load
duke
parents:
diff changeset
150 //---------------------------stop_and_kill_map---------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
151 // Set _map to NULL, signalling a stop to further bytecode execution.
a61af66fc99e Initial load
duke
parents:
diff changeset
152 // First smash the current map's control to a constant, to mark it dead.
a61af66fc99e Initial load
duke
parents:
diff changeset
153 void GraphKit::stop_and_kill_map() {
a61af66fc99e Initial load
duke
parents:
diff changeset
154 SafePointNode* dead_map = stop();
a61af66fc99e Initial load
duke
parents:
diff changeset
155 if (dead_map != NULL) {
7196
2aff40cb4703 7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents: 7194
diff changeset
156 dead_map->disconnect_inputs(NULL, C); // Mark the map as killed.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
157 assert(dead_map->is_killed(), "must be so marked");
a61af66fc99e Initial load
duke
parents:
diff changeset
158 }
a61af66fc99e Initial load
duke
parents:
diff changeset
159 }
a61af66fc99e Initial load
duke
parents:
diff changeset
160
a61af66fc99e Initial load
duke
parents:
diff changeset
161
a61af66fc99e Initial load
duke
parents:
diff changeset
162 //--------------------------------stopped--------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
163 // Tell if _map is NULL, or control is top.
a61af66fc99e Initial load
duke
parents:
diff changeset
164 bool GraphKit::stopped() {
a61af66fc99e Initial load
duke
parents:
diff changeset
165 if (map() == NULL) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
166 else if (control() == top()) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
167 else return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
168 }
a61af66fc99e Initial load
duke
parents:
diff changeset
169
a61af66fc99e Initial load
duke
parents:
diff changeset
170
a61af66fc99e Initial load
duke
parents:
diff changeset
171 //-----------------------------has_ex_handler----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
172 // Tell if this method or any caller method has exception handlers.
a61af66fc99e Initial load
duke
parents:
diff changeset
173 bool GraphKit::has_ex_handler() {
a61af66fc99e Initial load
duke
parents:
diff changeset
174 for (JVMState* jvmsp = jvms(); jvmsp != NULL; jvmsp = jvmsp->caller()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
175 if (jvmsp->has_method() && jvmsp->method()->has_exception_handlers()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
176 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
177 }
a61af66fc99e Initial load
duke
parents:
diff changeset
178 }
a61af66fc99e Initial load
duke
parents:
diff changeset
179 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
180 }
a61af66fc99e Initial load
duke
parents:
diff changeset
181
a61af66fc99e Initial load
duke
parents:
diff changeset
182 //------------------------------save_ex_oop------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
183 // Save an exception without blowing stack contents or other JVM state.
a61af66fc99e Initial load
duke
parents:
diff changeset
184 void GraphKit::set_saved_ex_oop(SafePointNode* ex_map, Node* ex_oop) {
a61af66fc99e Initial load
duke
parents:
diff changeset
185 assert(!has_saved_ex_oop(ex_map), "clear ex-oop before setting again");
a61af66fc99e Initial load
duke
parents:
diff changeset
186 ex_map->add_req(ex_oop);
a61af66fc99e Initial load
duke
parents:
diff changeset
187 debug_only(verify_exception_state(ex_map));
a61af66fc99e Initial load
duke
parents:
diff changeset
188 }
a61af66fc99e Initial load
duke
parents:
diff changeset
189
a61af66fc99e Initial load
duke
parents:
diff changeset
190 inline static Node* common_saved_ex_oop(SafePointNode* ex_map, bool clear_it) {
a61af66fc99e Initial load
duke
parents:
diff changeset
191 assert(GraphKit::has_saved_ex_oop(ex_map), "ex_oop must be there");
a61af66fc99e Initial load
duke
parents:
diff changeset
192 Node* ex_oop = ex_map->in(ex_map->req()-1);
a61af66fc99e Initial load
duke
parents:
diff changeset
193 if (clear_it) ex_map->del_req(ex_map->req()-1);
a61af66fc99e Initial load
duke
parents:
diff changeset
194 return ex_oop;
a61af66fc99e Initial load
duke
parents:
diff changeset
195 }
a61af66fc99e Initial load
duke
parents:
diff changeset
196
a61af66fc99e Initial load
duke
parents:
diff changeset
197 //-----------------------------saved_ex_oop------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
198 // Recover a saved exception from its map.
a61af66fc99e Initial load
duke
parents:
diff changeset
199 Node* GraphKit::saved_ex_oop(SafePointNode* ex_map) {
a61af66fc99e Initial load
duke
parents:
diff changeset
200 return common_saved_ex_oop(ex_map, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
201 }
a61af66fc99e Initial load
duke
parents:
diff changeset
202
a61af66fc99e Initial load
duke
parents:
diff changeset
203 //--------------------------clear_saved_ex_oop---------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
204 // Erase a previously saved exception from its map.
a61af66fc99e Initial load
duke
parents:
diff changeset
205 Node* GraphKit::clear_saved_ex_oop(SafePointNode* ex_map) {
a61af66fc99e Initial load
duke
parents:
diff changeset
206 return common_saved_ex_oop(ex_map, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
207 }
a61af66fc99e Initial load
duke
parents:
diff changeset
208
a61af66fc99e Initial load
duke
parents:
diff changeset
209 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
210 //---------------------------has_saved_ex_oop----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
211 // Erase a previously saved exception from its map.
a61af66fc99e Initial load
duke
parents:
diff changeset
212 bool GraphKit::has_saved_ex_oop(SafePointNode* ex_map) {
a61af66fc99e Initial load
duke
parents:
diff changeset
213 return ex_map->req() == ex_map->jvms()->endoff()+1;
a61af66fc99e Initial load
duke
parents:
diff changeset
214 }
a61af66fc99e Initial load
duke
parents:
diff changeset
215 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
216
a61af66fc99e Initial load
duke
parents:
diff changeset
217 //-------------------------make_exception_state--------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
218 // Turn the current JVM state into an exception state, appending the ex_oop.
a61af66fc99e Initial load
duke
parents:
diff changeset
219 SafePointNode* GraphKit::make_exception_state(Node* ex_oop) {
a61af66fc99e Initial load
duke
parents:
diff changeset
220 sync_jvms();
a61af66fc99e Initial load
duke
parents:
diff changeset
221 SafePointNode* ex_map = stop(); // do not manipulate this map any more
a61af66fc99e Initial load
duke
parents:
diff changeset
222 set_saved_ex_oop(ex_map, ex_oop);
a61af66fc99e Initial load
duke
parents:
diff changeset
223 return ex_map;
a61af66fc99e Initial load
duke
parents:
diff changeset
224 }
a61af66fc99e Initial load
duke
parents:
diff changeset
225
a61af66fc99e Initial load
duke
parents:
diff changeset
226
a61af66fc99e Initial load
duke
parents:
diff changeset
227 //--------------------------add_exception_state--------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
228 // Add an exception to my list of exceptions.
a61af66fc99e Initial load
duke
parents:
diff changeset
229 void GraphKit::add_exception_state(SafePointNode* ex_map) {
a61af66fc99e Initial load
duke
parents:
diff changeset
230 if (ex_map == NULL || ex_map->control() == top()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
231 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
232 }
a61af66fc99e Initial load
duke
parents:
diff changeset
233 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
234 verify_exception_state(ex_map);
a61af66fc99e Initial load
duke
parents:
diff changeset
235 if (has_exceptions()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
236 assert(ex_map->jvms()->same_calls_as(_exceptions->jvms()), "all collected exceptions must come from the same place");
a61af66fc99e Initial load
duke
parents:
diff changeset
237 }
a61af66fc99e Initial load
duke
parents:
diff changeset
238 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
239
a61af66fc99e Initial load
duke
parents:
diff changeset
240 // If there is already an exception of exactly this type, merge with it.
a61af66fc99e Initial load
duke
parents:
diff changeset
241 // In particular, null-checks and other low-level exceptions common up here.
a61af66fc99e Initial load
duke
parents:
diff changeset
242 Node* ex_oop = saved_ex_oop(ex_map);
a61af66fc99e Initial load
duke
parents:
diff changeset
243 const Type* ex_type = _gvn.type(ex_oop);
a61af66fc99e Initial load
duke
parents:
diff changeset
244 if (ex_oop == top()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
245 // No action needed.
a61af66fc99e Initial load
duke
parents:
diff changeset
246 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
247 }
a61af66fc99e Initial load
duke
parents:
diff changeset
248 assert(ex_type->isa_instptr(), "exception must be an instance");
a61af66fc99e Initial load
duke
parents:
diff changeset
249 for (SafePointNode* e2 = _exceptions; e2 != NULL; e2 = e2->next_exception()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
250 const Type* ex_type2 = _gvn.type(saved_ex_oop(e2));
a61af66fc99e Initial load
duke
parents:
diff changeset
251 // We check sp also because call bytecodes can generate exceptions
a61af66fc99e Initial load
duke
parents:
diff changeset
252 // both before and after arguments are popped!
a61af66fc99e Initial load
duke
parents:
diff changeset
253 if (ex_type2 == ex_type
a61af66fc99e Initial load
duke
parents:
diff changeset
254 && e2->_jvms->sp() == ex_map->_jvms->sp()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
255 combine_exception_states(ex_map, e2);
a61af66fc99e Initial load
duke
parents:
diff changeset
256 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
257 }
a61af66fc99e Initial load
duke
parents:
diff changeset
258 }
a61af66fc99e Initial load
duke
parents:
diff changeset
259
a61af66fc99e Initial load
duke
parents:
diff changeset
260 // No pre-existing exception of the same type. Chain it on the list.
a61af66fc99e Initial load
duke
parents:
diff changeset
261 push_exception_state(ex_map);
a61af66fc99e Initial load
duke
parents:
diff changeset
262 }
a61af66fc99e Initial load
duke
parents:
diff changeset
263
a61af66fc99e Initial load
duke
parents:
diff changeset
264 //-----------------------add_exception_states_from-----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
265 void GraphKit::add_exception_states_from(JVMState* jvms) {
a61af66fc99e Initial load
duke
parents:
diff changeset
266 SafePointNode* ex_map = jvms->map()->next_exception();
a61af66fc99e Initial load
duke
parents:
diff changeset
267 if (ex_map != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
268 jvms->map()->set_next_exception(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
269 for (SafePointNode* next_map; ex_map != NULL; ex_map = next_map) {
a61af66fc99e Initial load
duke
parents:
diff changeset
270 next_map = ex_map->next_exception();
a61af66fc99e Initial load
duke
parents:
diff changeset
271 ex_map->set_next_exception(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
272 add_exception_state(ex_map);
a61af66fc99e Initial load
duke
parents:
diff changeset
273 }
a61af66fc99e Initial load
duke
parents:
diff changeset
274 }
a61af66fc99e Initial load
duke
parents:
diff changeset
275 }
a61af66fc99e Initial load
duke
parents:
diff changeset
276
a61af66fc99e Initial load
duke
parents:
diff changeset
277 //-----------------------transfer_exceptions_into_jvms-------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
278 JVMState* GraphKit::transfer_exceptions_into_jvms() {
a61af66fc99e Initial load
duke
parents:
diff changeset
279 if (map() == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
280 // We need a JVMS to carry the exceptions, but the map has gone away.
a61af66fc99e Initial load
duke
parents:
diff changeset
281 // Create a scratch JVMS, cloned from any of the exception states...
a61af66fc99e Initial load
duke
parents:
diff changeset
282 if (has_exceptions()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
283 _map = _exceptions;
a61af66fc99e Initial load
duke
parents:
diff changeset
284 _map = clone_map();
a61af66fc99e Initial load
duke
parents:
diff changeset
285 _map->set_next_exception(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
286 clear_saved_ex_oop(_map);
a61af66fc99e Initial load
duke
parents:
diff changeset
287 debug_only(verify_map());
a61af66fc99e Initial load
duke
parents:
diff changeset
288 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
289 // ...or created from scratch
a61af66fc99e Initial load
duke
parents:
diff changeset
290 JVMState* jvms = new (C) JVMState(_method, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
291 jvms->set_bci(_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
292 jvms->set_sp(_sp);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
293 jvms->set_map(new (C) SafePointNode(TypeFunc::Parms, jvms));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
294 set_jvms(jvms);
a61af66fc99e Initial load
duke
parents:
diff changeset
295 for (uint i = 0; i < map()->req(); i++) map()->init_req(i, top());
a61af66fc99e Initial load
duke
parents:
diff changeset
296 set_all_memory(top());
a61af66fc99e Initial load
duke
parents:
diff changeset
297 while (map()->req() < jvms->endoff()) map()->add_req(top());
a61af66fc99e Initial load
duke
parents:
diff changeset
298 }
a61af66fc99e Initial load
duke
parents:
diff changeset
299 // (This is a kludge, in case you didn't notice.)
a61af66fc99e Initial load
duke
parents:
diff changeset
300 set_control(top());
a61af66fc99e Initial load
duke
parents:
diff changeset
301 }
a61af66fc99e Initial load
duke
parents:
diff changeset
302 JVMState* jvms = sync_jvms();
a61af66fc99e Initial load
duke
parents:
diff changeset
303 assert(!jvms->map()->has_exceptions(), "no exceptions on this map yet");
a61af66fc99e Initial load
duke
parents:
diff changeset
304 jvms->map()->set_next_exception(_exceptions);
a61af66fc99e Initial load
duke
parents:
diff changeset
305 _exceptions = NULL; // done with this set of exceptions
a61af66fc99e Initial load
duke
parents:
diff changeset
306 return jvms;
a61af66fc99e Initial load
duke
parents:
diff changeset
307 }
a61af66fc99e Initial load
duke
parents:
diff changeset
308
a61af66fc99e Initial load
duke
parents:
diff changeset
309 static inline void add_n_reqs(Node* dstphi, Node* srcphi) {
a61af66fc99e Initial load
duke
parents:
diff changeset
310 assert(is_hidden_merge(dstphi), "must be a special merge node");
a61af66fc99e Initial load
duke
parents:
diff changeset
311 assert(is_hidden_merge(srcphi), "must be a special merge node");
a61af66fc99e Initial load
duke
parents:
diff changeset
312 uint limit = srcphi->req();
a61af66fc99e Initial load
duke
parents:
diff changeset
313 for (uint i = PhiNode::Input; i < limit; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
314 dstphi->add_req(srcphi->in(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
315 }
a61af66fc99e Initial load
duke
parents:
diff changeset
316 }
a61af66fc99e Initial load
duke
parents:
diff changeset
317 static inline void add_one_req(Node* dstphi, Node* src) {
a61af66fc99e Initial load
duke
parents:
diff changeset
318 assert(is_hidden_merge(dstphi), "must be a special merge node");
a61af66fc99e Initial load
duke
parents:
diff changeset
319 assert(!is_hidden_merge(src), "must not be a special merge node");
a61af66fc99e Initial load
duke
parents:
diff changeset
320 dstphi->add_req(src);
a61af66fc99e Initial load
duke
parents:
diff changeset
321 }
a61af66fc99e Initial load
duke
parents:
diff changeset
322
a61af66fc99e Initial load
duke
parents:
diff changeset
323 //-----------------------combine_exception_states------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
324 // This helper function combines exception states by building phis on a
a61af66fc99e Initial load
duke
parents:
diff changeset
325 // specially marked state-merging region. These regions and phis are
a61af66fc99e Initial load
duke
parents:
diff changeset
326 // untransformed, and can build up gradually. The region is marked by
a61af66fc99e Initial load
duke
parents:
diff changeset
327 // having a control input of its exception map, rather than NULL. Such
a61af66fc99e Initial load
duke
parents:
diff changeset
328 // regions do not appear except in this function, and in use_exception_state.
a61af66fc99e Initial load
duke
parents:
diff changeset
329 void GraphKit::combine_exception_states(SafePointNode* ex_map, SafePointNode* phi_map) {
a61af66fc99e Initial load
duke
parents:
diff changeset
330 if (failing()) return; // dying anyway...
a61af66fc99e Initial load
duke
parents:
diff changeset
331 JVMState* ex_jvms = ex_map->_jvms;
a61af66fc99e Initial load
duke
parents:
diff changeset
332 assert(ex_jvms->same_calls_as(phi_map->_jvms), "consistent call chains");
a61af66fc99e Initial load
duke
parents:
diff changeset
333 assert(ex_jvms->stkoff() == phi_map->_jvms->stkoff(), "matching locals");
a61af66fc99e Initial load
duke
parents:
diff changeset
334 assert(ex_jvms->sp() == phi_map->_jvms->sp(), "matching stack sizes");
a61af66fc99e Initial load
duke
parents:
diff changeset
335 assert(ex_jvms->monoff() == phi_map->_jvms->monoff(), "matching JVMS");
a61af66fc99e Initial load
duke
parents:
diff changeset
336 assert(ex_map->req() == phi_map->req(), "matching maps");
a61af66fc99e Initial load
duke
parents:
diff changeset
337 uint tos = ex_jvms->stkoff() + ex_jvms->sp();
a61af66fc99e Initial load
duke
parents:
diff changeset
338 Node* hidden_merge_mark = root();
a61af66fc99e Initial load
duke
parents:
diff changeset
339 Node* region = phi_map->control();
a61af66fc99e Initial load
duke
parents:
diff changeset
340 MergeMemNode* phi_mem = phi_map->merged_memory();
a61af66fc99e Initial load
duke
parents:
diff changeset
341 MergeMemNode* ex_mem = ex_map->merged_memory();
a61af66fc99e Initial load
duke
parents:
diff changeset
342 if (region->in(0) != hidden_merge_mark) {
a61af66fc99e Initial load
duke
parents:
diff changeset
343 // The control input is not (yet) a specially-marked region in phi_map.
a61af66fc99e Initial load
duke
parents:
diff changeset
344 // Make it so, and build some phis.
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
345 region = new (C) RegionNode(2);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
346 _gvn.set_type(region, Type::CONTROL);
a61af66fc99e Initial load
duke
parents:
diff changeset
347 region->set_req(0, hidden_merge_mark); // marks an internal ex-state
a61af66fc99e Initial load
duke
parents:
diff changeset
348 region->init_req(1, phi_map->control());
a61af66fc99e Initial load
duke
parents:
diff changeset
349 phi_map->set_control(region);
a61af66fc99e Initial load
duke
parents:
diff changeset
350 Node* io_phi = PhiNode::make(region, phi_map->i_o(), Type::ABIO);
a61af66fc99e Initial load
duke
parents:
diff changeset
351 record_for_igvn(io_phi);
a61af66fc99e Initial load
duke
parents:
diff changeset
352 _gvn.set_type(io_phi, Type::ABIO);
a61af66fc99e Initial load
duke
parents:
diff changeset
353 phi_map->set_i_o(io_phi);
a61af66fc99e Initial load
duke
parents:
diff changeset
354 for (MergeMemStream mms(phi_mem); mms.next_non_empty(); ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
355 Node* m = mms.memory();
a61af66fc99e Initial load
duke
parents:
diff changeset
356 Node* m_phi = PhiNode::make(region, m, Type::MEMORY, mms.adr_type(C));
a61af66fc99e Initial load
duke
parents:
diff changeset
357 record_for_igvn(m_phi);
a61af66fc99e Initial load
duke
parents:
diff changeset
358 _gvn.set_type(m_phi, Type::MEMORY);
a61af66fc99e Initial load
duke
parents:
diff changeset
359 mms.set_memory(m_phi);
a61af66fc99e Initial load
duke
parents:
diff changeset
360 }
a61af66fc99e Initial load
duke
parents:
diff changeset
361 }
a61af66fc99e Initial load
duke
parents:
diff changeset
362
a61af66fc99e Initial load
duke
parents:
diff changeset
363 // Either or both of phi_map and ex_map might already be converted into phis.
a61af66fc99e Initial load
duke
parents:
diff changeset
364 Node* ex_control = ex_map->control();
a61af66fc99e Initial load
duke
parents:
diff changeset
365 // if there is special marking on ex_map also, we add multiple edges from src
a61af66fc99e Initial load
duke
parents:
diff changeset
366 bool add_multiple = (ex_control->in(0) == hidden_merge_mark);
a61af66fc99e Initial load
duke
parents:
diff changeset
367 // how wide was the destination phi_map, originally?
a61af66fc99e Initial load
duke
parents:
diff changeset
368 uint orig_width = region->req();
a61af66fc99e Initial load
duke
parents:
diff changeset
369
a61af66fc99e Initial load
duke
parents:
diff changeset
370 if (add_multiple) {
a61af66fc99e Initial load
duke
parents:
diff changeset
371 add_n_reqs(region, ex_control);
a61af66fc99e Initial load
duke
parents:
diff changeset
372 add_n_reqs(phi_map->i_o(), ex_map->i_o());
a61af66fc99e Initial load
duke
parents:
diff changeset
373 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
374 // ex_map has no merges, so we just add single edges everywhere
a61af66fc99e Initial load
duke
parents:
diff changeset
375 add_one_req(region, ex_control);
a61af66fc99e Initial load
duke
parents:
diff changeset
376 add_one_req(phi_map->i_o(), ex_map->i_o());
a61af66fc99e Initial load
duke
parents:
diff changeset
377 }
a61af66fc99e Initial load
duke
parents:
diff changeset
378 for (MergeMemStream mms(phi_mem, ex_mem); mms.next_non_empty2(); ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
379 if (mms.is_empty()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
380 // get a copy of the base memory, and patch some inputs into it
a61af66fc99e Initial load
duke
parents:
diff changeset
381 const TypePtr* adr_type = mms.adr_type(C);
a61af66fc99e Initial load
duke
parents:
diff changeset
382 Node* phi = mms.force_memory()->as_Phi()->slice_memory(adr_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
383 assert(phi->as_Phi()->region() == mms.base_memory()->in(0), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
384 mms.set_memory(phi);
a61af66fc99e Initial load
duke
parents:
diff changeset
385 // Prepare to append interesting stuff onto the newly sliced phi:
a61af66fc99e Initial load
duke
parents:
diff changeset
386 while (phi->req() > orig_width) phi->del_req(phi->req()-1);
a61af66fc99e Initial load
duke
parents:
diff changeset
387 }
a61af66fc99e Initial load
duke
parents:
diff changeset
388 // Append stuff from ex_map:
a61af66fc99e Initial load
duke
parents:
diff changeset
389 if (add_multiple) {
a61af66fc99e Initial load
duke
parents:
diff changeset
390 add_n_reqs(mms.memory(), mms.memory2());
a61af66fc99e Initial load
duke
parents:
diff changeset
391 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
392 add_one_req(mms.memory(), mms.memory2());
a61af66fc99e Initial load
duke
parents:
diff changeset
393 }
a61af66fc99e Initial load
duke
parents:
diff changeset
394 }
a61af66fc99e Initial load
duke
parents:
diff changeset
395 uint limit = ex_map->req();
a61af66fc99e Initial load
duke
parents:
diff changeset
396 for (uint i = TypeFunc::Parms; i < limit; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
397 // Skip everything in the JVMS after tos. (The ex_oop follows.)
a61af66fc99e Initial load
duke
parents:
diff changeset
398 if (i == tos) i = ex_jvms->monoff();
a61af66fc99e Initial load
duke
parents:
diff changeset
399 Node* src = ex_map->in(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
400 Node* dst = phi_map->in(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
401 if (src != dst) {
a61af66fc99e Initial load
duke
parents:
diff changeset
402 PhiNode* phi;
a61af66fc99e Initial load
duke
parents:
diff changeset
403 if (dst->in(0) != region) {
a61af66fc99e Initial load
duke
parents:
diff changeset
404 dst = phi = PhiNode::make(region, dst, _gvn.type(dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
405 record_for_igvn(phi);
a61af66fc99e Initial load
duke
parents:
diff changeset
406 _gvn.set_type(phi, phi->type());
a61af66fc99e Initial load
duke
parents:
diff changeset
407 phi_map->set_req(i, dst);
a61af66fc99e Initial load
duke
parents:
diff changeset
408 // Prepare to append interesting stuff onto the new phi:
a61af66fc99e Initial load
duke
parents:
diff changeset
409 while (dst->req() > orig_width) dst->del_req(dst->req()-1);
a61af66fc99e Initial load
duke
parents:
diff changeset
410 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
411 assert(dst->is_Phi(), "nobody else uses a hidden region");
a61af66fc99e Initial load
duke
parents:
diff changeset
412 phi = (PhiNode*)dst;
a61af66fc99e Initial load
duke
parents:
diff changeset
413 }
a61af66fc99e Initial load
duke
parents:
diff changeset
414 if (add_multiple && src->in(0) == ex_control) {
a61af66fc99e Initial load
duke
parents:
diff changeset
415 // Both are phis.
a61af66fc99e Initial load
duke
parents:
diff changeset
416 add_n_reqs(dst, src);
a61af66fc99e Initial load
duke
parents:
diff changeset
417 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
418 while (dst->req() < region->req()) add_one_req(dst, src);
a61af66fc99e Initial load
duke
parents:
diff changeset
419 }
a61af66fc99e Initial load
duke
parents:
diff changeset
420 const Type* srctype = _gvn.type(src);
a61af66fc99e Initial load
duke
parents:
diff changeset
421 if (phi->type() != srctype) {
a61af66fc99e Initial load
duke
parents:
diff changeset
422 const Type* dsttype = phi->type()->meet(srctype);
a61af66fc99e Initial load
duke
parents:
diff changeset
423 if (phi->type() != dsttype) {
a61af66fc99e Initial load
duke
parents:
diff changeset
424 phi->set_type(dsttype);
a61af66fc99e Initial load
duke
parents:
diff changeset
425 _gvn.set_type(phi, dsttype);
a61af66fc99e Initial load
duke
parents:
diff changeset
426 }
a61af66fc99e Initial load
duke
parents:
diff changeset
427 }
a61af66fc99e Initial load
duke
parents:
diff changeset
428 }
a61af66fc99e Initial load
duke
parents:
diff changeset
429 }
a61af66fc99e Initial load
duke
parents:
diff changeset
430 }
a61af66fc99e Initial load
duke
parents:
diff changeset
431
a61af66fc99e Initial load
duke
parents:
diff changeset
432 //--------------------------use_exception_state--------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
433 Node* GraphKit::use_exception_state(SafePointNode* phi_map) {
a61af66fc99e Initial load
duke
parents:
diff changeset
434 if (failing()) { stop(); return top(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
435 Node* region = phi_map->control();
a61af66fc99e Initial load
duke
parents:
diff changeset
436 Node* hidden_merge_mark = root();
a61af66fc99e Initial load
duke
parents:
diff changeset
437 assert(phi_map->jvms()->map() == phi_map, "sanity: 1-1 relation");
a61af66fc99e Initial load
duke
parents:
diff changeset
438 Node* ex_oop = clear_saved_ex_oop(phi_map);
a61af66fc99e Initial load
duke
parents:
diff changeset
439 if (region->in(0) == hidden_merge_mark) {
a61af66fc99e Initial load
duke
parents:
diff changeset
440 // Special marking for internal ex-states. Process the phis now.
a61af66fc99e Initial load
duke
parents:
diff changeset
441 region->set_req(0, region); // now it's an ordinary region
a61af66fc99e Initial load
duke
parents:
diff changeset
442 set_jvms(phi_map->jvms()); // ...so now we can use it as a map
a61af66fc99e Initial load
duke
parents:
diff changeset
443 // Note: Setting the jvms also sets the bci and sp.
a61af66fc99e Initial load
duke
parents:
diff changeset
444 set_control(_gvn.transform(region));
a61af66fc99e Initial load
duke
parents:
diff changeset
445 uint tos = jvms()->stkoff() + sp();
a61af66fc99e Initial load
duke
parents:
diff changeset
446 for (uint i = 1; i < tos; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
447 Node* x = phi_map->in(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
448 if (x->in(0) == region) {
a61af66fc99e Initial load
duke
parents:
diff changeset
449 assert(x->is_Phi(), "expected a special phi");
a61af66fc99e Initial load
duke
parents:
diff changeset
450 phi_map->set_req(i, _gvn.transform(x));
a61af66fc99e Initial load
duke
parents:
diff changeset
451 }
a61af66fc99e Initial load
duke
parents:
diff changeset
452 }
a61af66fc99e Initial load
duke
parents:
diff changeset
453 for (MergeMemStream mms(merged_memory()); mms.next_non_empty(); ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
454 Node* x = mms.memory();
a61af66fc99e Initial load
duke
parents:
diff changeset
455 if (x->in(0) == region) {
a61af66fc99e Initial load
duke
parents:
diff changeset
456 assert(x->is_Phi(), "nobody else uses a hidden region");
a61af66fc99e Initial load
duke
parents:
diff changeset
457 mms.set_memory(_gvn.transform(x));
a61af66fc99e Initial load
duke
parents:
diff changeset
458 }
a61af66fc99e Initial load
duke
parents:
diff changeset
459 }
a61af66fc99e Initial load
duke
parents:
diff changeset
460 if (ex_oop->in(0) == region) {
a61af66fc99e Initial load
duke
parents:
diff changeset
461 assert(ex_oop->is_Phi(), "expected a special phi");
a61af66fc99e Initial load
duke
parents:
diff changeset
462 ex_oop = _gvn.transform(ex_oop);
a61af66fc99e Initial load
duke
parents:
diff changeset
463 }
a61af66fc99e Initial load
duke
parents:
diff changeset
464 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
465 set_jvms(phi_map->jvms());
a61af66fc99e Initial load
duke
parents:
diff changeset
466 }
a61af66fc99e Initial load
duke
parents:
diff changeset
467
a61af66fc99e Initial load
duke
parents:
diff changeset
468 assert(!is_hidden_merge(phi_map->control()), "hidden ex. states cleared");
a61af66fc99e Initial load
duke
parents:
diff changeset
469 assert(!is_hidden_merge(phi_map->i_o()), "hidden ex. states cleared");
a61af66fc99e Initial load
duke
parents:
diff changeset
470 return ex_oop;
a61af66fc99e Initial load
duke
parents:
diff changeset
471 }
a61af66fc99e Initial load
duke
parents:
diff changeset
472
a61af66fc99e Initial load
duke
parents:
diff changeset
473 //---------------------------------java_bc-------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
474 Bytecodes::Code GraphKit::java_bc() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
475 ciMethod* method = this->method();
a61af66fc99e Initial load
duke
parents:
diff changeset
476 int bci = this->bci();
a61af66fc99e Initial load
duke
parents:
diff changeset
477 if (method != NULL && bci != InvocationEntryBci)
a61af66fc99e Initial load
duke
parents:
diff changeset
478 return method->java_code_at_bci(bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
479 else
a61af66fc99e Initial load
duke
parents:
diff changeset
480 return Bytecodes::_illegal;
a61af66fc99e Initial load
duke
parents:
diff changeset
481 }
a61af66fc99e Initial load
duke
parents:
diff changeset
482
1213
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
483 void GraphKit::uncommon_trap_if_should_post_on_exceptions(Deoptimization::DeoptReason reason,
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
484 bool must_throw) {
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
485 // if the exception capability is set, then we will generate code
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
486 // to check the JavaThread.should_post_on_exceptions flag to see
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
487 // if we actually need to report exception events (for this
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
488 // thread). If we don't need to report exception events, we will
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
489 // take the normal fast path provided by add_exception_events. If
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
490 // exception event reporting is enabled for this thread, we will
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
491 // take the uncommon_trap in the BuildCutout below.
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
492
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
493 // first must access the should_post_on_exceptions_flag in this thread's JavaThread
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
494 Node* jthread = _gvn.transform(new (C) ThreadLocalNode());
1213
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
495 Node* adr = basic_plus_adr(top(), jthread, in_bytes(JavaThread::should_post_on_exceptions_flag_offset()));
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
496 Node* should_post_flag = make_load(control(), adr, TypeInt::INT, T_INT, Compile::AliasIdxRaw, false);
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
497
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
498 // Test the should_post_on_exceptions_flag vs. 0
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
499 Node* chk = _gvn.transform( new (C) CmpINode(should_post_flag, intcon(0)) );
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
500 Node* tst = _gvn.transform( new (C) BoolNode(chk, BoolTest::eq) );
1213
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
501
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
502 // Branch to slow_path if should_post_on_exceptions_flag was true
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
503 { BuildCutout unless(this, tst, PROB_MAX);
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
504 // Do not try anything fancy if we're notifying the VM on every throw.
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
505 // Cf. case Bytecodes::_athrow in parse2.cpp.
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
506 uncommon_trap(reason, Deoptimization::Action_none,
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
507 (ciKlass*)NULL, (char*)NULL, must_throw);
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
508 }
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
509
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
510 }
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
511
0
a61af66fc99e Initial load
duke
parents:
diff changeset
512 //------------------------------builtin_throw----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
513 void GraphKit::builtin_throw(Deoptimization::DeoptReason reason, Node* arg) {
a61af66fc99e Initial load
duke
parents:
diff changeset
514 bool must_throw = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
515
1213
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
516 if (env()->jvmti_can_post_on_exceptions()) {
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
517 // check if we must post exception events, take uncommon trap if so
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
518 uncommon_trap_if_should_post_on_exceptions(reason, must_throw);
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
519 // here if should_post_on_exceptions is false
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
520 // continue on with the normal codegen
0
a61af66fc99e Initial load
duke
parents:
diff changeset
521 }
a61af66fc99e Initial load
duke
parents:
diff changeset
522
a61af66fc99e Initial load
duke
parents:
diff changeset
523 // If this particular condition has not yet happened at this
a61af66fc99e Initial load
duke
parents:
diff changeset
524 // bytecode, then use the uncommon trap mechanism, and allow for
a61af66fc99e Initial load
duke
parents:
diff changeset
525 // a future recompilation if several traps occur here.
a61af66fc99e Initial load
duke
parents:
diff changeset
526 // If the throw is hot, try to use a more complicated inline mechanism
a61af66fc99e Initial load
duke
parents:
diff changeset
527 // which keeps execution inside the compiled code.
a61af66fc99e Initial load
duke
parents:
diff changeset
528 bool treat_throw_as_hot = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
529 ciMethodData* md = method()->method_data();
a61af66fc99e Initial load
duke
parents:
diff changeset
530
a61af66fc99e Initial load
duke
parents:
diff changeset
531 if (ProfileTraps) {
a61af66fc99e Initial load
duke
parents:
diff changeset
532 if (too_many_traps(reason)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
533 treat_throw_as_hot = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
534 }
a61af66fc99e Initial load
duke
parents:
diff changeset
535 // (If there is no MDO at all, assume it is early in
a61af66fc99e Initial load
duke
parents:
diff changeset
536 // execution, and that any deopts are part of the
a61af66fc99e Initial load
duke
parents:
diff changeset
537 // startup transient, and don't need to be remembered.)
a61af66fc99e Initial load
duke
parents:
diff changeset
538
a61af66fc99e Initial load
duke
parents:
diff changeset
539 // Also, if there is a local exception handler, treat all throws
a61af66fc99e Initial load
duke
parents:
diff changeset
540 // as hot if there has been at least one in this method.
a61af66fc99e Initial load
duke
parents:
diff changeset
541 if (C->trap_count(reason) != 0
a61af66fc99e Initial load
duke
parents:
diff changeset
542 && method()->method_data()->trap_count(reason) != 0
a61af66fc99e Initial load
duke
parents:
diff changeset
543 && has_ex_handler()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
544 treat_throw_as_hot = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
545 }
a61af66fc99e Initial load
duke
parents:
diff changeset
546 }
a61af66fc99e Initial load
duke
parents:
diff changeset
547
a61af66fc99e Initial load
duke
parents:
diff changeset
548 // If this throw happens frequently, an uncommon trap might cause
a61af66fc99e Initial load
duke
parents:
diff changeset
549 // a performance pothole. If there is a local exception handler,
a61af66fc99e Initial load
duke
parents:
diff changeset
550 // and if this particular bytecode appears to be deoptimizing often,
a61af66fc99e Initial load
duke
parents:
diff changeset
551 // let us handle the throw inline, with a preconstructed instance.
a61af66fc99e Initial load
duke
parents:
diff changeset
552 // Note: If the deopt count has blown up, the uncommon trap
a61af66fc99e Initial load
duke
parents:
diff changeset
553 // runtime is going to flush this nmethod, not matter what.
a61af66fc99e Initial load
duke
parents:
diff changeset
554 if (treat_throw_as_hot
a61af66fc99e Initial load
duke
parents:
diff changeset
555 && (!StackTraceInThrowable || OmitStackTraceInFastThrow)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
556 // If the throw is local, we use a pre-existing instance and
a61af66fc99e Initial load
duke
parents:
diff changeset
557 // punt on the backtrace. This would lead to a missing backtrace
a61af66fc99e Initial load
duke
parents:
diff changeset
558 // (a repeat of 4292742) if the backtrace object is ever asked
a61af66fc99e Initial load
duke
parents:
diff changeset
559 // for its backtrace.
a61af66fc99e Initial load
duke
parents:
diff changeset
560 // Fixing this remaining case of 4292742 requires some flavor of
a61af66fc99e Initial load
duke
parents:
diff changeset
561 // escape analysis. Leave that for the future.
a61af66fc99e Initial load
duke
parents:
diff changeset
562 ciInstance* ex_obj = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
563 switch (reason) {
a61af66fc99e Initial load
duke
parents:
diff changeset
564 case Deoptimization::Reason_null_check:
a61af66fc99e Initial load
duke
parents:
diff changeset
565 ex_obj = env()->NullPointerException_instance();
a61af66fc99e Initial load
duke
parents:
diff changeset
566 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
567 case Deoptimization::Reason_div0_check:
a61af66fc99e Initial load
duke
parents:
diff changeset
568 ex_obj = env()->ArithmeticException_instance();
a61af66fc99e Initial load
duke
parents:
diff changeset
569 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
570 case Deoptimization::Reason_range_check:
a61af66fc99e Initial load
duke
parents:
diff changeset
571 ex_obj = env()->ArrayIndexOutOfBoundsException_instance();
a61af66fc99e Initial load
duke
parents:
diff changeset
572 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
573 case Deoptimization::Reason_class_check:
a61af66fc99e Initial load
duke
parents:
diff changeset
574 if (java_bc() == Bytecodes::_aastore) {
a61af66fc99e Initial load
duke
parents:
diff changeset
575 ex_obj = env()->ArrayStoreException_instance();
a61af66fc99e Initial load
duke
parents:
diff changeset
576 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
577 ex_obj = env()->ClassCastException_instance();
a61af66fc99e Initial load
duke
parents:
diff changeset
578 }
a61af66fc99e Initial load
duke
parents:
diff changeset
579 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
580 }
a61af66fc99e Initial load
duke
parents:
diff changeset
581 if (failing()) { stop(); return; } // exception allocation might fail
a61af66fc99e Initial load
duke
parents:
diff changeset
582 if (ex_obj != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
583 // Cheat with a preallocated exception object.
a61af66fc99e Initial load
duke
parents:
diff changeset
584 if (C->log() != NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
585 C->log()->elem("hot_throw preallocated='1' reason='%s'",
a61af66fc99e Initial load
duke
parents:
diff changeset
586 Deoptimization::trap_reason_name(reason));
a61af66fc99e Initial load
duke
parents:
diff changeset
587 const TypeInstPtr* ex_con = TypeInstPtr::make(ex_obj);
164
c436414a719e 6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents: 113
diff changeset
588 Node* ex_node = _gvn.transform( ConNode::make(C, ex_con) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
589
a61af66fc99e Initial load
duke
parents:
diff changeset
590 // Clear the detail message of the preallocated exception object.
a61af66fc99e Initial load
duke
parents:
diff changeset
591 // Weblogic sometimes mutates the detail message of exceptions
a61af66fc99e Initial load
duke
parents:
diff changeset
592 // using reflection.
a61af66fc99e Initial load
duke
parents:
diff changeset
593 int offset = java_lang_Throwable::get_detailMessage_offset();
a61af66fc99e Initial load
duke
parents:
diff changeset
594 const TypePtr* adr_typ = ex_con->add_offset(offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
595
a61af66fc99e Initial load
duke
parents:
diff changeset
596 Node *adr = basic_plus_adr(ex_node, ex_node, offset);
1965
f264f4c42799 7000491: assert(false) failed: should be optimized out in SharedRuntime::g1_wb_pre
kvn
parents: 1786
diff changeset
597 const TypeOopPtr* val_type = TypeOopPtr::make_from_klass(env()->String_klass());
f264f4c42799 7000491: assert(false) failed: should be optimized out in SharedRuntime::g1_wb_pre
kvn
parents: 1786
diff changeset
598 Node *store = store_oop_to_object(control(), ex_node, adr, adr_typ, null(), val_type, T_OBJECT);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
599
a61af66fc99e Initial load
duke
parents:
diff changeset
600 add_exception_state(make_exception_state(ex_node));
a61af66fc99e Initial load
duke
parents:
diff changeset
601 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
602 }
a61af66fc99e Initial load
duke
parents:
diff changeset
603 }
a61af66fc99e Initial load
duke
parents:
diff changeset
604
a61af66fc99e Initial load
duke
parents:
diff changeset
605 // %%% Maybe add entry to OptoRuntime which directly throws the exc.?
a61af66fc99e Initial load
duke
parents:
diff changeset
606 // It won't be much cheaper than bailing to the interp., since we'll
a61af66fc99e Initial load
duke
parents:
diff changeset
607 // have to pass up all the debug-info, and the runtime will have to
a61af66fc99e Initial load
duke
parents:
diff changeset
608 // create the stack trace.
a61af66fc99e Initial load
duke
parents:
diff changeset
609
a61af66fc99e Initial load
duke
parents:
diff changeset
610 // Usual case: Bail to interpreter.
a61af66fc99e Initial load
duke
parents:
diff changeset
611 // Reserve the right to recompile if we haven't seen anything yet.
a61af66fc99e Initial load
duke
parents:
diff changeset
612
a61af66fc99e Initial load
duke
parents:
diff changeset
613 Deoptimization::DeoptAction action = Deoptimization::Action_maybe_recompile;
a61af66fc99e Initial load
duke
parents:
diff changeset
614 if (treat_throw_as_hot
a61af66fc99e Initial load
duke
parents:
diff changeset
615 && (method()->method_data()->trap_recompiled_at(bci())
a61af66fc99e Initial load
duke
parents:
diff changeset
616 || C->too_many_traps(reason))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
617 // We cannot afford to take more traps here. Suffer in the interpreter.
a61af66fc99e Initial load
duke
parents:
diff changeset
618 if (C->log() != NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
619 C->log()->elem("hot_throw preallocated='0' reason='%s' mcount='%d'",
a61af66fc99e Initial load
duke
parents:
diff changeset
620 Deoptimization::trap_reason_name(reason),
a61af66fc99e Initial load
duke
parents:
diff changeset
621 C->trap_count(reason));
a61af66fc99e Initial load
duke
parents:
diff changeset
622 action = Deoptimization::Action_none;
a61af66fc99e Initial load
duke
parents:
diff changeset
623 }
a61af66fc99e Initial load
duke
parents:
diff changeset
624
a61af66fc99e Initial load
duke
parents:
diff changeset
625 // "must_throw" prunes the JVM state to include only the stack, if there
a61af66fc99e Initial load
duke
parents:
diff changeset
626 // are no local exception handlers. This should cut down on register
a61af66fc99e Initial load
duke
parents:
diff changeset
627 // allocation time and code size, by drastically reducing the number
a61af66fc99e Initial load
duke
parents:
diff changeset
628 // of in-edges on the call to the uncommon trap.
a61af66fc99e Initial load
duke
parents:
diff changeset
629
a61af66fc99e Initial load
duke
parents:
diff changeset
630 uncommon_trap(reason, action, (ciKlass*)NULL, (char*)NULL, must_throw);
a61af66fc99e Initial load
duke
parents:
diff changeset
631 }
a61af66fc99e Initial load
duke
parents:
diff changeset
632
a61af66fc99e Initial load
duke
parents:
diff changeset
633
a61af66fc99e Initial load
duke
parents:
diff changeset
634 //----------------------------PreserveJVMState---------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
635 PreserveJVMState::PreserveJVMState(GraphKit* kit, bool clone_map) {
a61af66fc99e Initial load
duke
parents:
diff changeset
636 debug_only(kit->verify_map());
a61af66fc99e Initial load
duke
parents:
diff changeset
637 _kit = kit;
a61af66fc99e Initial load
duke
parents:
diff changeset
638 _map = kit->map(); // preserve the map
a61af66fc99e Initial load
duke
parents:
diff changeset
639 _sp = kit->sp();
a61af66fc99e Initial load
duke
parents:
diff changeset
640 kit->set_map(clone_map ? kit->clone_map() : NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
641 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
642 _bci = kit->bci();
a61af66fc99e Initial load
duke
parents:
diff changeset
643 Parse* parser = kit->is_Parse();
367
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 366
diff changeset
644 int block = (parser == NULL || parser->block() == NULL) ? -1 : parser->block()->rpo();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
645 _block = block;
a61af66fc99e Initial load
duke
parents:
diff changeset
646 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
647 }
a61af66fc99e Initial load
duke
parents:
diff changeset
648 PreserveJVMState::~PreserveJVMState() {
a61af66fc99e Initial load
duke
parents:
diff changeset
649 GraphKit* kit = _kit;
a61af66fc99e Initial load
duke
parents:
diff changeset
650 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
651 assert(kit->bci() == _bci, "bci must not shift");
a61af66fc99e Initial load
duke
parents:
diff changeset
652 Parse* parser = kit->is_Parse();
367
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 366
diff changeset
653 int block = (parser == NULL || parser->block() == NULL) ? -1 : parser->block()->rpo();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
654 assert(block == _block, "block must not shift");
a61af66fc99e Initial load
duke
parents:
diff changeset
655 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
656 kit->set_map(_map);
a61af66fc99e Initial load
duke
parents:
diff changeset
657 kit->set_sp(_sp);
a61af66fc99e Initial load
duke
parents:
diff changeset
658 }
a61af66fc99e Initial load
duke
parents:
diff changeset
659
a61af66fc99e Initial load
duke
parents:
diff changeset
660
a61af66fc99e Initial load
duke
parents:
diff changeset
661 //-----------------------------BuildCutout-------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
662 BuildCutout::BuildCutout(GraphKit* kit, Node* p, float prob, float cnt)
a61af66fc99e Initial load
duke
parents:
diff changeset
663 : PreserveJVMState(kit)
a61af66fc99e Initial load
duke
parents:
diff changeset
664 {
a61af66fc99e Initial load
duke
parents:
diff changeset
665 assert(p->is_Con() || p->is_Bool(), "test must be a bool");
a61af66fc99e Initial load
duke
parents:
diff changeset
666 SafePointNode* outer_map = _map; // preserved map is caller's
a61af66fc99e Initial load
duke
parents:
diff changeset
667 SafePointNode* inner_map = kit->map();
a61af66fc99e Initial load
duke
parents:
diff changeset
668 IfNode* iff = kit->create_and_map_if(outer_map->control(), p, prob, cnt);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
669 outer_map->set_control(kit->gvn().transform( new (kit->C) IfTrueNode(iff) ));
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
670 inner_map->set_control(kit->gvn().transform( new (kit->C) IfFalseNode(iff) ));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
671 }
a61af66fc99e Initial load
duke
parents:
diff changeset
672 BuildCutout::~BuildCutout() {
a61af66fc99e Initial load
duke
parents:
diff changeset
673 GraphKit* kit = _kit;
a61af66fc99e Initial load
duke
parents:
diff changeset
674 assert(kit->stopped(), "cutout code must stop, throw, return, etc.");
a61af66fc99e Initial load
duke
parents:
diff changeset
675 }
a61af66fc99e Initial load
duke
parents:
diff changeset
676
900
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 851
diff changeset
677 //---------------------------PreserveReexecuteState----------------------------
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 851
diff changeset
678 PreserveReexecuteState::PreserveReexecuteState(GraphKit* kit) {
950
8fe1963e3964 6875577: CTW fails with /hotspot/src/share/vm/opto/memnode.cpp
kvn
parents: 900
diff changeset
679 assert(!kit->stopped(), "must call stopped() before");
900
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 851
diff changeset
680 _kit = kit;
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 851
diff changeset
681 _sp = kit->sp();
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 851
diff changeset
682 _reexecute = kit->jvms()->_reexecute;
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 851
diff changeset
683 }
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 851
diff changeset
684 PreserveReexecuteState::~PreserveReexecuteState() {
950
8fe1963e3964 6875577: CTW fails with /hotspot/src/share/vm/opto/memnode.cpp
kvn
parents: 900
diff changeset
685 if (_kit->stopped()) return;
900
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 851
diff changeset
686 _kit->jvms()->_reexecute = _reexecute;
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 851
diff changeset
687 _kit->set_sp(_sp);
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 851
diff changeset
688 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
689
a61af66fc99e Initial load
duke
parents:
diff changeset
690 //------------------------------clone_map--------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
691 // Implementation of PreserveJVMState
a61af66fc99e Initial load
duke
parents:
diff changeset
692 //
a61af66fc99e Initial load
duke
parents:
diff changeset
693 // Only clone_map(...) here. If this function is only used in the
a61af66fc99e Initial load
duke
parents:
diff changeset
694 // PreserveJVMState class we may want to get rid of this extra
a61af66fc99e Initial load
duke
parents:
diff changeset
695 // function eventually and do it all there.
a61af66fc99e Initial load
duke
parents:
diff changeset
696
a61af66fc99e Initial load
duke
parents:
diff changeset
697 SafePointNode* GraphKit::clone_map() {
a61af66fc99e Initial load
duke
parents:
diff changeset
698 if (map() == NULL) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
699
a61af66fc99e Initial load
duke
parents:
diff changeset
700 // Clone the memory edge first
a61af66fc99e Initial load
duke
parents:
diff changeset
701 Node* mem = MergeMemNode::make(C, map()->memory());
a61af66fc99e Initial load
duke
parents:
diff changeset
702 gvn().set_type_bottom(mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
703
a61af66fc99e Initial load
duke
parents:
diff changeset
704 SafePointNode *clonemap = (SafePointNode*)map()->clone();
a61af66fc99e Initial load
duke
parents:
diff changeset
705 JVMState* jvms = this->jvms();
a61af66fc99e Initial load
duke
parents:
diff changeset
706 JVMState* clonejvms = jvms->clone_shallow(C);
a61af66fc99e Initial load
duke
parents:
diff changeset
707 clonemap->set_memory(mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
708 clonemap->set_jvms(clonejvms);
a61af66fc99e Initial load
duke
parents:
diff changeset
709 clonejvms->set_map(clonemap);
a61af66fc99e Initial load
duke
parents:
diff changeset
710 record_for_igvn(clonemap);
a61af66fc99e Initial load
duke
parents:
diff changeset
711 gvn().set_type_bottom(clonemap);
a61af66fc99e Initial load
duke
parents:
diff changeset
712 return clonemap;
a61af66fc99e Initial load
duke
parents:
diff changeset
713 }
a61af66fc99e Initial load
duke
parents:
diff changeset
714
a61af66fc99e Initial load
duke
parents:
diff changeset
715
a61af66fc99e Initial load
duke
parents:
diff changeset
716 //-----------------------------set_map_clone-----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
717 void GraphKit::set_map_clone(SafePointNode* m) {
a61af66fc99e Initial load
duke
parents:
diff changeset
718 _map = m;
a61af66fc99e Initial load
duke
parents:
diff changeset
719 _map = clone_map();
a61af66fc99e Initial load
duke
parents:
diff changeset
720 _map->set_next_exception(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
721 debug_only(verify_map());
a61af66fc99e Initial load
duke
parents:
diff changeset
722 }
a61af66fc99e Initial load
duke
parents:
diff changeset
723
a61af66fc99e Initial load
duke
parents:
diff changeset
724
a61af66fc99e Initial load
duke
parents:
diff changeset
725 //----------------------------kill_dead_locals---------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
726 // Detect any locals which are known to be dead, and force them to top.
a61af66fc99e Initial load
duke
parents:
diff changeset
727 void GraphKit::kill_dead_locals() {
a61af66fc99e Initial load
duke
parents:
diff changeset
728 // Consult the liveness information for the locals. If any
a61af66fc99e Initial load
duke
parents:
diff changeset
729 // of them are unused, then they can be replaced by top(). This
a61af66fc99e Initial load
duke
parents:
diff changeset
730 // should help register allocation time and cut down on the size
a61af66fc99e Initial load
duke
parents:
diff changeset
731 // of the deoptimization information.
a61af66fc99e Initial load
duke
parents:
diff changeset
732
a61af66fc99e Initial load
duke
parents:
diff changeset
733 // This call is made from many of the bytecode handling
a61af66fc99e Initial load
duke
parents:
diff changeset
734 // subroutines called from the Big Switch in do_one_bytecode.
a61af66fc99e Initial load
duke
parents:
diff changeset
735 // Every bytecode which might include a slow path is responsible
a61af66fc99e Initial load
duke
parents:
diff changeset
736 // for killing its dead locals. The more consistent we
a61af66fc99e Initial load
duke
parents:
diff changeset
737 // are about killing deads, the fewer useless phis will be
a61af66fc99e Initial load
duke
parents:
diff changeset
738 // constructed for them at various merge points.
a61af66fc99e Initial load
duke
parents:
diff changeset
739
a61af66fc99e Initial load
duke
parents:
diff changeset
740 // bci can be -1 (InvocationEntryBci). We return the entry
a61af66fc99e Initial load
duke
parents:
diff changeset
741 // liveness for the method.
a61af66fc99e Initial load
duke
parents:
diff changeset
742
a61af66fc99e Initial load
duke
parents:
diff changeset
743 if (method() == NULL || method()->code_size() == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
744 // We are building a graph for a call to a native method.
a61af66fc99e Initial load
duke
parents:
diff changeset
745 // All locals are live.
a61af66fc99e Initial load
duke
parents:
diff changeset
746 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
747 }
a61af66fc99e Initial load
duke
parents:
diff changeset
748
a61af66fc99e Initial load
duke
parents:
diff changeset
749 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
750
a61af66fc99e Initial load
duke
parents:
diff changeset
751 // Consult the liveness information for the locals. If any
a61af66fc99e Initial load
duke
parents:
diff changeset
752 // of them are unused, then they can be replaced by top(). This
a61af66fc99e Initial load
duke
parents:
diff changeset
753 // should help register allocation time and cut down on the size
a61af66fc99e Initial load
duke
parents:
diff changeset
754 // of the deoptimization information.
a61af66fc99e Initial load
duke
parents:
diff changeset
755 MethodLivenessResult live_locals = method()->liveness_at_bci(bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
756
a61af66fc99e Initial load
duke
parents:
diff changeset
757 int len = (int)live_locals.size();
a61af66fc99e Initial load
duke
parents:
diff changeset
758 assert(len <= jvms()->loc_size(), "too many live locals");
a61af66fc99e Initial load
duke
parents:
diff changeset
759 for (int local = 0; local < len; local++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
760 if (!live_locals.at(local)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
761 set_local(local, top());
a61af66fc99e Initial load
duke
parents:
diff changeset
762 }
a61af66fc99e Initial load
duke
parents:
diff changeset
763 }
a61af66fc99e Initial load
duke
parents:
diff changeset
764 }
a61af66fc99e Initial load
duke
parents:
diff changeset
765
a61af66fc99e Initial load
duke
parents:
diff changeset
766 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
767 //-------------------------dead_locals_are_killed------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
768 // Return true if all dead locals are set to top in the map.
a61af66fc99e Initial load
duke
parents:
diff changeset
769 // Used to assert "clean" debug info at various points.
a61af66fc99e Initial load
duke
parents:
diff changeset
770 bool GraphKit::dead_locals_are_killed() {
a61af66fc99e Initial load
duke
parents:
diff changeset
771 if (method() == NULL || method()->code_size() == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
772 // No locals need to be dead, so all is as it should be.
a61af66fc99e Initial load
duke
parents:
diff changeset
773 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
774 }
a61af66fc99e Initial load
duke
parents:
diff changeset
775
a61af66fc99e Initial load
duke
parents:
diff changeset
776 // Make sure somebody called kill_dead_locals upstream.
a61af66fc99e Initial load
duke
parents:
diff changeset
777 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
778 for (JVMState* jvms = this->jvms(); jvms != NULL; jvms = jvms->caller()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
779 if (jvms->loc_size() == 0) continue; // no locals to consult
a61af66fc99e Initial load
duke
parents:
diff changeset
780 SafePointNode* map = jvms->map();
a61af66fc99e Initial load
duke
parents:
diff changeset
781 ciMethod* method = jvms->method();
a61af66fc99e Initial load
duke
parents:
diff changeset
782 int bci = jvms->bci();
a61af66fc99e Initial load
duke
parents:
diff changeset
783 if (jvms == this->jvms()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
784 bci = this->bci(); // it might not yet be synched
a61af66fc99e Initial load
duke
parents:
diff changeset
785 }
a61af66fc99e Initial load
duke
parents:
diff changeset
786 MethodLivenessResult live_locals = method->liveness_at_bci(bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
787 int len = (int)live_locals.size();
a61af66fc99e Initial load
duke
parents:
diff changeset
788 if (!live_locals.is_valid() || len == 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
789 // This method is trivial, or is poisoned by a breakpoint.
a61af66fc99e Initial load
duke
parents:
diff changeset
790 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
791 assert(len == jvms->loc_size(), "live map consistent with locals map");
a61af66fc99e Initial load
duke
parents:
diff changeset
792 for (int local = 0; local < len; local++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
793 if (!live_locals.at(local) && map->local(jvms, local) != top()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
794 if (PrintMiscellaneous && (Verbose || WizardMode)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
795 tty->print_cr("Zombie local %d: ", local);
a61af66fc99e Initial load
duke
parents:
diff changeset
796 jvms->dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
797 }
a61af66fc99e Initial load
duke
parents:
diff changeset
798 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
799 }
a61af66fc99e Initial load
duke
parents:
diff changeset
800 }
a61af66fc99e Initial load
duke
parents:
diff changeset
801 }
a61af66fc99e Initial load
duke
parents:
diff changeset
802 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
803 }
a61af66fc99e Initial load
duke
parents:
diff changeset
804
a61af66fc99e Initial load
duke
parents:
diff changeset
805 #endif //ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
806
900
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 851
diff changeset
807 // Helper function for enforcing certain bytecodes to reexecute if
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 851
diff changeset
808 // deoptimization happens
1252
f516d5d7a019 6910605: C2: NullPointerException/ClassCaseException is thrown when C2 with DeoptimizeALot is used
kvn
parents: 1166
diff changeset
809 static bool should_reexecute_implied_by_bytecode(JVMState *jvms, bool is_anewarray) {
900
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 851
diff changeset
810 ciMethod* cur_method = jvms->method();
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 851
diff changeset
811 int cur_bci = jvms->bci();
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 851
diff changeset
812 if (cur_method != NULL && cur_bci != InvocationEntryBci) {
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 851
diff changeset
813 Bytecodes::Code code = cur_method->java_code_at_bci(cur_bci);
1252
f516d5d7a019 6910605: C2: NullPointerException/ClassCaseException is thrown when C2 with DeoptimizeALot is used
kvn
parents: 1166
diff changeset
814 return Interpreter::bytecode_should_reexecute(code) ||
f516d5d7a019 6910605: C2: NullPointerException/ClassCaseException is thrown when C2 with DeoptimizeALot is used
kvn
parents: 1166
diff changeset
815 is_anewarray && code == Bytecodes::_multianewarray;
f516d5d7a019 6910605: C2: NullPointerException/ClassCaseException is thrown when C2 with DeoptimizeALot is used
kvn
parents: 1166
diff changeset
816 // Reexecute _multianewarray bytecode which was replaced with
f516d5d7a019 6910605: C2: NullPointerException/ClassCaseException is thrown when C2 with DeoptimizeALot is used
kvn
parents: 1166
diff changeset
817 // sequence of [a]newarray. See Parse::do_multianewarray().
f516d5d7a019 6910605: C2: NullPointerException/ClassCaseException is thrown when C2 with DeoptimizeALot is used
kvn
parents: 1166
diff changeset
818 //
f516d5d7a019 6910605: C2: NullPointerException/ClassCaseException is thrown when C2 with DeoptimizeALot is used
kvn
parents: 1166
diff changeset
819 // Note: interpreter should not have it set since this optimization
f516d5d7a019 6910605: C2: NullPointerException/ClassCaseException is thrown when C2 with DeoptimizeALot is used
kvn
parents: 1166
diff changeset
820 // is limited by dimensions and guarded by flag so in some cases
f516d5d7a019 6910605: C2: NullPointerException/ClassCaseException is thrown when C2 with DeoptimizeALot is used
kvn
parents: 1166
diff changeset
821 // multianewarray() runtime calls will be generated and
f516d5d7a019 6910605: C2: NullPointerException/ClassCaseException is thrown when C2 with DeoptimizeALot is used
kvn
parents: 1166
diff changeset
822 // the bytecode should not be reexecutes (stack will not be reset).
900
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 851
diff changeset
823 } else
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 851
diff changeset
824 return false;
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 851
diff changeset
825 }
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 851
diff changeset
826
0
a61af66fc99e Initial load
duke
parents:
diff changeset
827 // Helper function for adding JVMState and debug information to node
a61af66fc99e Initial load
duke
parents:
diff changeset
828 void GraphKit::add_safepoint_edges(SafePointNode* call, bool must_throw) {
a61af66fc99e Initial load
duke
parents:
diff changeset
829 // Add the safepoint edges to the call (or other safepoint).
a61af66fc99e Initial load
duke
parents:
diff changeset
830
a61af66fc99e Initial load
duke
parents:
diff changeset
831 // Make sure dead locals are set to top. This
a61af66fc99e Initial load
duke
parents:
diff changeset
832 // should help register allocation time and cut down on the size
a61af66fc99e Initial load
duke
parents:
diff changeset
833 // of the deoptimization information.
a61af66fc99e Initial load
duke
parents:
diff changeset
834 assert(dead_locals_are_killed(), "garbage in debug info before safepoint");
a61af66fc99e Initial load
duke
parents:
diff changeset
835
a61af66fc99e Initial load
duke
parents:
diff changeset
836 // Walk the inline list to fill in the correct set of JVMState's
a61af66fc99e Initial load
duke
parents:
diff changeset
837 // Also fill in the associated edges for each JVMState.
a61af66fc99e Initial load
duke
parents:
diff changeset
838
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
839 // If the bytecode needs to be reexecuted we need to put
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
840 // the arguments back on the stack.
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
841 const bool should_reexecute = jvms()->should_reexecute();
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
842 JVMState* youngest_jvms = should_reexecute ? sync_jvms_for_reexecute() : sync_jvms();
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
843
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
844 // NOTE: set_bci (called from sync_jvms) might reset the reexecute bit to
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
845 // undefined if the bci is different. This is normal for Parse but it
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
846 // should not happen for LibraryCallKit because only one bci is processed.
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
847 assert(!is_LibraryCallKit() || (jvms()->should_reexecute() == should_reexecute),
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
848 "in LibraryCallKit the reexecute bit should not change");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
849
a61af66fc99e Initial load
duke
parents:
diff changeset
850 // If we are guaranteed to throw, we can prune everything but the
a61af66fc99e Initial load
duke
parents:
diff changeset
851 // input to the current bytecode.
a61af66fc99e Initial load
duke
parents:
diff changeset
852 bool can_prune_locals = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
853 uint stack_slots_not_pruned = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
854 int inputs = 0, depth = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
855 if (must_throw) {
a61af66fc99e Initial load
duke
parents:
diff changeset
856 assert(method() == youngest_jvms->method(), "sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
857 if (compute_stack_effects(inputs, depth)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
858 can_prune_locals = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
859 stack_slots_not_pruned = inputs;
a61af66fc99e Initial load
duke
parents:
diff changeset
860 }
a61af66fc99e Initial load
duke
parents:
diff changeset
861 }
a61af66fc99e Initial load
duke
parents:
diff changeset
862
1397
b4776199210f 6943485: JVMTI always on capabilities change code generation too much
never
parents: 1257
diff changeset
863 if (env()->jvmti_can_access_local_variables()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
864 // At any safepoint, this method can get breakpointed, which would
a61af66fc99e Initial load
duke
parents:
diff changeset
865 // then require an immediate deoptimization.
a61af66fc99e Initial load
duke
parents:
diff changeset
866 can_prune_locals = false; // do not prune locals
a61af66fc99e Initial load
duke
parents:
diff changeset
867 stack_slots_not_pruned = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
868 }
a61af66fc99e Initial load
duke
parents:
diff changeset
869
a61af66fc99e Initial load
duke
parents:
diff changeset
870 // do not scribble on the input jvms
a61af66fc99e Initial load
duke
parents:
diff changeset
871 JVMState* out_jvms = youngest_jvms->clone_deep(C);
a61af66fc99e Initial load
duke
parents:
diff changeset
872 call->set_jvms(out_jvms); // Start jvms list for call node
a61af66fc99e Initial load
duke
parents:
diff changeset
873
900
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 851
diff changeset
874 // For a known set of bytecodes, the interpreter should reexecute them if
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 851
diff changeset
875 // deoptimization happens. We set the reexecute state for them here
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 851
diff changeset
876 if (out_jvms->is_reexecute_undefined() && //don't change if already specified
1252
f516d5d7a019 6910605: C2: NullPointerException/ClassCaseException is thrown when C2 with DeoptimizeALot is used
kvn
parents: 1166
diff changeset
877 should_reexecute_implied_by_bytecode(out_jvms, call->is_AllocateArray())) {
900
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 851
diff changeset
878 out_jvms->set_should_reexecute(true); //NOTE: youngest_jvms not changed
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 851
diff changeset
879 }
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 851
diff changeset
880
0
a61af66fc99e Initial load
duke
parents:
diff changeset
881 // Presize the call:
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
882 DEBUG_ONLY(uint non_debug_edges = call->req());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
883 call->add_req_batch(top(), youngest_jvms->debug_depth());
a61af66fc99e Initial load
duke
parents:
diff changeset
884 assert(call->req() == non_debug_edges + youngest_jvms->debug_depth(), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
885
a61af66fc99e Initial load
duke
parents:
diff changeset
886 // Set up edges so that the call looks like this:
a61af66fc99e Initial load
duke
parents:
diff changeset
887 // Call [state:] ctl io mem fptr retadr
a61af66fc99e Initial load
duke
parents:
diff changeset
888 // [parms:] parm0 ... parmN
a61af66fc99e Initial load
duke
parents:
diff changeset
889 // [root:] loc0 ... locN stk0 ... stkSP mon0 obj0 ... monN objN
a61af66fc99e Initial load
duke
parents:
diff changeset
890 // [...mid:] loc0 ... locN stk0 ... stkSP mon0 obj0 ... monN objN [...]
a61af66fc99e Initial load
duke
parents:
diff changeset
891 // [young:] loc0 ... locN stk0 ... stkSP mon0 obj0 ... monN objN
a61af66fc99e Initial load
duke
parents:
diff changeset
892 // Note that caller debug info precedes callee debug info.
a61af66fc99e Initial load
duke
parents:
diff changeset
893
a61af66fc99e Initial load
duke
parents:
diff changeset
894 // Fill pointer walks backwards from "young:" to "root:" in the diagram above:
a61af66fc99e Initial load
duke
parents:
diff changeset
895 uint debug_ptr = call->req();
a61af66fc99e Initial load
duke
parents:
diff changeset
896
a61af66fc99e Initial load
duke
parents:
diff changeset
897 // Loop over the map input edges associated with jvms, add them
a61af66fc99e Initial load
duke
parents:
diff changeset
898 // to the call node, & reset all offsets to match call node array.
a61af66fc99e Initial load
duke
parents:
diff changeset
899 for (JVMState* in_jvms = youngest_jvms; in_jvms != NULL; ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
900 uint debug_end = debug_ptr;
a61af66fc99e Initial load
duke
parents:
diff changeset
901 uint debug_start = debug_ptr - in_jvms->debug_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
902 debug_ptr = debug_start; // back up the ptr
a61af66fc99e Initial load
duke
parents:
diff changeset
903
a61af66fc99e Initial load
duke
parents:
diff changeset
904 uint p = debug_start; // walks forward in [debug_start, debug_end)
a61af66fc99e Initial load
duke
parents:
diff changeset
905 uint j, k, l;
a61af66fc99e Initial load
duke
parents:
diff changeset
906 SafePointNode* in_map = in_jvms->map();
a61af66fc99e Initial load
duke
parents:
diff changeset
907 out_jvms->set_map(call);
a61af66fc99e Initial load
duke
parents:
diff changeset
908
a61af66fc99e Initial load
duke
parents:
diff changeset
909 if (can_prune_locals) {
a61af66fc99e Initial load
duke
parents:
diff changeset
910 assert(in_jvms->method() == out_jvms->method(), "sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
911 // If the current throw can reach an exception handler in this JVMS,
a61af66fc99e Initial load
duke
parents:
diff changeset
912 // then we must keep everything live that can reach that handler.
a61af66fc99e Initial load
duke
parents:
diff changeset
913 // As a quick and dirty approximation, we look for any handlers at all.
a61af66fc99e Initial load
duke
parents:
diff changeset
914 if (in_jvms->method()->has_exception_handlers()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
915 can_prune_locals = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
916 }
a61af66fc99e Initial load
duke
parents:
diff changeset
917 }
a61af66fc99e Initial load
duke
parents:
diff changeset
918
a61af66fc99e Initial load
duke
parents:
diff changeset
919 // Add the Locals
a61af66fc99e Initial load
duke
parents:
diff changeset
920 k = in_jvms->locoff();
a61af66fc99e Initial load
duke
parents:
diff changeset
921 l = in_jvms->loc_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
922 out_jvms->set_locoff(p);
1397
b4776199210f 6943485: JVMTI always on capabilities change code generation too much
never
parents: 1257
diff changeset
923 if (!can_prune_locals) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
924 for (j = 0; j < l; j++)
a61af66fc99e Initial load
duke
parents:
diff changeset
925 call->set_req(p++, in_map->in(k+j));
a61af66fc99e Initial load
duke
parents:
diff changeset
926 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
927 p += l; // already set to top above by add_req_batch
a61af66fc99e Initial load
duke
parents:
diff changeset
928 }
a61af66fc99e Initial load
duke
parents:
diff changeset
929
a61af66fc99e Initial load
duke
parents:
diff changeset
930 // Add the Expression Stack
a61af66fc99e Initial load
duke
parents:
diff changeset
931 k = in_jvms->stkoff();
a61af66fc99e Initial load
duke
parents:
diff changeset
932 l = in_jvms->sp();
a61af66fc99e Initial load
duke
parents:
diff changeset
933 out_jvms->set_stkoff(p);
1397
b4776199210f 6943485: JVMTI always on capabilities change code generation too much
never
parents: 1257
diff changeset
934 if (!can_prune_locals) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
935 for (j = 0; j < l; j++)
a61af66fc99e Initial load
duke
parents:
diff changeset
936 call->set_req(p++, in_map->in(k+j));
a61af66fc99e Initial load
duke
parents:
diff changeset
937 } else if (can_prune_locals && stack_slots_not_pruned != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
938 // Divide stack into {S0,...,S1}, where S0 is set to top.
a61af66fc99e Initial load
duke
parents:
diff changeset
939 uint s1 = stack_slots_not_pruned;
a61af66fc99e Initial load
duke
parents:
diff changeset
940 stack_slots_not_pruned = 0; // for next iteration
a61af66fc99e Initial load
duke
parents:
diff changeset
941 if (s1 > l) s1 = l;
a61af66fc99e Initial load
duke
parents:
diff changeset
942 uint s0 = l - s1;
a61af66fc99e Initial load
duke
parents:
diff changeset
943 p += s0; // skip the tops preinstalled by add_req_batch
a61af66fc99e Initial load
duke
parents:
diff changeset
944 for (j = s0; j < l; j++)
a61af66fc99e Initial load
duke
parents:
diff changeset
945 call->set_req(p++, in_map->in(k+j));
a61af66fc99e Initial load
duke
parents:
diff changeset
946 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
947 p += l; // already set to top above by add_req_batch
a61af66fc99e Initial load
duke
parents:
diff changeset
948 }
a61af66fc99e Initial load
duke
parents:
diff changeset
949
a61af66fc99e Initial load
duke
parents:
diff changeset
950 // Add the Monitors
a61af66fc99e Initial load
duke
parents:
diff changeset
951 k = in_jvms->monoff();
a61af66fc99e Initial load
duke
parents:
diff changeset
952 l = in_jvms->mon_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
953 out_jvms->set_monoff(p);
a61af66fc99e Initial load
duke
parents:
diff changeset
954 for (j = 0; j < l; j++)
a61af66fc99e Initial load
duke
parents:
diff changeset
955 call->set_req(p++, in_map->in(k+j));
a61af66fc99e Initial load
duke
parents:
diff changeset
956
63
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 29
diff changeset
957 // Copy any scalar object fields.
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 29
diff changeset
958 k = in_jvms->scloff();
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 29
diff changeset
959 l = in_jvms->scl_size();
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 29
diff changeset
960 out_jvms->set_scloff(p);
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 29
diff changeset
961 for (j = 0; j < l; j++)
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 29
diff changeset
962 call->set_req(p++, in_map->in(k+j));
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 29
diff changeset
963
0
a61af66fc99e Initial load
duke
parents:
diff changeset
964 // Finish the new jvms.
a61af66fc99e Initial load
duke
parents:
diff changeset
965 out_jvms->set_endoff(p);
a61af66fc99e Initial load
duke
parents:
diff changeset
966
a61af66fc99e Initial load
duke
parents:
diff changeset
967 assert(out_jvms->endoff() == debug_end, "fill ptr must match");
a61af66fc99e Initial load
duke
parents:
diff changeset
968 assert(out_jvms->depth() == in_jvms->depth(), "depth must match");
a61af66fc99e Initial load
duke
parents:
diff changeset
969 assert(out_jvms->loc_size() == in_jvms->loc_size(), "size must match");
a61af66fc99e Initial load
duke
parents:
diff changeset
970 assert(out_jvms->mon_size() == in_jvms->mon_size(), "size must match");
63
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 29
diff changeset
971 assert(out_jvms->scl_size() == in_jvms->scl_size(), "size must match");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
972 assert(out_jvms->debug_size() == in_jvms->debug_size(), "size must match");
a61af66fc99e Initial load
duke
parents:
diff changeset
973
a61af66fc99e Initial load
duke
parents:
diff changeset
974 // Update the two tail pointers in parallel.
a61af66fc99e Initial load
duke
parents:
diff changeset
975 out_jvms = out_jvms->caller();
a61af66fc99e Initial load
duke
parents:
diff changeset
976 in_jvms = in_jvms->caller();
a61af66fc99e Initial load
duke
parents:
diff changeset
977 }
a61af66fc99e Initial load
duke
parents:
diff changeset
978
a61af66fc99e Initial load
duke
parents:
diff changeset
979 assert(debug_ptr == non_debug_edges, "debug info must fit exactly");
a61af66fc99e Initial load
duke
parents:
diff changeset
980
a61af66fc99e Initial load
duke
parents:
diff changeset
981 // Test the correctness of JVMState::debug_xxx accessors:
a61af66fc99e Initial load
duke
parents:
diff changeset
982 assert(call->jvms()->debug_start() == non_debug_edges, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
983 assert(call->jvms()->debug_end() == call->req(), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
984 assert(call->jvms()->debug_depth() == call->req() - non_debug_edges, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
985 }
a61af66fc99e Initial load
duke
parents:
diff changeset
986
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
987 bool GraphKit::compute_stack_effects(int& inputs, int& depth) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
988 Bytecodes::Code code = java_bc();
a61af66fc99e Initial load
duke
parents:
diff changeset
989 if (code == Bytecodes::_wide) {
a61af66fc99e Initial load
duke
parents:
diff changeset
990 code = method()->java_code_at_bci(bci() + 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
991 }
a61af66fc99e Initial load
duke
parents:
diff changeset
992
a61af66fc99e Initial load
duke
parents:
diff changeset
993 BasicType rtype = T_ILLEGAL;
a61af66fc99e Initial load
duke
parents:
diff changeset
994 int rsize = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
995
a61af66fc99e Initial load
duke
parents:
diff changeset
996 if (code != Bytecodes::_illegal) {
a61af66fc99e Initial load
duke
parents:
diff changeset
997 depth = Bytecodes::depth(code); // checkcast=0, athrow=-1
a61af66fc99e Initial load
duke
parents:
diff changeset
998 rtype = Bytecodes::result_type(code); // checkcast=P, athrow=V
a61af66fc99e Initial load
duke
parents:
diff changeset
999 if (rtype < T_CONFLICT)
a61af66fc99e Initial load
duke
parents:
diff changeset
1000 rsize = type2size[rtype];
a61af66fc99e Initial load
duke
parents:
diff changeset
1001 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1002
a61af66fc99e Initial load
duke
parents:
diff changeset
1003 switch (code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1004 case Bytecodes::_illegal:
a61af66fc99e Initial load
duke
parents:
diff changeset
1005 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1006
a61af66fc99e Initial load
duke
parents:
diff changeset
1007 case Bytecodes::_ldc:
a61af66fc99e Initial load
duke
parents:
diff changeset
1008 case Bytecodes::_ldc_w:
a61af66fc99e Initial load
duke
parents:
diff changeset
1009 case Bytecodes::_ldc2_w:
a61af66fc99e Initial load
duke
parents:
diff changeset
1010 inputs = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1011 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1012
a61af66fc99e Initial load
duke
parents:
diff changeset
1013 case Bytecodes::_dup: inputs = 1; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1014 case Bytecodes::_dup_x1: inputs = 2; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1015 case Bytecodes::_dup_x2: inputs = 3; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1016 case Bytecodes::_dup2: inputs = 2; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1017 case Bytecodes::_dup2_x1: inputs = 3; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1018 case Bytecodes::_dup2_x2: inputs = 4; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1019 case Bytecodes::_swap: inputs = 2; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1020 case Bytecodes::_arraylength: inputs = 1; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1021
a61af66fc99e Initial load
duke
parents:
diff changeset
1022 case Bytecodes::_getstatic:
a61af66fc99e Initial load
duke
parents:
diff changeset
1023 case Bytecodes::_putstatic:
a61af66fc99e Initial load
duke
parents:
diff changeset
1024 case Bytecodes::_getfield:
a61af66fc99e Initial load
duke
parents:
diff changeset
1025 case Bytecodes::_putfield:
a61af66fc99e Initial load
duke
parents:
diff changeset
1026 {
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
1027 bool ignored_will_link;
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
1028 ciField* field = method()->get_field_at_bci(bci(), ignored_will_link);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
1029 int size = field->type()->size();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1030 bool is_get = (depth >= 0), is_static = (depth & 1);
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
1031 inputs = (is_static ? 0 : 1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1032 if (is_get) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1033 depth = size - inputs;
a61af66fc99e Initial load
duke
parents:
diff changeset
1034 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1035 inputs += size; // putxxx pops the value from the stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1036 depth = - inputs;
a61af66fc99e Initial load
duke
parents:
diff changeset
1037 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1038 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1039 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1040
a61af66fc99e Initial load
duke
parents:
diff changeset
1041 case Bytecodes::_invokevirtual:
a61af66fc99e Initial load
duke
parents:
diff changeset
1042 case Bytecodes::_invokespecial:
a61af66fc99e Initial load
duke
parents:
diff changeset
1043 case Bytecodes::_invokestatic:
726
be93aad57795 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 647
diff changeset
1044 case Bytecodes::_invokedynamic:
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1045 case Bytecodes::_invokeinterface:
a61af66fc99e Initial load
duke
parents:
diff changeset
1046 {
6634
7f813940ac35 7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents: 6266
diff changeset
1047 bool ignored_will_link;
7f813940ac35 7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents: 6266
diff changeset
1048 ciSignature* declared_signature = NULL;
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
1049 ciMethod* ignored_callee = method()->get_method_at_bci(bci(), ignored_will_link, &declared_signature);
6634
7f813940ac35 7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents: 6266
diff changeset
1050 assert(declared_signature != NULL, "cannot be null");
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
1051 inputs = declared_signature->arg_size_for_bc(code);
6634
7f813940ac35 7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents: 6266
diff changeset
1052 int size = declared_signature->return_type()->size();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1053 depth = size - inputs;
a61af66fc99e Initial load
duke
parents:
diff changeset
1054 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1055 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1056
a61af66fc99e Initial load
duke
parents:
diff changeset
1057 case Bytecodes::_multianewarray:
a61af66fc99e Initial load
duke
parents:
diff changeset
1058 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1059 ciBytecodeStream iter(method());
a61af66fc99e Initial load
duke
parents:
diff changeset
1060 iter.reset_to_bci(bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
1061 iter.next();
a61af66fc99e Initial load
duke
parents:
diff changeset
1062 inputs = iter.get_dimensions();
a61af66fc99e Initial load
duke
parents:
diff changeset
1063 assert(rsize == 1, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
1064 depth = rsize - inputs;
a61af66fc99e Initial load
duke
parents:
diff changeset
1065 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1066 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1067
a61af66fc99e Initial load
duke
parents:
diff changeset
1068 case Bytecodes::_ireturn:
a61af66fc99e Initial load
duke
parents:
diff changeset
1069 case Bytecodes::_lreturn:
a61af66fc99e Initial load
duke
parents:
diff changeset
1070 case Bytecodes::_freturn:
a61af66fc99e Initial load
duke
parents:
diff changeset
1071 case Bytecodes::_dreturn:
a61af66fc99e Initial load
duke
parents:
diff changeset
1072 case Bytecodes::_areturn:
a61af66fc99e Initial load
duke
parents:
diff changeset
1073 assert(rsize = -depth, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
1074 inputs = rsize;
a61af66fc99e Initial load
duke
parents:
diff changeset
1075 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1076
a61af66fc99e Initial load
duke
parents:
diff changeset
1077 case Bytecodes::_jsr:
a61af66fc99e Initial load
duke
parents:
diff changeset
1078 case Bytecodes::_jsr_w:
a61af66fc99e Initial load
duke
parents:
diff changeset
1079 inputs = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1080 depth = 1; // S.B. depth=1, not zero
a61af66fc99e Initial load
duke
parents:
diff changeset
1081 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1082
a61af66fc99e Initial load
duke
parents:
diff changeset
1083 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
1084 // bytecode produces a typed result
a61af66fc99e Initial load
duke
parents:
diff changeset
1085 inputs = rsize - depth;
a61af66fc99e Initial load
duke
parents:
diff changeset
1086 assert(inputs >= 0, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
1087 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1088 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1089
a61af66fc99e Initial load
duke
parents:
diff changeset
1090 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1091 // spot check
a61af66fc99e Initial load
duke
parents:
diff changeset
1092 int outputs = depth + inputs;
a61af66fc99e Initial load
duke
parents:
diff changeset
1093 assert(outputs >= 0, "sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
1094 switch (code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1095 case Bytecodes::_checkcast: assert(inputs == 1 && outputs == 1, ""); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1096 case Bytecodes::_athrow: assert(inputs == 1 && outputs == 0, ""); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1097 case Bytecodes::_aload_0: assert(inputs == 0 && outputs == 1, ""); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1098 case Bytecodes::_return: assert(inputs == 0 && outputs == 0, ""); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1099 case Bytecodes::_drem: assert(inputs == 4 && outputs == 2, ""); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1100 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1101 #endif //ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1102
a61af66fc99e Initial load
duke
parents:
diff changeset
1103 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1104 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1105
a61af66fc99e Initial load
duke
parents:
diff changeset
1106
a61af66fc99e Initial load
duke
parents:
diff changeset
1107
a61af66fc99e Initial load
duke
parents:
diff changeset
1108 //------------------------------basic_plus_adr---------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1109 Node* GraphKit::basic_plus_adr(Node* base, Node* ptr, Node* offset) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1110 // short-circuit a common case
a61af66fc99e Initial load
duke
parents:
diff changeset
1111 if (offset == intcon(0)) return ptr;
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
1112 return _gvn.transform( new (C) AddPNode(base, ptr, offset) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1113 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1114
a61af66fc99e Initial load
duke
parents:
diff changeset
1115 Node* GraphKit::ConvI2L(Node* offset) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1116 // short-circuit a common case
a61af66fc99e Initial load
duke
parents:
diff changeset
1117 jint offset_con = find_int_con(offset, Type::OffsetBot);
a61af66fc99e Initial load
duke
parents:
diff changeset
1118 if (offset_con != Type::OffsetBot) {
6846
377508648226 8000313: C2 should use jlong for 64bit values
vlivanov
parents: 6804
diff changeset
1119 return longcon((jlong) offset_con);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1120 }
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
1121 return _gvn.transform( new (C) ConvI2LNode(offset));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1122 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1123 Node* GraphKit::ConvL2I(Node* offset) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1124 // short-circuit a common case
a61af66fc99e Initial load
duke
parents:
diff changeset
1125 jlong offset_con = find_long_con(offset, (jlong)Type::OffsetBot);
a61af66fc99e Initial load
duke
parents:
diff changeset
1126 if (offset_con != (jlong)Type::OffsetBot) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1127 return intcon((int) offset_con);
a61af66fc99e Initial load
duke
parents:
diff changeset
1128 }
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
1129 return _gvn.transform( new (C) ConvL2INode(offset));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1130 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1131
a61af66fc99e Initial load
duke
parents:
diff changeset
1132 //-------------------------load_object_klass-----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1133 Node* GraphKit::load_object_klass(Node* obj) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1134 // Special-case a fresh allocation to avoid building nodes:
a61af66fc99e Initial load
duke
parents:
diff changeset
1135 Node* akls = AllocateNode::Ideal_klass(obj, &_gvn);
a61af66fc99e Initial load
duke
parents:
diff changeset
1136 if (akls != NULL) return akls;
a61af66fc99e Initial load
duke
parents:
diff changeset
1137 Node* k_adr = basic_plus_adr(obj, oopDesc::klass_offset_in_bytes());
164
c436414a719e 6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents: 113
diff changeset
1138 return _gvn.transform( LoadKlassNode::make(_gvn, immutable_memory(), k_adr, TypeInstPtr::KLASS) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1139 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1140
a61af66fc99e Initial load
duke
parents:
diff changeset
1141 //-------------------------load_array_length-----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1142 Node* GraphKit::load_array_length(Node* array) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1143 // Special-case a fresh allocation to avoid building nodes:
366
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 332
diff changeset
1144 AllocateArrayNode* alloc = AllocateArrayNode::Ideal_array_allocation(array, &_gvn);
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 332
diff changeset
1145 Node *alen;
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 332
diff changeset
1146 if (alloc == NULL) {
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 332
diff changeset
1147 Node *r_adr = basic_plus_adr(array, arrayOopDesc::length_offset_in_bytes());
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
1148 alen = _gvn.transform( new (C) LoadRangeNode(0, immutable_memory(), r_adr, TypeInt::POS));
366
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 332
diff changeset
1149 } else {
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 332
diff changeset
1150 alen = alloc->Ideal_length();
954
0f1c19b7a52d 6875619: CTW fails with /hotspot/src/share/vm/opto/type.hpp
kvn
parents: 950
diff changeset
1151 Node* ccast = alloc->make_ideal_length(_gvn.type(array)->is_oopptr(), &_gvn);
366
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 332
diff changeset
1152 if (ccast != alen) {
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 332
diff changeset
1153 alen = _gvn.transform(ccast);
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 332
diff changeset
1154 }
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 332
diff changeset
1155 }
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 332
diff changeset
1156 return alen;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1157 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1158
a61af66fc99e Initial load
duke
parents:
diff changeset
1159 //------------------------------do_null_check----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1160 // Helper function to do a NULL pointer check. Returned value is
a61af66fc99e Initial load
duke
parents:
diff changeset
1161 // the incoming address with NULL casted away. You are allowed to use the
a61af66fc99e Initial load
duke
parents:
diff changeset
1162 // not-null value only if you are control dependent on the test.
a61af66fc99e Initial load
duke
parents:
diff changeset
1163 extern int explicit_null_checks_inserted,
a61af66fc99e Initial load
duke
parents:
diff changeset
1164 explicit_null_checks_elided;
a61af66fc99e Initial load
duke
parents:
diff changeset
1165 Node* GraphKit::null_check_common(Node* value, BasicType type,
a61af66fc99e Initial load
duke
parents:
diff changeset
1166 // optional arguments for variations:
a61af66fc99e Initial load
duke
parents:
diff changeset
1167 bool assert_null,
a61af66fc99e Initial load
duke
parents:
diff changeset
1168 Node* *null_control) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1169 assert(!assert_null || null_control == NULL, "not both at once");
a61af66fc99e Initial load
duke
parents:
diff changeset
1170 if (stopped()) return top();
a61af66fc99e Initial load
duke
parents:
diff changeset
1171 if (!GenerateCompilerNullChecks && !assert_null && null_control == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1172 // For some performance testing, we may wish to suppress null checking.
a61af66fc99e Initial load
duke
parents:
diff changeset
1173 value = cast_not_null(value); // Make it appear to be non-null (4962416).
a61af66fc99e Initial load
duke
parents:
diff changeset
1174 return value;
a61af66fc99e Initial load
duke
parents:
diff changeset
1175 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1176 explicit_null_checks_inserted++;
a61af66fc99e Initial load
duke
parents:
diff changeset
1177
a61af66fc99e Initial load
duke
parents:
diff changeset
1178 // Construct NULL check
a61af66fc99e Initial load
duke
parents:
diff changeset
1179 Node *chk = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1180 switch(type) {
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
1181 case T_LONG : chk = new (C) CmpLNode(value, _gvn.zerocon(T_LONG)); break;
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
1182 case T_INT : chk = new (C) CmpINode(value, _gvn.intcon(0)); break;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1183 case T_ARRAY : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
1184 type = T_OBJECT; // simplify further tests
a61af66fc99e Initial load
duke
parents:
diff changeset
1185 case T_OBJECT : {
a61af66fc99e Initial load
duke
parents:
diff changeset
1186 const Type *t = _gvn.type( value );
a61af66fc99e Initial load
duke
parents:
diff changeset
1187
950
8fe1963e3964 6875577: CTW fails with /hotspot/src/share/vm/opto/memnode.cpp
kvn
parents: 900
diff changeset
1188 const TypeOopPtr* tp = t->isa_oopptr();
955
26fbe81d30cf 6880052: SIGSEGV in GraphKit::null_check_common()
kvn
parents: 954
diff changeset
1189 if (tp != NULL && tp->klass() != NULL && !tp->klass()->is_loaded()
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1190 // Only for do_null_check, not any of its siblings:
a61af66fc99e Initial load
duke
parents:
diff changeset
1191 && !assert_null && null_control == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1192 // Usually, any field access or invocation on an unloaded oop type
a61af66fc99e Initial load
duke
parents:
diff changeset
1193 // will simply fail to link, since the statically linked class is
a61af66fc99e Initial load
duke
parents:
diff changeset
1194 // likely also to be unloaded. However, in -Xcomp mode, sometimes
a61af66fc99e Initial load
duke
parents:
diff changeset
1195 // the static class is loaded but the sharper oop type is not.
a61af66fc99e Initial load
duke
parents:
diff changeset
1196 // Rather than checking for this obscure case in lots of places,
a61af66fc99e Initial load
duke
parents:
diff changeset
1197 // we simply observe that a null check on an unloaded class
a61af66fc99e Initial load
duke
parents:
diff changeset
1198 // will always be followed by a nonsense operation, so we
a61af66fc99e Initial load
duke
parents:
diff changeset
1199 // can just issue the uncommon trap here.
a61af66fc99e Initial load
duke
parents:
diff changeset
1200 // Our access to the unloaded class will only be correct
a61af66fc99e Initial load
duke
parents:
diff changeset
1201 // after it has been loaded and initialized, which requires
a61af66fc99e Initial load
duke
parents:
diff changeset
1202 // a trip through the interpreter.
a61af66fc99e Initial load
duke
parents:
diff changeset
1203 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1204 if (WizardMode) { tty->print("Null check of unloaded "); tp->klass()->print(); tty->cr(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
1205 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1206 uncommon_trap(Deoptimization::Reason_unloaded,
a61af66fc99e Initial load
duke
parents:
diff changeset
1207 Deoptimization::Action_reinterpret,
a61af66fc99e Initial load
duke
parents:
diff changeset
1208 tp->klass(), "!loaded");
a61af66fc99e Initial load
duke
parents:
diff changeset
1209 return top();
a61af66fc99e Initial load
duke
parents:
diff changeset
1210 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1211
a61af66fc99e Initial load
duke
parents:
diff changeset
1212 if (assert_null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1213 // See if the type is contained in NULL_PTR.
a61af66fc99e Initial load
duke
parents:
diff changeset
1214 // If so, then the value is already null.
a61af66fc99e Initial load
duke
parents:
diff changeset
1215 if (t->higher_equal(TypePtr::NULL_PTR)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1216 explicit_null_checks_elided++;
a61af66fc99e Initial load
duke
parents:
diff changeset
1217 return value; // Elided null assert quickly!
a61af66fc99e Initial load
duke
parents:
diff changeset
1218 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1219 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1220 // See if mixing in the NULL pointer changes type.
a61af66fc99e Initial load
duke
parents:
diff changeset
1221 // If so, then the NULL pointer was not allowed in the original
a61af66fc99e Initial load
duke
parents:
diff changeset
1222 // type. In other words, "value" was not-null.
a61af66fc99e Initial load
duke
parents:
diff changeset
1223 if (t->meet(TypePtr::NULL_PTR) != t) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1224 // same as: if (!TypePtr::NULL_PTR->higher_equal(t)) ...
a61af66fc99e Initial load
duke
parents:
diff changeset
1225 explicit_null_checks_elided++;
a61af66fc99e Initial load
duke
parents:
diff changeset
1226 return value; // Elided null check quickly!
a61af66fc99e Initial load
duke
parents:
diff changeset
1227 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1228 }
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
1229 chk = new (C) CmpPNode( value, null() );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1230 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1231 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1232
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
1233 default:
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
1234 fatal(err_msg_res("unexpected type: %s", type2name(type)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1235 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1236 assert(chk != NULL, "sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
1237 chk = _gvn.transform(chk);
a61af66fc99e Initial load
duke
parents:
diff changeset
1238
a61af66fc99e Initial load
duke
parents:
diff changeset
1239 BoolTest::mask btest = assert_null ? BoolTest::eq : BoolTest::ne;
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
1240 BoolNode *btst = new (C) BoolNode( chk, btest);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1241 Node *tst = _gvn.transform( btst );
a61af66fc99e Initial load
duke
parents:
diff changeset
1242
a61af66fc99e Initial load
duke
parents:
diff changeset
1243 //-----------
605
98cb887364d3 6810672: Comment typos
twisti
parents: 570
diff changeset
1244 // if peephole optimizations occurred, a prior test existed.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1245 // If a prior test existed, maybe it dominates as we can avoid this test.
a61af66fc99e Initial load
duke
parents:
diff changeset
1246 if (tst != btst && type == T_OBJECT) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1247 // At this point we want to scan up the CFG to see if we can
a61af66fc99e Initial load
duke
parents:
diff changeset
1248 // find an identical test (and so avoid this test altogether).
a61af66fc99e Initial load
duke
parents:
diff changeset
1249 Node *cfg = control();
a61af66fc99e Initial load
duke
parents:
diff changeset
1250 int depth = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1251 while( depth < 16 ) { // Limit search depth for speed
a61af66fc99e Initial load
duke
parents:
diff changeset
1252 if( cfg->Opcode() == Op_IfTrue &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1253 cfg->in(0)->in(1) == tst ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1254 // Found prior test. Use "cast_not_null" to construct an identical
a61af66fc99e Initial load
duke
parents:
diff changeset
1255 // CastPP (and hence hash to) as already exists for the prior test.
a61af66fc99e Initial load
duke
parents:
diff changeset
1256 // Return that casted value.
a61af66fc99e Initial load
duke
parents:
diff changeset
1257 if (assert_null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1258 replace_in_map(value, null());
a61af66fc99e Initial load
duke
parents:
diff changeset
1259 return null(); // do not issue the redundant test
a61af66fc99e Initial load
duke
parents:
diff changeset
1260 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1261 Node *oldcontrol = control();
a61af66fc99e Initial load
duke
parents:
diff changeset
1262 set_control(cfg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1263 Node *res = cast_not_null(value);
a61af66fc99e Initial load
duke
parents:
diff changeset
1264 set_control(oldcontrol);
a61af66fc99e Initial load
duke
parents:
diff changeset
1265 explicit_null_checks_elided++;
a61af66fc99e Initial load
duke
parents:
diff changeset
1266 return res;
a61af66fc99e Initial load
duke
parents:
diff changeset
1267 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1268 cfg = IfNode::up_one_dom(cfg, /*linear_only=*/ true);
a61af66fc99e Initial load
duke
parents:
diff changeset
1269 if (cfg == NULL) break; // Quit at region nodes
a61af66fc99e Initial load
duke
parents:
diff changeset
1270 depth++;
a61af66fc99e Initial load
duke
parents:
diff changeset
1271 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1272 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1273
a61af66fc99e Initial load
duke
parents:
diff changeset
1274 //-----------
a61af66fc99e Initial load
duke
parents:
diff changeset
1275 // Branch to failure if null
a61af66fc99e Initial load
duke
parents:
diff changeset
1276 float ok_prob = PROB_MAX; // a priori estimate: nulls never happen
a61af66fc99e Initial load
duke
parents:
diff changeset
1277 Deoptimization::DeoptReason reason;
a61af66fc99e Initial load
duke
parents:
diff changeset
1278 if (assert_null)
a61af66fc99e Initial load
duke
parents:
diff changeset
1279 reason = Deoptimization::Reason_null_assert;
a61af66fc99e Initial load
duke
parents:
diff changeset
1280 else if (type == T_OBJECT)
a61af66fc99e Initial load
duke
parents:
diff changeset
1281 reason = Deoptimization::Reason_null_check;
a61af66fc99e Initial load
duke
parents:
diff changeset
1282 else
a61af66fc99e Initial load
duke
parents:
diff changeset
1283 reason = Deoptimization::Reason_div0_check;
a61af66fc99e Initial load
duke
parents:
diff changeset
1284
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
1285 // %%% Since Reason_unhandled is not recorded on a per-bytecode basis,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
1286 // ciMethodData::has_trap_at will return a conservative -1 if any
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
1287 // must-be-null assertion has failed. This could cause performance
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
1288 // problems for a method after its first do_null_assert failure.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
1289 // Consider using 'Reason_class_check' instead?
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
1290
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1291 // To cause an implicit null check, we set the not-null probability
605
98cb887364d3 6810672: Comment typos
twisti
parents: 570
diff changeset
1292 // to the maximum (PROB_MAX). For an explicit check the probability
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1293 // is set to a smaller value.
a61af66fc99e Initial load
duke
parents:
diff changeset
1294 if (null_control != NULL || too_many_traps(reason)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1295 // probability is less likely
a61af66fc99e Initial load
duke
parents:
diff changeset
1296 ok_prob = PROB_LIKELY_MAG(3);
a61af66fc99e Initial load
duke
parents:
diff changeset
1297 } else if (!assert_null &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1298 (ImplicitNullCheckThreshold > 0) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1299 method() != NULL &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1300 (method()->method_data()->trap_count(reason)
a61af66fc99e Initial load
duke
parents:
diff changeset
1301 >= (uint)ImplicitNullCheckThreshold)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1302 ok_prob = PROB_LIKELY_MAG(3);
a61af66fc99e Initial load
duke
parents:
diff changeset
1303 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1304
a61af66fc99e Initial load
duke
parents:
diff changeset
1305 if (null_control != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1306 IfNode* iff = create_and_map_if(control(), tst, ok_prob, COUNT_UNKNOWN);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
1307 Node* null_true = _gvn.transform( new (C) IfFalseNode(iff));
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
1308 set_control( _gvn.transform( new (C) IfTrueNode(iff)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1309 if (null_true == top())
a61af66fc99e Initial load
duke
parents:
diff changeset
1310 explicit_null_checks_elided++;
a61af66fc99e Initial load
duke
parents:
diff changeset
1311 (*null_control) = null_true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1312 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1313 BuildCutout unless(this, tst, ok_prob);
a61af66fc99e Initial load
duke
parents:
diff changeset
1314 // Check for optimizer eliding test at parse time
a61af66fc99e Initial load
duke
parents:
diff changeset
1315 if (stopped()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1316 // Failure not possible; do not bother making uncommon trap.
a61af66fc99e Initial load
duke
parents:
diff changeset
1317 explicit_null_checks_elided++;
a61af66fc99e Initial load
duke
parents:
diff changeset
1318 } else if (assert_null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1319 uncommon_trap(reason,
a61af66fc99e Initial load
duke
parents:
diff changeset
1320 Deoptimization::Action_make_not_entrant,
a61af66fc99e Initial load
duke
parents:
diff changeset
1321 NULL, "assert_null");
a61af66fc99e Initial load
duke
parents:
diff changeset
1322 } else {
332
c792b641b8bd 6746907: Improve implicit null check generation
kvn
parents: 196
diff changeset
1323 replace_in_map(value, zerocon(type));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1324 builtin_throw(reason);
a61af66fc99e Initial load
duke
parents:
diff changeset
1325 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1326 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1327
a61af66fc99e Initial load
duke
parents:
diff changeset
1328 // Must throw exception, fall-thru not possible?
a61af66fc99e Initial load
duke
parents:
diff changeset
1329 if (stopped()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1330 return top(); // No result
a61af66fc99e Initial load
duke
parents:
diff changeset
1331 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1332
a61af66fc99e Initial load
duke
parents:
diff changeset
1333 if (assert_null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1334 // Cast obj to null on this path.
a61af66fc99e Initial load
duke
parents:
diff changeset
1335 replace_in_map(value, zerocon(type));
a61af66fc99e Initial load
duke
parents:
diff changeset
1336 return zerocon(type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1337 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1338
a61af66fc99e Initial load
duke
parents:
diff changeset
1339 // Cast obj to not-null on this path, if there is no null_control.
a61af66fc99e Initial load
duke
parents:
diff changeset
1340 // (If there is a null_control, a non-null value may come back to haunt us.)
a61af66fc99e Initial load
duke
parents:
diff changeset
1341 if (type == T_OBJECT) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1342 Node* cast = cast_not_null(value, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
1343 if (null_control == NULL || (*null_control) == top())
a61af66fc99e Initial load
duke
parents:
diff changeset
1344 replace_in_map(value, cast);
a61af66fc99e Initial load
duke
parents:
diff changeset
1345 value = cast;
a61af66fc99e Initial load
duke
parents:
diff changeset
1346 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1347
a61af66fc99e Initial load
duke
parents:
diff changeset
1348 return value;
a61af66fc99e Initial load
duke
parents:
diff changeset
1349 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1350
a61af66fc99e Initial load
duke
parents:
diff changeset
1351
a61af66fc99e Initial load
duke
parents:
diff changeset
1352 //------------------------------cast_not_null----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1353 // Cast obj to not-null on this path
a61af66fc99e Initial load
duke
parents:
diff changeset
1354 Node* GraphKit::cast_not_null(Node* obj, bool do_replace_in_map) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1355 const Type *t = _gvn.type(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
1356 const Type *t_not_null = t->join(TypePtr::NOTNULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1357 // Object is already not-null?
a61af66fc99e Initial load
duke
parents:
diff changeset
1358 if( t == t_not_null ) return obj;
a61af66fc99e Initial load
duke
parents:
diff changeset
1359
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
1360 Node *cast = new (C) CastPPNode(obj,t_not_null);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1361 cast->init_req(0, control());
a61af66fc99e Initial load
duke
parents:
diff changeset
1362 cast = _gvn.transform( cast );
a61af66fc99e Initial load
duke
parents:
diff changeset
1363
a61af66fc99e Initial load
duke
parents:
diff changeset
1364 // Scan for instances of 'obj' in the current JVM mapping.
a61af66fc99e Initial load
duke
parents:
diff changeset
1365 // These instances are known to be not-null after the test.
a61af66fc99e Initial load
duke
parents:
diff changeset
1366 if (do_replace_in_map)
a61af66fc99e Initial load
duke
parents:
diff changeset
1367 replace_in_map(obj, cast);
a61af66fc99e Initial load
duke
parents:
diff changeset
1368
a61af66fc99e Initial load
duke
parents:
diff changeset
1369 return cast; // Return casted value
a61af66fc99e Initial load
duke
parents:
diff changeset
1370 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1371
a61af66fc99e Initial load
duke
parents:
diff changeset
1372
a61af66fc99e Initial load
duke
parents:
diff changeset
1373 //--------------------------replace_in_map-------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1374 void GraphKit::replace_in_map(Node* old, Node* neww) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1375 this->map()->replace_edge(old, neww);
a61af66fc99e Initial load
duke
parents:
diff changeset
1376
a61af66fc99e Initial load
duke
parents:
diff changeset
1377 // Note: This operation potentially replaces any edge
a61af66fc99e Initial load
duke
parents:
diff changeset
1378 // on the map. This includes locals, stack, and monitors
a61af66fc99e Initial load
duke
parents:
diff changeset
1379 // of the current (innermost) JVM state.
a61af66fc99e Initial load
duke
parents:
diff changeset
1380
a61af66fc99e Initial load
duke
parents:
diff changeset
1381 // We can consider replacing in caller maps.
a61af66fc99e Initial load
duke
parents:
diff changeset
1382 // The idea would be that an inlined function's null checks
a61af66fc99e Initial load
duke
parents:
diff changeset
1383 // can be shared with the entire inlining tree.
a61af66fc99e Initial load
duke
parents:
diff changeset
1384 // The expense of doing this is that the PreserveJVMState class
a61af66fc99e Initial load
duke
parents:
diff changeset
1385 // would have to preserve caller states too, with a deep copy.
a61af66fc99e Initial load
duke
parents:
diff changeset
1386 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1387
a61af66fc99e Initial load
duke
parents:
diff changeset
1388
a61af66fc99e Initial load
duke
parents:
diff changeset
1389 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
1390 //--------------------------------memory---------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1391 Node* GraphKit::memory(uint alias_idx) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1392 MergeMemNode* mem = merged_memory();
a61af66fc99e Initial load
duke
parents:
diff changeset
1393 Node* p = mem->memory_at(alias_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1394 _gvn.set_type(p, Type::MEMORY); // must be mapped
a61af66fc99e Initial load
duke
parents:
diff changeset
1395 return p;
a61af66fc99e Initial load
duke
parents:
diff changeset
1396 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1397
a61af66fc99e Initial load
duke
parents:
diff changeset
1398 //-----------------------------reset_memory------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1399 Node* GraphKit::reset_memory() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1400 Node* mem = map()->memory();
a61af66fc99e Initial load
duke
parents:
diff changeset
1401 // do not use this node for any more parsing!
a61af66fc99e Initial load
duke
parents:
diff changeset
1402 debug_only( map()->set_memory((Node*)NULL) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1403 return _gvn.transform( mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
1404 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1405
a61af66fc99e Initial load
duke
parents:
diff changeset
1406 //------------------------------set_all_memory---------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1407 void GraphKit::set_all_memory(Node* newmem) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1408 Node* mergemem = MergeMemNode::make(C, newmem);
a61af66fc99e Initial load
duke
parents:
diff changeset
1409 gvn().set_type_bottom(mergemem);
a61af66fc99e Initial load
duke
parents:
diff changeset
1410 map()->set_memory(mergemem);
a61af66fc99e Initial load
duke
parents:
diff changeset
1411 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1412
a61af66fc99e Initial load
duke
parents:
diff changeset
1413 //------------------------------set_all_memory_call----------------------------
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1414 void GraphKit::set_all_memory_call(Node* call, bool separate_io_proj) {
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
1415 Node* newmem = _gvn.transform( new (C) ProjNode(call, TypeFunc::Memory, separate_io_proj) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1416 set_all_memory(newmem);
a61af66fc99e Initial load
duke
parents:
diff changeset
1417 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1418
a61af66fc99e Initial load
duke
parents:
diff changeset
1419 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
1420 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1421 // parser factory methods for MemNodes
a61af66fc99e Initial load
duke
parents:
diff changeset
1422 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1423 // These are layered on top of the factory methods in LoadNode and StoreNode,
a61af66fc99e Initial load
duke
parents:
diff changeset
1424 // and integrate with the parser's memory state and _gvn engine.
a61af66fc99e Initial load
duke
parents:
diff changeset
1425 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1426
a61af66fc99e Initial load
duke
parents:
diff changeset
1427 // factory methods in "int adr_idx"
a61af66fc99e Initial load
duke
parents:
diff changeset
1428 Node* GraphKit::make_load(Node* ctl, Node* adr, const Type* t, BasicType bt,
a61af66fc99e Initial load
duke
parents:
diff changeset
1429 int adr_idx,
a61af66fc99e Initial load
duke
parents:
diff changeset
1430 bool require_atomic_access) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1431 assert(adr_idx != Compile::AliasIdxTop, "use other make_load factory" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1432 const TypePtr* adr_type = NULL; // debug-mode-only argument
a61af66fc99e Initial load
duke
parents:
diff changeset
1433 debug_only(adr_type = C->get_adr_type(adr_idx));
a61af66fc99e Initial load
duke
parents:
diff changeset
1434 Node* mem = memory(adr_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1435 Node* ld;
a61af66fc99e Initial load
duke
parents:
diff changeset
1436 if (require_atomic_access && bt == T_LONG) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1437 ld = LoadLNode::make_atomic(C, ctl, mem, adr, adr_type, t);
a61af66fc99e Initial load
duke
parents:
diff changeset
1438 } else {
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 74
diff changeset
1439 ld = LoadNode::make(_gvn, ctl, mem, adr, adr_type, t, bt);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1440 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1441 return _gvn.transform(ld);
a61af66fc99e Initial load
duke
parents:
diff changeset
1442 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1443
a61af66fc99e Initial load
duke
parents:
diff changeset
1444 Node* GraphKit::store_to_memory(Node* ctl, Node* adr, Node *val, BasicType bt,
a61af66fc99e Initial load
duke
parents:
diff changeset
1445 int adr_idx,
a61af66fc99e Initial load
duke
parents:
diff changeset
1446 bool require_atomic_access) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1447 assert(adr_idx != Compile::AliasIdxTop, "use other store_to_memory factory" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1448 const TypePtr* adr_type = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1449 debug_only(adr_type = C->get_adr_type(adr_idx));
a61af66fc99e Initial load
duke
parents:
diff changeset
1450 Node *mem = memory(adr_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1451 Node* st;
a61af66fc99e Initial load
duke
parents:
diff changeset
1452 if (require_atomic_access && bt == T_LONG) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1453 st = StoreLNode::make_atomic(C, ctl, mem, adr, adr_type, val);
a61af66fc99e Initial load
duke
parents:
diff changeset
1454 } else {
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 74
diff changeset
1455 st = StoreNode::make(_gvn, ctl, mem, adr, adr_type, val, bt);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1456 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1457 st = _gvn.transform(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
1458 set_memory(st, adr_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1459 // Back-to-back stores can only remove intermediate store with DU info
a61af66fc99e Initial load
duke
parents:
diff changeset
1460 // so push on worklist for optimizer.
a61af66fc99e Initial load
duke
parents:
diff changeset
1461 if (mem->req() > MemNode::Address && adr == mem->in(MemNode::Address))
a61af66fc99e Initial load
duke
parents:
diff changeset
1462 record_for_igvn(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
1463
a61af66fc99e Initial load
duke
parents:
diff changeset
1464 return st;
a61af66fc99e Initial load
duke
parents:
diff changeset
1465 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1466
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
1467
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
1468 void GraphKit::pre_barrier(bool do_load,
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
1469 Node* ctl,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1470 Node* obj,
a61af66fc99e Initial load
duke
parents:
diff changeset
1471 Node* adr,
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
1472 uint adr_idx,
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
1473 Node* val,
825
8f5825e0aeaa 6818666: G1: Type lost in g1 pre-barrier
never
parents: 780
diff changeset
1474 const TypeOopPtr* val_type,
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
1475 Node* pre_val,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1476 BasicType bt) {
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
1477
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1478 BarrierSet* bs = Universe::heap()->barrier_set();
a61af66fc99e Initial load
duke
parents:
diff changeset
1479 set_control(ctl);
a61af66fc99e Initial load
duke
parents:
diff changeset
1480 switch (bs->kind()) {
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
1481 case BarrierSet::G1SATBCT:
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
1482 case BarrierSet::G1SATBCTLogging:
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
1483 g1_write_barrier_pre(do_load, obj, adr, adr_idx, val, val_type, pre_val, bt);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
1484 break;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1485
a61af66fc99e Initial load
duke
parents:
diff changeset
1486 case BarrierSet::CardTableModRef:
a61af66fc99e Initial load
duke
parents:
diff changeset
1487 case BarrierSet::CardTableExtension:
a61af66fc99e Initial load
duke
parents:
diff changeset
1488 case BarrierSet::ModRef:
a61af66fc99e Initial load
duke
parents:
diff changeset
1489 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1490
a61af66fc99e Initial load
duke
parents:
diff changeset
1491 case BarrierSet::Other:
a61af66fc99e Initial load
duke
parents:
diff changeset
1492 default :
a61af66fc99e Initial load
duke
parents:
diff changeset
1493 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1494
a61af66fc99e Initial load
duke
parents:
diff changeset
1495 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1496 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1497
a61af66fc99e Initial load
duke
parents:
diff changeset
1498 void GraphKit::post_barrier(Node* ctl,
a61af66fc99e Initial load
duke
parents:
diff changeset
1499 Node* store,
a61af66fc99e Initial load
duke
parents:
diff changeset
1500 Node* obj,
a61af66fc99e Initial load
duke
parents:
diff changeset
1501 Node* adr,
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
1502 uint adr_idx,
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
1503 Node* val,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1504 BasicType bt,
a61af66fc99e Initial load
duke
parents:
diff changeset
1505 bool use_precise) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1506 BarrierSet* bs = Universe::heap()->barrier_set();
a61af66fc99e Initial load
duke
parents:
diff changeset
1507 set_control(ctl);
a61af66fc99e Initial load
duke
parents:
diff changeset
1508 switch (bs->kind()) {
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
1509 case BarrierSet::G1SATBCT:
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
1510 case BarrierSet::G1SATBCTLogging:
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
1511 g1_write_barrier_post(store, obj, adr, adr_idx, val, bt, use_precise);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
1512 break;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1513
a61af66fc99e Initial load
duke
parents:
diff changeset
1514 case BarrierSet::CardTableModRef:
a61af66fc99e Initial load
duke
parents:
diff changeset
1515 case BarrierSet::CardTableExtension:
985
685e959d09ea 6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents: 955
diff changeset
1516 write_barrier_post(store, obj, adr, adr_idx, val, use_precise);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1517 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1518
a61af66fc99e Initial load
duke
parents:
diff changeset
1519 case BarrierSet::ModRef:
a61af66fc99e Initial load
duke
parents:
diff changeset
1520 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1521
a61af66fc99e Initial load
duke
parents:
diff changeset
1522 case BarrierSet::Other:
a61af66fc99e Initial load
duke
parents:
diff changeset
1523 default :
a61af66fc99e Initial load
duke
parents:
diff changeset
1524 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1525
a61af66fc99e Initial load
duke
parents:
diff changeset
1526 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1527 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1528
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
1529 Node* GraphKit::store_oop(Node* ctl,
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
1530 Node* obj,
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
1531 Node* adr,
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
1532 const TypePtr* adr_type,
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
1533 Node* val,
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
1534 const TypeOopPtr* val_type,
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
1535 BasicType bt,
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
1536 bool use_precise) {
4894
b9bc6cae88f2 7143491: G1 C2 CTW: assert(p2x->outcnt() == 2) failed: expects 2 users: Xor and URShift nodes
kvn
parents: 4763
diff changeset
1537 // Transformation of a value which could be NULL pointer (CastPP #NULL)
b9bc6cae88f2 7143491: G1 C2 CTW: assert(p2x->outcnt() == 2) failed: expects 2 users: Xor and URShift nodes
kvn
parents: 4763
diff changeset
1538 // could be delayed during Parse (for example, in adjust_map_after_if()).
b9bc6cae88f2 7143491: G1 C2 CTW: assert(p2x->outcnt() == 2) failed: expects 2 users: Xor and URShift nodes
kvn
parents: 4763
diff changeset
1539 // Execute transformation here to avoid barrier generation in such case.
b9bc6cae88f2 7143491: G1 C2 CTW: assert(p2x->outcnt() == 2) failed: expects 2 users: Xor and URShift nodes
kvn
parents: 4763
diff changeset
1540 if (_gvn.type(val) == TypePtr::NULL_PTR)
b9bc6cae88f2 7143491: G1 C2 CTW: assert(p2x->outcnt() == 2) failed: expects 2 users: Xor and URShift nodes
kvn
parents: 4763
diff changeset
1541 val = _gvn.makecon(TypePtr::NULL_PTR);
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
1542
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
1543 set_control(ctl);
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
1544 if (stopped()) return top(); // Dead path ?
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
1545
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
1546 assert(bt == T_OBJECT, "sanity");
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
1547 assert(val != NULL, "not dead path");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1548 uint adr_idx = C->get_alias_index(adr_type);
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
1549 assert(adr_idx != Compile::AliasIdxTop, "use other store_to_memory factory" );
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
1550
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
1551 pre_barrier(true /* do_load */,
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
1552 control(), obj, adr, adr_idx, val, val_type,
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
1553 NULL /* pre_val */,
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
1554 bt);
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
1555
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
1556 Node* store = store_to_memory(control(), adr, val, bt, adr_idx);
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
1557 post_barrier(control(), store, obj, adr, adr_idx, val, bt, use_precise);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1558 return store;
a61af66fc99e Initial load
duke
parents:
diff changeset
1559 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1560
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
1561 // Could be an array or object we don't know at compile time (unsafe ref.)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1562 Node* GraphKit::store_oop_to_unknown(Node* ctl,
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
1563 Node* obj, // containing obj
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
1564 Node* adr, // actual adress to store val at
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
1565 const TypePtr* adr_type,
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
1566 Node* val,
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
1567 BasicType bt) {
825
8f5825e0aeaa 6818666: G1: Type lost in g1 pre-barrier
never
parents: 780
diff changeset
1568 Compile::AliasType* at = C->alias_type(adr_type);
8f5825e0aeaa 6818666: G1: Type lost in g1 pre-barrier
never
parents: 780
diff changeset
1569 const TypeOopPtr* val_type = NULL;
8f5825e0aeaa 6818666: G1: Type lost in g1 pre-barrier
never
parents: 780
diff changeset
1570 if (adr_type->isa_instptr()) {
8f5825e0aeaa 6818666: G1: Type lost in g1 pre-barrier
never
parents: 780
diff changeset
1571 if (at->field() != NULL) {
8f5825e0aeaa 6818666: G1: Type lost in g1 pre-barrier
never
parents: 780
diff changeset
1572 // known field. This code is a copy of the do_put_xxx logic.
8f5825e0aeaa 6818666: G1: Type lost in g1 pre-barrier
never
parents: 780
diff changeset
1573 ciField* field = at->field();
8f5825e0aeaa 6818666: G1: Type lost in g1 pre-barrier
never
parents: 780
diff changeset
1574 if (!field->type()->is_loaded()) {
8f5825e0aeaa 6818666: G1: Type lost in g1 pre-barrier
never
parents: 780
diff changeset
1575 val_type = TypeInstPtr::BOTTOM;
8f5825e0aeaa 6818666: G1: Type lost in g1 pre-barrier
never
parents: 780
diff changeset
1576 } else {
8f5825e0aeaa 6818666: G1: Type lost in g1 pre-barrier
never
parents: 780
diff changeset
1577 val_type = TypeOopPtr::make_from_klass(field->type()->as_klass());
8f5825e0aeaa 6818666: G1: Type lost in g1 pre-barrier
never
parents: 780
diff changeset
1578 }
8f5825e0aeaa 6818666: G1: Type lost in g1 pre-barrier
never
parents: 780
diff changeset
1579 }
8f5825e0aeaa 6818666: G1: Type lost in g1 pre-barrier
never
parents: 780
diff changeset
1580 } else if (adr_type->isa_aryptr()) {
827
bf3489cc0aa0 6856025: assert(_base >= OopPtr && _base <= KlassPtr,"Not a Java pointer")
never
parents: 825
diff changeset
1581 val_type = adr_type->is_aryptr()->elem()->make_oopptr();
825
8f5825e0aeaa 6818666: G1: Type lost in g1 pre-barrier
never
parents: 780
diff changeset
1582 }
8f5825e0aeaa 6818666: G1: Type lost in g1 pre-barrier
never
parents: 780
diff changeset
1583 if (val_type == NULL) {
8f5825e0aeaa 6818666: G1: Type lost in g1 pre-barrier
never
parents: 780
diff changeset
1584 val_type = TypeInstPtr::BOTTOM;
8f5825e0aeaa 6818666: G1: Type lost in g1 pre-barrier
never
parents: 780
diff changeset
1585 }
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
1586 return store_oop(ctl, obj, adr, adr_type, val, val_type, bt, true);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1587 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1588
a61af66fc99e Initial load
duke
parents:
diff changeset
1589
a61af66fc99e Initial load
duke
parents:
diff changeset
1590 //-------------------------array_element_address-------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1591 Node* GraphKit::array_element_address(Node* ary, Node* idx, BasicType elembt,
a61af66fc99e Initial load
duke
parents:
diff changeset
1592 const TypeInt* sizetype) {
29
d5fc211aea19 6633953: type2aelembytes{T_ADDRESS} should be 8 bytes in 64 bit VM
kvn
parents: 23
diff changeset
1593 uint shift = exact_log2(type2aelembytes(elembt));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1594 uint header = arrayOopDesc::base_offset_in_bytes(elembt);
a61af66fc99e Initial load
duke
parents:
diff changeset
1595
a61af66fc99e Initial load
duke
parents:
diff changeset
1596 // short-circuit a common case (saves lots of confusing waste motion)
a61af66fc99e Initial load
duke
parents:
diff changeset
1597 jint idx_con = find_int_con(idx, -1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1598 if (idx_con >= 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1599 intptr_t offset = header + ((intptr_t)idx_con << shift);
a61af66fc99e Initial load
duke
parents:
diff changeset
1600 return basic_plus_adr(ary, offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
1601 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1602
a61af66fc99e Initial load
duke
parents:
diff changeset
1603 // must be correct type for alignment purposes
a61af66fc99e Initial load
duke
parents:
diff changeset
1604 Node* base = basic_plus_adr(ary, header);
a61af66fc99e Initial load
duke
parents:
diff changeset
1605 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
1606 // The scaled index operand to AddP must be a clean 64-bit value.
a61af66fc99e Initial load
duke
parents:
diff changeset
1607 // Java allows a 32-bit int to be incremented to a negative
a61af66fc99e Initial load
duke
parents:
diff changeset
1608 // value, which appears in a 64-bit register as a large
a61af66fc99e Initial load
duke
parents:
diff changeset
1609 // positive number. Using that large positive number as an
a61af66fc99e Initial load
duke
parents:
diff changeset
1610 // operand in pointer arithmetic has bad consequences.
a61af66fc99e Initial load
duke
parents:
diff changeset
1611 // On the other hand, 32-bit overflow is rare, and the possibility
a61af66fc99e Initial load
duke
parents:
diff changeset
1612 // can often be excluded, if we annotate the ConvI2L node with
a61af66fc99e Initial load
duke
parents:
diff changeset
1613 // a type assertion that its value is known to be a small positive
a61af66fc99e Initial load
duke
parents:
diff changeset
1614 // number. (The prior range check has ensured this.)
a61af66fc99e Initial load
duke
parents:
diff changeset
1615 // This assertion is used by ConvI2LNode::Ideal.
a61af66fc99e Initial load
duke
parents:
diff changeset
1616 int index_max = max_jint - 1; // array size is max_jint, index is one less
a61af66fc99e Initial load
duke
parents:
diff changeset
1617 if (sizetype != NULL) index_max = sizetype->_hi - 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1618 const TypeLong* lidxtype = TypeLong::make(CONST64(0), index_max, Type::WidenMax);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
1619 idx = _gvn.transform( new (C) ConvI2LNode(idx, lidxtype) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1620 #endif
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
1621 Node* scale = _gvn.transform( new (C) LShiftXNode(idx, intcon(shift)) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1622 return basic_plus_adr(ary, base, scale);
a61af66fc99e Initial load
duke
parents:
diff changeset
1623 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1624
a61af66fc99e Initial load
duke
parents:
diff changeset
1625 //-------------------------load_array_element-------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1626 Node* GraphKit::load_array_element(Node* ctl, Node* ary, Node* idx, const TypeAryPtr* arytype) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1627 const Type* elemtype = arytype->elem();
a61af66fc99e Initial load
duke
parents:
diff changeset
1628 BasicType elembt = elemtype->array_element_basic_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
1629 Node* adr = array_element_address(ary, idx, elembt, arytype->size());
a61af66fc99e Initial load
duke
parents:
diff changeset
1630 Node* ld = make_load(ctl, adr, elemtype, elembt, arytype);
a61af66fc99e Initial load
duke
parents:
diff changeset
1631 return ld;
a61af66fc99e Initial load
duke
parents:
diff changeset
1632 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1633
a61af66fc99e Initial load
duke
parents:
diff changeset
1634 //-------------------------set_arguments_for_java_call-------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1635 // Arguments (pre-popped from the stack) are taken from the JVMS.
a61af66fc99e Initial load
duke
parents:
diff changeset
1636 void GraphKit::set_arguments_for_java_call(CallJavaNode* call) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1637 // Add the call arguments:
a61af66fc99e Initial load
duke
parents:
diff changeset
1638 uint nargs = call->method()->arg_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
1639 for (uint i = 0; i < nargs; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1640 Node* arg = argument(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1641 call->init_req(i + TypeFunc::Parms, arg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1642 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1643 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1644
a61af66fc99e Initial load
duke
parents:
diff changeset
1645 //---------------------------set_edges_for_java_call---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1646 // Connect a newly created call into the current JVMS.
a61af66fc99e Initial load
duke
parents:
diff changeset
1647 // A return value node (if any) is returned from set_edges_for_java_call.
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1648 void GraphKit::set_edges_for_java_call(CallJavaNode* call, bool must_throw, bool separate_io_proj) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1649
a61af66fc99e Initial load
duke
parents:
diff changeset
1650 // Add the predefined inputs:
a61af66fc99e Initial load
duke
parents:
diff changeset
1651 call->init_req( TypeFunc::Control, control() );
a61af66fc99e Initial load
duke
parents:
diff changeset
1652 call->init_req( TypeFunc::I_O , i_o() );
a61af66fc99e Initial load
duke
parents:
diff changeset
1653 call->init_req( TypeFunc::Memory , reset_memory() );
a61af66fc99e Initial load
duke
parents:
diff changeset
1654 call->init_req( TypeFunc::FramePtr, frameptr() );
a61af66fc99e Initial load
duke
parents:
diff changeset
1655 call->init_req( TypeFunc::ReturnAdr, top() );
a61af66fc99e Initial load
duke
parents:
diff changeset
1656
a61af66fc99e Initial load
duke
parents:
diff changeset
1657 add_safepoint_edges(call, must_throw);
a61af66fc99e Initial load
duke
parents:
diff changeset
1658
a61af66fc99e Initial load
duke
parents:
diff changeset
1659 Node* xcall = _gvn.transform(call);
a61af66fc99e Initial load
duke
parents:
diff changeset
1660
a61af66fc99e Initial load
duke
parents:
diff changeset
1661 if (xcall == top()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1662 set_control(top());
a61af66fc99e Initial load
duke
parents:
diff changeset
1663 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1664 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1665 assert(xcall == call, "call identity is stable");
a61af66fc99e Initial load
duke
parents:
diff changeset
1666
a61af66fc99e Initial load
duke
parents:
diff changeset
1667 // Re-use the current map to produce the result.
a61af66fc99e Initial load
duke
parents:
diff changeset
1668
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
1669 set_control(_gvn.transform(new (C) ProjNode(call, TypeFunc::Control)));
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
1670 set_i_o( _gvn.transform(new (C) ProjNode(call, TypeFunc::I_O , separate_io_proj)));
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1671 set_all_memory_call(xcall, separate_io_proj);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1672
a61af66fc99e Initial load
duke
parents:
diff changeset
1673 //return xcall; // no need, caller already has it
a61af66fc99e Initial load
duke
parents:
diff changeset
1674 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1675
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1676 Node* GraphKit::set_results_for_java_call(CallJavaNode* call, bool separate_io_proj) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1677 if (stopped()) return top(); // maybe the call folded up?
a61af66fc99e Initial load
duke
parents:
diff changeset
1678
a61af66fc99e Initial load
duke
parents:
diff changeset
1679 // Capture the return value, if any.
a61af66fc99e Initial load
duke
parents:
diff changeset
1680 Node* ret;
a61af66fc99e Initial load
duke
parents:
diff changeset
1681 if (call->method() == NULL ||
a61af66fc99e Initial load
duke
parents:
diff changeset
1682 call->method()->return_type()->basic_type() == T_VOID)
a61af66fc99e Initial load
duke
parents:
diff changeset
1683 ret = top();
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
1684 else ret = _gvn.transform(new (C) ProjNode(call, TypeFunc::Parms));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1685
a61af66fc99e Initial load
duke
parents:
diff changeset
1686 // Note: Since any out-of-line call can produce an exception,
a61af66fc99e Initial load
duke
parents:
diff changeset
1687 // we always insert an I_O projection from the call into the result.
a61af66fc99e Initial load
duke
parents:
diff changeset
1688
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1689 make_slow_call_ex(call, env()->Throwable_klass(), separate_io_proj);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1690
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1691 if (separate_io_proj) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1692 // The caller requested separate projections be used by the fall
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1693 // through and exceptional paths, so replace the projections for
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1694 // the fall through path.
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
1695 set_i_o(_gvn.transform( new (C) ProjNode(call, TypeFunc::I_O) ));
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
1696 set_all_memory(_gvn.transform( new (C) ProjNode(call, TypeFunc::Memory) ));
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1697 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1698 return ret;
a61af66fc99e Initial load
duke
parents:
diff changeset
1699 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1700
a61af66fc99e Initial load
duke
parents:
diff changeset
1701 //--------------------set_predefined_input_for_runtime_call--------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1702 // Reading and setting the memory state is way conservative here.
a61af66fc99e Initial load
duke
parents:
diff changeset
1703 // The real problem is that I am not doing real Type analysis on memory,
a61af66fc99e Initial load
duke
parents:
diff changeset
1704 // so I cannot distinguish card mark stores from other stores. Across a GC
a61af66fc99e Initial load
duke
parents:
diff changeset
1705 // point the Store Barrier and the card mark memory has to agree. I cannot
a61af66fc99e Initial load
duke
parents:
diff changeset
1706 // have a card mark store and its barrier split across the GC point from
a61af66fc99e Initial load
duke
parents:
diff changeset
1707 // either above or below. Here I get that to happen by reading ALL of memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
1708 // A better answer would be to separate out card marks from other memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
1709 // For now, return the input memory state, so that it can be reused
a61af66fc99e Initial load
duke
parents:
diff changeset
1710 // after the call, if this call has restricted memory effects.
a61af66fc99e Initial load
duke
parents:
diff changeset
1711 Node* GraphKit::set_predefined_input_for_runtime_call(SafePointNode* call) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1712 // Set fixed predefined input arguments
a61af66fc99e Initial load
duke
parents:
diff changeset
1713 Node* memory = reset_memory();
a61af66fc99e Initial load
duke
parents:
diff changeset
1714 call->init_req( TypeFunc::Control, control() );
a61af66fc99e Initial load
duke
parents:
diff changeset
1715 call->init_req( TypeFunc::I_O, top() ); // does no i/o
a61af66fc99e Initial load
duke
parents:
diff changeset
1716 call->init_req( TypeFunc::Memory, memory ); // may gc ptrs
a61af66fc99e Initial load
duke
parents:
diff changeset
1717 call->init_req( TypeFunc::FramePtr, frameptr() );
a61af66fc99e Initial load
duke
parents:
diff changeset
1718 call->init_req( TypeFunc::ReturnAdr, top() );
a61af66fc99e Initial load
duke
parents:
diff changeset
1719 return memory;
a61af66fc99e Initial load
duke
parents:
diff changeset
1720 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1721
a61af66fc99e Initial load
duke
parents:
diff changeset
1722 //-------------------set_predefined_output_for_runtime_call--------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1723 // Set control and memory (not i_o) from the call.
a61af66fc99e Initial load
duke
parents:
diff changeset
1724 // If keep_mem is not NULL, use it for the output state,
a61af66fc99e Initial load
duke
parents:
diff changeset
1725 // except for the RawPtr output of the call, if hook_mem is TypeRawPtr::BOTTOM.
a61af66fc99e Initial load
duke
parents:
diff changeset
1726 // If hook_mem is NULL, this call produces no memory effects at all.
a61af66fc99e Initial load
duke
parents:
diff changeset
1727 // If hook_mem is a Java-visible memory slice (such as arraycopy operands),
a61af66fc99e Initial load
duke
parents:
diff changeset
1728 // then only that memory slice is taken from the call.
a61af66fc99e Initial load
duke
parents:
diff changeset
1729 // In the last case, we must put an appropriate memory barrier before
a61af66fc99e Initial load
duke
parents:
diff changeset
1730 // the call, so as to create the correct anti-dependencies on loads
a61af66fc99e Initial load
duke
parents:
diff changeset
1731 // preceding the call.
a61af66fc99e Initial load
duke
parents:
diff changeset
1732 void GraphKit::set_predefined_output_for_runtime_call(Node* call,
a61af66fc99e Initial load
duke
parents:
diff changeset
1733 Node* keep_mem,
a61af66fc99e Initial load
duke
parents:
diff changeset
1734 const TypePtr* hook_mem) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1735 // no i/o
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
1736 set_control(_gvn.transform( new (C) ProjNode(call,TypeFunc::Control) ));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1737 if (keep_mem) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1738 // First clone the existing memory state
a61af66fc99e Initial load
duke
parents:
diff changeset
1739 set_all_memory(keep_mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
1740 if (hook_mem != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1741 // Make memory for the call
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
1742 Node* mem = _gvn.transform( new (C) ProjNode(call, TypeFunc::Memory) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1743 // Set the RawPtr memory state only. This covers all the heap top/GC stuff
a61af66fc99e Initial load
duke
parents:
diff changeset
1744 // We also use hook_mem to extract specific effects from arraycopy stubs.
a61af66fc99e Initial load
duke
parents:
diff changeset
1745 set_memory(mem, hook_mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
1746 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1747 // ...else the call has NO memory effects.
a61af66fc99e Initial load
duke
parents:
diff changeset
1748
a61af66fc99e Initial load
duke
parents:
diff changeset
1749 // Make sure the call advertises its memory effects precisely.
a61af66fc99e Initial load
duke
parents:
diff changeset
1750 // This lets us build accurate anti-dependences in gcm.cpp.
a61af66fc99e Initial load
duke
parents:
diff changeset
1751 assert(C->alias_type(call->adr_type()) == C->alias_type(hook_mem),
a61af66fc99e Initial load
duke
parents:
diff changeset
1752 "call node must be constructed correctly");
a61af66fc99e Initial load
duke
parents:
diff changeset
1753 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1754 assert(hook_mem == NULL, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
1755 // This is not a "slow path" call; all memory comes from the call.
a61af66fc99e Initial load
duke
parents:
diff changeset
1756 set_all_memory_call(call);
a61af66fc99e Initial load
duke
parents:
diff changeset
1757 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1758 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1759
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1760
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1761 // Replace the call with the current state of the kit.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1762 void GraphKit::replace_call(CallNode* call, Node* result) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1763 JVMState* ejvms = NULL;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1764 if (has_exceptions()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1765 ejvms = transfer_exceptions_into_jvms();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1766 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1767
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1768 SafePointNode* final_state = stop();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1769
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1770 // Find all the needed outputs of this call
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1771 CallProjections callprojs;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1772 call->extract_projections(&callprojs, true);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1773
7421
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1774 Node* init_mem = call->in(TypeFunc::Memory);
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1775 Node* final_mem = final_state->in(TypeFunc::Memory);
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1776 Node* final_ctl = final_state->in(TypeFunc::Control);
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1777 Node* final_io = final_state->in(TypeFunc::I_O);
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1778
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1779 // Replace all the old call edges with the edges from the inlining result
7421
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1780 if (callprojs.fallthrough_catchproj != NULL) {
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1781 C->gvn_replace_by(callprojs.fallthrough_catchproj, final_ctl);
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1782 }
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1783 if (callprojs.fallthrough_memproj != NULL) {
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1784 C->gvn_replace_by(callprojs.fallthrough_memproj, final_mem);
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1785 }
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1786 if (callprojs.fallthrough_ioproj != NULL) {
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1787 C->gvn_replace_by(callprojs.fallthrough_ioproj, final_io);
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1788 }
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1789
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1790 // Replace the result with the new result if it exists and is used
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1791 if (callprojs.resproj != NULL && result != NULL) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1792 C->gvn_replace_by(callprojs.resproj, result);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1793 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1794
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1795 if (ejvms == NULL) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1796 // No exception edges to simply kill off those paths
7473
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7428
diff changeset
1797 if (callprojs.catchall_catchproj != NULL) {
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7428
diff changeset
1798 C->gvn_replace_by(callprojs.catchall_catchproj, C->top());
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7428
diff changeset
1799 }
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7428
diff changeset
1800 if (callprojs.catchall_memproj != NULL) {
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7428
diff changeset
1801 C->gvn_replace_by(callprojs.catchall_memproj, C->top());
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7428
diff changeset
1802 }
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7428
diff changeset
1803 if (callprojs.catchall_ioproj != NULL) {
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7428
diff changeset
1804 C->gvn_replace_by(callprojs.catchall_ioproj, C->top());
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7428
diff changeset
1805 }
1099
c5d3d979ae27 6908167: jbb2005, OptimizeStringConcat causes assert in EA
never
parents: 1080
diff changeset
1806 // Replace the old exception object with top
c5d3d979ae27 6908167: jbb2005, OptimizeStringConcat causes assert in EA
never
parents: 1080
diff changeset
1807 if (callprojs.exobj != NULL) {
c5d3d979ae27 6908167: jbb2005, OptimizeStringConcat causes assert in EA
never
parents: 1080
diff changeset
1808 C->gvn_replace_by(callprojs.exobj, C->top());
c5d3d979ae27 6908167: jbb2005, OptimizeStringConcat causes assert in EA
never
parents: 1080
diff changeset
1809 }
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1810 } else {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1811 GraphKit ekit(ejvms);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1812
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1813 // Load my combined exception state into the kit, with all phis transformed:
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1814 SafePointNode* ex_map = ekit.combine_and_pop_all_exception_states();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1815
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1816 Node* ex_oop = ekit.use_exception_state(ex_map);
7473
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7428
diff changeset
1817 if (callprojs.catchall_catchproj != NULL) {
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7428
diff changeset
1818 C->gvn_replace_by(callprojs.catchall_catchproj, ekit.control());
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7428
diff changeset
1819 }
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7428
diff changeset
1820 if (callprojs.catchall_memproj != NULL) {
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7428
diff changeset
1821 C->gvn_replace_by(callprojs.catchall_memproj, ekit.reset_memory());
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7428
diff changeset
1822 }
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7428
diff changeset
1823 if (callprojs.catchall_ioproj != NULL) {
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7428
diff changeset
1824 C->gvn_replace_by(callprojs.catchall_ioproj, ekit.i_o());
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7428
diff changeset
1825 }
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1826
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1827 // Replace the old exception object with the newly created one
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1828 if (callprojs.exobj != NULL) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1829 C->gvn_replace_by(callprojs.exobj, ex_oop);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1830 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1831 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1832
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1833 // Disconnect the call from the graph
7196
2aff40cb4703 7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents: 7194
diff changeset
1834 call->disconnect_inputs(NULL, C);
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1835 C->gvn_replace_by(call, C->top());
1786
f9883ee8ce39 6965815: OptimizeStringConcat: assert(!q->is_MergeMem()) failed with specjbb2000
never
parents: 1748
diff changeset
1836
f9883ee8ce39 6965815: OptimizeStringConcat: assert(!q->is_MergeMem()) failed with specjbb2000
never
parents: 1748
diff changeset
1837 // Clean up any MergeMems that feed other MergeMems since the
f9883ee8ce39 6965815: OptimizeStringConcat: assert(!q->is_MergeMem()) failed with specjbb2000
never
parents: 1748
diff changeset
1838 // optimizer doesn't like that.
f9883ee8ce39 6965815: OptimizeStringConcat: assert(!q->is_MergeMem()) failed with specjbb2000
never
parents: 1748
diff changeset
1839 if (final_mem->is_MergeMem()) {
f9883ee8ce39 6965815: OptimizeStringConcat: assert(!q->is_MergeMem()) failed with specjbb2000
never
parents: 1748
diff changeset
1840 Node_List wl;
f9883ee8ce39 6965815: OptimizeStringConcat: assert(!q->is_MergeMem()) failed with specjbb2000
never
parents: 1748
diff changeset
1841 for (SimpleDUIterator i(final_mem); i.has_next(); i.next()) {
f9883ee8ce39 6965815: OptimizeStringConcat: assert(!q->is_MergeMem()) failed with specjbb2000
never
parents: 1748
diff changeset
1842 Node* m = i.get();
f9883ee8ce39 6965815: OptimizeStringConcat: assert(!q->is_MergeMem()) failed with specjbb2000
never
parents: 1748
diff changeset
1843 if (m->is_MergeMem() && !wl.contains(m)) {
f9883ee8ce39 6965815: OptimizeStringConcat: assert(!q->is_MergeMem()) failed with specjbb2000
never
parents: 1748
diff changeset
1844 wl.push(m);
f9883ee8ce39 6965815: OptimizeStringConcat: assert(!q->is_MergeMem()) failed with specjbb2000
never
parents: 1748
diff changeset
1845 }
f9883ee8ce39 6965815: OptimizeStringConcat: assert(!q->is_MergeMem()) failed with specjbb2000
never
parents: 1748
diff changeset
1846 }
f9883ee8ce39 6965815: OptimizeStringConcat: assert(!q->is_MergeMem()) failed with specjbb2000
never
parents: 1748
diff changeset
1847 while (wl.size() > 0) {
f9883ee8ce39 6965815: OptimizeStringConcat: assert(!q->is_MergeMem()) failed with specjbb2000
never
parents: 1748
diff changeset
1848 _gvn.transform(wl.pop());
f9883ee8ce39 6965815: OptimizeStringConcat: assert(!q->is_MergeMem()) failed with specjbb2000
never
parents: 1748
diff changeset
1849 }
f9883ee8ce39 6965815: OptimizeStringConcat: assert(!q->is_MergeMem()) failed with specjbb2000
never
parents: 1748
diff changeset
1850 }
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1851 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1852
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1853
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1854 //------------------------------increment_counter------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1855 // for statistics: increment a VM counter by 1
a61af66fc99e Initial load
duke
parents:
diff changeset
1856
a61af66fc99e Initial load
duke
parents:
diff changeset
1857 void GraphKit::increment_counter(address counter_addr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1858 Node* adr1 = makecon(TypeRawPtr::make(counter_addr));
a61af66fc99e Initial load
duke
parents:
diff changeset
1859 increment_counter(adr1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1860 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1861
a61af66fc99e Initial load
duke
parents:
diff changeset
1862 void GraphKit::increment_counter(Node* counter_addr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1863 int adr_type = Compile::AliasIdxRaw;
1609
4311f23817fd 6959430: Make sure raw loads have control edge
kvn
parents: 1594
diff changeset
1864 Node* ctrl = control();
4311f23817fd 6959430: Make sure raw loads have control edge
kvn
parents: 1594
diff changeset
1865 Node* cnt = make_load(ctrl, counter_addr, TypeInt::INT, T_INT, adr_type);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
1866 Node* incr = _gvn.transform(new (C) AddINode(cnt, _gvn.intcon(1)));
1609
4311f23817fd 6959430: Make sure raw loads have control edge
kvn
parents: 1594
diff changeset
1867 store_to_memory( ctrl, counter_addr, incr, T_INT, adr_type );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1868 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1869
a61af66fc99e Initial load
duke
parents:
diff changeset
1870
a61af66fc99e Initial load
duke
parents:
diff changeset
1871 //------------------------------uncommon_trap----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1872 // Bail out to the interpreter in mid-method. Implemented by calling the
a61af66fc99e Initial load
duke
parents:
diff changeset
1873 // uncommon_trap blob. This helper function inserts a runtime call with the
a61af66fc99e Initial load
duke
parents:
diff changeset
1874 // right debug info.
a61af66fc99e Initial load
duke
parents:
diff changeset
1875 void GraphKit::uncommon_trap(int trap_request,
a61af66fc99e Initial load
duke
parents:
diff changeset
1876 ciKlass* klass, const char* comment,
a61af66fc99e Initial load
duke
parents:
diff changeset
1877 bool must_throw,
a61af66fc99e Initial load
duke
parents:
diff changeset
1878 bool keep_exact_action) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1879 if (failing()) stop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1880 if (stopped()) return; // trap reachable?
a61af66fc99e Initial load
duke
parents:
diff changeset
1881
a61af66fc99e Initial load
duke
parents:
diff changeset
1882 // Note: If ProfileTraps is true, and if a deopt. actually
a61af66fc99e Initial load
duke
parents:
diff changeset
1883 // occurs here, the runtime will make sure an MDO exists. There is
2007
5ddfcf4b079e 7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents: 1972
diff changeset
1884 // no need to call method()->ensure_method_data() at this point.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1885
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
1886 // Set the stack pointer to the right value for reexecution:
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
1887 set_sp(reexecute_sp());
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
1888
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1889 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1890 if (!must_throw) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1891 // Make sure the stack has at least enough depth to execute
a61af66fc99e Initial load
duke
parents:
diff changeset
1892 // the current bytecode.
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
1893 int inputs, ignored_depth;
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
1894 if (compute_stack_effects(inputs, ignored_depth)) {
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
1895 assert(sp() >= inputs, err_msg_res("must have enough JVMS stack to execute %s: sp=%d, inputs=%d",
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
1896 Bytecodes::name(java_bc()), sp(), inputs));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1897 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1898 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1899 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1900
a61af66fc99e Initial load
duke
parents:
diff changeset
1901 Deoptimization::DeoptReason reason = Deoptimization::trap_request_reason(trap_request);
a61af66fc99e Initial load
duke
parents:
diff changeset
1902 Deoptimization::DeoptAction action = Deoptimization::trap_request_action(trap_request);
a61af66fc99e Initial load
duke
parents:
diff changeset
1903
a61af66fc99e Initial load
duke
parents:
diff changeset
1904 switch (action) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1905 case Deoptimization::Action_maybe_recompile:
a61af66fc99e Initial load
duke
parents:
diff changeset
1906 case Deoptimization::Action_reinterpret:
a61af66fc99e Initial load
duke
parents:
diff changeset
1907 // Temporary fix for 6529811 to allow virtual calls to be sure they
a61af66fc99e Initial load
duke
parents:
diff changeset
1908 // get the chance to go from mono->bi->mega
a61af66fc99e Initial load
duke
parents:
diff changeset
1909 if (!keep_exact_action &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1910 Deoptimization::trap_request_index(trap_request) < 0 &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1911 too_many_recompiles(reason)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1912 // This BCI is causing too many recompilations.
a61af66fc99e Initial load
duke
parents:
diff changeset
1913 action = Deoptimization::Action_none;
a61af66fc99e Initial load
duke
parents:
diff changeset
1914 trap_request = Deoptimization::make_trap_request(reason, action);
a61af66fc99e Initial load
duke
parents:
diff changeset
1915 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1916 C->set_trap_can_recompile(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
1917 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1918 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1919 case Deoptimization::Action_make_not_entrant:
a61af66fc99e Initial load
duke
parents:
diff changeset
1920 C->set_trap_can_recompile(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
1921 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1922 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1923 case Deoptimization::Action_none:
a61af66fc99e Initial load
duke
parents:
diff changeset
1924 case Deoptimization::Action_make_not_compilable:
a61af66fc99e Initial load
duke
parents:
diff changeset
1925 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1926 default:
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
1927 fatal(err_msg_res("unknown action %d: %s", action, Deoptimization::trap_action_name(action)));
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
1928 break;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1929 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1930 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1931
a61af66fc99e Initial load
duke
parents:
diff changeset
1932 if (TraceOptoParse) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1933 char buf[100];
a61af66fc99e Initial load
duke
parents:
diff changeset
1934 tty->print_cr("Uncommon trap %s at bci:%d",
a61af66fc99e Initial load
duke
parents:
diff changeset
1935 Deoptimization::format_trap_request(buf, sizeof(buf),
a61af66fc99e Initial load
duke
parents:
diff changeset
1936 trap_request), bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
1937 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1938
a61af66fc99e Initial load
duke
parents:
diff changeset
1939 CompileLog* log = C->log();
a61af66fc99e Initial load
duke
parents:
diff changeset
1940 if (log != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1941 int kid = (klass == NULL)? -1: log->identify(klass);
a61af66fc99e Initial load
duke
parents:
diff changeset
1942 log->begin_elem("uncommon_trap bci='%d'", bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
1943 char buf[100];
a61af66fc99e Initial load
duke
parents:
diff changeset
1944 log->print(" %s", Deoptimization::format_trap_request(buf, sizeof(buf),
a61af66fc99e Initial load
duke
parents:
diff changeset
1945 trap_request));
a61af66fc99e Initial load
duke
parents:
diff changeset
1946 if (kid >= 0) log->print(" klass='%d'", kid);
a61af66fc99e Initial load
duke
parents:
diff changeset
1947 if (comment != NULL) log->print(" comment='%s'", comment);
a61af66fc99e Initial load
duke
parents:
diff changeset
1948 log->end_elem();
a61af66fc99e Initial load
duke
parents:
diff changeset
1949 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1950
a61af66fc99e Initial load
duke
parents:
diff changeset
1951 // Make sure any guarding test views this path as very unlikely
a61af66fc99e Initial load
duke
parents:
diff changeset
1952 Node *i0 = control()->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1953 if (i0 != NULL && i0->is_If()) { // Found a guarding if test?
a61af66fc99e Initial load
duke
parents:
diff changeset
1954 IfNode *iff = i0->as_If();
a61af66fc99e Initial load
duke
parents:
diff changeset
1955 float f = iff->_prob; // Get prob
a61af66fc99e Initial load
duke
parents:
diff changeset
1956 if (control()->Opcode() == Op_IfTrue) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1957 if (f > PROB_UNLIKELY_MAG(4))
a61af66fc99e Initial load
duke
parents:
diff changeset
1958 iff->_prob = PROB_MIN;
a61af66fc99e Initial load
duke
parents:
diff changeset
1959 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1960 if (f < PROB_LIKELY_MAG(4))
a61af66fc99e Initial load
duke
parents:
diff changeset
1961 iff->_prob = PROB_MAX;
a61af66fc99e Initial load
duke
parents:
diff changeset
1962 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1963 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1964
a61af66fc99e Initial load
duke
parents:
diff changeset
1965 // Clear out dead values from the debug info.
a61af66fc99e Initial load
duke
parents:
diff changeset
1966 kill_dead_locals();
a61af66fc99e Initial load
duke
parents:
diff changeset
1967
a61af66fc99e Initial load
duke
parents:
diff changeset
1968 // Now insert the uncommon trap subroutine call
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1746
diff changeset
1969 address call_addr = SharedRuntime::uncommon_trap_blob()->entry_point();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1970 const TypePtr* no_memory_effects = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1971 // Pass the index of the class to be loaded
a61af66fc99e Initial load
duke
parents:
diff changeset
1972 Node* call = make_runtime_call(RC_NO_LEAF | RC_UNCOMMON |
a61af66fc99e Initial load
duke
parents:
diff changeset
1973 (must_throw ? RC_MUST_THROW : 0),
a61af66fc99e Initial load
duke
parents:
diff changeset
1974 OptoRuntime::uncommon_trap_Type(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1975 call_addr, "uncommon_trap", no_memory_effects,
a61af66fc99e Initial load
duke
parents:
diff changeset
1976 intcon(trap_request));
a61af66fc99e Initial load
duke
parents:
diff changeset
1977 assert(call->as_CallStaticJava()->uncommon_trap_request() == trap_request,
a61af66fc99e Initial load
duke
parents:
diff changeset
1978 "must extract request correctly from the graph");
a61af66fc99e Initial load
duke
parents:
diff changeset
1979 assert(trap_request != 0, "zero value reserved by uncommon_trap_request");
a61af66fc99e Initial load
duke
parents:
diff changeset
1980
a61af66fc99e Initial load
duke
parents:
diff changeset
1981 call->set_req(TypeFunc::ReturnAdr, returnadr());
a61af66fc99e Initial load
duke
parents:
diff changeset
1982 // The debug info is the only real input to this call.
a61af66fc99e Initial load
duke
parents:
diff changeset
1983
a61af66fc99e Initial load
duke
parents:
diff changeset
1984 // Halt-and-catch fire here. The above call should never return!
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
1985 HaltNode* halt = new(C) HaltNode(control(), frameptr());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1986 _gvn.set_type_bottom(halt);
a61af66fc99e Initial load
duke
parents:
diff changeset
1987 root()->add_req(halt);
a61af66fc99e Initial load
duke
parents:
diff changeset
1988
a61af66fc99e Initial load
duke
parents:
diff changeset
1989 stop_and_kill_map();
a61af66fc99e Initial load
duke
parents:
diff changeset
1990 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1991
a61af66fc99e Initial load
duke
parents:
diff changeset
1992
a61af66fc99e Initial load
duke
parents:
diff changeset
1993 //--------------------------just_allocated_object------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1994 // Report the object that was just allocated.
a61af66fc99e Initial load
duke
parents:
diff changeset
1995 // It must be the case that there are no intervening safepoints.
a61af66fc99e Initial load
duke
parents:
diff changeset
1996 // We use this to determine if an object is so "fresh" that
a61af66fc99e Initial load
duke
parents:
diff changeset
1997 // it does not require card marks.
a61af66fc99e Initial load
duke
parents:
diff changeset
1998 Node* GraphKit::just_allocated_object(Node* current_control) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1999 if (C->recent_alloc_ctl() == current_control)
a61af66fc99e Initial load
duke
parents:
diff changeset
2000 return C->recent_alloc_obj();
a61af66fc99e Initial load
duke
parents:
diff changeset
2001 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2002 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2003
a61af66fc99e Initial load
duke
parents:
diff changeset
2004
a61af66fc99e Initial load
duke
parents:
diff changeset
2005 void GraphKit::round_double_arguments(ciMethod* dest_method) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2006 // (Note: TypeFunc::make has a cache that makes this fast.)
a61af66fc99e Initial load
duke
parents:
diff changeset
2007 const TypeFunc* tf = TypeFunc::make(dest_method);
a61af66fc99e Initial load
duke
parents:
diff changeset
2008 int nargs = tf->_domain->_cnt - TypeFunc::Parms;
a61af66fc99e Initial load
duke
parents:
diff changeset
2009 for (int j = 0; j < nargs; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2010 const Type *targ = tf->_domain->field_at(j + TypeFunc::Parms);
a61af66fc99e Initial load
duke
parents:
diff changeset
2011 if( targ->basic_type() == T_DOUBLE ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2012 // If any parameters are doubles, they must be rounded before
a61af66fc99e Initial load
duke
parents:
diff changeset
2013 // the call, dstore_rounding does gvn.transform
a61af66fc99e Initial load
duke
parents:
diff changeset
2014 Node *arg = argument(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
2015 arg = dstore_rounding(arg);
a61af66fc99e Initial load
duke
parents:
diff changeset
2016 set_argument(j, arg);
a61af66fc99e Initial load
duke
parents:
diff changeset
2017 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2018 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2019 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2020
a61af66fc99e Initial load
duke
parents:
diff changeset
2021 void GraphKit::round_double_result(ciMethod* dest_method) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2022 // A non-strict method may return a double value which has an extended
a61af66fc99e Initial load
duke
parents:
diff changeset
2023 // exponent, but this must not be visible in a caller which is 'strict'
a61af66fc99e Initial load
duke
parents:
diff changeset
2024 // If a strict caller invokes a non-strict callee, round a double result
a61af66fc99e Initial load
duke
parents:
diff changeset
2025
a61af66fc99e Initial load
duke
parents:
diff changeset
2026 BasicType result_type = dest_method->return_type()->basic_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
2027 assert( method() != NULL, "must have caller context");
a61af66fc99e Initial load
duke
parents:
diff changeset
2028 if( result_type == T_DOUBLE && method()->is_strict() && !dest_method->is_strict() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2029 // Destination method's return value is on top of stack
a61af66fc99e Initial load
duke
parents:
diff changeset
2030 // dstore_rounding() does gvn.transform
a61af66fc99e Initial load
duke
parents:
diff changeset
2031 Node *result = pop_pair();
a61af66fc99e Initial load
duke
parents:
diff changeset
2032 result = dstore_rounding(result);
a61af66fc99e Initial load
duke
parents:
diff changeset
2033 push_pair(result);
a61af66fc99e Initial load
duke
parents:
diff changeset
2034 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2035 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2036
a61af66fc99e Initial load
duke
parents:
diff changeset
2037 // rounding for strict float precision conformance
a61af66fc99e Initial load
duke
parents:
diff changeset
2038 Node* GraphKit::precision_rounding(Node* n) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2039 return UseStrictFP && _method->flags().is_strict()
a61af66fc99e Initial load
duke
parents:
diff changeset
2040 && UseSSE == 0 && Matcher::strict_fp_requires_explicit_rounding
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2041 ? _gvn.transform( new (C) RoundFloatNode(0, n) )
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2042 : n;
a61af66fc99e Initial load
duke
parents:
diff changeset
2043 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2044
a61af66fc99e Initial load
duke
parents:
diff changeset
2045 // rounding for strict double precision conformance
a61af66fc99e Initial load
duke
parents:
diff changeset
2046 Node* GraphKit::dprecision_rounding(Node *n) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2047 return UseStrictFP && _method->flags().is_strict()
a61af66fc99e Initial load
duke
parents:
diff changeset
2048 && UseSSE <= 1 && Matcher::strict_fp_requires_explicit_rounding
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2049 ? _gvn.transform( new (C) RoundDoubleNode(0, n) )
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2050 : n;
a61af66fc99e Initial load
duke
parents:
diff changeset
2051 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2052
a61af66fc99e Initial load
duke
parents:
diff changeset
2053 // rounding for non-strict double stores
a61af66fc99e Initial load
duke
parents:
diff changeset
2054 Node* GraphKit::dstore_rounding(Node* n) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2055 return Matcher::strict_fp_requires_explicit_rounding
a61af66fc99e Initial load
duke
parents:
diff changeset
2056 && UseSSE <= 1
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2057 ? _gvn.transform( new (C) RoundDoubleNode(0, n) )
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2058 : n;
a61af66fc99e Initial load
duke
parents:
diff changeset
2059 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2060
a61af66fc99e Initial load
duke
parents:
diff changeset
2061 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
2062 // Generate a fast path/slow path idiom. Graph looks like:
a61af66fc99e Initial load
duke
parents:
diff changeset
2063 // [foo] indicates that 'foo' is a parameter
a61af66fc99e Initial load
duke
parents:
diff changeset
2064 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2065 // [in] NULL
a61af66fc99e Initial load
duke
parents:
diff changeset
2066 // \ /
a61af66fc99e Initial load
duke
parents:
diff changeset
2067 // CmpP
a61af66fc99e Initial load
duke
parents:
diff changeset
2068 // Bool ne
a61af66fc99e Initial load
duke
parents:
diff changeset
2069 // If
a61af66fc99e Initial load
duke
parents:
diff changeset
2070 // / \
a61af66fc99e Initial load
duke
parents:
diff changeset
2071 // True False-<2>
a61af66fc99e Initial load
duke
parents:
diff changeset
2072 // / |
a61af66fc99e Initial load
duke
parents:
diff changeset
2073 // / cast_not_null
a61af66fc99e Initial load
duke
parents:
diff changeset
2074 // Load | | ^
a61af66fc99e Initial load
duke
parents:
diff changeset
2075 // [fast_test] | |
a61af66fc99e Initial load
duke
parents:
diff changeset
2076 // gvn to opt_test | |
a61af66fc99e Initial load
duke
parents:
diff changeset
2077 // / \ | <1>
a61af66fc99e Initial load
duke
parents:
diff changeset
2078 // True False |
a61af66fc99e Initial load
duke
parents:
diff changeset
2079 // | \\ |
a61af66fc99e Initial load
duke
parents:
diff changeset
2080 // [slow_call] \[fast_result]
a61af66fc99e Initial load
duke
parents:
diff changeset
2081 // Ctl Val \ \
a61af66fc99e Initial load
duke
parents:
diff changeset
2082 // | \ \
a61af66fc99e Initial load
duke
parents:
diff changeset
2083 // Catch <1> \ \
a61af66fc99e Initial load
duke
parents:
diff changeset
2084 // / \ ^ \ \
a61af66fc99e Initial load
duke
parents:
diff changeset
2085 // Ex No_Ex | \ \
a61af66fc99e Initial load
duke
parents:
diff changeset
2086 // | \ \ | \ <2> \
a61af66fc99e Initial load
duke
parents:
diff changeset
2087 // ... \ [slow_res] | | \ [null_result]
a61af66fc99e Initial load
duke
parents:
diff changeset
2088 // \ \--+--+--- | |
a61af66fc99e Initial load
duke
parents:
diff changeset
2089 // \ | / \ | /
a61af66fc99e Initial load
duke
parents:
diff changeset
2090 // --------Region Phi
a61af66fc99e Initial load
duke
parents:
diff changeset
2091 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2092 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
2093 // Code is structured as a series of driver functions all called 'do_XXX' that
a61af66fc99e Initial load
duke
parents:
diff changeset
2094 // call a set of helper functions. Helper functions first, then drivers.
a61af66fc99e Initial load
duke
parents:
diff changeset
2095
a61af66fc99e Initial load
duke
parents:
diff changeset
2096 //------------------------------null_check_oop---------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2097 // Null check oop. Set null-path control into Region in slot 3.
a61af66fc99e Initial load
duke
parents:
diff changeset
2098 // Make a cast-not-nullness use the other not-null control. Return cast.
a61af66fc99e Initial load
duke
parents:
diff changeset
2099 Node* GraphKit::null_check_oop(Node* value, Node* *null_control,
a61af66fc99e Initial load
duke
parents:
diff changeset
2100 bool never_see_null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2101 // Initial NULL check taken path
a61af66fc99e Initial load
duke
parents:
diff changeset
2102 (*null_control) = top();
a61af66fc99e Initial load
duke
parents:
diff changeset
2103 Node* cast = null_check_common(value, T_OBJECT, false, null_control);
a61af66fc99e Initial load
duke
parents:
diff changeset
2104
a61af66fc99e Initial load
duke
parents:
diff changeset
2105 // Generate uncommon_trap:
a61af66fc99e Initial load
duke
parents:
diff changeset
2106 if (never_see_null && (*null_control) != top()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2107 // If we see an unexpected null at a check-cast we record it and force a
a61af66fc99e Initial load
duke
parents:
diff changeset
2108 // recompile; the offending check-cast will be compiled to handle NULLs.
a61af66fc99e Initial load
duke
parents:
diff changeset
2109 // If we see more than one offending BCI, then all checkcasts in the
a61af66fc99e Initial load
duke
parents:
diff changeset
2110 // method will be compiled to handle NULLs.
a61af66fc99e Initial load
duke
parents:
diff changeset
2111 PreserveJVMState pjvms(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2112 set_control(*null_control);
332
c792b641b8bd 6746907: Improve implicit null check generation
kvn
parents: 196
diff changeset
2113 replace_in_map(value, null());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2114 uncommon_trap(Deoptimization::Reason_null_check,
a61af66fc99e Initial load
duke
parents:
diff changeset
2115 Deoptimization::Action_make_not_entrant);
a61af66fc99e Initial load
duke
parents:
diff changeset
2116 (*null_control) = top(); // NULL path is dead
a61af66fc99e Initial load
duke
parents:
diff changeset
2117 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2118
a61af66fc99e Initial load
duke
parents:
diff changeset
2119 // Cast away null-ness on the result
a61af66fc99e Initial load
duke
parents:
diff changeset
2120 return cast;
a61af66fc99e Initial load
duke
parents:
diff changeset
2121 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2122
a61af66fc99e Initial load
duke
parents:
diff changeset
2123 //------------------------------opt_iff----------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2124 // Optimize the fast-check IfNode. Set the fast-path region slot 2.
a61af66fc99e Initial load
duke
parents:
diff changeset
2125 // Return slow-path control.
a61af66fc99e Initial load
duke
parents:
diff changeset
2126 Node* GraphKit::opt_iff(Node* region, Node* iff) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2127 IfNode *opt_iff = _gvn.transform(iff)->as_If();
a61af66fc99e Initial load
duke
parents:
diff changeset
2128
a61af66fc99e Initial load
duke
parents:
diff changeset
2129 // Fast path taken; set region slot 2
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2130 Node *fast_taken = _gvn.transform( new (C) IfFalseNode(opt_iff) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2131 region->init_req(2,fast_taken); // Capture fast-control
a61af66fc99e Initial load
duke
parents:
diff changeset
2132
a61af66fc99e Initial load
duke
parents:
diff changeset
2133 // Fast path not-taken, i.e. slow path
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2134 Node *slow_taken = _gvn.transform( new (C) IfTrueNode(opt_iff) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2135 return slow_taken;
a61af66fc99e Initial load
duke
parents:
diff changeset
2136 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2137
a61af66fc99e Initial load
duke
parents:
diff changeset
2138 //-----------------------------make_runtime_call-------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2139 Node* GraphKit::make_runtime_call(int flags,
a61af66fc99e Initial load
duke
parents:
diff changeset
2140 const TypeFunc* call_type, address call_addr,
a61af66fc99e Initial load
duke
parents:
diff changeset
2141 const char* call_name,
a61af66fc99e Initial load
duke
parents:
diff changeset
2142 const TypePtr* adr_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
2143 // The following parms are all optional.
a61af66fc99e Initial load
duke
parents:
diff changeset
2144 // The first NULL ends the list.
a61af66fc99e Initial load
duke
parents:
diff changeset
2145 Node* parm0, Node* parm1,
a61af66fc99e Initial load
duke
parents:
diff changeset
2146 Node* parm2, Node* parm3,
a61af66fc99e Initial load
duke
parents:
diff changeset
2147 Node* parm4, Node* parm5,
a61af66fc99e Initial load
duke
parents:
diff changeset
2148 Node* parm6, Node* parm7) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2149 // Slow-path call
a61af66fc99e Initial load
duke
parents:
diff changeset
2150 bool is_leaf = !(flags & RC_NO_LEAF);
a61af66fc99e Initial load
duke
parents:
diff changeset
2151 bool has_io = (!is_leaf && !(flags & RC_NO_IO));
a61af66fc99e Initial load
duke
parents:
diff changeset
2152 if (call_name == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2153 assert(!is_leaf, "must supply name for leaf");
a61af66fc99e Initial load
duke
parents:
diff changeset
2154 call_name = OptoRuntime::stub_name(call_addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
2155 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2156 CallNode* call;
a61af66fc99e Initial load
duke
parents:
diff changeset
2157 if (!is_leaf) {
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2158 call = new(C) CallStaticJavaNode(call_type, call_addr, call_name,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2159 bci(), adr_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
2160 } else if (flags & RC_NO_FP) {
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2161 call = new(C) CallLeafNoFPNode(call_type, call_addr, call_name, adr_type);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2162 } else {
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2163 call = new(C) CallLeafNode(call_type, call_addr, call_name, adr_type);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2164 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2165
a61af66fc99e Initial load
duke
parents:
diff changeset
2166 // The following is similar to set_edges_for_java_call,
a61af66fc99e Initial load
duke
parents:
diff changeset
2167 // except that the memory effects of the call are restricted to AliasIdxRaw.
a61af66fc99e Initial load
duke
parents:
diff changeset
2168
a61af66fc99e Initial load
duke
parents:
diff changeset
2169 // Slow path call has no side-effects, uses few values
a61af66fc99e Initial load
duke
parents:
diff changeset
2170 bool wide_in = !(flags & RC_NARROW_MEM);
a61af66fc99e Initial load
duke
parents:
diff changeset
2171 bool wide_out = (C->get_alias_index(adr_type) == Compile::AliasIdxBot);
a61af66fc99e Initial load
duke
parents:
diff changeset
2172
a61af66fc99e Initial load
duke
parents:
diff changeset
2173 Node* prev_mem = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2174 if (wide_in) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2175 prev_mem = set_predefined_input_for_runtime_call(call);
a61af66fc99e Initial load
duke
parents:
diff changeset
2176 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2177 assert(!wide_out, "narrow in => narrow out");
a61af66fc99e Initial load
duke
parents:
diff changeset
2178 Node* narrow_mem = memory(adr_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
2179 prev_mem = reset_memory();
a61af66fc99e Initial load
duke
parents:
diff changeset
2180 map()->set_memory(narrow_mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
2181 set_predefined_input_for_runtime_call(call);
a61af66fc99e Initial load
duke
parents:
diff changeset
2182 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2183
a61af66fc99e Initial load
duke
parents:
diff changeset
2184 // Hook each parm in order. Stop looking at the first NULL.
a61af66fc99e Initial load
duke
parents:
diff changeset
2185 if (parm0 != NULL) { call->init_req(TypeFunc::Parms+0, parm0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2186 if (parm1 != NULL) { call->init_req(TypeFunc::Parms+1, parm1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2187 if (parm2 != NULL) { call->init_req(TypeFunc::Parms+2, parm2);
a61af66fc99e Initial load
duke
parents:
diff changeset
2188 if (parm3 != NULL) { call->init_req(TypeFunc::Parms+3, parm3);
a61af66fc99e Initial load
duke
parents:
diff changeset
2189 if (parm4 != NULL) { call->init_req(TypeFunc::Parms+4, parm4);
a61af66fc99e Initial load
duke
parents:
diff changeset
2190 if (parm5 != NULL) { call->init_req(TypeFunc::Parms+5, parm5);
a61af66fc99e Initial load
duke
parents:
diff changeset
2191 if (parm6 != NULL) { call->init_req(TypeFunc::Parms+6, parm6);
a61af66fc99e Initial load
duke
parents:
diff changeset
2192 if (parm7 != NULL) { call->init_req(TypeFunc::Parms+7, parm7);
a61af66fc99e Initial load
duke
parents:
diff changeset
2193 /* close each nested if ===> */ } } } } } } } }
a61af66fc99e Initial load
duke
parents:
diff changeset
2194 assert(call->in(call->req()-1) != NULL, "must initialize all parms");
a61af66fc99e Initial load
duke
parents:
diff changeset
2195
a61af66fc99e Initial load
duke
parents:
diff changeset
2196 if (!is_leaf) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2197 // Non-leaves can block and take safepoints:
a61af66fc99e Initial load
duke
parents:
diff changeset
2198 add_safepoint_edges(call, ((flags & RC_MUST_THROW) != 0));
a61af66fc99e Initial load
duke
parents:
diff changeset
2199 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2200 // Non-leaves can throw exceptions:
a61af66fc99e Initial load
duke
parents:
diff changeset
2201 if (has_io) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2202 call->set_req(TypeFunc::I_O, i_o());
a61af66fc99e Initial load
duke
parents:
diff changeset
2203 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2204
a61af66fc99e Initial load
duke
parents:
diff changeset
2205 if (flags & RC_UNCOMMON) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2206 // Set the count to a tiny probability. Cf. Estimate_Block_Frequency.
a61af66fc99e Initial load
duke
parents:
diff changeset
2207 // (An "if" probability corresponds roughly to an unconditional count.
a61af66fc99e Initial load
duke
parents:
diff changeset
2208 // Sort of.)
a61af66fc99e Initial load
duke
parents:
diff changeset
2209 call->set_cnt(PROB_UNLIKELY_MAG(4));
a61af66fc99e Initial load
duke
parents:
diff changeset
2210 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2211
a61af66fc99e Initial load
duke
parents:
diff changeset
2212 Node* c = _gvn.transform(call);
a61af66fc99e Initial load
duke
parents:
diff changeset
2213 assert(c == call, "cannot disappear");
a61af66fc99e Initial load
duke
parents:
diff changeset
2214
a61af66fc99e Initial load
duke
parents:
diff changeset
2215 if (wide_out) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2216 // Slow path call has full side-effects.
a61af66fc99e Initial load
duke
parents:
diff changeset
2217 set_predefined_output_for_runtime_call(call);
a61af66fc99e Initial load
duke
parents:
diff changeset
2218 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2219 // Slow path call has few side-effects, and/or sets few values.
a61af66fc99e Initial load
duke
parents:
diff changeset
2220 set_predefined_output_for_runtime_call(call, prev_mem, adr_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
2221 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2222
a61af66fc99e Initial load
duke
parents:
diff changeset
2223 if (has_io) {
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2224 set_i_o(_gvn.transform(new (C) ProjNode(call, TypeFunc::I_O)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2225 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2226 return call;
a61af66fc99e Initial load
duke
parents:
diff changeset
2227
a61af66fc99e Initial load
duke
parents:
diff changeset
2228 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2229
a61af66fc99e Initial load
duke
parents:
diff changeset
2230 //------------------------------merge_memory-----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2231 // Merge memory from one path into the current memory state.
a61af66fc99e Initial load
duke
parents:
diff changeset
2232 void GraphKit::merge_memory(Node* new_mem, Node* region, int new_path) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2233 for (MergeMemStream mms(merged_memory(), new_mem->as_MergeMem()); mms.next_non_empty2(); ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2234 Node* old_slice = mms.force_memory();
a61af66fc99e Initial load
duke
parents:
diff changeset
2235 Node* new_slice = mms.memory2();
a61af66fc99e Initial load
duke
parents:
diff changeset
2236 if (old_slice != new_slice) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2237 PhiNode* phi;
a61af66fc99e Initial load
duke
parents:
diff changeset
2238 if (new_slice->is_Phi() && new_slice->as_Phi()->region() == region) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2239 phi = new_slice->as_Phi();
a61af66fc99e Initial load
duke
parents:
diff changeset
2240 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
2241 if (old_slice->is_Phi() && old_slice->as_Phi()->region() == region)
a61af66fc99e Initial load
duke
parents:
diff changeset
2242 old_slice = old_slice->in(new_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
2243 // Caller is responsible for ensuring that any pre-existing
a61af66fc99e Initial load
duke
parents:
diff changeset
2244 // phis are already aware of old memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
2245 int old_path = (new_path > 1) ? 1 : 2; // choose old_path != new_path
a61af66fc99e Initial load
duke
parents:
diff changeset
2246 assert(phi->in(old_path) == old_slice, "pre-existing phis OK");
a61af66fc99e Initial load
duke
parents:
diff changeset
2247 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2248 mms.set_memory(phi);
a61af66fc99e Initial load
duke
parents:
diff changeset
2249 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2250 phi = PhiNode::make(region, old_slice, Type::MEMORY, mms.adr_type(C));
a61af66fc99e Initial load
duke
parents:
diff changeset
2251 _gvn.set_type(phi, Type::MEMORY);
a61af66fc99e Initial load
duke
parents:
diff changeset
2252 phi->set_req(new_path, new_slice);
a61af66fc99e Initial load
duke
parents:
diff changeset
2253 mms.set_memory(_gvn.transform(phi)); // assume it is complete
a61af66fc99e Initial load
duke
parents:
diff changeset
2254 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2255 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2256 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2257 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2258
a61af66fc99e Initial load
duke
parents:
diff changeset
2259 //------------------------------make_slow_call_ex------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2260 // Make the exception handler hookups for the slow call
a61af66fc99e Initial load
duke
parents:
diff changeset
2261 void GraphKit::make_slow_call_ex(Node* call, ciInstanceKlass* ex_klass, bool separate_io_proj) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2262 if (stopped()) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2263
a61af66fc99e Initial load
duke
parents:
diff changeset
2264 // Make a catch node with just two handlers: fall-through and catch-all
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2265 Node* i_o = _gvn.transform( new (C) ProjNode(call, TypeFunc::I_O, separate_io_proj) );
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2266 Node* catc = _gvn.transform( new (C) CatchNode(control(), i_o, 2) );
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2267 Node* norm = _gvn.transform( new (C) CatchProjNode(catc, CatchProjNode::fall_through_index, CatchProjNode::no_handler_bci) );
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2268 Node* excp = _gvn.transform( new (C) CatchProjNode(catc, CatchProjNode::catch_all_index, CatchProjNode::no_handler_bci) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2269
a61af66fc99e Initial load
duke
parents:
diff changeset
2270 { PreserveJVMState pjvms(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2271 set_control(excp);
a61af66fc99e Initial load
duke
parents:
diff changeset
2272 set_i_o(i_o);
a61af66fc99e Initial load
duke
parents:
diff changeset
2273
a61af66fc99e Initial load
duke
parents:
diff changeset
2274 if (excp != top()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2275 // Create an exception state also.
a61af66fc99e Initial load
duke
parents:
diff changeset
2276 // Use an exact type if the caller has specified a specific exception.
a61af66fc99e Initial load
duke
parents:
diff changeset
2277 const Type* ex_type = TypeOopPtr::make_from_klass_unique(ex_klass)->cast_to_ptr_type(TypePtr::NotNull);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2278 Node* ex_oop = new (C) CreateExNode(ex_type, control(), i_o);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2279 add_exception_state(make_exception_state(_gvn.transform(ex_oop)));
a61af66fc99e Initial load
duke
parents:
diff changeset
2280 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2281 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2282
a61af66fc99e Initial load
duke
parents:
diff changeset
2283 // Get the no-exception control from the CatchNode.
a61af66fc99e Initial load
duke
parents:
diff changeset
2284 set_control(norm);
a61af66fc99e Initial load
duke
parents:
diff changeset
2285 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2286
a61af66fc99e Initial load
duke
parents:
diff changeset
2287
a61af66fc99e Initial load
duke
parents:
diff changeset
2288 //-------------------------------gen_subtype_check-----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2289 // Generate a subtyping check. Takes as input the subtype and supertype.
a61af66fc99e Initial load
duke
parents:
diff changeset
2290 // Returns 2 values: sets the default control() to the true path and returns
a61af66fc99e Initial load
duke
parents:
diff changeset
2291 // the false path. Only reads invariant memory; sets no (visible) memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
2292 // The PartialSubtypeCheckNode sets the hidden 1-word cache in the encoding
a61af66fc99e Initial load
duke
parents:
diff changeset
2293 // but that's not exposed to the optimizer. This call also doesn't take in an
a61af66fc99e Initial load
duke
parents:
diff changeset
2294 // Object; if you wish to check an Object you need to load the Object's class
a61af66fc99e Initial load
duke
parents:
diff changeset
2295 // prior to coming here.
a61af66fc99e Initial load
duke
parents:
diff changeset
2296 Node* GraphKit::gen_subtype_check(Node* subklass, Node* superklass) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2297 // Fast check for identical types, perhaps identical constants.
a61af66fc99e Initial load
duke
parents:
diff changeset
2298 // The types can even be identical non-constants, in cases
a61af66fc99e Initial load
duke
parents:
diff changeset
2299 // involving Array.newInstance, Object.clone, etc.
a61af66fc99e Initial load
duke
parents:
diff changeset
2300 if (subklass == superklass)
a61af66fc99e Initial load
duke
parents:
diff changeset
2301 return top(); // false path is dead; no test needed.
a61af66fc99e Initial load
duke
parents:
diff changeset
2302
a61af66fc99e Initial load
duke
parents:
diff changeset
2303 if (_gvn.type(superklass)->singleton()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2304 ciKlass* superk = _gvn.type(superklass)->is_klassptr()->klass();
a61af66fc99e Initial load
duke
parents:
diff changeset
2305 ciKlass* subk = _gvn.type(subklass)->is_klassptr()->klass();
a61af66fc99e Initial load
duke
parents:
diff changeset
2306
a61af66fc99e Initial load
duke
parents:
diff changeset
2307 // In the common case of an exact superklass, try to fold up the
a61af66fc99e Initial load
duke
parents:
diff changeset
2308 // test before generating code. You may ask, why not just generate
a61af66fc99e Initial load
duke
parents:
diff changeset
2309 // the code and then let it fold up? The answer is that the generated
a61af66fc99e Initial load
duke
parents:
diff changeset
2310 // code will necessarily include null checks, which do not always
a61af66fc99e Initial load
duke
parents:
diff changeset
2311 // completely fold away. If they are also needless, then they turn
a61af66fc99e Initial load
duke
parents:
diff changeset
2312 // into a performance loss. Example:
a61af66fc99e Initial load
duke
parents:
diff changeset
2313 // Foo[] fa = blah(); Foo x = fa[0]; fa[1] = x;
a61af66fc99e Initial load
duke
parents:
diff changeset
2314 // Here, the type of 'fa' is often exact, so the store check
a61af66fc99e Initial load
duke
parents:
diff changeset
2315 // of fa[1]=x will fold up, without testing the nullness of x.
a61af66fc99e Initial load
duke
parents:
diff changeset
2316 switch (static_subtype_check(superk, subk)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2317 case SSC_always_false:
a61af66fc99e Initial load
duke
parents:
diff changeset
2318 {
a61af66fc99e Initial load
duke
parents:
diff changeset
2319 Node* always_fail = control();
a61af66fc99e Initial load
duke
parents:
diff changeset
2320 set_control(top());
a61af66fc99e Initial load
duke
parents:
diff changeset
2321 return always_fail;
a61af66fc99e Initial load
duke
parents:
diff changeset
2322 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2323 case SSC_always_true:
a61af66fc99e Initial load
duke
parents:
diff changeset
2324 return top();
a61af66fc99e Initial load
duke
parents:
diff changeset
2325 case SSC_easy_test:
a61af66fc99e Initial load
duke
parents:
diff changeset
2326 {
a61af66fc99e Initial load
duke
parents:
diff changeset
2327 // Just do a direct pointer compare and be done.
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2328 Node* cmp = _gvn.transform( new(C) CmpPNode(subklass, superklass) );
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2329 Node* bol = _gvn.transform( new(C) BoolNode(cmp, BoolTest::eq) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2330 IfNode* iff = create_and_xform_if(control(), bol, PROB_STATIC_FREQUENT, COUNT_UNKNOWN);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2331 set_control( _gvn.transform( new(C) IfTrueNode (iff) ) );
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2332 return _gvn.transform( new(C) IfFalseNode(iff) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2333 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2334 case SSC_full_test:
a61af66fc99e Initial load
duke
parents:
diff changeset
2335 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2336 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
2337 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
2338 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2339 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2340
a61af66fc99e Initial load
duke
parents:
diff changeset
2341 // %%% Possible further optimization: Even if the superklass is not exact,
a61af66fc99e Initial load
duke
parents:
diff changeset
2342 // if the subklass is the unique subtype of the superklass, the check
a61af66fc99e Initial load
duke
parents:
diff changeset
2343 // will always succeed. We could leave a dependency behind to ensure this.
a61af66fc99e Initial load
duke
parents:
diff changeset
2344
a61af66fc99e Initial load
duke
parents:
diff changeset
2345 // First load the super-klass's check-offset
4762
069ab3f976d3 7118863: Move sizeof(klassOopDesc) into the *Klass::*_offset_in_bytes() functions
stefank
parents: 3849
diff changeset
2346 Node *p1 = basic_plus_adr( superklass, superklass, in_bytes(Klass::super_check_offset_offset()) );
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2347 Node *chk_off = _gvn.transform( new (C) LoadINode( NULL, memory(p1), p1, _gvn.type(p1)->is_ptr() ) );
4762
069ab3f976d3 7118863: Move sizeof(klassOopDesc) into the *Klass::*_offset_in_bytes() functions
stefank
parents: 3849
diff changeset
2348 int cacheoff_con = in_bytes(Klass::secondary_super_cache_offset());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2349 bool might_be_cache = (find_int_con(chk_off, cacheoff_con) == cacheoff_con);
a61af66fc99e Initial load
duke
parents:
diff changeset
2350
a61af66fc99e Initial load
duke
parents:
diff changeset
2351 // Load from the sub-klass's super-class display list, or a 1-word cache of
a61af66fc99e Initial load
duke
parents:
diff changeset
2352 // the secondary superclass list, or a failing value with a sentinel offset
a61af66fc99e Initial load
duke
parents:
diff changeset
2353 // if the super-klass is an interface or exceptionally deep in the Java
a61af66fc99e Initial load
duke
parents:
diff changeset
2354 // hierarchy and we have to scan the secondary superclass list the hard way.
a61af66fc99e Initial load
duke
parents:
diff changeset
2355 // Worst-case type is a little odd: NULL is allowed as a result (usually
a61af66fc99e Initial load
duke
parents:
diff changeset
2356 // klass loads can never produce a NULL).
a61af66fc99e Initial load
duke
parents:
diff changeset
2357 Node *chk_off_X = ConvI2X(chk_off);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2358 Node *p2 = _gvn.transform( new (C) AddPNode(subklass,subklass,chk_off_X) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2359 // For some types like interfaces the following loadKlass is from a 1-word
a61af66fc99e Initial load
duke
parents:
diff changeset
2360 // cache which is mutable so can't use immutable memory. Other
a61af66fc99e Initial load
duke
parents:
diff changeset
2361 // types load from the super-class display table which is immutable.
a61af66fc99e Initial load
duke
parents:
diff changeset
2362 Node *kmem = might_be_cache ? memory(p2) : immutable_memory();
164
c436414a719e 6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents: 113
diff changeset
2363 Node *nkls = _gvn.transform( LoadKlassNode::make( _gvn, kmem, p2, _gvn.type(p2)->is_ptr(), TypeKlassPtr::OBJECT_OR_NULL ) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2364
a61af66fc99e Initial load
duke
parents:
diff changeset
2365 // Compile speed common case: ARE a subtype and we canNOT fail
a61af66fc99e Initial load
duke
parents:
diff changeset
2366 if( superklass == nkls )
a61af66fc99e Initial load
duke
parents:
diff changeset
2367 return top(); // false path is dead; no test needed.
a61af66fc99e Initial load
duke
parents:
diff changeset
2368
a61af66fc99e Initial load
duke
parents:
diff changeset
2369 // See if we get an immediate positive hit. Happens roughly 83% of the
a61af66fc99e Initial load
duke
parents:
diff changeset
2370 // time. Test to see if the value loaded just previously from the subklass
a61af66fc99e Initial load
duke
parents:
diff changeset
2371 // is exactly the superklass.
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2372 Node *cmp1 = _gvn.transform( new (C) CmpPNode( superklass, nkls ) );
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2373 Node *bol1 = _gvn.transform( new (C) BoolNode( cmp1, BoolTest::eq ) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2374 IfNode *iff1 = create_and_xform_if( control(), bol1, PROB_LIKELY(0.83f), COUNT_UNKNOWN );
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2375 Node *iftrue1 = _gvn.transform( new (C) IfTrueNode ( iff1 ) );
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2376 set_control( _gvn.transform( new (C) IfFalseNode( iff1 ) ) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2377
a61af66fc99e Initial load
duke
parents:
diff changeset
2378 // Compile speed common case: Check for being deterministic right now. If
a61af66fc99e Initial load
duke
parents:
diff changeset
2379 // chk_off is a constant and not equal to cacheoff then we are NOT a
a61af66fc99e Initial load
duke
parents:
diff changeset
2380 // subklass. In this case we need exactly the 1 test above and we can
a61af66fc99e Initial load
duke
parents:
diff changeset
2381 // return those results immediately.
a61af66fc99e Initial load
duke
parents:
diff changeset
2382 if (!might_be_cache) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2383 Node* not_subtype_ctrl = control();
a61af66fc99e Initial load
duke
parents:
diff changeset
2384 set_control(iftrue1); // We need exactly the 1 test above
a61af66fc99e Initial load
duke
parents:
diff changeset
2385 return not_subtype_ctrl;
a61af66fc99e Initial load
duke
parents:
diff changeset
2386 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2387
a61af66fc99e Initial load
duke
parents:
diff changeset
2388 // Gather the various success & failures here
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2389 RegionNode *r_ok_subtype = new (C) RegionNode(4);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2390 record_for_igvn(r_ok_subtype);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2391 RegionNode *r_not_subtype = new (C) RegionNode(3);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2392 record_for_igvn(r_not_subtype);
a61af66fc99e Initial load
duke
parents:
diff changeset
2393
a61af66fc99e Initial load
duke
parents:
diff changeset
2394 r_ok_subtype->init_req(1, iftrue1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2395
a61af66fc99e Initial load
duke
parents:
diff changeset
2396 // Check for immediate negative hit. Happens roughly 11% of the time (which
a61af66fc99e Initial load
duke
parents:
diff changeset
2397 // is roughly 63% of the remaining cases). Test to see if the loaded
a61af66fc99e Initial load
duke
parents:
diff changeset
2398 // check-offset points into the subklass display list or the 1-element
a61af66fc99e Initial load
duke
parents:
diff changeset
2399 // cache. If it points to the display (and NOT the cache) and the display
a61af66fc99e Initial load
duke
parents:
diff changeset
2400 // missed then it's not a subtype.
a61af66fc99e Initial load
duke
parents:
diff changeset
2401 Node *cacheoff = _gvn.intcon(cacheoff_con);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2402 Node *cmp2 = _gvn.transform( new (C) CmpINode( chk_off, cacheoff ) );
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2403 Node *bol2 = _gvn.transform( new (C) BoolNode( cmp2, BoolTest::ne ) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2404 IfNode *iff2 = create_and_xform_if( control(), bol2, PROB_LIKELY(0.63f), COUNT_UNKNOWN );
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2405 r_not_subtype->init_req(1, _gvn.transform( new (C) IfTrueNode (iff2) ) );
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2406 set_control( _gvn.transform( new (C) IfFalseNode(iff2) ) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2407
644
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 605
diff changeset
2408 // Check for self. Very rare to get here, but it is taken 1/3 the time.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2409 // No performance impact (too rare) but allows sharing of secondary arrays
a61af66fc99e Initial load
duke
parents:
diff changeset
2410 // which has some footprint reduction.
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2411 Node *cmp3 = _gvn.transform( new (C) CmpPNode( subklass, superklass ) );
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2412 Node *bol3 = _gvn.transform( new (C) BoolNode( cmp3, BoolTest::eq ) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2413 IfNode *iff3 = create_and_xform_if( control(), bol3, PROB_LIKELY(0.36f), COUNT_UNKNOWN );
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2414 r_ok_subtype->init_req(2, _gvn.transform( new (C) IfTrueNode ( iff3 ) ) );
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2415 set_control( _gvn.transform( new (C) IfFalseNode( iff3 ) ) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2416
644
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 605
diff changeset
2417 // -- Roads not taken here: --
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 605
diff changeset
2418 // We could also have chosen to perform the self-check at the beginning
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 605
diff changeset
2419 // of this code sequence, as the assembler does. This would not pay off
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 605
diff changeset
2420 // the same way, since the optimizer, unlike the assembler, can perform
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 605
diff changeset
2421 // static type analysis to fold away many successful self-checks.
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 605
diff changeset
2422 // Non-foldable self checks work better here in second position, because
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 605
diff changeset
2423 // the initial primary superclass check subsumes a self-check for most
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 605
diff changeset
2424 // types. An exception would be a secondary type like array-of-interface,
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 605
diff changeset
2425 // which does not appear in its own primary supertype display.
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 605
diff changeset
2426 // Finally, we could have chosen to move the self-check into the
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 605
diff changeset
2427 // PartialSubtypeCheckNode, and from there out-of-line in a platform
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 605
diff changeset
2428 // dependent manner. But it is worthwhile to have the check here,
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 605
diff changeset
2429 // where it can be perhaps be optimized. The cost in code space is
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 605
diff changeset
2430 // small (register compare, branch).
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 605
diff changeset
2431
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2432 // Now do a linear scan of the secondary super-klass array. Again, no real
a61af66fc99e Initial load
duke
parents:
diff changeset
2433 // performance impact (too rare) but it's gotta be done.
a61af66fc99e Initial load
duke
parents:
diff changeset
2434 // Since the code is rarely used, there is no penalty for moving it
644
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 605
diff changeset
2435 // out of line, and it can only improve I-cache density.
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 605
diff changeset
2436 // The decision to inline or out-of-line this final check is platform
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 605
diff changeset
2437 // dependent, and is found in the AD file definition of PartialSubtypeCheck.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2438 Node* psc = _gvn.transform(
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2439 new (C) PartialSubtypeCheckNode(control(), subklass, superklass) );
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2440
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2441 Node *cmp4 = _gvn.transform( new (C) CmpPNode( psc, null() ) );
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2442 Node *bol4 = _gvn.transform( new (C) BoolNode( cmp4, BoolTest::ne ) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2443 IfNode *iff4 = create_and_xform_if( control(), bol4, PROB_FAIR, COUNT_UNKNOWN );
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2444 r_not_subtype->init_req(2, _gvn.transform( new (C) IfTrueNode (iff4) ) );
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2445 r_ok_subtype ->init_req(3, _gvn.transform( new (C) IfFalseNode(iff4) ) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2446
a61af66fc99e Initial load
duke
parents:
diff changeset
2447 // Return false path; set default control to true path.
a61af66fc99e Initial load
duke
parents:
diff changeset
2448 set_control( _gvn.transform(r_ok_subtype) );
a61af66fc99e Initial load
duke
parents:
diff changeset
2449 return _gvn.transform(r_not_subtype);
a61af66fc99e Initial load
duke
parents:
diff changeset
2450 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2451
a61af66fc99e Initial load
duke
parents:
diff changeset
2452 //----------------------------static_subtype_check-----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2453 // Shortcut important common cases when superklass is exact:
a61af66fc99e Initial load
duke
parents:
diff changeset
2454 // (0) superklass is java.lang.Object (can occur in reflective code)
a61af66fc99e Initial load
duke
parents:
diff changeset
2455 // (1) subklass is already limited to a subtype of superklass => always ok
a61af66fc99e Initial load
duke
parents:
diff changeset
2456 // (2) subklass does not overlap with superklass => always fail
a61af66fc99e Initial load
duke
parents:
diff changeset
2457 // (3) superklass has NO subtypes and we can check with a simple compare.
a61af66fc99e Initial load
duke
parents:
diff changeset
2458 int GraphKit::static_subtype_check(ciKlass* superk, ciKlass* subk) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2459 if (StressReflectiveCode) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2460 return SSC_full_test; // Let caller generate the general case.
a61af66fc99e Initial load
duke
parents:
diff changeset
2461 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2462
a61af66fc99e Initial load
duke
parents:
diff changeset
2463 if (superk == env()->Object_klass()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2464 return SSC_always_true; // (0) this test cannot fail
a61af66fc99e Initial load
duke
parents:
diff changeset
2465 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2466
a61af66fc99e Initial load
duke
parents:
diff changeset
2467 ciType* superelem = superk;
a61af66fc99e Initial load
duke
parents:
diff changeset
2468 if (superelem->is_array_klass())
a61af66fc99e Initial load
duke
parents:
diff changeset
2469 superelem = superelem->as_array_klass()->base_element_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
2470
a61af66fc99e Initial load
duke
parents:
diff changeset
2471 if (!subk->is_interface()) { // cannot trust static interface types yet
a61af66fc99e Initial load
duke
parents:
diff changeset
2472 if (subk->is_subtype_of(superk)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2473 return SSC_always_true; // (1) false path dead; no dynamic test needed
a61af66fc99e Initial load
duke
parents:
diff changeset
2474 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2475 if (!(superelem->is_klass() && superelem->as_klass()->is_interface()) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2476 !superk->is_subtype_of(subk)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2477 return SSC_always_false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2478 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2479 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2480
a61af66fc99e Initial load
duke
parents:
diff changeset
2481 // If casting to an instance klass, it must have no subtypes
a61af66fc99e Initial load
duke
parents:
diff changeset
2482 if (superk->is_interface()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2483 // Cannot trust interfaces yet.
a61af66fc99e Initial load
duke
parents:
diff changeset
2484 // %%% S.B. superk->nof_implementors() == 1
a61af66fc99e Initial load
duke
parents:
diff changeset
2485 } else if (superelem->is_instance_klass()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2486 ciInstanceKlass* ik = superelem->as_instance_klass();
a61af66fc99e Initial load
duke
parents:
diff changeset
2487 if (!ik->has_subklass() && !ik->is_interface()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2488 if (!ik->is_final()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2489 // Add a dependency if there is a chance of a later subclass.
a61af66fc99e Initial load
duke
parents:
diff changeset
2490 C->dependencies()->assert_leaf_type(ik);
a61af66fc99e Initial load
duke
parents:
diff changeset
2491 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2492 return SSC_easy_test; // (3) caller can do a simple ptr comparison
a61af66fc99e Initial load
duke
parents:
diff changeset
2493 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2494 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2495 // A primitive array type has no subtypes.
a61af66fc99e Initial load
duke
parents:
diff changeset
2496 return SSC_easy_test; // (3) caller can do a simple ptr comparison
a61af66fc99e Initial load
duke
parents:
diff changeset
2497 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2498
a61af66fc99e Initial load
duke
parents:
diff changeset
2499 return SSC_full_test;
a61af66fc99e Initial load
duke
parents:
diff changeset
2500 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2501
a61af66fc99e Initial load
duke
parents:
diff changeset
2502 // Profile-driven exact type check:
a61af66fc99e Initial load
duke
parents:
diff changeset
2503 Node* GraphKit::type_check_receiver(Node* receiver, ciKlass* klass,
a61af66fc99e Initial load
duke
parents:
diff changeset
2504 float prob,
a61af66fc99e Initial load
duke
parents:
diff changeset
2505 Node* *casted_receiver) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2506 const TypeKlassPtr* tklass = TypeKlassPtr::make(klass);
a61af66fc99e Initial load
duke
parents:
diff changeset
2507 Node* recv_klass = load_object_klass(receiver);
a61af66fc99e Initial load
duke
parents:
diff changeset
2508 Node* want_klass = makecon(tklass);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2509 Node* cmp = _gvn.transform( new(C) CmpPNode(recv_klass, want_klass) );
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2510 Node* bol = _gvn.transform( new(C) BoolNode(cmp, BoolTest::eq) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2511 IfNode* iff = create_and_xform_if(control(), bol, prob, COUNT_UNKNOWN);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2512 set_control( _gvn.transform( new(C) IfTrueNode (iff) ));
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2513 Node* fail = _gvn.transform( new(C) IfFalseNode(iff) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2514
a61af66fc99e Initial load
duke
parents:
diff changeset
2515 const TypeOopPtr* recv_xtype = tklass->as_instance_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
2516 assert(recv_xtype->klass_is_exact(), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
2517
a61af66fc99e Initial load
duke
parents:
diff changeset
2518 // Subsume downstream occurrences of receiver with a cast to
a61af66fc99e Initial load
duke
parents:
diff changeset
2519 // recv_xtype, since now we know what the type will be.
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2520 Node* cast = new(C) CheckCastPPNode(control(), receiver, recv_xtype);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2521 (*casted_receiver) = _gvn.transform(cast);
a61af66fc99e Initial load
duke
parents:
diff changeset
2522 // (User must make the replace_in_map call.)
a61af66fc99e Initial load
duke
parents:
diff changeset
2523
a61af66fc99e Initial load
duke
parents:
diff changeset
2524 return fail;
a61af66fc99e Initial load
duke
parents:
diff changeset
2525 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2526
a61af66fc99e Initial load
duke
parents:
diff changeset
2527
1746
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2528 //------------------------------seems_never_null-------------------------------
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2529 // Use null_seen information if it is available from the profile.
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2530 // If we see an unexpected null at a type check we record it and force a
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2531 // recompile; the offending check will be recompiled to handle NULLs.
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2532 // If we see several offending BCIs, then all checks in the
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2533 // method will be recompiled.
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2534 bool GraphKit::seems_never_null(Node* obj, ciProfileData* data) {
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2535 if (UncommonNullCast // Cutout for this technique
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2536 && obj != null() // And not the -Xcomp stupid case?
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2537 && !too_many_traps(Deoptimization::Reason_null_check)
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2538 ) {
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2539 if (data == NULL)
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2540 // Edge case: no mature data. Be optimistic here.
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2541 return true;
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2542 // If the profile has not seen a null, assume it won't happen.
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2543 assert(java_bc() == Bytecodes::_checkcast ||
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2544 java_bc() == Bytecodes::_instanceof ||
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2545 java_bc() == Bytecodes::_aastore, "MDO must collect null_seen bit here");
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2546 return !data->as_BitData()->null_seen();
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2547 }
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2548 return false;
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2549 }
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2550
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2551 //------------------------maybe_cast_profiled_receiver-------------------------
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2552 // If the profile has seen exactly one type, narrow to exactly that type.
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2553 // Subsequent type checks will always fold up.
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2554 Node* GraphKit::maybe_cast_profiled_receiver(Node* not_null_obj,
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2555 ciProfileData* data,
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2556 ciKlass* require_klass) {
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2557 if (!UseTypeProfile || !TypeProfileCasts) return NULL;
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2558 if (data == NULL) return NULL;
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2559
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2560 // Make sure we haven't already deoptimized from this tactic.
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2561 if (too_many_traps(Deoptimization::Reason_class_check))
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2562 return NULL;
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2563
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2564 // (No, this isn't a call, but it's enough like a virtual call
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2565 // to use the same ciMethod accessor to get the profile info...)
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2566 ciCallProfile profile = method()->call_profile_at_bci(bci());
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2567 if (profile.count() >= 0 && // no cast failures here
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2568 profile.has_receiver(0) &&
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2569 profile.morphism() == 1) {
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2570 ciKlass* exact_kls = profile.receiver(0);
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2571 if (require_klass == NULL ||
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2572 static_subtype_check(require_klass, exact_kls) == SSC_always_true) {
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2573 // If we narrow the type to match what the type profile sees,
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2574 // we can then remove the rest of the cast.
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2575 // This is a win, even if the exact_kls is very specific,
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2576 // because downstream operations, such as method calls,
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2577 // will often benefit from the sharper type.
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2578 Node* exact_obj = not_null_obj; // will get updated in place...
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2579 Node* slow_ctl = type_check_receiver(exact_obj, exact_kls, 1.0,
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2580 &exact_obj);
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2581 { PreserveJVMState pjvms(this);
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2582 set_control(slow_ctl);
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2583 uncommon_trap(Deoptimization::Reason_class_check,
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2584 Deoptimization::Action_maybe_recompile);
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2585 }
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2586 replace_in_map(not_null_obj, exact_obj);
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2587 return exact_obj;
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2588 }
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2589 // assert(ssc == SSC_always_true)... except maybe the profile lied to us.
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2590 }
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2591
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2592 return NULL;
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2593 }
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2594
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2595
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2596 //-------------------------------gen_instanceof--------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2597 // Generate an instance-of idiom. Used by both the instance-of bytecode
a61af66fc99e Initial load
duke
parents:
diff changeset
2598 // and the reflective instance-of call.
1746
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2599 Node* GraphKit::gen_instanceof(Node* obj, Node* superklass) {
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2600 kill_dead_locals(); // Benefit all the uncommon traps
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2601 assert( !stopped(), "dead parse path should be checked in callers" );
a61af66fc99e Initial load
duke
parents:
diff changeset
2602 assert(!TypePtr::NULL_PTR->higher_equal(_gvn.type(superklass)->is_klassptr()),
a61af66fc99e Initial load
duke
parents:
diff changeset
2603 "must check for not-null not-dead klass in callers");
a61af66fc99e Initial load
duke
parents:
diff changeset
2604
a61af66fc99e Initial load
duke
parents:
diff changeset
2605 // Make the merge point
a61af66fc99e Initial load
duke
parents:
diff changeset
2606 enum { _obj_path = 1, _fail_path, _null_path, PATH_LIMIT };
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2607 RegionNode* region = new(C) RegionNode(PATH_LIMIT);
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2608 Node* phi = new(C) PhiNode(region, TypeInt::BOOL);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2609 C->set_has_split_ifs(true); // Has chance for split-if optimization
a61af66fc99e Initial load
duke
parents:
diff changeset
2610
1746
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2611 ciProfileData* data = NULL;
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2612 if (java_bc() == Bytecodes::_instanceof) { // Only for the bytecode
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2613 data = method()->method_data()->bci_to_data(bci());
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2614 }
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2615 bool never_see_null = (ProfileDynamicTypes // aggressive use of profile
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2616 && seems_never_null(obj, data));
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2617
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2618 // Null check; get casted pointer; set region slot 3
a61af66fc99e Initial load
duke
parents:
diff changeset
2619 Node* null_ctl = top();
1746
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2620 Node* not_null_obj = null_check_oop(obj, &null_ctl, never_see_null);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2621
a61af66fc99e Initial load
duke
parents:
diff changeset
2622 // If not_null_obj is dead, only null-path is taken
a61af66fc99e Initial load
duke
parents:
diff changeset
2623 if (stopped()) { // Doing instance-of on a NULL?
a61af66fc99e Initial load
duke
parents:
diff changeset
2624 set_control(null_ctl);
a61af66fc99e Initial load
duke
parents:
diff changeset
2625 return intcon(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2626 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2627 region->init_req(_null_path, null_ctl);
a61af66fc99e Initial load
duke
parents:
diff changeset
2628 phi ->init_req(_null_path, intcon(0)); // Set null path value
1746
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2629 if (null_ctl == top()) {
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2630 // Do this eagerly, so that pattern matches like is_diamond_phi
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2631 // will work even during parsing.
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2632 assert(_null_path == PATH_LIMIT-1, "delete last");
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2633 region->del_req(_null_path);
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2634 phi ->del_req(_null_path);
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2635 }
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2636
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2637 if (ProfileDynamicTypes && data != NULL) {
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2638 Node* cast_obj = maybe_cast_profiled_receiver(not_null_obj, data, NULL);
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2639 if (stopped()) { // Profile disagrees with this path.
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2640 set_control(null_ctl); // Null is the only remaining possibility.
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2641 return intcon(0);
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2642 }
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2643 if (cast_obj != NULL)
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2644 not_null_obj = cast_obj;
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2645 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2646
a61af66fc99e Initial load
duke
parents:
diff changeset
2647 // Load the object's klass
a61af66fc99e Initial load
duke
parents:
diff changeset
2648 Node* obj_klass = load_object_klass(not_null_obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2649
a61af66fc99e Initial load
duke
parents:
diff changeset
2650 // Generate the subtype check
a61af66fc99e Initial load
duke
parents:
diff changeset
2651 Node* not_subtype_ctrl = gen_subtype_check(obj_klass, superklass);
a61af66fc99e Initial load
duke
parents:
diff changeset
2652
a61af66fc99e Initial load
duke
parents:
diff changeset
2653 // Plug in the success path to the general merge in slot 1.
a61af66fc99e Initial load
duke
parents:
diff changeset
2654 region->init_req(_obj_path, control());
a61af66fc99e Initial load
duke
parents:
diff changeset
2655 phi ->init_req(_obj_path, intcon(1));
a61af66fc99e Initial load
duke
parents:
diff changeset
2656
a61af66fc99e Initial load
duke
parents:
diff changeset
2657 // Plug in the failing path to the general merge in slot 2.
a61af66fc99e Initial load
duke
parents:
diff changeset
2658 region->init_req(_fail_path, not_subtype_ctrl);
a61af66fc99e Initial load
duke
parents:
diff changeset
2659 phi ->init_req(_fail_path, intcon(0));
a61af66fc99e Initial load
duke
parents:
diff changeset
2660
a61af66fc99e Initial load
duke
parents:
diff changeset
2661 // Return final merged results
a61af66fc99e Initial load
duke
parents:
diff changeset
2662 set_control( _gvn.transform(region) );
a61af66fc99e Initial load
duke
parents:
diff changeset
2663 record_for_igvn(region);
a61af66fc99e Initial load
duke
parents:
diff changeset
2664 return _gvn.transform(phi);
a61af66fc99e Initial load
duke
parents:
diff changeset
2665 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2666
a61af66fc99e Initial load
duke
parents:
diff changeset
2667 //-------------------------------gen_checkcast---------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2668 // Generate a checkcast idiom. Used by both the checkcast bytecode and the
a61af66fc99e Initial load
duke
parents:
diff changeset
2669 // array store bytecode. Stack must be as-if BEFORE doing the bytecode so the
a61af66fc99e Initial load
duke
parents:
diff changeset
2670 // uncommon-trap paths work. Adjust stack after this call.
a61af66fc99e Initial load
duke
parents:
diff changeset
2671 // If failure_control is supplied and not null, it is filled in with
a61af66fc99e Initial load
duke
parents:
diff changeset
2672 // the control edge for the cast failure. Otherwise, an appropriate
a61af66fc99e Initial load
duke
parents:
diff changeset
2673 // uncommon trap or exception is thrown.
a61af66fc99e Initial load
duke
parents:
diff changeset
2674 Node* GraphKit::gen_checkcast(Node *obj, Node* superklass,
a61af66fc99e Initial load
duke
parents:
diff changeset
2675 Node* *failure_control) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2676 kill_dead_locals(); // Benefit all the uncommon traps
a61af66fc99e Initial load
duke
parents:
diff changeset
2677 const TypeKlassPtr *tk = _gvn.type(superklass)->is_klassptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
2678 const Type *toop = TypeOopPtr::make_from_klass(tk->klass());
a61af66fc99e Initial load
duke
parents:
diff changeset
2679
a61af66fc99e Initial load
duke
parents:
diff changeset
2680 // Fast cutout: Check the case that the cast is vacuously true.
a61af66fc99e Initial load
duke
parents:
diff changeset
2681 // This detects the common cases where the test will short-circuit
a61af66fc99e Initial load
duke
parents:
diff changeset
2682 // away completely. We do this before we perform the null check,
a61af66fc99e Initial load
duke
parents:
diff changeset
2683 // because if the test is going to turn into zero code, we don't
a61af66fc99e Initial load
duke
parents:
diff changeset
2684 // want a residual null check left around. (Causes a slowdown,
a61af66fc99e Initial load
duke
parents:
diff changeset
2685 // for example, in some objArray manipulations, such as a[i]=a[j].)
a61af66fc99e Initial load
duke
parents:
diff changeset
2686 if (tk->singleton()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2687 const TypeOopPtr* objtp = _gvn.type(obj)->isa_oopptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
2688 if (objtp != NULL && objtp->klass() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2689 switch (static_subtype_check(tk->klass(), objtp->klass())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2690 case SSC_always_true:
a61af66fc99e Initial load
duke
parents:
diff changeset
2691 return obj;
a61af66fc99e Initial load
duke
parents:
diff changeset
2692 case SSC_always_false:
a61af66fc99e Initial load
duke
parents:
diff changeset
2693 // It needs a null check because a null will *pass* the cast check.
a61af66fc99e Initial load
duke
parents:
diff changeset
2694 // A non-null value will always produce an exception.
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
2695 return null_assert(obj);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2696 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2697 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2698 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2699
a61af66fc99e Initial load
duke
parents:
diff changeset
2700 ciProfileData* data = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2701 if (failure_control == NULL) { // use MDO in regular case only
a61af66fc99e Initial load
duke
parents:
diff changeset
2702 assert(java_bc() == Bytecodes::_aastore ||
a61af66fc99e Initial load
duke
parents:
diff changeset
2703 java_bc() == Bytecodes::_checkcast,
a61af66fc99e Initial load
duke
parents:
diff changeset
2704 "interpreter profiles type checks only for these BCs");
a61af66fc99e Initial load
duke
parents:
diff changeset
2705 data = method()->method_data()->bci_to_data(bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
2706 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2707
a61af66fc99e Initial load
duke
parents:
diff changeset
2708 // Make the merge point
a61af66fc99e Initial load
duke
parents:
diff changeset
2709 enum { _obj_path = 1, _null_path, PATH_LIMIT };
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2710 RegionNode* region = new (C) RegionNode(PATH_LIMIT);
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2711 Node* phi = new (C) PhiNode(region, toop);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2712 C->set_has_split_ifs(true); // Has chance for split-if optimization
a61af66fc99e Initial load
duke
parents:
diff changeset
2713
a61af66fc99e Initial load
duke
parents:
diff changeset
2714 // Use null-cast information if it is available
1746
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2715 bool never_see_null = ((failure_control == NULL) // regular case only
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2716 && seems_never_null(obj, data));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2717
a61af66fc99e Initial load
duke
parents:
diff changeset
2718 // Null check; get casted pointer; set region slot 3
a61af66fc99e Initial load
duke
parents:
diff changeset
2719 Node* null_ctl = top();
a61af66fc99e Initial load
duke
parents:
diff changeset
2720 Node* not_null_obj = null_check_oop(obj, &null_ctl, never_see_null);
a61af66fc99e Initial load
duke
parents:
diff changeset
2721
a61af66fc99e Initial load
duke
parents:
diff changeset
2722 // If not_null_obj is dead, only null-path is taken
a61af66fc99e Initial load
duke
parents:
diff changeset
2723 if (stopped()) { // Doing instance-of on a NULL?
a61af66fc99e Initial load
duke
parents:
diff changeset
2724 set_control(null_ctl);
a61af66fc99e Initial load
duke
parents:
diff changeset
2725 return null();
a61af66fc99e Initial load
duke
parents:
diff changeset
2726 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2727 region->init_req(_null_path, null_ctl);
a61af66fc99e Initial load
duke
parents:
diff changeset
2728 phi ->init_req(_null_path, null()); // Set null path value
1746
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2729 if (null_ctl == top()) {
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2730 // Do this eagerly, so that pattern matches like is_diamond_phi
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2731 // will work even during parsing.
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2732 assert(_null_path == PATH_LIMIT-1, "delete last");
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2733 region->del_req(_null_path);
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2734 phi ->del_req(_null_path);
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2735 }
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2736
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2737 Node* cast_obj = NULL;
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2738 if (data != NULL &&
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2739 // Counter has never been decremented (due to cast failure).
a61af66fc99e Initial load
duke
parents:
diff changeset
2740 // ...This is a reasonable thing to expect. It is true of
a61af66fc99e Initial load
duke
parents:
diff changeset
2741 // all casts inserted by javac to implement generic types.
1746
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2742 data->as_CounterData()->count() >= 0) {
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2743 cast_obj = maybe_cast_profiled_receiver(not_null_obj, data, tk->klass());
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2744 if (cast_obj != NULL) {
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2745 if (failure_control != NULL) // failure is now impossible
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2746 (*failure_control) = top();
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2747 // adjust the type of the phi to the exact klass:
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2748 phi->raise_bottom_type(_gvn.type(cast_obj)->meet(TypePtr::NULL_PTR));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2749 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2750 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2751
a61af66fc99e Initial load
duke
parents:
diff changeset
2752 if (cast_obj == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2753 // Load the object's klass
a61af66fc99e Initial load
duke
parents:
diff changeset
2754 Node* obj_klass = load_object_klass(not_null_obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2755
a61af66fc99e Initial load
duke
parents:
diff changeset
2756 // Generate the subtype check
a61af66fc99e Initial load
duke
parents:
diff changeset
2757 Node* not_subtype_ctrl = gen_subtype_check( obj_klass, superklass );
a61af66fc99e Initial load
duke
parents:
diff changeset
2758
a61af66fc99e Initial load
duke
parents:
diff changeset
2759 // Plug in success path into the merge
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2760 cast_obj = _gvn.transform(new (C) CheckCastPPNode(control(),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2761 not_null_obj, toop));
a61af66fc99e Initial load
duke
parents:
diff changeset
2762 // Failure path ends in uncommon trap (or may be dead - failure impossible)
a61af66fc99e Initial load
duke
parents:
diff changeset
2763 if (failure_control == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2764 if (not_subtype_ctrl != top()) { // If failure is possible
a61af66fc99e Initial load
duke
parents:
diff changeset
2765 PreserveJVMState pjvms(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2766 set_control(not_subtype_ctrl);
a61af66fc99e Initial load
duke
parents:
diff changeset
2767 builtin_throw(Deoptimization::Reason_class_check, obj_klass);
a61af66fc99e Initial load
duke
parents:
diff changeset
2768 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2769 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2770 (*failure_control) = not_subtype_ctrl;
a61af66fc99e Initial load
duke
parents:
diff changeset
2771 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2772 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2773
a61af66fc99e Initial load
duke
parents:
diff changeset
2774 region->init_req(_obj_path, control());
a61af66fc99e Initial load
duke
parents:
diff changeset
2775 phi ->init_req(_obj_path, cast_obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2776
a61af66fc99e Initial load
duke
parents:
diff changeset
2777 // A merge of NULL or Casted-NotNull obj
a61af66fc99e Initial load
duke
parents:
diff changeset
2778 Node* res = _gvn.transform(phi);
a61af66fc99e Initial load
duke
parents:
diff changeset
2779
a61af66fc99e Initial load
duke
parents:
diff changeset
2780 // Note I do NOT always 'replace_in_map(obj,result)' here.
a61af66fc99e Initial load
duke
parents:
diff changeset
2781 // if( tk->klass()->can_be_primary_super() )
a61af66fc99e Initial load
duke
parents:
diff changeset
2782 // This means that if I successfully store an Object into an array-of-String
a61af66fc99e Initial load
duke
parents:
diff changeset
2783 // I 'forget' that the Object is really now known to be a String. I have to
a61af66fc99e Initial load
duke
parents:
diff changeset
2784 // do this because we don't have true union types for interfaces - if I store
a61af66fc99e Initial load
duke
parents:
diff changeset
2785 // a Baz into an array-of-Interface and then tell the optimizer it's an
a61af66fc99e Initial load
duke
parents:
diff changeset
2786 // Interface, I forget that it's also a Baz and cannot do Baz-like field
a61af66fc99e Initial load
duke
parents:
diff changeset
2787 // references to it. FIX THIS WHEN UNION TYPES APPEAR!
a61af66fc99e Initial load
duke
parents:
diff changeset
2788 // replace_in_map( obj, res );
a61af66fc99e Initial load
duke
parents:
diff changeset
2789
a61af66fc99e Initial load
duke
parents:
diff changeset
2790 // Return final merged results
a61af66fc99e Initial load
duke
parents:
diff changeset
2791 set_control( _gvn.transform(region) );
a61af66fc99e Initial load
duke
parents:
diff changeset
2792 record_for_igvn(region);
a61af66fc99e Initial load
duke
parents:
diff changeset
2793 return res;
a61af66fc99e Initial load
duke
parents:
diff changeset
2794 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2795
a61af66fc99e Initial load
duke
parents:
diff changeset
2796 //------------------------------next_monitor-----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2797 // What number should be given to the next monitor?
a61af66fc99e Initial load
duke
parents:
diff changeset
2798 int GraphKit::next_monitor() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2799 int current = jvms()->monitor_depth()* C->sync_stack_slots();
a61af66fc99e Initial load
duke
parents:
diff changeset
2800 int next = current + C->sync_stack_slots();
a61af66fc99e Initial load
duke
parents:
diff changeset
2801 // Keep the toplevel high water mark current:
a61af66fc99e Initial load
duke
parents:
diff changeset
2802 if (C->fixed_slots() < next) C->set_fixed_slots(next);
a61af66fc99e Initial load
duke
parents:
diff changeset
2803 return current;
a61af66fc99e Initial load
duke
parents:
diff changeset
2804 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2805
a61af66fc99e Initial load
duke
parents:
diff changeset
2806 //------------------------------insert_mem_bar---------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2807 // Memory barrier to avoid floating things around
a61af66fc99e Initial load
duke
parents:
diff changeset
2808 // The membar serves as a pinch point between both control and all memory slices.
a61af66fc99e Initial load
duke
parents:
diff changeset
2809 Node* GraphKit::insert_mem_bar(int opcode, Node* precedent) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2810 MemBarNode* mb = MemBarNode::make(C, opcode, Compile::AliasIdxBot, precedent);
a61af66fc99e Initial load
duke
parents:
diff changeset
2811 mb->init_req(TypeFunc::Control, control());
a61af66fc99e Initial load
duke
parents:
diff changeset
2812 mb->init_req(TypeFunc::Memory, reset_memory());
a61af66fc99e Initial load
duke
parents:
diff changeset
2813 Node* membar = _gvn.transform(mb);
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
2814 set_control(_gvn.transform(new (C) ProjNode(membar, TypeFunc::Control)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2815 set_all_memory_call(membar);
a61af66fc99e Initial load
duke
parents:
diff changeset
2816 return membar;
a61af66fc99e Initial load
duke
parents:
diff changeset
2817 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2818
a61af66fc99e Initial load
duke
parents:
diff changeset
2819 //-------------------------insert_mem_bar_volatile----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2820 // Memory barrier to avoid floating things around
a61af66fc99e Initial load
duke
parents:
diff changeset
2821 // The membar serves as a pinch point between both control and memory(alias_idx).
a61af66fc99e Initial load
duke
parents:
diff changeset
2822 // If you want to make a pinch point on all memory slices, do not use this
a61af66fc99e Initial load
duke
parents:
diff changeset
2823 // function (even with AliasIdxBot); use insert_mem_bar() instead.
a61af66fc99e Initial load
duke
parents:
diff changeset
2824 Node* GraphKit::insert_mem_bar_volatile(int opcode, int alias_idx, Node* precedent) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2825 // When Parse::do_put_xxx updates a volatile field, it appends a series
a61af66fc99e Initial load
duke
parents:
diff changeset
2826 // of MemBarVolatile nodes, one for *each* volatile field alias category.
a61af66fc99e Initial load
duke
parents:
diff changeset
2827 // The first membar is on the same memory slice as the field store opcode.
a61af66fc99e Initial load
duke
parents:
diff changeset
2828 // This forces the membar to follow the store. (Bug 6500685 broke this.)
a61af66fc99e Initial load
duke
parents:
diff changeset
2829 // All the other membars (for other volatile slices, including AliasIdxBot,
a61af66fc99e Initial load
duke
parents:
diff changeset
2830 // which stands for all unknown volatile slices) are control-dependent
a61af66fc99e Initial load
duke
parents:
diff changeset
2831 // on the first membar. This prevents later volatile loads or stores
a61af66fc99e Initial load
duke
parents:
diff changeset
2832 // from sliding up past the just-emitted store.
a61af66fc99e Initial load
duke
parents:
diff changeset
2833
a61af66fc99e Initial load
duke
parents:
diff changeset
2834 MemBarNode* mb = MemBarNode::make(C, opcode, alias_idx, precedent);
a61af66fc99e Initial load
duke
parents:
diff changeset
2835 mb->set_req(TypeFunc::Control,control());
a61af66fc99e Initial load
duke
parents:
diff changeset
2836 if (alias_idx == Compile::AliasIdxBot) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2837 mb->set_req(TypeFunc::Memory, merged_memory()->base_memory());
a61af66fc99e Initial load
duke
parents:
diff changeset
2838 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2839 assert(!(opcode == Op_Initialize && alias_idx != Compile::AliasIdxRaw), "fix caller");
a61af66fc99e Initial load
duke
parents:
diff changeset
2840 mb->set_req(TypeFunc::Memory, memory(alias_idx));
a61af66fc99e Initial load
duke
parents:
diff changeset
2841 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2842 Node* membar = _gvn.transform(mb);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2843 set_control(_gvn.transform(new (C) ProjNode(membar, TypeFunc::Control)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2844 if (alias_idx == Compile::AliasIdxBot) {
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2845 merged_memory()->set_base_memory(_gvn.transform(new (C) ProjNode(membar, TypeFunc::Memory)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2846 } else {
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2847 set_memory(_gvn.transform(new (C) ProjNode(membar, TypeFunc::Memory)),alias_idx);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2848 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2849 return membar;
a61af66fc99e Initial load
duke
parents:
diff changeset
2850 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2851
a61af66fc99e Initial load
duke
parents:
diff changeset
2852 //------------------------------shared_lock------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2853 // Emit locking code.
a61af66fc99e Initial load
duke
parents:
diff changeset
2854 FastLockNode* GraphKit::shared_lock(Node* obj) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2855 // bci is either a monitorenter bc or InvocationEntryBci
a61af66fc99e Initial load
duke
parents:
diff changeset
2856 // %%% SynchronizationEntryBCI is redundant; use InvocationEntryBci in interfaces
a61af66fc99e Initial load
duke
parents:
diff changeset
2857 assert(SynchronizationEntryBCI == InvocationEntryBci, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
2858
a61af66fc99e Initial load
duke
parents:
diff changeset
2859 if( !GenerateSynchronizationCode )
a61af66fc99e Initial load
duke
parents:
diff changeset
2860 return NULL; // Not locking things?
a61af66fc99e Initial load
duke
parents:
diff changeset
2861 if (stopped()) // Dead monitor?
a61af66fc99e Initial load
duke
parents:
diff changeset
2862 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2863
a61af66fc99e Initial load
duke
parents:
diff changeset
2864 assert(dead_locals_are_killed(), "should kill locals before sync. point");
a61af66fc99e Initial load
duke
parents:
diff changeset
2865
a61af66fc99e Initial load
duke
parents:
diff changeset
2866 // Box the stack location
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2867 Node* box = _gvn.transform(new (C) BoxLockNode(next_monitor()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2868 Node* mem = reset_memory();
a61af66fc99e Initial load
duke
parents:
diff changeset
2869
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2870 FastLockNode * flock = _gvn.transform(new (C) FastLockNode(0, obj, box) )->as_FastLock();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2871 if (PrintPreciseBiasedLockingStatistics) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2872 // Create the counters for this fast lock.
a61af66fc99e Initial load
duke
parents:
diff changeset
2873 flock->create_lock_counter(sync_jvms()); // sync_jvms used to get current bci
a61af66fc99e Initial load
duke
parents:
diff changeset
2874 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2875 // Add monitor to debug info for the slow path. If we block inside the
a61af66fc99e Initial load
duke
parents:
diff changeset
2876 // slow path and de-opt, we need the monitor hanging around
a61af66fc99e Initial load
duke
parents:
diff changeset
2877 map()->push_monitor( flock );
a61af66fc99e Initial load
duke
parents:
diff changeset
2878
a61af66fc99e Initial load
duke
parents:
diff changeset
2879 const TypeFunc *tf = LockNode::lock_type();
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2880 LockNode *lock = new (C) LockNode(C, tf);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2881
a61af66fc99e Initial load
duke
parents:
diff changeset
2882 lock->init_req( TypeFunc::Control, control() );
a61af66fc99e Initial load
duke
parents:
diff changeset
2883 lock->init_req( TypeFunc::Memory , mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
2884 lock->init_req( TypeFunc::I_O , top() ) ; // does no i/o
a61af66fc99e Initial load
duke
parents:
diff changeset
2885 lock->init_req( TypeFunc::FramePtr, frameptr() );
a61af66fc99e Initial load
duke
parents:
diff changeset
2886 lock->init_req( TypeFunc::ReturnAdr, top() );
a61af66fc99e Initial load
duke
parents:
diff changeset
2887
a61af66fc99e Initial load
duke
parents:
diff changeset
2888 lock->init_req(TypeFunc::Parms + 0, obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2889 lock->init_req(TypeFunc::Parms + 1, box);
a61af66fc99e Initial load
duke
parents:
diff changeset
2890 lock->init_req(TypeFunc::Parms + 2, flock);
a61af66fc99e Initial load
duke
parents:
diff changeset
2891 add_safepoint_edges(lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
2892
a61af66fc99e Initial load
duke
parents:
diff changeset
2893 lock = _gvn.transform( lock )->as_Lock();
a61af66fc99e Initial load
duke
parents:
diff changeset
2894
a61af66fc99e Initial load
duke
parents:
diff changeset
2895 // lock has no side-effects, sets few values
a61af66fc99e Initial load
duke
parents:
diff changeset
2896 set_predefined_output_for_runtime_call(lock, mem, TypeRawPtr::BOTTOM);
a61af66fc99e Initial load
duke
parents:
diff changeset
2897
3849
f1c12354c3f7 7074017: Introduce MemBarAcquireLock/MemBarReleaseLock nodes for monitor enter/exit code paths
roland
parents: 3345
diff changeset
2898 insert_mem_bar(Op_MemBarAcquireLock);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2899
a61af66fc99e Initial load
duke
parents:
diff changeset
2900 // Add this to the worklist so that the lock can be eliminated
a61af66fc99e Initial load
duke
parents:
diff changeset
2901 record_for_igvn(lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
2902
a61af66fc99e Initial load
duke
parents:
diff changeset
2903 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
2904 if (PrintLockStatistics) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2905 // Update the counter for this lock. Don't bother using an atomic
a61af66fc99e Initial load
duke
parents:
diff changeset
2906 // operation since we don't require absolute accuracy.
a61af66fc99e Initial load
duke
parents:
diff changeset
2907 lock->create_lock_counter(map()->jvms());
1609
4311f23817fd 6959430: Make sure raw loads have control edge
kvn
parents: 1594
diff changeset
2908 increment_counter(lock->counter()->addr());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2909 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2910 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2911
a61af66fc99e Initial load
duke
parents:
diff changeset
2912 return flock;
a61af66fc99e Initial load
duke
parents:
diff changeset
2913 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2914
a61af66fc99e Initial load
duke
parents:
diff changeset
2915
a61af66fc99e Initial load
duke
parents:
diff changeset
2916 //------------------------------shared_unlock----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2917 // Emit unlocking code.
a61af66fc99e Initial load
duke
parents:
diff changeset
2918 void GraphKit::shared_unlock(Node* box, Node* obj) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2919 // bci is either a monitorenter bc or InvocationEntryBci
a61af66fc99e Initial load
duke
parents:
diff changeset
2920 // %%% SynchronizationEntryBCI is redundant; use InvocationEntryBci in interfaces
a61af66fc99e Initial load
duke
parents:
diff changeset
2921 assert(SynchronizationEntryBCI == InvocationEntryBci, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
2922
a61af66fc99e Initial load
duke
parents:
diff changeset
2923 if( !GenerateSynchronizationCode )
a61af66fc99e Initial load
duke
parents:
diff changeset
2924 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2925 if (stopped()) { // Dead monitor?
a61af66fc99e Initial load
duke
parents:
diff changeset
2926 map()->pop_monitor(); // Kill monitor from debug info
a61af66fc99e Initial load
duke
parents:
diff changeset
2927 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2928 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2929
a61af66fc99e Initial load
duke
parents:
diff changeset
2930 // Memory barrier to avoid floating things down past the locked region
3849
f1c12354c3f7 7074017: Introduce MemBarAcquireLock/MemBarReleaseLock nodes for monitor enter/exit code paths
roland
parents: 3345
diff changeset
2931 insert_mem_bar(Op_MemBarReleaseLock);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2932
a61af66fc99e Initial load
duke
parents:
diff changeset
2933 const TypeFunc *tf = OptoRuntime::complete_monitor_exit_Type();
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2934 UnlockNode *unlock = new (C) UnlockNode(C, tf);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2935 uint raw_idx = Compile::AliasIdxRaw;
a61af66fc99e Initial load
duke
parents:
diff changeset
2936 unlock->init_req( TypeFunc::Control, control() );
a61af66fc99e Initial load
duke
parents:
diff changeset
2937 unlock->init_req( TypeFunc::Memory , memory(raw_idx) );
a61af66fc99e Initial load
duke
parents:
diff changeset
2938 unlock->init_req( TypeFunc::I_O , top() ) ; // does no i/o
a61af66fc99e Initial load
duke
parents:
diff changeset
2939 unlock->init_req( TypeFunc::FramePtr, frameptr() );
a61af66fc99e Initial load
duke
parents:
diff changeset
2940 unlock->init_req( TypeFunc::ReturnAdr, top() );
a61af66fc99e Initial load
duke
parents:
diff changeset
2941
a61af66fc99e Initial load
duke
parents:
diff changeset
2942 unlock->init_req(TypeFunc::Parms + 0, obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2943 unlock->init_req(TypeFunc::Parms + 1, box);
a61af66fc99e Initial load
duke
parents:
diff changeset
2944 unlock = _gvn.transform(unlock)->as_Unlock();
a61af66fc99e Initial load
duke
parents:
diff changeset
2945
a61af66fc99e Initial load
duke
parents:
diff changeset
2946 Node* mem = reset_memory();
a61af66fc99e Initial load
duke
parents:
diff changeset
2947
a61af66fc99e Initial load
duke
parents:
diff changeset
2948 // unlock has no side-effects, sets few values
a61af66fc99e Initial load
duke
parents:
diff changeset
2949 set_predefined_output_for_runtime_call(unlock, mem, TypeRawPtr::BOTTOM);
a61af66fc99e Initial load
duke
parents:
diff changeset
2950
a61af66fc99e Initial load
duke
parents:
diff changeset
2951 // Kill monitor from debug info
a61af66fc99e Initial load
duke
parents:
diff changeset
2952 map()->pop_monitor( );
a61af66fc99e Initial load
duke
parents:
diff changeset
2953 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2954
a61af66fc99e Initial load
duke
parents:
diff changeset
2955 //-------------------------------get_layout_helper-----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2956 // If the given klass is a constant or known to be an array,
a61af66fc99e Initial load
duke
parents:
diff changeset
2957 // fetch the constant layout helper value into constant_value
a61af66fc99e Initial load
duke
parents:
diff changeset
2958 // and return (Node*)NULL. Otherwise, load the non-constant
a61af66fc99e Initial load
duke
parents:
diff changeset
2959 // layout helper value, and return the node which represents it.
a61af66fc99e Initial load
duke
parents:
diff changeset
2960 // This two-faced routine is useful because allocation sites
a61af66fc99e Initial load
duke
parents:
diff changeset
2961 // almost always feature constant types.
a61af66fc99e Initial load
duke
parents:
diff changeset
2962 Node* GraphKit::get_layout_helper(Node* klass_node, jint& constant_value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2963 const TypeKlassPtr* inst_klass = _gvn.type(klass_node)->isa_klassptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
2964 if (!StressReflectiveCode && inst_klass != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2965 ciKlass* klass = inst_klass->klass();
a61af66fc99e Initial load
duke
parents:
diff changeset
2966 bool xklass = inst_klass->klass_is_exact();
a61af66fc99e Initial load
duke
parents:
diff changeset
2967 if (xklass || klass->is_array_klass()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2968 jint lhelper = klass->layout_helper();
a61af66fc99e Initial load
duke
parents:
diff changeset
2969 if (lhelper != Klass::_lh_neutral_value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2970 constant_value = lhelper;
a61af66fc99e Initial load
duke
parents:
diff changeset
2971 return (Node*) NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2972 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2973 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2974 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2975 constant_value = Klass::_lh_neutral_value; // put in a known value
4762
069ab3f976d3 7118863: Move sizeof(klassOopDesc) into the *Klass::*_offset_in_bytes() functions
stefank
parents: 3849
diff changeset
2976 Node* lhp = basic_plus_adr(klass_node, klass_node, in_bytes(Klass::layout_helper_offset()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2977 return make_load(NULL, lhp, TypeInt::INT, T_INT);
a61af66fc99e Initial load
duke
parents:
diff changeset
2978 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2979
a61af66fc99e Initial load
duke
parents:
diff changeset
2980 // We just put in an allocate/initialize with a big raw-memory effect.
a61af66fc99e Initial load
duke
parents:
diff changeset
2981 // Hook selected additional alias categories on the initialization.
a61af66fc99e Initial load
duke
parents:
diff changeset
2982 static void hook_memory_on_init(GraphKit& kit, int alias_idx,
a61af66fc99e Initial load
duke
parents:
diff changeset
2983 MergeMemNode* init_in_merge,
a61af66fc99e Initial load
duke
parents:
diff changeset
2984 Node* init_out_raw) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2985 DEBUG_ONLY(Node* init_in_raw = init_in_merge->base_memory());
a61af66fc99e Initial load
duke
parents:
diff changeset
2986 assert(init_in_merge->memory_at(alias_idx) == init_in_raw, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
2987
a61af66fc99e Initial load
duke
parents:
diff changeset
2988 Node* prevmem = kit.memory(alias_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
2989 init_in_merge->set_memory_at(alias_idx, prevmem);
a61af66fc99e Initial load
duke
parents:
diff changeset
2990 kit.set_memory(init_out_raw, alias_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
2991 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2992
a61af66fc99e Initial load
duke
parents:
diff changeset
2993 //---------------------------set_output_for_allocation-------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2994 Node* GraphKit::set_output_for_allocation(AllocateNode* alloc,
3278
66b0e2371912 7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents: 2468
diff changeset
2995 const TypeOopPtr* oop_type) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2996 int rawidx = Compile::AliasIdxRaw;
a61af66fc99e Initial load
duke
parents:
diff changeset
2997 alloc->set_req( TypeFunc::FramePtr, frameptr() );
a61af66fc99e Initial load
duke
parents:
diff changeset
2998 add_safepoint_edges(alloc);
a61af66fc99e Initial load
duke
parents:
diff changeset
2999 Node* allocx = _gvn.transform(alloc);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3000 set_control( _gvn.transform(new (C) ProjNode(allocx, TypeFunc::Control) ) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3001 // create memory projection for i_o
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3002 set_memory ( _gvn.transform( new (C) ProjNode(allocx, TypeFunc::Memory, true) ), rawidx );
7428
2d6c433b1f38 8004741: Missing compiled exception handle table entry for multidimensional array allocation
kvn
parents: 7421
diff changeset
3003 make_slow_call_ex(allocx, env()->Throwable_klass(), true);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3004
a61af66fc99e Initial load
duke
parents:
diff changeset
3005 // create a memory projection as for the normal control path
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3006 Node* malloc = _gvn.transform(new (C) ProjNode(allocx, TypeFunc::Memory));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3007 set_memory(malloc, rawidx);
a61af66fc99e Initial load
duke
parents:
diff changeset
3008
a61af66fc99e Initial load
duke
parents:
diff changeset
3009 // a normal slow-call doesn't change i_o, but an allocation does
a61af66fc99e Initial load
duke
parents:
diff changeset
3010 // we create a separate i_o projection for the normal control path
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3011 set_i_o(_gvn.transform( new (C) ProjNode(allocx, TypeFunc::I_O, false) ) );
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3012 Node* rawoop = _gvn.transform( new (C) ProjNode(allocx, TypeFunc::Parms) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3013
a61af66fc99e Initial load
duke
parents:
diff changeset
3014 // put in an initialization barrier
a61af66fc99e Initial load
duke
parents:
diff changeset
3015 InitializeNode* init = insert_mem_bar_volatile(Op_Initialize, rawidx,
a61af66fc99e Initial load
duke
parents:
diff changeset
3016 rawoop)->as_Initialize();
a61af66fc99e Initial load
duke
parents:
diff changeset
3017 assert(alloc->initialization() == init, "2-way macro link must work");
a61af66fc99e Initial load
duke
parents:
diff changeset
3018 assert(init ->allocation() == alloc, "2-way macro link must work");
3278
66b0e2371912 7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents: 2468
diff changeset
3019 {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3020 // Extract memory strands which may participate in the new object's
a61af66fc99e Initial load
duke
parents:
diff changeset
3021 // initialization, and source them from the new InitializeNode.
a61af66fc99e Initial load
duke
parents:
diff changeset
3022 // This will allow us to observe initializations when they occur,
a61af66fc99e Initial load
duke
parents:
diff changeset
3023 // and link them properly (as a group) to the InitializeNode.
a61af66fc99e Initial load
duke
parents:
diff changeset
3024 assert(init->in(InitializeNode::Memory) == malloc, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
3025 MergeMemNode* minit_in = MergeMemNode::make(C, malloc);
a61af66fc99e Initial load
duke
parents:
diff changeset
3026 init->set_req(InitializeNode::Memory, minit_in);
a61af66fc99e Initial load
duke
parents:
diff changeset
3027 record_for_igvn(minit_in); // fold it up later, if possible
a61af66fc99e Initial load
duke
parents:
diff changeset
3028 Node* minit_out = memory(rawidx);
a61af66fc99e Initial load
duke
parents:
diff changeset
3029 assert(minit_out->is_Proj() && minit_out->in(0) == init, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
3030 if (oop_type->isa_aryptr()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3031 const TypePtr* telemref = oop_type->add_offset(Type::OffsetBot);
a61af66fc99e Initial load
duke
parents:
diff changeset
3032 int elemidx = C->get_alias_index(telemref);
a61af66fc99e Initial load
duke
parents:
diff changeset
3033 hook_memory_on_init(*this, elemidx, minit_in, minit_out);
a61af66fc99e Initial load
duke
parents:
diff changeset
3034 } else if (oop_type->isa_instptr()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3035 ciInstanceKlass* ik = oop_type->klass()->as_instance_klass();
a61af66fc99e Initial load
duke
parents:
diff changeset
3036 for (int i = 0, len = ik->nof_nonstatic_fields(); i < len; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3037 ciField* field = ik->nonstatic_field_at(i);
23
9bdad1bb1c31 6621098: "* HeapWordSize" for TrackedInitializationLimit is missing
kvn
parents: 0
diff changeset
3038 if (field->offset() >= TrackedInitializationLimit * HeapWordSize)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3039 continue; // do not bother to track really large numbers of fields
a61af66fc99e Initial load
duke
parents:
diff changeset
3040 // Find (or create) the alias category for this field:
a61af66fc99e Initial load
duke
parents:
diff changeset
3041 int fieldidx = C->alias_type(field)->index();
a61af66fc99e Initial load
duke
parents:
diff changeset
3042 hook_memory_on_init(*this, fieldidx, minit_in, minit_out);
a61af66fc99e Initial load
duke
parents:
diff changeset
3043 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3044 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3045 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3046
a61af66fc99e Initial load
duke
parents:
diff changeset
3047 // Cast raw oop to the real thing...
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3048 Node* javaoop = new (C) CheckCastPPNode(control(), rawoop, oop_type);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3049 javaoop = _gvn.transform(javaoop);
a61af66fc99e Initial load
duke
parents:
diff changeset
3050 C->set_recent_alloc(control(), javaoop);
a61af66fc99e Initial load
duke
parents:
diff changeset
3051 assert(just_allocated_object(control()) == javaoop, "just allocated");
a61af66fc99e Initial load
duke
parents:
diff changeset
3052
a61af66fc99e Initial load
duke
parents:
diff changeset
3053 #ifdef ASSERT
366
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 332
diff changeset
3054 { // Verify that the AllocateNode::Ideal_allocation recognizers work:
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 332
diff changeset
3055 assert(AllocateNode::Ideal_allocation(rawoop, &_gvn) == alloc,
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 332
diff changeset
3056 "Ideal_allocation works");
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 332
diff changeset
3057 assert(AllocateNode::Ideal_allocation(javaoop, &_gvn) == alloc,
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 332
diff changeset
3058 "Ideal_allocation works");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3059 if (alloc->is_AllocateArray()) {
366
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 332
diff changeset
3060 assert(AllocateArrayNode::Ideal_array_allocation(rawoop, &_gvn) == alloc->as_AllocateArray(),
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 332
diff changeset
3061 "Ideal_allocation works");
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 332
diff changeset
3062 assert(AllocateArrayNode::Ideal_array_allocation(javaoop, &_gvn) == alloc->as_AllocateArray(),
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 332
diff changeset
3063 "Ideal_allocation works");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3064 } else {
366
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 332
diff changeset
3065 assert(alloc->in(AllocateNode::ALength)->is_top(), "no length, please");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3066 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3067 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3068 #endif //ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
3069
a61af66fc99e Initial load
duke
parents:
diff changeset
3070 return javaoop;
a61af66fc99e Initial load
duke
parents:
diff changeset
3071 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3072
a61af66fc99e Initial load
duke
parents:
diff changeset
3073 //---------------------------new_instance--------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
3074 // This routine takes a klass_node which may be constant (for a static type)
a61af66fc99e Initial load
duke
parents:
diff changeset
3075 // or may be non-constant (for reflective code). It will work equally well
a61af66fc99e Initial load
duke
parents:
diff changeset
3076 // for either, and the graph will fold nicely if the optimizer later reduces
a61af66fc99e Initial load
duke
parents:
diff changeset
3077 // the type to a constant.
a61af66fc99e Initial load
duke
parents:
diff changeset
3078 // The optional arguments are for specialized use by intrinsics:
a61af66fc99e Initial load
duke
parents:
diff changeset
3079 // - If 'extra_slow_test' if not null is an extra condition for the slow-path.
a61af66fc99e Initial load
duke
parents:
diff changeset
3080 // - If 'return_size_val', report the the total object size to the caller.
a61af66fc99e Initial load
duke
parents:
diff changeset
3081 Node* GraphKit::new_instance(Node* klass_node,
a61af66fc99e Initial load
duke
parents:
diff changeset
3082 Node* extra_slow_test,
a61af66fc99e Initial load
duke
parents:
diff changeset
3083 Node* *return_size_val) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3084 // Compute size in doublewords
a61af66fc99e Initial load
duke
parents:
diff changeset
3085 // The size is always an integral number of doublewords, represented
a61af66fc99e Initial load
duke
parents:
diff changeset
3086 // as a positive bytewise size stored in the klass's layout_helper.
a61af66fc99e Initial load
duke
parents:
diff changeset
3087 // The layout_helper also encodes (in a low bit) the need for a slow path.
a61af66fc99e Initial load
duke
parents:
diff changeset
3088 jint layout_con = Klass::_lh_neutral_value;
a61af66fc99e Initial load
duke
parents:
diff changeset
3089 Node* layout_val = get_layout_helper(klass_node, layout_con);
a61af66fc99e Initial load
duke
parents:
diff changeset
3090 int layout_is_con = (layout_val == NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
3091
a61af66fc99e Initial load
duke
parents:
diff changeset
3092 if (extra_slow_test == NULL) extra_slow_test = intcon(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
3093 // Generate the initial go-slow test. It's either ALWAYS (return a
a61af66fc99e Initial load
duke
parents:
diff changeset
3094 // Node for 1) or NEVER (return a NULL) or perhaps (in the reflective
a61af66fc99e Initial load
duke
parents:
diff changeset
3095 // case) a computed value derived from the layout_helper.
a61af66fc99e Initial load
duke
parents:
diff changeset
3096 Node* initial_slow_test = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3097 if (layout_is_con) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3098 assert(!StressReflectiveCode, "stress mode does not use these paths");
a61af66fc99e Initial load
duke
parents:
diff changeset
3099 bool must_go_slow = Klass::layout_helper_needs_slow_path(layout_con);
a61af66fc99e Initial load
duke
parents:
diff changeset
3100 initial_slow_test = must_go_slow? intcon(1): extra_slow_test;
a61af66fc99e Initial load
duke
parents:
diff changeset
3101
a61af66fc99e Initial load
duke
parents:
diff changeset
3102 } else { // reflective case
a61af66fc99e Initial load
duke
parents:
diff changeset
3103 // This reflective path is used by Unsafe.allocateInstance.
a61af66fc99e Initial load
duke
parents:
diff changeset
3104 // (It may be stress-tested by specifying StressReflectiveCode.)
a61af66fc99e Initial load
duke
parents:
diff changeset
3105 // Basically, we want to get into the VM is there's an illegal argument.
a61af66fc99e Initial load
duke
parents:
diff changeset
3106 Node* bit = intcon(Klass::_lh_instance_slow_path_bit);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3107 initial_slow_test = _gvn.transform( new (C) AndINode(layout_val, bit) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3108 if (extra_slow_test != intcon(0)) {
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3109 initial_slow_test = _gvn.transform( new (C) OrINode(initial_slow_test, extra_slow_test) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3110 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3111 // (Macro-expander will further convert this to a Bool, if necessary.)
a61af66fc99e Initial load
duke
parents:
diff changeset
3112 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3113
a61af66fc99e Initial load
duke
parents:
diff changeset
3114 // Find the size in bytes. This is easy; it's the layout_helper.
a61af66fc99e Initial load
duke
parents:
diff changeset
3115 // The size value must be valid even if the slow path is taken.
a61af66fc99e Initial load
duke
parents:
diff changeset
3116 Node* size = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3117 if (layout_is_con) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3118 size = MakeConX(Klass::layout_helper_size_in_bytes(layout_con));
a61af66fc99e Initial load
duke
parents:
diff changeset
3119 } else { // reflective case
a61af66fc99e Initial load
duke
parents:
diff changeset
3120 // This reflective path is used by clone and Unsafe.allocateInstance.
a61af66fc99e Initial load
duke
parents:
diff changeset
3121 size = ConvI2X(layout_val);
a61af66fc99e Initial load
duke
parents:
diff changeset
3122
a61af66fc99e Initial load
duke
parents:
diff changeset
3123 // Clear the low bits to extract layout_helper_size_in_bytes:
a61af66fc99e Initial load
duke
parents:
diff changeset
3124 assert((int)Klass::_lh_instance_slow_path_bit < BytesPerLong, "clear bit");
a61af66fc99e Initial load
duke
parents:
diff changeset
3125 Node* mask = MakeConX(~ (intptr_t)right_n_bits(LogBytesPerLong));
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3126 size = _gvn.transform( new (C) AndXNode(size, mask) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3127 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3128 if (return_size_val != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3129 (*return_size_val) = size;
a61af66fc99e Initial load
duke
parents:
diff changeset
3130 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3131
a61af66fc99e Initial load
duke
parents:
diff changeset
3132 // This is a precise notnull oop of the klass.
a61af66fc99e Initial load
duke
parents:
diff changeset
3133 // (Actually, it need not be precise if this is a reflective allocation.)
a61af66fc99e Initial load
duke
parents:
diff changeset
3134 // It's what we cast the result to.
a61af66fc99e Initial load
duke
parents:
diff changeset
3135 const TypeKlassPtr* tklass = _gvn.type(klass_node)->isa_klassptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
3136 if (!tklass) tklass = TypeKlassPtr::OBJECT;
a61af66fc99e Initial load
duke
parents:
diff changeset
3137 const TypeOopPtr* oop_type = tklass->as_instance_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
3138
a61af66fc99e Initial load
duke
parents:
diff changeset
3139 // Now generate allocation code
74
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 63
diff changeset
3140
565
7fe62bb75bf4 6799693: Server compiler leads to data corruption when expression throws an Exception
kvn
parents: 563
diff changeset
3141 // The entire memory state is needed for slow path of the allocation
7fe62bb75bf4 6799693: Server compiler leads to data corruption when expression throws an Exception
kvn
parents: 563
diff changeset
3142 // since GC and deoptimization can happened.
7fe62bb75bf4 6799693: Server compiler leads to data corruption when expression throws an Exception
kvn
parents: 563
diff changeset
3143 Node *mem = reset_memory();
7fe62bb75bf4 6799693: Server compiler leads to data corruption when expression throws an Exception
kvn
parents: 563
diff changeset
3144 set_all_memory(mem); // Create new memory state
74
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 63
diff changeset
3145
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3146 AllocateNode* alloc
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3147 = new (C) AllocateNode(C, AllocateNode::alloc_type(),
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3148 control(), mem, i_o(),
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3149 size, klass_node,
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3150 initial_slow_test);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3151
3278
66b0e2371912 7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents: 2468
diff changeset
3152 return set_output_for_allocation(alloc, oop_type);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3153 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3154
a61af66fc99e Initial load
duke
parents:
diff changeset
3155 //-------------------------------new_array-------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
3156 // helper for both newarray and anewarray
a61af66fc99e Initial load
duke
parents:
diff changeset
3157 // The 'length' parameter is (obviously) the length of the array.
a61af66fc99e Initial load
duke
parents:
diff changeset
3158 // See comments on new_instance for the meaning of the other arguments.
a61af66fc99e Initial load
duke
parents:
diff changeset
3159 Node* GraphKit::new_array(Node* klass_node, // array klass (maybe variable)
a61af66fc99e Initial load
duke
parents:
diff changeset
3160 Node* length, // number of array elements
730
9c6be3edf0dc 6589834: deoptimization problem with -XX:+DeoptimizeALot
cfang
parents: 726
diff changeset
3161 int nargs, // number of arguments to push back for uncommon trap
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3162 Node* *return_size_val) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3163 jint layout_con = Klass::_lh_neutral_value;
a61af66fc99e Initial load
duke
parents:
diff changeset
3164 Node* layout_val = get_layout_helper(klass_node, layout_con);
a61af66fc99e Initial load
duke
parents:
diff changeset
3165 int layout_is_con = (layout_val == NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
3166
a61af66fc99e Initial load
duke
parents:
diff changeset
3167 if (!layout_is_con && !StressReflectiveCode &&
a61af66fc99e Initial load
duke
parents:
diff changeset
3168 !too_many_traps(Deoptimization::Reason_class_check)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3169 // This is a reflective array creation site.
a61af66fc99e Initial load
duke
parents:
diff changeset
3170 // Optimistically assume that it is a subtype of Object[],
a61af66fc99e Initial load
duke
parents:
diff changeset
3171 // so that we can fold up all the address arithmetic.
a61af66fc99e Initial load
duke
parents:
diff changeset
3172 layout_con = Klass::array_layout_helper(T_OBJECT);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3173 Node* cmp_lh = _gvn.transform( new(C) CmpINode(layout_val, intcon(layout_con)) );
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3174 Node* bol_lh = _gvn.transform( new(C) BoolNode(cmp_lh, BoolTest::eq) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3175 { BuildCutout unless(this, bol_lh, PROB_MAX);
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
3176 inc_sp(nargs);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3177 uncommon_trap(Deoptimization::Reason_class_check,
a61af66fc99e Initial load
duke
parents:
diff changeset
3178 Deoptimization::Action_maybe_recompile);
a61af66fc99e Initial load
duke
parents:
diff changeset
3179 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3180 layout_val = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3181 layout_is_con = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3182 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3183
a61af66fc99e Initial load
duke
parents:
diff changeset
3184 // Generate the initial go-slow test. Make sure we do not overflow
a61af66fc99e Initial load
duke
parents:
diff changeset
3185 // if length is huge (near 2Gig) or negative! We do not need
a61af66fc99e Initial load
duke
parents:
diff changeset
3186 // exact double-words here, just a close approximation of needed
a61af66fc99e Initial load
duke
parents:
diff changeset
3187 // double-words. We can't add any offset or rounding bits, lest we
a61af66fc99e Initial load
duke
parents:
diff changeset
3188 // take a size -1 of bytes and make it positive. Use an unsigned
a61af66fc99e Initial load
duke
parents:
diff changeset
3189 // compare, so negative sizes look hugely positive.
a61af66fc99e Initial load
duke
parents:
diff changeset
3190 int fast_size_limit = FastAllocateSizeLimit;
a61af66fc99e Initial load
duke
parents:
diff changeset
3191 if (layout_is_con) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3192 assert(!StressReflectiveCode, "stress mode does not use these paths");
a61af66fc99e Initial load
duke
parents:
diff changeset
3193 // Increase the size limit if we have exact knowledge of array type.
a61af66fc99e Initial load
duke
parents:
diff changeset
3194 int log2_esize = Klass::layout_helper_log2_element_size(layout_con);
a61af66fc99e Initial load
duke
parents:
diff changeset
3195 fast_size_limit <<= (LogBytesPerLong - log2_esize);
a61af66fc99e Initial load
duke
parents:
diff changeset
3196 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3197
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3198 Node* initial_slow_cmp = _gvn.transform( new (C) CmpUNode( length, intcon( fast_size_limit ) ) );
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3199 Node* initial_slow_test = _gvn.transform( new (C) BoolNode( initial_slow_cmp, BoolTest::gt ) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3200 if (initial_slow_test->is_Bool()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3201 // Hide it behind a CMoveI, or else PhaseIdealLoop::split_up will get sick.
a61af66fc99e Initial load
duke
parents:
diff changeset
3202 initial_slow_test = initial_slow_test->as_Bool()->as_int_value(&_gvn);
a61af66fc99e Initial load
duke
parents:
diff changeset
3203 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3204
a61af66fc99e Initial load
duke
parents:
diff changeset
3205 // --- Size Computation ---
a61af66fc99e Initial load
duke
parents:
diff changeset
3206 // array_size = round_to_heap(array_header + (length << elem_shift));
a61af66fc99e Initial load
duke
parents:
diff changeset
3207 // where round_to_heap(x) == round_to(x, MinObjAlignmentInBytes)
a61af66fc99e Initial load
duke
parents:
diff changeset
3208 // and round_to(x, y) == ((x + y-1) & ~(y-1))
a61af66fc99e Initial load
duke
parents:
diff changeset
3209 // The rounding mask is strength-reduced, if possible.
a61af66fc99e Initial load
duke
parents:
diff changeset
3210 int round_mask = MinObjAlignmentInBytes - 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
3211 Node* header_size = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3212 int header_size_min = arrayOopDesc::base_offset_in_bytes(T_BYTE);
a61af66fc99e Initial load
duke
parents:
diff changeset
3213 // (T_BYTE has the weakest alignment and size restrictions...)
a61af66fc99e Initial load
duke
parents:
diff changeset
3214 if (layout_is_con) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3215 int hsize = Klass::layout_helper_header_size(layout_con);
a61af66fc99e Initial load
duke
parents:
diff changeset
3216 int eshift = Klass::layout_helper_log2_element_size(layout_con);
a61af66fc99e Initial load
duke
parents:
diff changeset
3217 BasicType etype = Klass::layout_helper_element_type(layout_con);
a61af66fc99e Initial load
duke
parents:
diff changeset
3218 if ((round_mask & ~right_n_bits(eshift)) == 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
3219 round_mask = 0; // strength-reduce it if it goes away completely
a61af66fc99e Initial load
duke
parents:
diff changeset
3220 assert((hsize & right_n_bits(eshift)) == 0, "hsize is pre-rounded");
a61af66fc99e Initial load
duke
parents:
diff changeset
3221 assert(header_size_min <= hsize, "generic minimum is smallest");
a61af66fc99e Initial load
duke
parents:
diff changeset
3222 header_size_min = hsize;
a61af66fc99e Initial load
duke
parents:
diff changeset
3223 header_size = intcon(hsize + round_mask);
a61af66fc99e Initial load
duke
parents:
diff changeset
3224 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3225 Node* hss = intcon(Klass::_lh_header_size_shift);
a61af66fc99e Initial load
duke
parents:
diff changeset
3226 Node* hsm = intcon(Klass::_lh_header_size_mask);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3227 Node* hsize = _gvn.transform( new(C) URShiftINode(layout_val, hss) );
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3228 hsize = _gvn.transform( new(C) AndINode(hsize, hsm) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3229 Node* mask = intcon(round_mask);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3230 header_size = _gvn.transform( new(C) AddINode(hsize, mask) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3231 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3232
a61af66fc99e Initial load
duke
parents:
diff changeset
3233 Node* elem_shift = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3234 if (layout_is_con) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3235 int eshift = Klass::layout_helper_log2_element_size(layout_con);
a61af66fc99e Initial load
duke
parents:
diff changeset
3236 if (eshift != 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
3237 elem_shift = intcon(eshift);
a61af66fc99e Initial load
duke
parents:
diff changeset
3238 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3239 // There is no need to mask or shift this value.
a61af66fc99e Initial load
duke
parents:
diff changeset
3240 // The semantics of LShiftINode include an implicit mask to 0x1F.
a61af66fc99e Initial load
duke
parents:
diff changeset
3241 assert(Klass::_lh_log2_element_size_shift == 0, "use shift in place");
a61af66fc99e Initial load
duke
parents:
diff changeset
3242 elem_shift = layout_val;
a61af66fc99e Initial load
duke
parents:
diff changeset
3243 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3244
a61af66fc99e Initial load
duke
parents:
diff changeset
3245 // Transition to native address size for all offset calculations:
a61af66fc99e Initial load
duke
parents:
diff changeset
3246 Node* lengthx = ConvI2X(length);
a61af66fc99e Initial load
duke
parents:
diff changeset
3247 Node* headerx = ConvI2X(header_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
3248 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
3249 { const TypeLong* tllen = _gvn.find_long_type(lengthx);
a61af66fc99e Initial load
duke
parents:
diff changeset
3250 if (tllen != NULL && tllen->_lo < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3251 // Add a manual constraint to a positive range. Cf. array_element_address.
a61af66fc99e Initial load
duke
parents:
diff changeset
3252 jlong size_max = arrayOopDesc::max_array_length(T_BYTE);
a61af66fc99e Initial load
duke
parents:
diff changeset
3253 if (size_max > tllen->_hi) size_max = tllen->_hi;
a61af66fc99e Initial load
duke
parents:
diff changeset
3254 const TypeLong* tlcon = TypeLong::make(CONST64(0), size_max, Type::WidenMin);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3255 lengthx = _gvn.transform( new (C) ConvI2LNode(length, tlcon));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3256 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3257 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3258 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
3259
a61af66fc99e Initial load
duke
parents:
diff changeset
3260 // Combine header size (plus rounding) and body size. Then round down.
a61af66fc99e Initial load
duke
parents:
diff changeset
3261 // This computation cannot overflow, because it is used only in two
a61af66fc99e Initial load
duke
parents:
diff changeset
3262 // places, one where the length is sharply limited, and the other
a61af66fc99e Initial load
duke
parents:
diff changeset
3263 // after a successful allocation.
a61af66fc99e Initial load
duke
parents:
diff changeset
3264 Node* abody = lengthx;
a61af66fc99e Initial load
duke
parents:
diff changeset
3265 if (elem_shift != NULL)
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3266 abody = _gvn.transform( new(C) LShiftXNode(lengthx, elem_shift) );
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3267 Node* size = _gvn.transform( new(C) AddXNode(headerx, abody) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3268 if (round_mask != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3269 Node* mask = MakeConX(~round_mask);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3270 size = _gvn.transform( new(C) AndXNode(size, mask) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3271 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3272 // else if round_mask == 0, the size computation is self-rounding
a61af66fc99e Initial load
duke
parents:
diff changeset
3273
a61af66fc99e Initial load
duke
parents:
diff changeset
3274 if (return_size_val != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3275 // This is the size
a61af66fc99e Initial load
duke
parents:
diff changeset
3276 (*return_size_val) = size;
a61af66fc99e Initial load
duke
parents:
diff changeset
3277 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3278
a61af66fc99e Initial load
duke
parents:
diff changeset
3279 // Now generate allocation code
74
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 63
diff changeset
3280
565
7fe62bb75bf4 6799693: Server compiler leads to data corruption when expression throws an Exception
kvn
parents: 563
diff changeset
3281 // The entire memory state is needed for slow path of the allocation
7fe62bb75bf4 6799693: Server compiler leads to data corruption when expression throws an Exception
kvn
parents: 563
diff changeset
3282 // since GC and deoptimization can happened.
7fe62bb75bf4 6799693: Server compiler leads to data corruption when expression throws an Exception
kvn
parents: 563
diff changeset
3283 Node *mem = reset_memory();
7fe62bb75bf4 6799693: Server compiler leads to data corruption when expression throws an Exception
kvn
parents: 563
diff changeset
3284 set_all_memory(mem); // Create new memory state
74
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 63
diff changeset
3285
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3286 // Create the AllocateArrayNode and its result projections
a61af66fc99e Initial load
duke
parents:
diff changeset
3287 AllocateArrayNode* alloc
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3288 = new (C) AllocateArrayNode(C, AllocateArrayNode::alloc_type(),
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3289 control(), mem, i_o(),
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3290 size, klass_node,
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3291 initial_slow_test,
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3292 length);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3293
a61af66fc99e Initial load
duke
parents:
diff changeset
3294 // Cast to correct type. Note that the klass_node may be constant or not,
a61af66fc99e Initial load
duke
parents:
diff changeset
3295 // and in the latter case the actual array type will be inexact also.
a61af66fc99e Initial load
duke
parents:
diff changeset
3296 // (This happens via a non-constant argument to inline_native_newArray.)
a61af66fc99e Initial load
duke
parents:
diff changeset
3297 // In any case, the value of klass_node provides the desired array type.
a61af66fc99e Initial load
duke
parents:
diff changeset
3298 const TypeInt* length_type = _gvn.find_int_type(length);
a61af66fc99e Initial load
duke
parents:
diff changeset
3299 const TypeOopPtr* ary_type = _gvn.type(klass_node)->is_klassptr()->as_instance_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
3300 if (ary_type->isa_aryptr() && length_type != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3301 // Try to get a better type than POS for the size
a61af66fc99e Initial load
duke
parents:
diff changeset
3302 ary_type = ary_type->is_aryptr()->cast_to_size(length_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
3303 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3304
3278
66b0e2371912 7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents: 2468
diff changeset
3305 Node* javaoop = set_output_for_allocation(alloc, ary_type);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3306
366
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 332
diff changeset
3307 // Cast length on remaining path to be as narrow as possible
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 332
diff changeset
3308 if (map()->find_edge(length) >= 0) {
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 332
diff changeset
3309 Node* ccast = alloc->make_ideal_length(ary_type, &_gvn);
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 332
diff changeset
3310 if (ccast != length) {
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 332
diff changeset
3311 _gvn.set_type_bottom(ccast);
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 332
diff changeset
3312 record_for_igvn(ccast);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3313 replace_in_map(length, ccast);
a61af66fc99e Initial load
duke
parents:
diff changeset
3314 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3315 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3316
a61af66fc99e Initial load
duke
parents:
diff changeset
3317 return javaoop;
a61af66fc99e Initial load
duke
parents:
diff changeset
3318 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3319
a61af66fc99e Initial load
duke
parents:
diff changeset
3320 // The following "Ideal_foo" functions are placed here because they recognize
a61af66fc99e Initial load
duke
parents:
diff changeset
3321 // the graph shapes created by the functions immediately above.
a61af66fc99e Initial load
duke
parents:
diff changeset
3322
a61af66fc99e Initial load
duke
parents:
diff changeset
3323 //---------------------------Ideal_allocation----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
3324 // Given an oop pointer or raw pointer, see if it feeds from an AllocateNode.
a61af66fc99e Initial load
duke
parents:
diff changeset
3325 AllocateNode* AllocateNode::Ideal_allocation(Node* ptr, PhaseTransform* phase) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3326 if (ptr == NULL) { // reduce dumb test in callers
a61af66fc99e Initial load
duke
parents:
diff changeset
3327 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3328 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3329 if (ptr->is_CheckCastPP()) { // strip a raw-to-oop cast
a61af66fc99e Initial load
duke
parents:
diff changeset
3330 ptr = ptr->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
3331 if (ptr == NULL) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3332 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3333 if (ptr->is_Proj()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3334 Node* allo = ptr->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
3335 if (allo != NULL && allo->is_Allocate()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3336 return allo->as_Allocate();
a61af66fc99e Initial load
duke
parents:
diff changeset
3337 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3338 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3339 // Report failure to match.
a61af66fc99e Initial load
duke
parents:
diff changeset
3340 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3341 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3342
a61af66fc99e Initial load
duke
parents:
diff changeset
3343 // Fancy version which also strips off an offset (and reports it to caller).
a61af66fc99e Initial load
duke
parents:
diff changeset
3344 AllocateNode* AllocateNode::Ideal_allocation(Node* ptr, PhaseTransform* phase,
a61af66fc99e Initial load
duke
parents:
diff changeset
3345 intptr_t& offset) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3346 Node* base = AddPNode::Ideal_base_and_offset(ptr, phase, offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
3347 if (base == NULL) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3348 return Ideal_allocation(base, phase);
a61af66fc99e Initial load
duke
parents:
diff changeset
3349 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3350
a61af66fc99e Initial load
duke
parents:
diff changeset
3351 // Trace Initialize <- Proj[Parm] <- Allocate
a61af66fc99e Initial load
duke
parents:
diff changeset
3352 AllocateNode* InitializeNode::allocation() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3353 Node* rawoop = in(InitializeNode::RawAddress);
a61af66fc99e Initial load
duke
parents:
diff changeset
3354 if (rawoop->is_Proj()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3355 Node* alloc = rawoop->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
3356 if (alloc->is_Allocate()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3357 return alloc->as_Allocate();
a61af66fc99e Initial load
duke
parents:
diff changeset
3358 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3359 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3360 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3361 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3362
a61af66fc99e Initial load
duke
parents:
diff changeset
3363 // Trace Allocate -> Proj[Parm] -> Initialize
a61af66fc99e Initial load
duke
parents:
diff changeset
3364 InitializeNode* AllocateNode::initialization() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3365 ProjNode* rawoop = proj_out(AllocateNode::RawAddress);
a61af66fc99e Initial load
duke
parents:
diff changeset
3366 if (rawoop == NULL) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3367 for (DUIterator_Fast imax, i = rawoop->fast_outs(imax); i < imax; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3368 Node* init = rawoop->fast_out(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
3369 if (init->is_Initialize()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3370 assert(init->as_Initialize()->allocation() == this, "2-way link");
a61af66fc99e Initial load
duke
parents:
diff changeset
3371 return init->as_Initialize();
a61af66fc99e Initial load
duke
parents:
diff changeset
3372 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3373 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3374 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3375 }
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3376
4763
1dc233a8c7fe 7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents: 4762
diff changeset
3377 // Trace Allocate -> Proj[Parm] -> MemBarStoreStore
1dc233a8c7fe 7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents: 4762
diff changeset
3378 MemBarStoreStoreNode* AllocateNode::storestore() {
1dc233a8c7fe 7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents: 4762
diff changeset
3379 ProjNode* rawoop = proj_out(AllocateNode::RawAddress);
1dc233a8c7fe 7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents: 4762
diff changeset
3380 if (rawoop == NULL) return NULL;
1dc233a8c7fe 7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents: 4762
diff changeset
3381 for (DUIterator_Fast imax, i = rawoop->fast_outs(imax); i < imax; i++) {
1dc233a8c7fe 7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents: 4762
diff changeset
3382 Node* storestore = rawoop->fast_out(i);
1dc233a8c7fe 7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents: 4762
diff changeset
3383 if (storestore->is_MemBarStoreStore()) {
1dc233a8c7fe 7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents: 4762
diff changeset
3384 return storestore->as_MemBarStoreStore();
1dc233a8c7fe 7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents: 4762
diff changeset
3385 }
1dc233a8c7fe 7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents: 4762
diff changeset
3386 }
1dc233a8c7fe 7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents: 4762
diff changeset
3387 return NULL;
1dc233a8c7fe 7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents: 4762
diff changeset
3388 }
1dc233a8c7fe 7121140: Allocation paths require explicit memory synchronization operations for RMO systems
roland
parents: 4762
diff changeset
3389
2383
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3390 //----------------------------- loop predicates ---------------------------
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3391
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3392 //------------------------------add_predicate_impl----------------------------
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3393 void GraphKit::add_predicate_impl(Deoptimization::DeoptReason reason, int nargs) {
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3394 // Too many traps seen?
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3395 if (too_many_traps(reason)) {
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3396 #ifdef ASSERT
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3397 if (TraceLoopPredicate) {
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3398 int tc = C->trap_count(reason);
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3399 tty->print("too many traps=%s tcount=%d in ",
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3400 Deoptimization::trap_reason_name(reason), tc);
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3401 method()->print(); // which method has too many predicate traps
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3402 tty->cr();
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3403 }
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3404 #endif
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3405 // We cannot afford to take more traps here,
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3406 // do not generate predicate.
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3407 return;
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3408 }
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3409
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3410 Node *cont = _gvn.intcon(1);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3411 Node* opq = _gvn.transform(new (C) Opaque1Node(C, cont));
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3412 Node *bol = _gvn.transform(new (C) Conv2BNode(opq));
2383
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3413 IfNode* iff = create_and_map_if(control(), bol, PROB_MAX, COUNT_UNKNOWN);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3414 Node* iffalse = _gvn.transform(new (C) IfFalseNode(iff));
2383
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3415 C->add_predicate_opaq(opq);
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3416 {
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3417 PreserveJVMState pjvms(this);
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3418 set_control(iffalse);
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
3419 inc_sp(nargs);
2383
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3420 uncommon_trap(reason, Deoptimization::Action_maybe_recompile);
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3421 }
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3422 Node* iftrue = _gvn.transform(new (C) IfTrueNode(iff));
2383
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3423 set_control(iftrue);
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3424 }
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3425
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3426 //------------------------------add_predicate---------------------------------
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3427 void GraphKit::add_predicate(int nargs) {
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3428 if (UseLoopPredicate) {
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3429 add_predicate_impl(Deoptimization::Reason_predicate, nargs);
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3430 }
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3284
diff changeset
3431 // loop's limit check predicate should be near the loop.
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3284
diff changeset
3432 if (LoopLimitCheck) {
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3284
diff changeset
3433 add_predicate_impl(Deoptimization::Reason_loop_limit_check, nargs);
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3284
diff changeset
3434 }
2383
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3435 }
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3436
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3437 //----------------------------- store barriers ----------------------------
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3438 #define __ ideal.
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3439
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3440 void GraphKit::sync_kit(IdealKit& ideal) {
2444
07acc51c1d2a 7032314: Allow to generate CallLeafNoFPNode in IdealKit
kvn
parents: 2383
diff changeset
3441 set_all_memory(__ merged_memory());
07acc51c1d2a 7032314: Allow to generate CallLeafNoFPNode in IdealKit
kvn
parents: 2383
diff changeset
3442 set_i_o(__ i_o());
07acc51c1d2a 7032314: Allow to generate CallLeafNoFPNode in IdealKit
kvn
parents: 2383
diff changeset
3443 set_control(__ ctrl());
07acc51c1d2a 7032314: Allow to generate CallLeafNoFPNode in IdealKit
kvn
parents: 2383
diff changeset
3444 }
07acc51c1d2a 7032314: Allow to generate CallLeafNoFPNode in IdealKit
kvn
parents: 2383
diff changeset
3445
07acc51c1d2a 7032314: Allow to generate CallLeafNoFPNode in IdealKit
kvn
parents: 2383
diff changeset
3446 void GraphKit::final_sync(IdealKit& ideal) {
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3447 // Final sync IdealKit and graphKit.
2444
07acc51c1d2a 7032314: Allow to generate CallLeafNoFPNode in IdealKit
kvn
parents: 2383
diff changeset
3448 sync_kit(ideal);
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3449 }
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3450
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3451 // vanilla/CMS post barrier
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3452 // Insert a write-barrier store. This is to let generational GC work; we have
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3453 // to flag all oop-stores before the next GC point.
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3454 void GraphKit::write_barrier_post(Node* oop_store,
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3455 Node* obj,
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3456 Node* adr,
985
685e959d09ea 6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents: 955
diff changeset
3457 uint adr_idx,
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3458 Node* val,
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3459 bool use_precise) {
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3460 // No store check needed if we're storing a NULL or an old object
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3461 // (latter case is probably a string constant). The concurrent
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3462 // mark sweep garbage collector, however, needs to have all nonNull
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3463 // oop updates flagged via card-marks.
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3464 if (val != NULL && val->is_Con()) {
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3465 // must be either an oop or NULL
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3466 const Type* t = val->bottom_type();
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3467 if (t == TypePtr::NULL_PTR || t == Type::TOP)
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3468 // stores of null never (?) need barriers
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3469 return;
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3470 }
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3471
1027
39b01ab7035a 6888898: CMS: ReduceInitialCardMarks unsafe in the presence of cms precleaning
ysr
parents: 985
diff changeset
3472 if (use_ReduceInitialCardMarks()
39b01ab7035a 6888898: CMS: ReduceInitialCardMarks unsafe in the presence of cms precleaning
ysr
parents: 985
diff changeset
3473 && obj == just_allocated_object(control())) {
39b01ab7035a 6888898: CMS: ReduceInitialCardMarks unsafe in the presence of cms precleaning
ysr
parents: 985
diff changeset
3474 // We can skip marks on a freshly-allocated object in Eden.
1166
7b0e9cba0307 6896647: card marks can be deferred too long
ysr
parents: 1137
diff changeset
3475 // Keep this code in sync with new_store_pre_barrier() in runtime.cpp.
7b0e9cba0307 6896647: card marks can be deferred too long
ysr
parents: 1137
diff changeset
3476 // That routine informs GC to take appropriate compensating steps,
7b0e9cba0307 6896647: card marks can be deferred too long
ysr
parents: 1137
diff changeset
3477 // upon a slow-path allocation, so as to make this card-mark
7b0e9cba0307 6896647: card marks can be deferred too long
ysr
parents: 1137
diff changeset
3478 // elision safe.
1027
39b01ab7035a 6888898: CMS: ReduceInitialCardMarks unsafe in the presence of cms precleaning
ysr
parents: 985
diff changeset
3479 return;
39b01ab7035a 6888898: CMS: ReduceInitialCardMarks unsafe in the presence of cms precleaning
ysr
parents: 985
diff changeset
3480 }
39b01ab7035a 6888898: CMS: ReduceInitialCardMarks unsafe in the presence of cms precleaning
ysr
parents: 985
diff changeset
3481
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3482 if (!use_precise) {
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3483 // All card marks for a (non-array) instance are in one place:
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3484 adr = obj;
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3485 }
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3486 // (Else it's an array (or unknown), and we want more precise card marks.)
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3487 assert(adr != NULL, "");
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3488
2444
07acc51c1d2a 7032314: Allow to generate CallLeafNoFPNode in IdealKit
kvn
parents: 2383
diff changeset
3489 IdealKit ideal(this, true);
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3490
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3491 // Convert the pointer to an int prior to doing math on it
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3492 Node* cast = __ CastPX(__ ctrl(), adr);
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3493
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3494 // Divide by card size
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3495 assert(Universe::heap()->barrier_set()->kind() == BarrierSet::CardTableModRef,
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3496 "Only one we handle so far.");
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3497 Node* card_offset = __ URShiftX( cast, __ ConI(CardTableModRefBS::card_shift) );
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3498
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3499 // Combine card table base and card offset
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3500 Node* card_adr = __ AddP(__ top(), byte_map_base_node(), card_offset );
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3501
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3502 // Get the alias_index for raw card-mark memory
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3503 int adr_type = Compile::AliasIdxRaw;
3282
149bb459be66 7029167: add support for conditional card marks
never
parents: 3280
diff changeset
3504 Node* zero = __ ConI(0); // Dirty card value
149bb459be66 7029167: add support for conditional card marks
never
parents: 3280
diff changeset
3505 BasicType bt = T_BYTE;
149bb459be66 7029167: add support for conditional card marks
never
parents: 3280
diff changeset
3506
149bb459be66 7029167: add support for conditional card marks
never
parents: 3280
diff changeset
3507 if (UseCondCardMark) {
149bb459be66 7029167: add support for conditional card marks
never
parents: 3280
diff changeset
3508 // The classic GC reference write barrier is typically implemented
149bb459be66 7029167: add support for conditional card marks
never
parents: 3280
diff changeset
3509 // as a store into the global card mark table. Unfortunately
149bb459be66 7029167: add support for conditional card marks
never
parents: 3280
diff changeset
3510 // unconditional stores can result in false sharing and excessive
149bb459be66 7029167: add support for conditional card marks
never
parents: 3280
diff changeset
3511 // coherence traffic as well as false transactional aborts.
149bb459be66 7029167: add support for conditional card marks
never
parents: 3280
diff changeset
3512 // UseCondCardMark enables MP "polite" conditional card mark
149bb459be66 7029167: add support for conditional card marks
never
parents: 3280
diff changeset
3513 // stores. In theory we could relax the load from ctrl() to
149bb459be66 7029167: add support for conditional card marks
never
parents: 3280
diff changeset
3514 // no_ctrl, but that doesn't buy much latitude.
149bb459be66 7029167: add support for conditional card marks
never
parents: 3280
diff changeset
3515 Node* card_val = __ load( __ ctrl(), card_adr, TypeInt::BYTE, bt, adr_type);
149bb459be66 7029167: add support for conditional card marks
never
parents: 3280
diff changeset
3516 __ if_then(card_val, BoolTest::ne, zero);
149bb459be66 7029167: add support for conditional card marks
never
parents: 3280
diff changeset
3517 }
149bb459be66 7029167: add support for conditional card marks
never
parents: 3280
diff changeset
3518
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3519 // Smash zero into card
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3520 if( !UseConcMarkSweepGC ) {
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3521 __ store(__ ctrl(), card_adr, zero, bt, adr_type);
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3522 } else {
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3523 // Specialized path for CM store barrier
985
685e959d09ea 6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents: 955
diff changeset
3524 __ storeCM(__ ctrl(), card_adr, zero, oop_store, adr_idx, bt, adr_type);
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3525 }
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3526
3282
149bb459be66 7029167: add support for conditional card marks
never
parents: 3280
diff changeset
3527 if (UseCondCardMark) {
149bb459be66 7029167: add support for conditional card marks
never
parents: 3280
diff changeset
3528 __ end_if();
149bb459be66 7029167: add support for conditional card marks
never
parents: 3280
diff changeset
3529 }
149bb459be66 7029167: add support for conditional card marks
never
parents: 3280
diff changeset
3530
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3531 // Final sync IdealKit and GraphKit.
2444
07acc51c1d2a 7032314: Allow to generate CallLeafNoFPNode in IdealKit
kvn
parents: 2383
diff changeset
3532 final_sync(ideal);
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3533 }
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3534
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3535 // G1 pre/post barriers
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3536 void GraphKit::g1_write_barrier_pre(bool do_load,
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3537 Node* obj,
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3538 Node* adr,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3539 uint alias_idx,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3540 Node* val,
825
8f5825e0aeaa 6818666: G1: Type lost in g1 pre-barrier
never
parents: 780
diff changeset
3541 const TypeOopPtr* val_type,
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3542 Node* pre_val,
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3543 BasicType bt) {
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3544
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3545 // Some sanity checks
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3546 // Note: val is unused in this routine.
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3547
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3548 if (do_load) {
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3549 // We need to generate the load of the previous value
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3550 assert(obj != NULL, "must have a base");
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3551 assert(adr != NULL, "where are loading from?");
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3552 assert(pre_val == NULL, "loaded already?");
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3553 assert(val_type != NULL, "need a type");
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3554 } else {
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3555 // In this case both val_type and alias_idx are unused.
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3556 assert(pre_val != NULL, "must be loaded already");
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3557 assert(pre_val->bottom_type()->basic_type() == T_OBJECT, "or we shouldn't be here");
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3558 }
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3559 assert(bt == T_OBJECT, "or we shouldn't be here");
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3560
2444
07acc51c1d2a 7032314: Allow to generate CallLeafNoFPNode in IdealKit
kvn
parents: 2383
diff changeset
3561 IdealKit ideal(this, true);
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3562
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3563 Node* tls = __ thread(); // ThreadLocalStorage
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3564
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3565 Node* no_ctrl = NULL;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3566 Node* no_base = __ top();
10185
d50cc62e94ff 8012715: G1: GraphKit accesses PtrQueue::_index as int but is size_t
johnc
parents: 8868
diff changeset
3567 Node* zero = __ ConI(0);
d50cc62e94ff 8012715: G1: GraphKit accesses PtrQueue::_index as int but is size_t
johnc
parents: 8868
diff changeset
3568 Node* zeroX = __ ConX(0);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3569
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3570 float likely = PROB_LIKELY(0.999);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3571 float unlikely = PROB_UNLIKELY(0.999);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3572
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3573 BasicType active_type = in_bytes(PtrQueue::byte_width_of_active()) == 4 ? T_INT : T_BYTE;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3574 assert(in_bytes(PtrQueue::byte_width_of_active()) == 4 || in_bytes(PtrQueue::byte_width_of_active()) == 1, "flag width");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3575
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3576 // Offsets into the thread
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3577 const int marking_offset = in_bytes(JavaThread::satb_mark_queue_offset() + // 648
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3578 PtrQueue::byte_offset_of_active());
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3579 const int index_offset = in_bytes(JavaThread::satb_mark_queue_offset() + // 656
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3580 PtrQueue::byte_offset_of_index());
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3581 const int buffer_offset = in_bytes(JavaThread::satb_mark_queue_offset() + // 652
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3582 PtrQueue::byte_offset_of_buf());
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3583
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3584 // Now the actual pointers into the thread
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3585 Node* marking_adr = __ AddP(no_base, tls, __ ConX(marking_offset));
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3586 Node* buffer_adr = __ AddP(no_base, tls, __ ConX(buffer_offset));
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3587 Node* index_adr = __ AddP(no_base, tls, __ ConX(index_offset));
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3588
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3589 // Now some of the values
544
82a980778b92 6793828: G1: invariant: queues are empty when activated
never
parents: 372
diff changeset
3590 Node* marking = __ load(__ ctrl(), marking_adr, TypeInt::INT, active_type, Compile::AliasIdxRaw);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3591
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3592 // if (!marking)
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3593 __ if_then(marking, BoolTest::ne, zero); {
10185
d50cc62e94ff 8012715: G1: GraphKit accesses PtrQueue::_index as int but is size_t
johnc
parents: 8868
diff changeset
3594 BasicType index_bt = TypeX_X->basic_type();
d50cc62e94ff 8012715: G1: GraphKit accesses PtrQueue::_index as int but is size_t
johnc
parents: 8868
diff changeset
3595 assert(sizeof(size_t) == type2aelembytes(index_bt), "Loading G1 PtrQueue::_index with wrong size.");
d50cc62e94ff 8012715: G1: GraphKit accesses PtrQueue::_index as int but is size_t
johnc
parents: 8868
diff changeset
3596 Node* index = __ load(__ ctrl(), index_adr, TypeX_X, index_bt, Compile::AliasIdxRaw);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3597
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3598 if (do_load) {
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3599 // load original value
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3600 // alias_idx correct??
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3601 pre_val = __ load(no_ctrl, adr, val_type, bt, alias_idx);
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3602 }
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3603
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3604 // if (pre_val != NULL)
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3605 __ if_then(pre_val, BoolTest::ne, null()); {
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3606 Node* buffer = __ load(__ ctrl(), buffer_adr, TypeRawPtr::NOTNULL, T_ADDRESS, Compile::AliasIdxRaw);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3607
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3608 // is the queue for this thread full?
10185
d50cc62e94ff 8012715: G1: GraphKit accesses PtrQueue::_index as int but is size_t
johnc
parents: 8868
diff changeset
3609 __ if_then(index, BoolTest::ne, zeroX, likely); {
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3610
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3611 // decrement the index
10185
d50cc62e94ff 8012715: G1: GraphKit accesses PtrQueue::_index as int but is size_t
johnc
parents: 8868
diff changeset
3612 Node* next_index = _gvn.transform(new (C) SubXNode(index, __ ConX(sizeof(intptr_t))));
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3613
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3614 // Now get the buffer location we will log the previous value into and store it
10185
d50cc62e94ff 8012715: G1: GraphKit accesses PtrQueue::_index as int but is size_t
johnc
parents: 8868
diff changeset
3615 Node *log_addr = __ AddP(no_base, buffer, next_index);
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3616 __ store(__ ctrl(), log_addr, pre_val, T_OBJECT, Compile::AliasIdxRaw);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3617 // update the index
10185
d50cc62e94ff 8012715: G1: GraphKit accesses PtrQueue::_index as int but is size_t
johnc
parents: 8868
diff changeset
3618 __ store(__ ctrl(), index_adr, next_index, index_bt, Compile::AliasIdxRaw);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3619
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3620 } __ else_(); {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3621
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3622 // logging buffer is full, call the runtime
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3623 const TypeFunc *tf = OptoRuntime::g1_wb_pre_Type();
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3624 __ make_leaf_call(tf, CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), "g1_wb_pre", pre_val, tls);
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3625 } __ end_if(); // (!index)
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3626 } __ end_if(); // (pre_val != NULL)
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3627 } __ end_if(); // (!marking)
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3628
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3629 // Final sync IdealKit and GraphKit.
2444
07acc51c1d2a 7032314: Allow to generate CallLeafNoFPNode in IdealKit
kvn
parents: 2383
diff changeset
3630 final_sync(ideal);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3631 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3632
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3633 //
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3634 // Update the card table and add card address to the queue
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3635 //
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3636 void GraphKit::g1_mark_card(IdealKit& ideal,
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3637 Node* card_adr,
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3638 Node* oop_store,
985
685e959d09ea 6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents: 955
diff changeset
3639 uint oop_alias_idx,
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3640 Node* index,
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3641 Node* index_adr,
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3642 Node* buffer,
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3643 const TypeFunc* tf) {
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3644
10185
d50cc62e94ff 8012715: G1: GraphKit accesses PtrQueue::_index as int but is size_t
johnc
parents: 8868
diff changeset
3645 Node* zero = __ ConI(0);
d50cc62e94ff 8012715: G1: GraphKit accesses PtrQueue::_index as int but is size_t
johnc
parents: 8868
diff changeset
3646 Node* zeroX = __ ConX(0);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3647 Node* no_base = __ top();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3648 BasicType card_bt = T_BYTE;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3649 // Smash zero into card. MUST BE ORDERED WRT TO STORE
985
685e959d09ea 6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents: 955
diff changeset
3650 __ storeCM(__ ctrl(), card_adr, zero, oop_store, oop_alias_idx, card_bt, Compile::AliasIdxRaw);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3651
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3652 // Now do the queue work
10185
d50cc62e94ff 8012715: G1: GraphKit accesses PtrQueue::_index as int but is size_t
johnc
parents: 8868
diff changeset
3653 __ if_then(index, BoolTest::ne, zeroX); {
d50cc62e94ff 8012715: G1: GraphKit accesses PtrQueue::_index as int but is size_t
johnc
parents: 8868
diff changeset
3654
d50cc62e94ff 8012715: G1: GraphKit accesses PtrQueue::_index as int but is size_t
johnc
parents: 8868
diff changeset
3655 Node* next_index = _gvn.transform(new (C) SubXNode(index, __ ConX(sizeof(intptr_t))));
d50cc62e94ff 8012715: G1: GraphKit accesses PtrQueue::_index as int but is size_t
johnc
parents: 8868
diff changeset
3656 Node* log_addr = __ AddP(no_base, buffer, next_index);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3657
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3658 __ store(__ ctrl(), log_addr, card_adr, T_ADDRESS, Compile::AliasIdxRaw);
10185
d50cc62e94ff 8012715: G1: GraphKit accesses PtrQueue::_index as int but is size_t
johnc
parents: 8868
diff changeset
3659 __ store(__ ctrl(), index_adr, next_index, TypeX_X->basic_type(), Compile::AliasIdxRaw);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3660
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3661 } __ else_(); {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3662 __ make_leaf_call(tf, CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_post), "g1_wb_post", card_adr, __ thread());
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3663 } __ end_if();
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3664
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3665 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3666
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3667 void GraphKit::g1_write_barrier_post(Node* oop_store,
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3668 Node* obj,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3669 Node* adr,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3670 uint alias_idx,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3671 Node* val,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3672 BasicType bt,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3673 bool use_precise) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3674 // If we are writing a NULL then we need no post barrier
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3675
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3676 if (val != NULL && val->is_Con() && val->bottom_type() == TypePtr::NULL_PTR) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3677 // Must be NULL
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3678 const Type* t = val->bottom_type();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3679 assert(t == Type::TOP || t == TypePtr::NULL_PTR, "must be NULL");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3680 // No post barrier if writing NULLx
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3681 return;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3682 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3683
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3684 if (!use_precise) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3685 // All card marks for a (non-array) instance are in one place:
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3686 adr = obj;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3687 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3688 // (Else it's an array (or unknown), and we want more precise card marks.)
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3689 assert(adr != NULL, "");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3690
2444
07acc51c1d2a 7032314: Allow to generate CallLeafNoFPNode in IdealKit
kvn
parents: 2383
diff changeset
3691 IdealKit ideal(this, true);
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3692
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3693 Node* tls = __ thread(); // ThreadLocalStorage
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3694
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3695 Node* no_base = __ top();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3696 float likely = PROB_LIKELY(0.999);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3697 float unlikely = PROB_UNLIKELY(0.999);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3698 Node* zero = __ ConI(0);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3699 Node* zeroX = __ ConX(0);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3700
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3701 // Get the alias_index for raw card-mark memory
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3702 const TypePtr* card_type = TypeRawPtr::BOTTOM;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3703
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3704 const TypeFunc *tf = OptoRuntime::g1_wb_post_Type();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3705
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3706 // Offsets into the thread
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3707 const int index_offset = in_bytes(JavaThread::dirty_card_queue_offset() +
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3708 PtrQueue::byte_offset_of_index());
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3709 const int buffer_offset = in_bytes(JavaThread::dirty_card_queue_offset() +
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3710 PtrQueue::byte_offset_of_buf());
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3711
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3712 // Pointers into the thread
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3713
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3714 Node* buffer_adr = __ AddP(no_base, tls, __ ConX(buffer_offset));
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3715 Node* index_adr = __ AddP(no_base, tls, __ ConX(index_offset));
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3716
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3717 // Now some values
1593
2458a1f25356 6953058: G1: A bigapp crashes with SIGSEGV in compiled code
johnc
parents: 1397
diff changeset
3718 // Use ctrl to avoid hoisting these values past a safepoint, which could
2458a1f25356 6953058: G1: A bigapp crashes with SIGSEGV in compiled code
johnc
parents: 1397
diff changeset
3719 // potentially reset these fields in the JavaThread.
10185
d50cc62e94ff 8012715: G1: GraphKit accesses PtrQueue::_index as int but is size_t
johnc
parents: 8868
diff changeset
3720 Node* index = __ load(__ ctrl(), index_adr, TypeX_X, TypeX_X->basic_type(), Compile::AliasIdxRaw);
1593
2458a1f25356 6953058: G1: A bigapp crashes with SIGSEGV in compiled code
johnc
parents: 1397
diff changeset
3721 Node* buffer = __ load(__ ctrl(), buffer_adr, TypeRawPtr::NOTNULL, T_ADDRESS, Compile::AliasIdxRaw);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3722
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3723 // Convert the store obj pointer to an int prior to doing math on it
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3724 // Must use ctrl to prevent "integerized oop" existing across safepoint
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3725 Node* cast = __ CastPX(__ ctrl(), adr);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3726
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3727 // Divide pointer by card size
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3728 Node* card_offset = __ URShiftX( cast, __ ConI(CardTableModRefBS::card_shift) );
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3729
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3730 // Combine card table base and card offset
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3731 Node* card_adr = __ AddP(no_base, byte_map_base_node(), card_offset );
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3732
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3733 // If we know the value being stored does it cross regions?
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3734
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3735 if (val != NULL) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3736 // Does the store cause us to cross regions?
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3737
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3738 // Should be able to do an unsigned compare of region_size instead of
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3739 // and extra shift. Do we have an unsigned compare??
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3740 // Node* region_size = __ ConI(1 << HeapRegion::LogOfHRGrainBytes);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3741 Node* xor_res = __ URShiftX ( __ XorX( cast, __ CastPX(__ ctrl(), val)), __ ConI(HeapRegion::LogOfHRGrainBytes));
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3742
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3743 // if (xor_res == 0) same region so skip
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3744 __ if_then(xor_res, BoolTest::ne, zeroX); {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3745
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3746 // No barrier if we are storing a NULL
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3747 __ if_then(val, BoolTest::ne, null(), unlikely); {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3748
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3749 // Ok must mark the card if not already dirty
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3750
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3751 // load the original value of the card
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3752 Node* card_val = __ load(__ ctrl(), card_adr, TypeInt::INT, T_BYTE, Compile::AliasIdxRaw);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3753
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3754 __ if_then(card_val, BoolTest::ne, zero); {
985
685e959d09ea 6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents: 955
diff changeset
3755 g1_mark_card(ideal, card_adr, oop_store, alias_idx, index, index_adr, buffer, tf);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3756 } __ end_if();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3757 } __ end_if();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3758 } __ end_if();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3759 } else {
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3760 // Object.clone() instrinsic uses this path.
985
685e959d09ea 6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents: 955
diff changeset
3761 g1_mark_card(ideal, card_adr, oop_store, alias_idx, index, index_adr, buffer, tf);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3762 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3763
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3764 // Final sync IdealKit and GraphKit.
2444
07acc51c1d2a 7032314: Allow to generate CallLeafNoFPNode in IdealKit
kvn
parents: 2383
diff changeset
3765 final_sync(ideal);
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3766 }
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3767 #undef __
6057
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3768
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3769
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3770
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3771 Node* GraphKit::load_String_offset(Node* ctrl, Node* str) {
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3772 if (java_lang_String::has_offset_field()) {
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3773 int offset_offset = java_lang_String::offset_offset_in_bytes();
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3774 const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(),
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3775 false, NULL, 0);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3776 const TypePtr* offset_field_type = string_type->add_offset(offset_offset);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3777 int offset_field_idx = C->get_alias_index(offset_field_type);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3778 return make_load(ctrl,
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3779 basic_plus_adr(str, str, offset_offset),
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3780 TypeInt::INT, T_INT, offset_field_idx);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3781 } else {
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3782 return intcon(0);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3783 }
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3784 }
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3785
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3786 Node* GraphKit::load_String_length(Node* ctrl, Node* str) {
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3787 if (java_lang_String::has_count_field()) {
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3788 int count_offset = java_lang_String::count_offset_in_bytes();
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3789 const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(),
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3790 false, NULL, 0);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3791 const TypePtr* count_field_type = string_type->add_offset(count_offset);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3792 int count_field_idx = C->get_alias_index(count_field_type);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3793 return make_load(ctrl,
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3794 basic_plus_adr(str, str, count_offset),
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3795 TypeInt::INT, T_INT, count_field_idx);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3796 } else {
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3797 return load_array_length(load_String_value(ctrl, str));
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3798 }
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3799 }
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3800
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3801 Node* GraphKit::load_String_value(Node* ctrl, Node* str) {
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3802 int value_offset = java_lang_String::value_offset_in_bytes();
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3803 const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(),
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3804 false, NULL, 0);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3805 const TypePtr* value_field_type = string_type->add_offset(value_offset);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3806 const TypeAryPtr* value_type = TypeAryPtr::make(TypePtr::NotNull,
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3807 TypeAry::make(TypeInt::CHAR,TypeInt::POS),
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3808 ciTypeArrayKlass::make(T_CHAR), true, 0);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3809 int value_field_idx = C->get_alias_index(value_field_type);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3810 return make_load(ctrl, basic_plus_adr(str, str, value_offset),
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3811 value_type, T_OBJECT, value_field_idx);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3812 }
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3813
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3814 void GraphKit::store_String_offset(Node* ctrl, Node* str, Node* value) {
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3815 int offset_offset = java_lang_String::offset_offset_in_bytes();
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3816 const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(),
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3817 false, NULL, 0);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3818 const TypePtr* offset_field_type = string_type->add_offset(offset_offset);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3819 int offset_field_idx = C->get_alias_index(offset_field_type);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3820 store_to_memory(ctrl, basic_plus_adr(str, offset_offset),
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3821 value, T_INT, offset_field_idx);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3822 }
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3823
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3824 void GraphKit::store_String_value(Node* ctrl, Node* str, Node* value) {
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3825 int value_offset = java_lang_String::value_offset_in_bytes();
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3826 const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(),
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3827 false, NULL, 0);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3828 const TypePtr* value_field_type = string_type->add_offset(value_offset);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3829 const TypeAryPtr* value_type = TypeAryPtr::make(TypePtr::NotNull,
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3830 TypeAry::make(TypeInt::CHAR,TypeInt::POS),
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3831 ciTypeArrayKlass::make(T_CHAR), true, 0);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3832 int value_field_idx = C->get_alias_index(value_field_type);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3833 store_to_memory(ctrl, basic_plus_adr(str, value_offset),
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3834 value, T_OBJECT, value_field_idx);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3835 }
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3836
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3837 void GraphKit::store_String_length(Node* ctrl, Node* str, Node* value) {
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3838 int count_offset = java_lang_String::count_offset_in_bytes();
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3839 const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(),
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3840 false, NULL, 0);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3841 const TypePtr* count_field_type = string_type->add_offset(count_offset);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3842 int count_field_idx = C->get_alias_index(count_field_type);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3843 store_to_memory(ctrl, basic_plus_adr(str, count_offset),
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3844 value, T_INT, count_field_idx);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
3845 }