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