annotate src/share/vm/opto/graphKit.cpp @ 1941:79d04223b8a5

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