Mercurial > hg > truffle
annotate src/share/vm/opto/graphKit.cpp @ 1721:413ad0331a0c
6977924: Changes for 6975078 produce build error with certain gcc versions
Summary: The changes introduced for 6975078 assign badHeapOopVal to the _allocation field in the ResourceObj class. In 32 bit linux builds with certain versions of gcc this assignment will be flagged as an error while compiling allocation.cpp. In 32 bit builds the constant value badHeapOopVal (which is cast to an intptr_t) is negative. The _allocation field is typed as an unsigned intptr_t and gcc catches this as an error.
Reviewed-by: jcoomes, ysr, phh
author | johnc |
---|---|
date | Wed, 18 Aug 2010 10:59:06 -0700 |
parents | 4311f23817fd |
children | 4b29a725c43c |
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)); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1027
diff
changeset
|
1742 |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1027
diff
changeset
|
1743 // 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
|
1744 if (callprojs.resproj != NULL && result != NULL) { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1027
diff
changeset
|
1745 C->gvn_replace_by(callprojs.resproj, result); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1027
diff
changeset
|
1746 } |
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 if (ejvms == NULL) { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1027
diff
changeset
|
1749 // No exception edges to simply kill off those paths |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1027
diff
changeset
|
1750 C->gvn_replace_by(callprojs.catchall_catchproj, C->top()); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1027
diff
changeset
|
1751 C->gvn_replace_by(callprojs.catchall_memproj, C->top()); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1027
diff
changeset
|
1752 C->gvn_replace_by(callprojs.catchall_ioproj, C->top()); |
1099
c5d3d979ae27
6908167: jbb2005, OptimizeStringConcat causes assert in EA
never
parents:
1080
diff
changeset
|
1753 |
c5d3d979ae27
6908167: jbb2005, OptimizeStringConcat causes assert in EA
never
parents:
1080
diff
changeset
|
1754 // Replace the old exception object with top |
c5d3d979ae27
6908167: jbb2005, OptimizeStringConcat causes assert in EA
never
parents:
1080
diff
changeset
|
1755 if (callprojs.exobj != NULL) { |
c5d3d979ae27
6908167: jbb2005, OptimizeStringConcat causes assert in EA
never
parents:
1080
diff
changeset
|
1756 C->gvn_replace_by(callprojs.exobj, C->top()); |
c5d3d979ae27
6908167: jbb2005, OptimizeStringConcat causes assert in EA
never
parents:
1080
diff
changeset
|
1757 } |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1027
diff
changeset
|
1758 } else { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1027
diff
changeset
|
1759 GraphKit ekit(ejvms); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1027
diff
changeset
|
1760 |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1027
diff
changeset
|
1761 // 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
|
1762 SafePointNode* ex_map = ekit.combine_and_pop_all_exception_states(); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1027
diff
changeset
|
1763 |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1027
diff
changeset
|
1764 Node* ex_oop = ekit.use_exception_state(ex_map); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1027
diff
changeset
|
1765 |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1027
diff
changeset
|
1766 C->gvn_replace_by(callprojs.catchall_catchproj, ekit.control()); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1027
diff
changeset
|
1767 C->gvn_replace_by(callprojs.catchall_memproj, ekit.reset_memory()); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1027
diff
changeset
|
1768 C->gvn_replace_by(callprojs.catchall_ioproj, ekit.i_o()); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1027
diff
changeset
|
1769 |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1027
diff
changeset
|
1770 // Replace the old exception object with the newly created one |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1027
diff
changeset
|
1771 if (callprojs.exobj != NULL) { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1027
diff
changeset
|
1772 C->gvn_replace_by(callprojs.exobj, ex_oop); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1027
diff
changeset
|
1773 } |
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 // Disconnect the call from the graph |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1027
diff
changeset
|
1777 call->disconnect_inputs(NULL); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1027
diff
changeset
|
1778 C->gvn_replace_by(call, C->top()); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1027
diff
changeset
|
1779 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1027
diff
changeset
|
1780 |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1027
diff
changeset
|
1781 |
0 | 1782 //------------------------------increment_counter------------------------------ |
1783 // for statistics: increment a VM counter by 1 | |
1784 | |
1785 void GraphKit::increment_counter(address counter_addr) { | |
1786 Node* adr1 = makecon(TypeRawPtr::make(counter_addr)); | |
1787 increment_counter(adr1); | |
1788 } | |
1789 | |
1790 void GraphKit::increment_counter(Node* counter_addr) { | |
1791 int adr_type = Compile::AliasIdxRaw; | |
1609 | 1792 Node* ctrl = control(); |
1793 Node* cnt = make_load(ctrl, counter_addr, TypeInt::INT, T_INT, adr_type); | |
0 | 1794 Node* incr = _gvn.transform(new (C, 3) AddINode(cnt, _gvn.intcon(1))); |
1609 | 1795 store_to_memory( ctrl, counter_addr, incr, T_INT, adr_type ); |
0 | 1796 } |
1797 | |
1798 | |
1799 //------------------------------uncommon_trap---------------------------------- | |
1800 // Bail out to the interpreter in mid-method. Implemented by calling the | |
1801 // uncommon_trap blob. This helper function inserts a runtime call with the | |
1802 // right debug info. | |
1803 void GraphKit::uncommon_trap(int trap_request, | |
1804 ciKlass* klass, const char* comment, | |
1805 bool must_throw, | |
1806 bool keep_exact_action) { | |
1807 if (failing()) stop(); | |
1808 if (stopped()) return; // trap reachable? | |
1809 | |
1810 // Note: If ProfileTraps is true, and if a deopt. actually | |
1811 // occurs here, the runtime will make sure an MDO exists. There is | |
1812 // no need to call method()->build_method_data() at this point. | |
1813 | |
1814 #ifdef ASSERT | |
1815 if (!must_throw) { | |
1816 // Make sure the stack has at least enough depth to execute | |
1817 // the current bytecode. | |
1818 int inputs, ignore; | |
1819 if (compute_stack_effects(inputs, ignore)) { | |
1820 assert(sp() >= inputs, "must have enough JVMS stack to execute"); | |
1821 // It is a frequent error in library_call.cpp to issue an | |
1822 // uncommon trap with the _sp value already popped. | |
1823 } | |
1824 } | |
1825 #endif | |
1826 | |
1827 Deoptimization::DeoptReason reason = Deoptimization::trap_request_reason(trap_request); | |
1828 Deoptimization::DeoptAction action = Deoptimization::trap_request_action(trap_request); | |
1829 | |
1830 switch (action) { | |
1831 case Deoptimization::Action_maybe_recompile: | |
1832 case Deoptimization::Action_reinterpret: | |
1833 // Temporary fix for 6529811 to allow virtual calls to be sure they | |
1834 // get the chance to go from mono->bi->mega | |
1835 if (!keep_exact_action && | |
1836 Deoptimization::trap_request_index(trap_request) < 0 && | |
1837 too_many_recompiles(reason)) { | |
1838 // This BCI is causing too many recompilations. | |
1839 action = Deoptimization::Action_none; | |
1840 trap_request = Deoptimization::make_trap_request(reason, action); | |
1841 } else { | |
1842 C->set_trap_can_recompile(true); | |
1843 } | |
1844 break; | |
1845 case Deoptimization::Action_make_not_entrant: | |
1846 C->set_trap_can_recompile(true); | |
1847 break; | |
1848 #ifdef ASSERT | |
1849 case Deoptimization::Action_none: | |
1850 case Deoptimization::Action_make_not_compilable: | |
1851 break; | |
1852 default: | |
1853 assert(false, "bad action"); | |
1854 #endif | |
1855 } | |
1856 | |
1857 if (TraceOptoParse) { | |
1858 char buf[100]; | |
1859 tty->print_cr("Uncommon trap %s at bci:%d", | |
1860 Deoptimization::format_trap_request(buf, sizeof(buf), | |
1861 trap_request), bci()); | |
1862 } | |
1863 | |
1864 CompileLog* log = C->log(); | |
1865 if (log != NULL) { | |
1866 int kid = (klass == NULL)? -1: log->identify(klass); | |
1867 log->begin_elem("uncommon_trap bci='%d'", bci()); | |
1868 char buf[100]; | |
1869 log->print(" %s", Deoptimization::format_trap_request(buf, sizeof(buf), | |
1870 trap_request)); | |
1871 if (kid >= 0) log->print(" klass='%d'", kid); | |
1872 if (comment != NULL) log->print(" comment='%s'", comment); | |
1873 log->end_elem(); | |
1874 } | |
1875 | |
1876 // Make sure any guarding test views this path as very unlikely | |
1877 Node *i0 = control()->in(0); | |
1878 if (i0 != NULL && i0->is_If()) { // Found a guarding if test? | |
1879 IfNode *iff = i0->as_If(); | |
1880 float f = iff->_prob; // Get prob | |
1881 if (control()->Opcode() == Op_IfTrue) { | |
1882 if (f > PROB_UNLIKELY_MAG(4)) | |
1883 iff->_prob = PROB_MIN; | |
1884 } else { | |
1885 if (f < PROB_LIKELY_MAG(4)) | |
1886 iff->_prob = PROB_MAX; | |
1887 } | |
1888 } | |
1889 | |
1890 // Clear out dead values from the debug info. | |
1891 kill_dead_locals(); | |
1892 | |
1893 // Now insert the uncommon trap subroutine call | |
1894 address call_addr = SharedRuntime::uncommon_trap_blob()->instructions_begin(); | |
1895 const TypePtr* no_memory_effects = NULL; | |
1896 // Pass the index of the class to be loaded | |
1897 Node* call = make_runtime_call(RC_NO_LEAF | RC_UNCOMMON | | |
1898 (must_throw ? RC_MUST_THROW : 0), | |
1899 OptoRuntime::uncommon_trap_Type(), | |
1900 call_addr, "uncommon_trap", no_memory_effects, | |
1901 intcon(trap_request)); | |
1902 assert(call->as_CallStaticJava()->uncommon_trap_request() == trap_request, | |
1903 "must extract request correctly from the graph"); | |
1904 assert(trap_request != 0, "zero value reserved by uncommon_trap_request"); | |
1905 | |
1906 call->set_req(TypeFunc::ReturnAdr, returnadr()); | |
1907 // The debug info is the only real input to this call. | |
1908 | |
1909 // Halt-and-catch fire here. The above call should never return! | |
1910 HaltNode* halt = new(C, TypeFunc::Parms) HaltNode(control(), frameptr()); | |
1911 _gvn.set_type_bottom(halt); | |
1912 root()->add_req(halt); | |
1913 | |
1914 stop_and_kill_map(); | |
1915 } | |
1916 | |
1917 | |
1918 //--------------------------just_allocated_object------------------------------ | |
1919 // Report the object that was just allocated. | |
1920 // It must be the case that there are no intervening safepoints. | |
1921 // We use this to determine if an object is so "fresh" that | |
1922 // it does not require card marks. | |
1923 Node* GraphKit::just_allocated_object(Node* current_control) { | |
1924 if (C->recent_alloc_ctl() == current_control) | |
1925 return C->recent_alloc_obj(); | |
1926 return NULL; | |
1927 } | |
1928 | |
1929 | |
1930 void GraphKit::round_double_arguments(ciMethod* dest_method) { | |
1931 // (Note: TypeFunc::make has a cache that makes this fast.) | |
1932 const TypeFunc* tf = TypeFunc::make(dest_method); | |
1933 int nargs = tf->_domain->_cnt - TypeFunc::Parms; | |
1934 for (int j = 0; j < nargs; j++) { | |
1935 const Type *targ = tf->_domain->field_at(j + TypeFunc::Parms); | |
1936 if( targ->basic_type() == T_DOUBLE ) { | |
1937 // If any parameters are doubles, they must be rounded before | |
1938 // the call, dstore_rounding does gvn.transform | |
1939 Node *arg = argument(j); | |
1940 arg = dstore_rounding(arg); | |
1941 set_argument(j, arg); | |
1942 } | |
1943 } | |
1944 } | |
1945 | |
1946 void GraphKit::round_double_result(ciMethod* dest_method) { | |
1947 // A non-strict method may return a double value which has an extended | |
1948 // exponent, but this must not be visible in a caller which is 'strict' | |
1949 // If a strict caller invokes a non-strict callee, round a double result | |
1950 | |
1951 BasicType result_type = dest_method->return_type()->basic_type(); | |
1952 assert( method() != NULL, "must have caller context"); | |
1953 if( result_type == T_DOUBLE && method()->is_strict() && !dest_method->is_strict() ) { | |
1954 // Destination method's return value is on top of stack | |
1955 // dstore_rounding() does gvn.transform | |
1956 Node *result = pop_pair(); | |
1957 result = dstore_rounding(result); | |
1958 push_pair(result); | |
1959 } | |
1960 } | |
1961 | |
1962 // rounding for strict float precision conformance | |
1963 Node* GraphKit::precision_rounding(Node* n) { | |
1964 return UseStrictFP && _method->flags().is_strict() | |
1965 && UseSSE == 0 && Matcher::strict_fp_requires_explicit_rounding | |
1966 ? _gvn.transform( new (C, 2) RoundFloatNode(0, n) ) | |
1967 : n; | |
1968 } | |
1969 | |
1970 // rounding for strict double precision conformance | |
1971 Node* GraphKit::dprecision_rounding(Node *n) { | |
1972 return UseStrictFP && _method->flags().is_strict() | |
1973 && UseSSE <= 1 && Matcher::strict_fp_requires_explicit_rounding | |
1974 ? _gvn.transform( new (C, 2) RoundDoubleNode(0, n) ) | |
1975 : n; | |
1976 } | |
1977 | |
1978 // rounding for non-strict double stores | |
1979 Node* GraphKit::dstore_rounding(Node* n) { | |
1980 return Matcher::strict_fp_requires_explicit_rounding | |
1981 && UseSSE <= 1 | |
1982 ? _gvn.transform( new (C, 2) RoundDoubleNode(0, n) ) | |
1983 : n; | |
1984 } | |
1985 | |
1986 //============================================================================= | |
1987 // Generate a fast path/slow path idiom. Graph looks like: | |
1988 // [foo] indicates that 'foo' is a parameter | |
1989 // | |
1990 // [in] NULL | |
1991 // \ / | |
1992 // CmpP | |
1993 // Bool ne | |
1994 // If | |
1995 // / \ | |
1996 // True False-<2> | |
1997 // / | | |
1998 // / cast_not_null | |
1999 // Load | | ^ | |
2000 // [fast_test] | | | |
2001 // gvn to opt_test | | | |
2002 // / \ | <1> | |
2003 // True False | | |
2004 // | \\ | | |
2005 // [slow_call] \[fast_result] | |
2006 // Ctl Val \ \ | |
2007 // | \ \ | |
2008 // Catch <1> \ \ | |
2009 // / \ ^ \ \ | |
2010 // Ex No_Ex | \ \ | |
2011 // | \ \ | \ <2> \ | |
2012 // ... \ [slow_res] | | \ [null_result] | |
2013 // \ \--+--+--- | | | |
2014 // \ | / \ | / | |
2015 // --------Region Phi | |
2016 // | |
2017 //============================================================================= | |
2018 // Code is structured as a series of driver functions all called 'do_XXX' that | |
2019 // call a set of helper functions. Helper functions first, then drivers. | |
2020 | |
2021 //------------------------------null_check_oop--------------------------------- | |
2022 // Null check oop. Set null-path control into Region in slot 3. | |
2023 // Make a cast-not-nullness use the other not-null control. Return cast. | |
2024 Node* GraphKit::null_check_oop(Node* value, Node* *null_control, | |
2025 bool never_see_null) { | |
2026 // Initial NULL check taken path | |
2027 (*null_control) = top(); | |
2028 Node* cast = null_check_common(value, T_OBJECT, false, null_control); | |
2029 | |
2030 // Generate uncommon_trap: | |
2031 if (never_see_null && (*null_control) != top()) { | |
2032 // If we see an unexpected null at a check-cast we record it and force a | |
2033 // recompile; the offending check-cast will be compiled to handle NULLs. | |
2034 // If we see more than one offending BCI, then all checkcasts in the | |
2035 // method will be compiled to handle NULLs. | |
2036 PreserveJVMState pjvms(this); | |
2037 set_control(*null_control); | |
332 | 2038 replace_in_map(value, null()); |
0 | 2039 uncommon_trap(Deoptimization::Reason_null_check, |
2040 Deoptimization::Action_make_not_entrant); | |
2041 (*null_control) = top(); // NULL path is dead | |
2042 } | |
2043 | |
2044 // Cast away null-ness on the result | |
2045 return cast; | |
2046 } | |
2047 | |
2048 //------------------------------opt_iff---------------------------------------- | |
2049 // Optimize the fast-check IfNode. Set the fast-path region slot 2. | |
2050 // Return slow-path control. | |
2051 Node* GraphKit::opt_iff(Node* region, Node* iff) { | |
2052 IfNode *opt_iff = _gvn.transform(iff)->as_If(); | |
2053 | |
2054 // Fast path taken; set region slot 2 | |
2055 Node *fast_taken = _gvn.transform( new (C, 1) IfFalseNode(opt_iff) ); | |
2056 region->init_req(2,fast_taken); // Capture fast-control | |
2057 | |
2058 // Fast path not-taken, i.e. slow path | |
2059 Node *slow_taken = _gvn.transform( new (C, 1) IfTrueNode(opt_iff) ); | |
2060 return slow_taken; | |
2061 } | |
2062 | |
2063 //-----------------------------make_runtime_call------------------------------- | |
2064 Node* GraphKit::make_runtime_call(int flags, | |
2065 const TypeFunc* call_type, address call_addr, | |
2066 const char* call_name, | |
2067 const TypePtr* adr_type, | |
2068 // The following parms are all optional. | |
2069 // The first NULL ends the list. | |
2070 Node* parm0, Node* parm1, | |
2071 Node* parm2, Node* parm3, | |
2072 Node* parm4, Node* parm5, | |
2073 Node* parm6, Node* parm7) { | |
2074 // Slow-path call | |
2075 int size = call_type->domain()->cnt(); | |
2076 bool is_leaf = !(flags & RC_NO_LEAF); | |
2077 bool has_io = (!is_leaf && !(flags & RC_NO_IO)); | |
2078 if (call_name == NULL) { | |
2079 assert(!is_leaf, "must supply name for leaf"); | |
2080 call_name = OptoRuntime::stub_name(call_addr); | |
2081 } | |
2082 CallNode* call; | |
2083 if (!is_leaf) { | |
2084 call = new(C, size) CallStaticJavaNode(call_type, call_addr, call_name, | |
2085 bci(), adr_type); | |
2086 } else if (flags & RC_NO_FP) { | |
2087 call = new(C, size) CallLeafNoFPNode(call_type, call_addr, call_name, adr_type); | |
2088 } else { | |
2089 call = new(C, size) CallLeafNode(call_type, call_addr, call_name, adr_type); | |
2090 } | |
2091 | |
2092 // The following is similar to set_edges_for_java_call, | |
2093 // except that the memory effects of the call are restricted to AliasIdxRaw. | |
2094 | |
2095 // Slow path call has no side-effects, uses few values | |
2096 bool wide_in = !(flags & RC_NARROW_MEM); | |
2097 bool wide_out = (C->get_alias_index(adr_type) == Compile::AliasIdxBot); | |
2098 | |
2099 Node* prev_mem = NULL; | |
2100 if (wide_in) { | |
2101 prev_mem = set_predefined_input_for_runtime_call(call); | |
2102 } else { | |
2103 assert(!wide_out, "narrow in => narrow out"); | |
2104 Node* narrow_mem = memory(adr_type); | |
2105 prev_mem = reset_memory(); | |
2106 map()->set_memory(narrow_mem); | |
2107 set_predefined_input_for_runtime_call(call); | |
2108 } | |
2109 | |
2110 // Hook each parm in order. Stop looking at the first NULL. | |
2111 if (parm0 != NULL) { call->init_req(TypeFunc::Parms+0, parm0); | |
2112 if (parm1 != NULL) { call->init_req(TypeFunc::Parms+1, parm1); | |
2113 if (parm2 != NULL) { call->init_req(TypeFunc::Parms+2, parm2); | |
2114 if (parm3 != NULL) { call->init_req(TypeFunc::Parms+3, parm3); | |
2115 if (parm4 != NULL) { call->init_req(TypeFunc::Parms+4, parm4); | |
2116 if (parm5 != NULL) { call->init_req(TypeFunc::Parms+5, parm5); | |
2117 if (parm6 != NULL) { call->init_req(TypeFunc::Parms+6, parm6); | |
2118 if (parm7 != NULL) { call->init_req(TypeFunc::Parms+7, parm7); | |
2119 /* close each nested if ===> */ } } } } } } } } | |
2120 assert(call->in(call->req()-1) != NULL, "must initialize all parms"); | |
2121 | |
2122 if (!is_leaf) { | |
2123 // Non-leaves can block and take safepoints: | |
2124 add_safepoint_edges(call, ((flags & RC_MUST_THROW) != 0)); | |
2125 } | |
2126 // Non-leaves can throw exceptions: | |
2127 if (has_io) { | |
2128 call->set_req(TypeFunc::I_O, i_o()); | |
2129 } | |
2130 | |
2131 if (flags & RC_UNCOMMON) { | |
2132 // Set the count to a tiny probability. Cf. Estimate_Block_Frequency. | |
2133 // (An "if" probability corresponds roughly to an unconditional count. | |
2134 // Sort of.) | |
2135 call->set_cnt(PROB_UNLIKELY_MAG(4)); | |
2136 } | |
2137 | |
2138 Node* c = _gvn.transform(call); | |
2139 assert(c == call, "cannot disappear"); | |
2140 | |
2141 if (wide_out) { | |
2142 // Slow path call has full side-effects. | |
2143 set_predefined_output_for_runtime_call(call); | |
2144 } else { | |
2145 // Slow path call has few side-effects, and/or sets few values. | |
2146 set_predefined_output_for_runtime_call(call, prev_mem, adr_type); | |
2147 } | |
2148 | |
2149 if (has_io) { | |
2150 set_i_o(_gvn.transform(new (C, 1) ProjNode(call, TypeFunc::I_O))); | |
2151 } | |
2152 return call; | |
2153 | |
2154 } | |
2155 | |
2156 //------------------------------merge_memory----------------------------------- | |
2157 // Merge memory from one path into the current memory state. | |
2158 void GraphKit::merge_memory(Node* new_mem, Node* region, int new_path) { | |
2159 for (MergeMemStream mms(merged_memory(), new_mem->as_MergeMem()); mms.next_non_empty2(); ) { | |
2160 Node* old_slice = mms.force_memory(); | |
2161 Node* new_slice = mms.memory2(); | |
2162 if (old_slice != new_slice) { | |
2163 PhiNode* phi; | |
2164 if (new_slice->is_Phi() && new_slice->as_Phi()->region() == region) { | |
2165 phi = new_slice->as_Phi(); | |
2166 #ifdef ASSERT | |
2167 if (old_slice->is_Phi() && old_slice->as_Phi()->region() == region) | |
2168 old_slice = old_slice->in(new_path); | |
2169 // Caller is responsible for ensuring that any pre-existing | |
2170 // phis are already aware of old memory. | |
2171 int old_path = (new_path > 1) ? 1 : 2; // choose old_path != new_path | |
2172 assert(phi->in(old_path) == old_slice, "pre-existing phis OK"); | |
2173 #endif | |
2174 mms.set_memory(phi); | |
2175 } else { | |
2176 phi = PhiNode::make(region, old_slice, Type::MEMORY, mms.adr_type(C)); | |
2177 _gvn.set_type(phi, Type::MEMORY); | |
2178 phi->set_req(new_path, new_slice); | |
2179 mms.set_memory(_gvn.transform(phi)); // assume it is complete | |
2180 } | |
2181 } | |
2182 } | |
2183 } | |
2184 | |
2185 //------------------------------make_slow_call_ex------------------------------ | |
2186 // Make the exception handler hookups for the slow call | |
2187 void GraphKit::make_slow_call_ex(Node* call, ciInstanceKlass* ex_klass, bool separate_io_proj) { | |
2188 if (stopped()) return; | |
2189 | |
2190 // Make a catch node with just two handlers: fall-through and catch-all | |
2191 Node* i_o = _gvn.transform( new (C, 1) ProjNode(call, TypeFunc::I_O, separate_io_proj) ); | |
2192 Node* catc = _gvn.transform( new (C, 2) CatchNode(control(), i_o, 2) ); | |
2193 Node* norm = _gvn.transform( new (C, 1) CatchProjNode(catc, CatchProjNode::fall_through_index, CatchProjNode::no_handler_bci) ); | |
2194 Node* excp = _gvn.transform( new (C, 1) CatchProjNode(catc, CatchProjNode::catch_all_index, CatchProjNode::no_handler_bci) ); | |
2195 | |
2196 { PreserveJVMState pjvms(this); | |
2197 set_control(excp); | |
2198 set_i_o(i_o); | |
2199 | |
2200 if (excp != top()) { | |
2201 // Create an exception state also. | |
2202 // Use an exact type if the caller has specified a specific exception. | |
2203 const Type* ex_type = TypeOopPtr::make_from_klass_unique(ex_klass)->cast_to_ptr_type(TypePtr::NotNull); | |
2204 Node* ex_oop = new (C, 2) CreateExNode(ex_type, control(), i_o); | |
2205 add_exception_state(make_exception_state(_gvn.transform(ex_oop))); | |
2206 } | |
2207 } | |
2208 | |
2209 // Get the no-exception control from the CatchNode. | |
2210 set_control(norm); | |
2211 } | |
2212 | |
2213 | |
2214 //-------------------------------gen_subtype_check----------------------------- | |
2215 // Generate a subtyping check. Takes as input the subtype and supertype. | |
2216 // Returns 2 values: sets the default control() to the true path and returns | |
2217 // the false path. Only reads invariant memory; sets no (visible) memory. | |
2218 // The PartialSubtypeCheckNode sets the hidden 1-word cache in the encoding | |
2219 // but that's not exposed to the optimizer. This call also doesn't take in an | |
2220 // Object; if you wish to check an Object you need to load the Object's class | |
2221 // prior to coming here. | |
2222 Node* GraphKit::gen_subtype_check(Node* subklass, Node* superklass) { | |
2223 // Fast check for identical types, perhaps identical constants. | |
2224 // The types can even be identical non-constants, in cases | |
2225 // involving Array.newInstance, Object.clone, etc. | |
2226 if (subklass == superklass) | |
2227 return top(); // false path is dead; no test needed. | |
2228 | |
2229 if (_gvn.type(superklass)->singleton()) { | |
2230 ciKlass* superk = _gvn.type(superklass)->is_klassptr()->klass(); | |
2231 ciKlass* subk = _gvn.type(subklass)->is_klassptr()->klass(); | |
2232 | |
2233 // In the common case of an exact superklass, try to fold up the | |
2234 // test before generating code. You may ask, why not just generate | |
2235 // the code and then let it fold up? The answer is that the generated | |
2236 // code will necessarily include null checks, which do not always | |
2237 // completely fold away. If they are also needless, then they turn | |
2238 // into a performance loss. Example: | |
2239 // Foo[] fa = blah(); Foo x = fa[0]; fa[1] = x; | |
2240 // Here, the type of 'fa' is often exact, so the store check | |
2241 // of fa[1]=x will fold up, without testing the nullness of x. | |
2242 switch (static_subtype_check(superk, subk)) { | |
2243 case SSC_always_false: | |
2244 { | |
2245 Node* always_fail = control(); | |
2246 set_control(top()); | |
2247 return always_fail; | |
2248 } | |
2249 case SSC_always_true: | |
2250 return top(); | |
2251 case SSC_easy_test: | |
2252 { | |
2253 // Just do a direct pointer compare and be done. | |
2254 Node* cmp = _gvn.transform( new(C, 3) CmpPNode(subklass, superklass) ); | |
2255 Node* bol = _gvn.transform( new(C, 2) BoolNode(cmp, BoolTest::eq) ); | |
2256 IfNode* iff = create_and_xform_if(control(), bol, PROB_STATIC_FREQUENT, COUNT_UNKNOWN); | |
2257 set_control( _gvn.transform( new(C, 1) IfTrueNode (iff) ) ); | |
2258 return _gvn.transform( new(C, 1) IfFalseNode(iff) ); | |
2259 } | |
2260 case SSC_full_test: | |
2261 break; | |
2262 default: | |
2263 ShouldNotReachHere(); | |
2264 } | |
2265 } | |
2266 | |
2267 // %%% Possible further optimization: Even if the superklass is not exact, | |
2268 // if the subklass is the unique subtype of the superklass, the check | |
2269 // will always succeed. We could leave a dependency behind to ensure this. | |
2270 | |
2271 // First load the super-klass's check-offset | |
2272 Node *p1 = basic_plus_adr( superklass, superklass, sizeof(oopDesc) + Klass::super_check_offset_offset_in_bytes() ); | |
2273 Node *chk_off = _gvn.transform( new (C, 3) LoadINode( NULL, memory(p1), p1, _gvn.type(p1)->is_ptr() ) ); | |
2274 int cacheoff_con = sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes(); | |
2275 bool might_be_cache = (find_int_con(chk_off, cacheoff_con) == cacheoff_con); | |
2276 | |
2277 // Load from the sub-klass's super-class display list, or a 1-word cache of | |
2278 // the secondary superclass list, or a failing value with a sentinel offset | |
2279 // if the super-klass is an interface or exceptionally deep in the Java | |
2280 // hierarchy and we have to scan the secondary superclass list the hard way. | |
2281 // Worst-case type is a little odd: NULL is allowed as a result (usually | |
2282 // klass loads can never produce a NULL). | |
2283 Node *chk_off_X = ConvI2X(chk_off); | |
2284 Node *p2 = _gvn.transform( new (C, 4) AddPNode(subklass,subklass,chk_off_X) ); | |
2285 // For some types like interfaces the following loadKlass is from a 1-word | |
2286 // cache which is mutable so can't use immutable memory. Other | |
2287 // types load from the super-class display table which is immutable. | |
2288 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
|
2289 Node *nkls = _gvn.transform( LoadKlassNode::make( _gvn, kmem, p2, _gvn.type(p2)->is_ptr(), TypeKlassPtr::OBJECT_OR_NULL ) ); |
0 | 2290 |
2291 // Compile speed common case: ARE a subtype and we canNOT fail | |
2292 if( superklass == nkls ) | |
2293 return top(); // false path is dead; no test needed. | |
2294 | |
2295 // See if we get an immediate positive hit. Happens roughly 83% of the | |
2296 // time. Test to see if the value loaded just previously from the subklass | |
2297 // is exactly the superklass. | |
2298 Node *cmp1 = _gvn.transform( new (C, 3) CmpPNode( superklass, nkls ) ); | |
2299 Node *bol1 = _gvn.transform( new (C, 2) BoolNode( cmp1, BoolTest::eq ) ); | |
2300 IfNode *iff1 = create_and_xform_if( control(), bol1, PROB_LIKELY(0.83f), COUNT_UNKNOWN ); | |
2301 Node *iftrue1 = _gvn.transform( new (C, 1) IfTrueNode ( iff1 ) ); | |
2302 set_control( _gvn.transform( new (C, 1) IfFalseNode( iff1 ) ) ); | |
2303 | |
2304 // Compile speed common case: Check for being deterministic right now. If | |
2305 // chk_off is a constant and not equal to cacheoff then we are NOT a | |
2306 // subklass. In this case we need exactly the 1 test above and we can | |
2307 // return those results immediately. | |
2308 if (!might_be_cache) { | |
2309 Node* not_subtype_ctrl = control(); | |
2310 set_control(iftrue1); // We need exactly the 1 test above | |
2311 return not_subtype_ctrl; | |
2312 } | |
2313 | |
2314 // Gather the various success & failures here | |
2315 RegionNode *r_ok_subtype = new (C, 4) RegionNode(4); | |
2316 record_for_igvn(r_ok_subtype); | |
2317 RegionNode *r_not_subtype = new (C, 3) RegionNode(3); | |
2318 record_for_igvn(r_not_subtype); | |
2319 | |
2320 r_ok_subtype->init_req(1, iftrue1); | |
2321 | |
2322 // Check for immediate negative hit. Happens roughly 11% of the time (which | |
2323 // is roughly 63% of the remaining cases). Test to see if the loaded | |
2324 // check-offset points into the subklass display list or the 1-element | |
2325 // cache. If it points to the display (and NOT the cache) and the display | |
2326 // missed then it's not a subtype. | |
2327 Node *cacheoff = _gvn.intcon(cacheoff_con); | |
2328 Node *cmp2 = _gvn.transform( new (C, 3) CmpINode( chk_off, cacheoff ) ); | |
2329 Node *bol2 = _gvn.transform( new (C, 2) BoolNode( cmp2, BoolTest::ne ) ); | |
2330 IfNode *iff2 = create_and_xform_if( control(), bol2, PROB_LIKELY(0.63f), COUNT_UNKNOWN ); | |
2331 r_not_subtype->init_req(1, _gvn.transform( new (C, 1) IfTrueNode (iff2) ) ); | |
2332 set_control( _gvn.transform( new (C, 1) IfFalseNode(iff2) ) ); | |
2333 | |
644
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
605
diff
changeset
|
2334 // Check for self. Very rare to get here, but it is taken 1/3 the time. |
0 | 2335 // No performance impact (too rare) but allows sharing of secondary arrays |
2336 // which has some footprint reduction. | |
2337 Node *cmp3 = _gvn.transform( new (C, 3) CmpPNode( subklass, superklass ) ); | |
2338 Node *bol3 = _gvn.transform( new (C, 2) BoolNode( cmp3, BoolTest::eq ) ); | |
2339 IfNode *iff3 = create_and_xform_if( control(), bol3, PROB_LIKELY(0.36f), COUNT_UNKNOWN ); | |
2340 r_ok_subtype->init_req(2, _gvn.transform( new (C, 1) IfTrueNode ( iff3 ) ) ); | |
2341 set_control( _gvn.transform( new (C, 1) IfFalseNode( iff3 ) ) ); | |
2342 | |
644
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
605
diff
changeset
|
2343 // -- Roads not taken here: -- |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
605
diff
changeset
|
2344 // 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
|
2345 // 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
|
2346 // 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
|
2347 // 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
|
2348 // 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
|
2349 // 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
|
2350 // 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
|
2351 // 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
|
2352 // 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
|
2353 // 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
|
2354 // 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
|
2355 // 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
|
2356 // small (register compare, branch). |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
605
diff
changeset
|
2357 |
0 | 2358 // Now do a linear scan of the secondary super-klass array. Again, no real |
2359 // performance impact (too rare) but it's gotta be done. | |
2360 // 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
|
2361 // 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
|
2362 // 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
|
2363 // dependent, and is found in the AD file definition of PartialSubtypeCheck. |
0 | 2364 Node* psc = _gvn.transform( |
2365 new (C, 3) PartialSubtypeCheckNode(control(), subklass, superklass) ); | |
2366 | |
2367 Node *cmp4 = _gvn.transform( new (C, 3) CmpPNode( psc, null() ) ); | |
2368 Node *bol4 = _gvn.transform( new (C, 2) BoolNode( cmp4, BoolTest::ne ) ); | |
2369 IfNode *iff4 = create_and_xform_if( control(), bol4, PROB_FAIR, COUNT_UNKNOWN ); | |
2370 r_not_subtype->init_req(2, _gvn.transform( new (C, 1) IfTrueNode (iff4) ) ); | |
2371 r_ok_subtype ->init_req(3, _gvn.transform( new (C, 1) IfFalseNode(iff4) ) ); | |
2372 | |
2373 // Return false path; set default control to true path. | |
2374 set_control( _gvn.transform(r_ok_subtype) ); | |
2375 return _gvn.transform(r_not_subtype); | |
2376 } | |
2377 | |
2378 //----------------------------static_subtype_check----------------------------- | |
2379 // Shortcut important common cases when superklass is exact: | |
2380 // (0) superklass is java.lang.Object (can occur in reflective code) | |
2381 // (1) subklass is already limited to a subtype of superklass => always ok | |
2382 // (2) subklass does not overlap with superklass => always fail | |
2383 // (3) superklass has NO subtypes and we can check with a simple compare. | |
2384 int GraphKit::static_subtype_check(ciKlass* superk, ciKlass* subk) { | |
2385 if (StressReflectiveCode) { | |
2386 return SSC_full_test; // Let caller generate the general case. | |
2387 } | |
2388 | |
2389 if (superk == env()->Object_klass()) { | |
2390 return SSC_always_true; // (0) this test cannot fail | |
2391 } | |
2392 | |
2393 ciType* superelem = superk; | |
2394 if (superelem->is_array_klass()) | |
2395 superelem = superelem->as_array_klass()->base_element_type(); | |
2396 | |
2397 if (!subk->is_interface()) { // cannot trust static interface types yet | |
2398 if (subk->is_subtype_of(superk)) { | |
2399 return SSC_always_true; // (1) false path dead; no dynamic test needed | |
2400 } | |
2401 if (!(superelem->is_klass() && superelem->as_klass()->is_interface()) && | |
2402 !superk->is_subtype_of(subk)) { | |
2403 return SSC_always_false; | |
2404 } | |
2405 } | |
2406 | |
2407 // If casting to an instance klass, it must have no subtypes | |
2408 if (superk->is_interface()) { | |
2409 // Cannot trust interfaces yet. | |
2410 // %%% S.B. superk->nof_implementors() == 1 | |
2411 } else if (superelem->is_instance_klass()) { | |
2412 ciInstanceKlass* ik = superelem->as_instance_klass(); | |
2413 if (!ik->has_subklass() && !ik->is_interface()) { | |
2414 if (!ik->is_final()) { | |
2415 // Add a dependency if there is a chance of a later subclass. | |
2416 C->dependencies()->assert_leaf_type(ik); | |
2417 } | |
2418 return SSC_easy_test; // (3) caller can do a simple ptr comparison | |
2419 } | |
2420 } else { | |
2421 // A primitive array type has no subtypes. | |
2422 return SSC_easy_test; // (3) caller can do a simple ptr comparison | |
2423 } | |
2424 | |
2425 return SSC_full_test; | |
2426 } | |
2427 | |
2428 // Profile-driven exact type check: | |
2429 Node* GraphKit::type_check_receiver(Node* receiver, ciKlass* klass, | |
2430 float prob, | |
2431 Node* *casted_receiver) { | |
2432 const TypeKlassPtr* tklass = TypeKlassPtr::make(klass); | |
2433 Node* recv_klass = load_object_klass(receiver); | |
2434 Node* want_klass = makecon(tklass); | |
2435 Node* cmp = _gvn.transform( new(C, 3) CmpPNode(recv_klass, want_klass) ); | |
2436 Node* bol = _gvn.transform( new(C, 2) BoolNode(cmp, BoolTest::eq) ); | |
2437 IfNode* iff = create_and_xform_if(control(), bol, prob, COUNT_UNKNOWN); | |
2438 set_control( _gvn.transform( new(C, 1) IfTrueNode (iff) )); | |
2439 Node* fail = _gvn.transform( new(C, 1) IfFalseNode(iff) ); | |
2440 | |
2441 const TypeOopPtr* recv_xtype = tklass->as_instance_type(); | |
2442 assert(recv_xtype->klass_is_exact(), ""); | |
2443 | |
2444 // Subsume downstream occurrences of receiver with a cast to | |
2445 // recv_xtype, since now we know what the type will be. | |
2446 Node* cast = new(C, 2) CheckCastPPNode(control(), receiver, recv_xtype); | |
2447 (*casted_receiver) = _gvn.transform(cast); | |
2448 // (User must make the replace_in_map call.) | |
2449 | |
2450 return fail; | |
2451 } | |
2452 | |
2453 | |
2454 //-------------------------------gen_instanceof-------------------------------- | |
2455 // Generate an instance-of idiom. Used by both the instance-of bytecode | |
2456 // and the reflective instance-of call. | |
2457 Node* GraphKit::gen_instanceof( Node *subobj, Node* superklass ) { | |
2458 C->set_has_split_ifs(true); // Has chance for split-if optimization | |
2459 assert( !stopped(), "dead parse path should be checked in callers" ); | |
2460 assert(!TypePtr::NULL_PTR->higher_equal(_gvn.type(superklass)->is_klassptr()), | |
2461 "must check for not-null not-dead klass in callers"); | |
2462 | |
2463 // Make the merge point | |
2464 enum { _obj_path = 1, _fail_path, _null_path, PATH_LIMIT }; | |
2465 RegionNode* region = new(C, PATH_LIMIT) RegionNode(PATH_LIMIT); | |
2466 Node* phi = new(C, PATH_LIMIT) PhiNode(region, TypeInt::BOOL); | |
2467 C->set_has_split_ifs(true); // Has chance for split-if optimization | |
2468 | |
2469 // Null check; get casted pointer; set region slot 3 | |
2470 Node* null_ctl = top(); | |
2471 Node* not_null_obj = null_check_oop(subobj, &null_ctl); | |
2472 | |
2473 // If not_null_obj is dead, only null-path is taken | |
2474 if (stopped()) { // Doing instance-of on a NULL? | |
2475 set_control(null_ctl); | |
2476 return intcon(0); | |
2477 } | |
2478 region->init_req(_null_path, null_ctl); | |
2479 phi ->init_req(_null_path, intcon(0)); // Set null path value | |
2480 | |
2481 // Load the object's klass | |
2482 Node* obj_klass = load_object_klass(not_null_obj); | |
2483 | |
2484 // Generate the subtype check | |
2485 Node* not_subtype_ctrl = gen_subtype_check(obj_klass, superklass); | |
2486 | |
2487 // Plug in the success path to the general merge in slot 1. | |
2488 region->init_req(_obj_path, control()); | |
2489 phi ->init_req(_obj_path, intcon(1)); | |
2490 | |
2491 // Plug in the failing path to the general merge in slot 2. | |
2492 region->init_req(_fail_path, not_subtype_ctrl); | |
2493 phi ->init_req(_fail_path, intcon(0)); | |
2494 | |
2495 // Return final merged results | |
2496 set_control( _gvn.transform(region) ); | |
2497 record_for_igvn(region); | |
2498 return _gvn.transform(phi); | |
2499 } | |
2500 | |
2501 //-------------------------------gen_checkcast--------------------------------- | |
2502 // Generate a checkcast idiom. Used by both the checkcast bytecode and the | |
2503 // array store bytecode. Stack must be as-if BEFORE doing the bytecode so the | |
2504 // uncommon-trap paths work. Adjust stack after this call. | |
2505 // If failure_control is supplied and not null, it is filled in with | |
2506 // the control edge for the cast failure. Otherwise, an appropriate | |
2507 // uncommon trap or exception is thrown. | |
2508 Node* GraphKit::gen_checkcast(Node *obj, Node* superklass, | |
2509 Node* *failure_control) { | |
2510 kill_dead_locals(); // Benefit all the uncommon traps | |
2511 const TypeKlassPtr *tk = _gvn.type(superklass)->is_klassptr(); | |
2512 const Type *toop = TypeOopPtr::make_from_klass(tk->klass()); | |
2513 | |
2514 // Fast cutout: Check the case that the cast is vacuously true. | |
2515 // This detects the common cases where the test will short-circuit | |
2516 // away completely. We do this before we perform the null check, | |
2517 // because if the test is going to turn into zero code, we don't | |
2518 // want a residual null check left around. (Causes a slowdown, | |
2519 // for example, in some objArray manipulations, such as a[i]=a[j].) | |
2520 if (tk->singleton()) { | |
2521 const TypeOopPtr* objtp = _gvn.type(obj)->isa_oopptr(); | |
2522 if (objtp != NULL && objtp->klass() != NULL) { | |
2523 switch (static_subtype_check(tk->klass(), objtp->klass())) { | |
2524 case SSC_always_true: | |
2525 return obj; | |
2526 case SSC_always_false: | |
2527 // It needs a null check because a null will *pass* the cast check. | |
2528 // A non-null value will always produce an exception. | |
2529 return do_null_assert(obj, T_OBJECT); | |
2530 } | |
2531 } | |
2532 } | |
2533 | |
2534 ciProfileData* data = NULL; | |
2535 if (failure_control == NULL) { // use MDO in regular case only | |
2536 assert(java_bc() == Bytecodes::_aastore || | |
2537 java_bc() == Bytecodes::_checkcast, | |
2538 "interpreter profiles type checks only for these BCs"); | |
2539 data = method()->method_data()->bci_to_data(bci()); | |
2540 } | |
2541 | |
2542 // Make the merge point | |
2543 enum { _obj_path = 1, _null_path, PATH_LIMIT }; | |
2544 RegionNode* region = new (C, PATH_LIMIT) RegionNode(PATH_LIMIT); | |
2545 Node* phi = new (C, PATH_LIMIT) PhiNode(region, toop); | |
2546 C->set_has_split_ifs(true); // Has chance for split-if optimization | |
2547 | |
2548 // Use null-cast information if it is available | |
2549 bool never_see_null = false; | |
2550 // If we see an unexpected null at a check-cast we record it and force a | |
2551 // recompile; the offending check-cast will be compiled to handle NULLs. | |
2552 // If we see several offending BCIs, then all checkcasts in the | |
2553 // method will be compiled to handle NULLs. | |
2554 if (UncommonNullCast // Cutout for this technique | |
2555 && failure_control == NULL // regular case | |
2556 && obj != null() // And not the -Xcomp stupid case? | |
2557 && !too_many_traps(Deoptimization::Reason_null_check)) { | |
2558 // Finally, check the "null_seen" bit from the interpreter. | |
2559 if (data == NULL || !data->as_BitData()->null_seen()) { | |
2560 never_see_null = true; | |
2561 } | |
2562 } | |
2563 | |
2564 // Null check; get casted pointer; set region slot 3 | |
2565 Node* null_ctl = top(); | |
2566 Node* not_null_obj = null_check_oop(obj, &null_ctl, never_see_null); | |
2567 | |
2568 // If not_null_obj is dead, only null-path is taken | |
2569 if (stopped()) { // Doing instance-of on a NULL? | |
2570 set_control(null_ctl); | |
2571 return null(); | |
2572 } | |
2573 region->init_req(_null_path, null_ctl); | |
2574 phi ->init_req(_null_path, null()); // Set null path value | |
2575 | |
2576 Node* cast_obj = NULL; // the casted version of the object | |
2577 | |
2578 // If the profile has seen exactly one type, narrow to that type. | |
2579 // (The subsequent subtype check will always fold up.) | |
2580 if (UseTypeProfile && TypeProfileCasts && data != NULL && | |
2581 // Counter has never been decremented (due to cast failure). | |
2582 // ...This is a reasonable thing to expect. It is true of | |
2583 // all casts inserted by javac to implement generic types. | |
2584 data->as_CounterData()->count() >= 0 && | |
2585 !too_many_traps(Deoptimization::Reason_class_check)) { | |
2586 // (No, this isn't a call, but it's enough like a virtual call | |
2587 // to use the same ciMethod accessor to get the profile info...) | |
2588 ciCallProfile profile = method()->call_profile_at_bci(bci()); | |
2589 if (profile.count() >= 0 && // no cast failures here | |
2590 profile.has_receiver(0) && | |
2591 profile.morphism() == 1) { | |
2592 ciKlass* exact_kls = profile.receiver(0); | |
2593 int ssc = static_subtype_check(tk->klass(), exact_kls); | |
2594 if (ssc == SSC_always_true) { | |
2595 // If we narrow the type to match what the type profile sees, | |
2596 // we can then remove the rest of the cast. | |
2597 // This is a win, even if the exact_kls is very specific, | |
2598 // because downstream operations, such as method calls, | |
2599 // will often benefit from the sharper type. | |
2600 Node* exact_obj = not_null_obj; // will get updated in place... | |
2601 Node* slow_ctl = type_check_receiver(exact_obj, exact_kls, 1.0, | |
2602 &exact_obj); | |
2603 { PreserveJVMState pjvms(this); | |
2604 set_control(slow_ctl); | |
2605 uncommon_trap(Deoptimization::Reason_class_check, | |
2606 Deoptimization::Action_maybe_recompile); | |
2607 } | |
2608 if (failure_control != NULL) // failure is now impossible | |
2609 (*failure_control) = top(); | |
2610 replace_in_map(not_null_obj, exact_obj); | |
2611 // adjust the type of the phi to the exact klass: | |
2612 phi->raise_bottom_type(_gvn.type(exact_obj)->meet(TypePtr::NULL_PTR)); | |
2613 cast_obj = exact_obj; | |
2614 } | |
2615 // assert(cast_obj != NULL)... except maybe the profile lied to us. | |
2616 } | |
2617 } | |
2618 | |
2619 if (cast_obj == NULL) { | |
2620 // Load the object's klass | |
2621 Node* obj_klass = load_object_klass(not_null_obj); | |
2622 | |
2623 // Generate the subtype check | |
2624 Node* not_subtype_ctrl = gen_subtype_check( obj_klass, superklass ); | |
2625 | |
2626 // Plug in success path into the merge | |
2627 cast_obj = _gvn.transform(new (C, 2) CheckCastPPNode(control(), | |
2628 not_null_obj, toop)); | |
2629 // Failure path ends in uncommon trap (or may be dead - failure impossible) | |
2630 if (failure_control == NULL) { | |
2631 if (not_subtype_ctrl != top()) { // If failure is possible | |
2632 PreserveJVMState pjvms(this); | |
2633 set_control(not_subtype_ctrl); | |
2634 builtin_throw(Deoptimization::Reason_class_check, obj_klass); | |
2635 } | |
2636 } else { | |
2637 (*failure_control) = not_subtype_ctrl; | |
2638 } | |
2639 } | |
2640 | |
2641 region->init_req(_obj_path, control()); | |
2642 phi ->init_req(_obj_path, cast_obj); | |
2643 | |
2644 // A merge of NULL or Casted-NotNull obj | |
2645 Node* res = _gvn.transform(phi); | |
2646 | |
2647 // Note I do NOT always 'replace_in_map(obj,result)' here. | |
2648 // if( tk->klass()->can_be_primary_super() ) | |
2649 // This means that if I successfully store an Object into an array-of-String | |
2650 // I 'forget' that the Object is really now known to be a String. I have to | |
2651 // do this because we don't have true union types for interfaces - if I store | |
2652 // a Baz into an array-of-Interface and then tell the optimizer it's an | |
2653 // Interface, I forget that it's also a Baz and cannot do Baz-like field | |
2654 // references to it. FIX THIS WHEN UNION TYPES APPEAR! | |
2655 // replace_in_map( obj, res ); | |
2656 | |
2657 // Return final merged results | |
2658 set_control( _gvn.transform(region) ); | |
2659 record_for_igvn(region); | |
2660 return res; | |
2661 } | |
2662 | |
2663 //------------------------------next_monitor----------------------------------- | |
2664 // What number should be given to the next monitor? | |
2665 int GraphKit::next_monitor() { | |
2666 int current = jvms()->monitor_depth()* C->sync_stack_slots(); | |
2667 int next = current + C->sync_stack_slots(); | |
2668 // Keep the toplevel high water mark current: | |
2669 if (C->fixed_slots() < next) C->set_fixed_slots(next); | |
2670 return current; | |
2671 } | |
2672 | |
2673 //------------------------------insert_mem_bar--------------------------------- | |
2674 // Memory barrier to avoid floating things around | |
2675 // The membar serves as a pinch point between both control and all memory slices. | |
2676 Node* GraphKit::insert_mem_bar(int opcode, Node* precedent) { | |
2677 MemBarNode* mb = MemBarNode::make(C, opcode, Compile::AliasIdxBot, precedent); | |
2678 mb->init_req(TypeFunc::Control, control()); | |
2679 mb->init_req(TypeFunc::Memory, reset_memory()); | |
2680 Node* membar = _gvn.transform(mb); | |
2681 set_control(_gvn.transform(new (C, 1) ProjNode(membar,TypeFunc::Control) )); | |
2682 set_all_memory_call(membar); | |
2683 return membar; | |
2684 } | |
2685 | |
2686 //-------------------------insert_mem_bar_volatile---------------------------- | |
2687 // Memory barrier to avoid floating things around | |
2688 // The membar serves as a pinch point between both control and memory(alias_idx). | |
2689 // If you want to make a pinch point on all memory slices, do not use this | |
2690 // function (even with AliasIdxBot); use insert_mem_bar() instead. | |
2691 Node* GraphKit::insert_mem_bar_volatile(int opcode, int alias_idx, Node* precedent) { | |
2692 // When Parse::do_put_xxx updates a volatile field, it appends a series | |
2693 // of MemBarVolatile nodes, one for *each* volatile field alias category. | |
2694 // The first membar is on the same memory slice as the field store opcode. | |
2695 // This forces the membar to follow the store. (Bug 6500685 broke this.) | |
2696 // All the other membars (for other volatile slices, including AliasIdxBot, | |
2697 // which stands for all unknown volatile slices) are control-dependent | |
2698 // on the first membar. This prevents later volatile loads or stores | |
2699 // from sliding up past the just-emitted store. | |
2700 | |
2701 MemBarNode* mb = MemBarNode::make(C, opcode, alias_idx, precedent); | |
2702 mb->set_req(TypeFunc::Control,control()); | |
2703 if (alias_idx == Compile::AliasIdxBot) { | |
2704 mb->set_req(TypeFunc::Memory, merged_memory()->base_memory()); | |
2705 } else { | |
2706 assert(!(opcode == Op_Initialize && alias_idx != Compile::AliasIdxRaw), "fix caller"); | |
2707 mb->set_req(TypeFunc::Memory, memory(alias_idx)); | |
2708 } | |
2709 Node* membar = _gvn.transform(mb); | |
2710 set_control(_gvn.transform(new (C, 1) ProjNode(membar, TypeFunc::Control))); | |
2711 if (alias_idx == Compile::AliasIdxBot) { | |
2712 merged_memory()->set_base_memory(_gvn.transform(new (C, 1) ProjNode(membar, TypeFunc::Memory))); | |
2713 } else { | |
2714 set_memory(_gvn.transform(new (C, 1) ProjNode(membar, TypeFunc::Memory)),alias_idx); | |
2715 } | |
2716 return membar; | |
2717 } | |
2718 | |
2719 //------------------------------shared_lock------------------------------------ | |
2720 // Emit locking code. | |
2721 FastLockNode* GraphKit::shared_lock(Node* obj) { | |
2722 // bci is either a monitorenter bc or InvocationEntryBci | |
2723 // %%% SynchronizationEntryBCI is redundant; use InvocationEntryBci in interfaces | |
2724 assert(SynchronizationEntryBCI == InvocationEntryBci, ""); | |
2725 | |
2726 if( !GenerateSynchronizationCode ) | |
2727 return NULL; // Not locking things? | |
2728 if (stopped()) // Dead monitor? | |
2729 return NULL; | |
2730 | |
2731 assert(dead_locals_are_killed(), "should kill locals before sync. point"); | |
2732 | |
2733 // Box the stack location | |
2734 Node* box = _gvn.transform(new (C, 1) BoxLockNode(next_monitor())); | |
2735 Node* mem = reset_memory(); | |
2736 | |
2737 FastLockNode * flock = _gvn.transform(new (C, 3) FastLockNode(0, obj, box) )->as_FastLock(); | |
2738 if (PrintPreciseBiasedLockingStatistics) { | |
2739 // Create the counters for this fast lock. | |
2740 flock->create_lock_counter(sync_jvms()); // sync_jvms used to get current bci | |
2741 } | |
2742 // Add monitor to debug info for the slow path. If we block inside the | |
2743 // slow path and de-opt, we need the monitor hanging around | |
2744 map()->push_monitor( flock ); | |
2745 | |
2746 const TypeFunc *tf = LockNode::lock_type(); | |
2747 LockNode *lock = new (C, tf->domain()->cnt()) LockNode(C, tf); | |
2748 | |
2749 lock->init_req( TypeFunc::Control, control() ); | |
2750 lock->init_req( TypeFunc::Memory , mem ); | |
2751 lock->init_req( TypeFunc::I_O , top() ) ; // does no i/o | |
2752 lock->init_req( TypeFunc::FramePtr, frameptr() ); | |
2753 lock->init_req( TypeFunc::ReturnAdr, top() ); | |
2754 | |
2755 lock->init_req(TypeFunc::Parms + 0, obj); | |
2756 lock->init_req(TypeFunc::Parms + 1, box); | |
2757 lock->init_req(TypeFunc::Parms + 2, flock); | |
2758 add_safepoint_edges(lock); | |
2759 | |
2760 lock = _gvn.transform( lock )->as_Lock(); | |
2761 | |
2762 // lock has no side-effects, sets few values | |
2763 set_predefined_output_for_runtime_call(lock, mem, TypeRawPtr::BOTTOM); | |
2764 | |
2765 insert_mem_bar(Op_MemBarAcquire); | |
2766 | |
2767 // Add this to the worklist so that the lock can be eliminated | |
2768 record_for_igvn(lock); | |
2769 | |
2770 #ifndef PRODUCT | |
2771 if (PrintLockStatistics) { | |
2772 // Update the counter for this lock. Don't bother using an atomic | |
2773 // operation since we don't require absolute accuracy. | |
2774 lock->create_lock_counter(map()->jvms()); | |
1609 | 2775 increment_counter(lock->counter()->addr()); |
0 | 2776 } |
2777 #endif | |
2778 | |
2779 return flock; | |
2780 } | |
2781 | |
2782 | |
2783 //------------------------------shared_unlock---------------------------------- | |
2784 // Emit unlocking code. | |
2785 void GraphKit::shared_unlock(Node* box, Node* obj) { | |
2786 // bci is either a monitorenter bc or InvocationEntryBci | |
2787 // %%% SynchronizationEntryBCI is redundant; use InvocationEntryBci in interfaces | |
2788 assert(SynchronizationEntryBCI == InvocationEntryBci, ""); | |
2789 | |
2790 if( !GenerateSynchronizationCode ) | |
2791 return; | |
2792 if (stopped()) { // Dead monitor? | |
2793 map()->pop_monitor(); // Kill monitor from debug info | |
2794 return; | |
2795 } | |
2796 | |
2797 // Memory barrier to avoid floating things down past the locked region | |
2798 insert_mem_bar(Op_MemBarRelease); | |
2799 | |
2800 const TypeFunc *tf = OptoRuntime::complete_monitor_exit_Type(); | |
2801 UnlockNode *unlock = new (C, tf->domain()->cnt()) UnlockNode(C, tf); | |
2802 uint raw_idx = Compile::AliasIdxRaw; | |
2803 unlock->init_req( TypeFunc::Control, control() ); | |
2804 unlock->init_req( TypeFunc::Memory , memory(raw_idx) ); | |
2805 unlock->init_req( TypeFunc::I_O , top() ) ; // does no i/o | |
2806 unlock->init_req( TypeFunc::FramePtr, frameptr() ); | |
2807 unlock->init_req( TypeFunc::ReturnAdr, top() ); | |
2808 | |
2809 unlock->init_req(TypeFunc::Parms + 0, obj); | |
2810 unlock->init_req(TypeFunc::Parms + 1, box); | |
2811 unlock = _gvn.transform(unlock)->as_Unlock(); | |
2812 | |
2813 Node* mem = reset_memory(); | |
2814 | |
2815 // unlock has no side-effects, sets few values | |
2816 set_predefined_output_for_runtime_call(unlock, mem, TypeRawPtr::BOTTOM); | |
2817 | |
2818 // Kill monitor from debug info | |
2819 map()->pop_monitor( ); | |
2820 } | |
2821 | |
2822 //-------------------------------get_layout_helper----------------------------- | |
2823 // If the given klass is a constant or known to be an array, | |
2824 // fetch the constant layout helper value into constant_value | |
2825 // and return (Node*)NULL. Otherwise, load the non-constant | |
2826 // layout helper value, and return the node which represents it. | |
2827 // This two-faced routine is useful because allocation sites | |
2828 // almost always feature constant types. | |
2829 Node* GraphKit::get_layout_helper(Node* klass_node, jint& constant_value) { | |
2830 const TypeKlassPtr* inst_klass = _gvn.type(klass_node)->isa_klassptr(); | |
2831 if (!StressReflectiveCode && inst_klass != NULL) { | |
2832 ciKlass* klass = inst_klass->klass(); | |
2833 bool xklass = inst_klass->klass_is_exact(); | |
2834 if (xklass || klass->is_array_klass()) { | |
2835 jint lhelper = klass->layout_helper(); | |
2836 if (lhelper != Klass::_lh_neutral_value) { | |
2837 constant_value = lhelper; | |
2838 return (Node*) NULL; | |
2839 } | |
2840 } | |
2841 } | |
2842 constant_value = Klass::_lh_neutral_value; // put in a known value | |
2843 Node* lhp = basic_plus_adr(klass_node, klass_node, Klass::layout_helper_offset_in_bytes() + sizeof(oopDesc)); | |
2844 return make_load(NULL, lhp, TypeInt::INT, T_INT); | |
2845 } | |
2846 | |
2847 // We just put in an allocate/initialize with a big raw-memory effect. | |
2848 // Hook selected additional alias categories on the initialization. | |
2849 static void hook_memory_on_init(GraphKit& kit, int alias_idx, | |
2850 MergeMemNode* init_in_merge, | |
2851 Node* init_out_raw) { | |
2852 DEBUG_ONLY(Node* init_in_raw = init_in_merge->base_memory()); | |
2853 assert(init_in_merge->memory_at(alias_idx) == init_in_raw, ""); | |
2854 | |
2855 Node* prevmem = kit.memory(alias_idx); | |
2856 init_in_merge->set_memory_at(alias_idx, prevmem); | |
2857 kit.set_memory(init_out_raw, alias_idx); | |
2858 } | |
2859 | |
2860 //---------------------------set_output_for_allocation------------------------- | |
2861 Node* GraphKit::set_output_for_allocation(AllocateNode* alloc, | |
2862 const TypeOopPtr* oop_type, | |
2863 bool raw_mem_only) { | |
2864 int rawidx = Compile::AliasIdxRaw; | |
2865 alloc->set_req( TypeFunc::FramePtr, frameptr() ); | |
2866 add_safepoint_edges(alloc); | |
2867 Node* allocx = _gvn.transform(alloc); | |
2868 set_control( _gvn.transform(new (C, 1) ProjNode(allocx, TypeFunc::Control) ) ); | |
2869 // create memory projection for i_o | |
2870 set_memory ( _gvn.transform( new (C, 1) ProjNode(allocx, TypeFunc::Memory, true) ), rawidx ); | |
2871 make_slow_call_ex(allocx, env()->OutOfMemoryError_klass(), true); | |
2872 | |
2873 // create a memory projection as for the normal control path | |
2874 Node* malloc = _gvn.transform(new (C, 1) ProjNode(allocx, TypeFunc::Memory)); | |
2875 set_memory(malloc, rawidx); | |
2876 | |
2877 // a normal slow-call doesn't change i_o, but an allocation does | |
2878 // we create a separate i_o projection for the normal control path | |
2879 set_i_o(_gvn.transform( new (C, 1) ProjNode(allocx, TypeFunc::I_O, false) ) ); | |
2880 Node* rawoop = _gvn.transform( new (C, 1) ProjNode(allocx, TypeFunc::Parms) ); | |
2881 | |
2882 // put in an initialization barrier | |
2883 InitializeNode* init = insert_mem_bar_volatile(Op_Initialize, rawidx, | |
2884 rawoop)->as_Initialize(); | |
2885 assert(alloc->initialization() == init, "2-way macro link must work"); | |
2886 assert(init ->allocation() == alloc, "2-way macro link must work"); | |
2887 if (ReduceFieldZeroing && !raw_mem_only) { | |
2888 // Extract memory strands which may participate in the new object's | |
2889 // initialization, and source them from the new InitializeNode. | |
2890 // This will allow us to observe initializations when they occur, | |
2891 // and link them properly (as a group) to the InitializeNode. | |
2892 assert(init->in(InitializeNode::Memory) == malloc, ""); | |
2893 MergeMemNode* minit_in = MergeMemNode::make(C, malloc); | |
2894 init->set_req(InitializeNode::Memory, minit_in); | |
2895 record_for_igvn(minit_in); // fold it up later, if possible | |
2896 Node* minit_out = memory(rawidx); | |
2897 assert(minit_out->is_Proj() && minit_out->in(0) == init, ""); | |
2898 if (oop_type->isa_aryptr()) { | |
2899 const TypePtr* telemref = oop_type->add_offset(Type::OffsetBot); | |
2900 int elemidx = C->get_alias_index(telemref); | |
2901 hook_memory_on_init(*this, elemidx, minit_in, minit_out); | |
2902 } else if (oop_type->isa_instptr()) { | |
2903 ciInstanceKlass* ik = oop_type->klass()->as_instance_klass(); | |
2904 for (int i = 0, len = ik->nof_nonstatic_fields(); i < len; i++) { | |
2905 ciField* field = ik->nonstatic_field_at(i); | |
23
9bdad1bb1c31
6621098: "* HeapWordSize" for TrackedInitializationLimit is missing
kvn
parents:
0
diff
changeset
|
2906 if (field->offset() >= TrackedInitializationLimit * HeapWordSize) |
0 | 2907 continue; // do not bother to track really large numbers of fields |
2908 // Find (or create) the alias category for this field: | |
2909 int fieldidx = C->alias_type(field)->index(); | |
2910 hook_memory_on_init(*this, fieldidx, minit_in, minit_out); | |
2911 } | |
2912 } | |
2913 } | |
2914 | |
2915 // Cast raw oop to the real thing... | |
2916 Node* javaoop = new (C, 2) CheckCastPPNode(control(), rawoop, oop_type); | |
2917 javaoop = _gvn.transform(javaoop); | |
2918 C->set_recent_alloc(control(), javaoop); | |
2919 assert(just_allocated_object(control()) == javaoop, "just allocated"); | |
2920 | |
2921 #ifdef ASSERT | |
366
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
332
diff
changeset
|
2922 { // 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
|
2923 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
|
2924 "Ideal_allocation works"); |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
332
diff
changeset
|
2925 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
|
2926 "Ideal_allocation works"); |
0 | 2927 if (alloc->is_AllocateArray()) { |
366
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
332
diff
changeset
|
2928 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
|
2929 "Ideal_allocation works"); |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
332
diff
changeset
|
2930 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
|
2931 "Ideal_allocation works"); |
0 | 2932 } else { |
366
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
332
diff
changeset
|
2933 assert(alloc->in(AllocateNode::ALength)->is_top(), "no length, please"); |
0 | 2934 } |
2935 } | |
2936 #endif //ASSERT | |
2937 | |
2938 return javaoop; | |
2939 } | |
2940 | |
2941 //---------------------------new_instance-------------------------------------- | |
2942 // This routine takes a klass_node which may be constant (for a static type) | |
2943 // or may be non-constant (for reflective code). It will work equally well | |
2944 // for either, and the graph will fold nicely if the optimizer later reduces | |
2945 // the type to a constant. | |
2946 // The optional arguments are for specialized use by intrinsics: | |
2947 // - If 'extra_slow_test' if not null is an extra condition for the slow-path. | |
2948 // - If 'raw_mem_only', do not cast the result to an oop. | |
2949 // - If 'return_size_val', report the the total object size to the caller. | |
2950 Node* GraphKit::new_instance(Node* klass_node, | |
2951 Node* extra_slow_test, | |
2952 bool raw_mem_only, // affect only raw memory | |
2953 Node* *return_size_val) { | |
2954 // Compute size in doublewords | |
2955 // The size is always an integral number of doublewords, represented | |
2956 // as a positive bytewise size stored in the klass's layout_helper. | |
2957 // The layout_helper also encodes (in a low bit) the need for a slow path. | |
2958 jint layout_con = Klass::_lh_neutral_value; | |
2959 Node* layout_val = get_layout_helper(klass_node, layout_con); | |
2960 int layout_is_con = (layout_val == NULL); | |
2961 | |
2962 if (extra_slow_test == NULL) extra_slow_test = intcon(0); | |
2963 // Generate the initial go-slow test. It's either ALWAYS (return a | |
2964 // Node for 1) or NEVER (return a NULL) or perhaps (in the reflective | |
2965 // case) a computed value derived from the layout_helper. | |
2966 Node* initial_slow_test = NULL; | |
2967 if (layout_is_con) { | |
2968 assert(!StressReflectiveCode, "stress mode does not use these paths"); | |
2969 bool must_go_slow = Klass::layout_helper_needs_slow_path(layout_con); | |
2970 initial_slow_test = must_go_slow? intcon(1): extra_slow_test; | |
2971 | |
2972 } else { // reflective case | |
2973 // This reflective path is used by Unsafe.allocateInstance. | |
2974 // (It may be stress-tested by specifying StressReflectiveCode.) | |
2975 // Basically, we want to get into the VM is there's an illegal argument. | |
2976 Node* bit = intcon(Klass::_lh_instance_slow_path_bit); | |
2977 initial_slow_test = _gvn.transform( new (C, 3) AndINode(layout_val, bit) ); | |
2978 if (extra_slow_test != intcon(0)) { | |
2979 initial_slow_test = _gvn.transform( new (C, 3) OrINode(initial_slow_test, extra_slow_test) ); | |
2980 } | |
2981 // (Macro-expander will further convert this to a Bool, if necessary.) | |
2982 } | |
2983 | |
2984 // Find the size in bytes. This is easy; it's the layout_helper. | |
2985 // The size value must be valid even if the slow path is taken. | |
2986 Node* size = NULL; | |
2987 if (layout_is_con) { | |
2988 size = MakeConX(Klass::layout_helper_size_in_bytes(layout_con)); | |
2989 } else { // reflective case | |
2990 // This reflective path is used by clone and Unsafe.allocateInstance. | |
2991 size = ConvI2X(layout_val); | |
2992 | |
2993 // Clear the low bits to extract layout_helper_size_in_bytes: | |
2994 assert((int)Klass::_lh_instance_slow_path_bit < BytesPerLong, "clear bit"); | |
2995 Node* mask = MakeConX(~ (intptr_t)right_n_bits(LogBytesPerLong)); | |
2996 size = _gvn.transform( new (C, 3) AndXNode(size, mask) ); | |
2997 } | |
2998 if (return_size_val != NULL) { | |
2999 (*return_size_val) = size; | |
3000 } | |
3001 | |
3002 // This is a precise notnull oop of the klass. | |
3003 // (Actually, it need not be precise if this is a reflective allocation.) | |
3004 // It's what we cast the result to. | |
3005 const TypeKlassPtr* tklass = _gvn.type(klass_node)->isa_klassptr(); | |
3006 if (!tklass) tklass = TypeKlassPtr::OBJECT; | |
3007 const TypeOopPtr* oop_type = tklass->as_instance_type(); | |
3008 | |
3009 // Now generate allocation code | |
74
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
63
diff
changeset
|
3010 |
565
7fe62bb75bf4
6799693: Server compiler leads to data corruption when expression throws an Exception
kvn
parents:
563
diff
changeset
|
3011 // 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
|
3012 // since GC and deoptimization can happened. |
7fe62bb75bf4
6799693: Server compiler leads to data corruption when expression throws an Exception
kvn
parents:
563
diff
changeset
|
3013 Node *mem = reset_memory(); |
7fe62bb75bf4
6799693: Server compiler leads to data corruption when expression throws an Exception
kvn
parents:
563
diff
changeset
|
3014 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
|
3015 |
0 | 3016 AllocateNode* alloc |
3017 = new (C, AllocateNode::ParmLimit) | |
3018 AllocateNode(C, AllocateNode::alloc_type(), | |
74
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
63
diff
changeset
|
3019 control(), mem, i_o(), |
0 | 3020 size, klass_node, |
3021 initial_slow_test); | |
3022 | |
3023 return set_output_for_allocation(alloc, oop_type, raw_mem_only); | |
3024 } | |
3025 | |
3026 //-------------------------------new_array------------------------------------- | |
3027 // helper for both newarray and anewarray | |
3028 // The 'length' parameter is (obviously) the length of the array. | |
3029 // See comments on new_instance for the meaning of the other arguments. | |
3030 Node* GraphKit::new_array(Node* klass_node, // array klass (maybe variable) | |
3031 Node* length, // number of array elements | |
730
9c6be3edf0dc
6589834: deoptimization problem with -XX:+DeoptimizeALot
cfang
parents:
726
diff
changeset
|
3032 int nargs, // number of arguments to push back for uncommon trap |
0 | 3033 bool raw_mem_only, // affect only raw memory |
3034 Node* *return_size_val) { | |
3035 jint layout_con = Klass::_lh_neutral_value; | |
3036 Node* layout_val = get_layout_helper(klass_node, layout_con); | |
3037 int layout_is_con = (layout_val == NULL); | |
3038 | |
3039 if (!layout_is_con && !StressReflectiveCode && | |
3040 !too_many_traps(Deoptimization::Reason_class_check)) { | |
3041 // This is a reflective array creation site. | |
3042 // Optimistically assume that it is a subtype of Object[], | |
3043 // so that we can fold up all the address arithmetic. | |
3044 layout_con = Klass::array_layout_helper(T_OBJECT); | |
3045 Node* cmp_lh = _gvn.transform( new(C, 3) CmpINode(layout_val, intcon(layout_con)) ); | |
3046 Node* bol_lh = _gvn.transform( new(C, 2) BoolNode(cmp_lh, BoolTest::eq) ); | |
3047 { BuildCutout unless(this, bol_lh, PROB_MAX); | |
730
9c6be3edf0dc
6589834: deoptimization problem with -XX:+DeoptimizeALot
cfang
parents:
726
diff
changeset
|
3048 _sp += nargs; |
0 | 3049 uncommon_trap(Deoptimization::Reason_class_check, |
3050 Deoptimization::Action_maybe_recompile); | |
3051 } | |
3052 layout_val = NULL; | |
3053 layout_is_con = true; | |
3054 } | |
3055 | |
3056 // Generate the initial go-slow test. Make sure we do not overflow | |
3057 // if length is huge (near 2Gig) or negative! We do not need | |
3058 // exact double-words here, just a close approximation of needed | |
3059 // double-words. We can't add any offset or rounding bits, lest we | |
3060 // take a size -1 of bytes and make it positive. Use an unsigned | |
3061 // compare, so negative sizes look hugely positive. | |
3062 int fast_size_limit = FastAllocateSizeLimit; | |
3063 if (layout_is_con) { | |
3064 assert(!StressReflectiveCode, "stress mode does not use these paths"); | |
3065 // Increase the size limit if we have exact knowledge of array type. | |
3066 int log2_esize = Klass::layout_helper_log2_element_size(layout_con); | |
3067 fast_size_limit <<= (LogBytesPerLong - log2_esize); | |
3068 } | |
3069 | |
3070 Node* initial_slow_cmp = _gvn.transform( new (C, 3) CmpUNode( length, intcon( fast_size_limit ) ) ); | |
3071 Node* initial_slow_test = _gvn.transform( new (C, 2) BoolNode( initial_slow_cmp, BoolTest::gt ) ); | |
3072 if (initial_slow_test->is_Bool()) { | |
3073 // Hide it behind a CMoveI, or else PhaseIdealLoop::split_up will get sick. | |
3074 initial_slow_test = initial_slow_test->as_Bool()->as_int_value(&_gvn); | |
3075 } | |
3076 | |
3077 // --- Size Computation --- | |
3078 // array_size = round_to_heap(array_header + (length << elem_shift)); | |
3079 // where round_to_heap(x) == round_to(x, MinObjAlignmentInBytes) | |
3080 // and round_to(x, y) == ((x + y-1) & ~(y-1)) | |
3081 // The rounding mask is strength-reduced, if possible. | |
3082 int round_mask = MinObjAlignmentInBytes - 1; | |
3083 Node* header_size = NULL; | |
3084 int header_size_min = arrayOopDesc::base_offset_in_bytes(T_BYTE); | |
3085 // (T_BYTE has the weakest alignment and size restrictions...) | |
3086 if (layout_is_con) { | |
3087 int hsize = Klass::layout_helper_header_size(layout_con); | |
3088 int eshift = Klass::layout_helper_log2_element_size(layout_con); | |
3089 BasicType etype = Klass::layout_helper_element_type(layout_con); | |
3090 if ((round_mask & ~right_n_bits(eshift)) == 0) | |
3091 round_mask = 0; // strength-reduce it if it goes away completely | |
3092 assert((hsize & right_n_bits(eshift)) == 0, "hsize is pre-rounded"); | |
3093 assert(header_size_min <= hsize, "generic minimum is smallest"); | |
3094 header_size_min = hsize; | |
3095 header_size = intcon(hsize + round_mask); | |
3096 } else { | |
3097 Node* hss = intcon(Klass::_lh_header_size_shift); | |
3098 Node* hsm = intcon(Klass::_lh_header_size_mask); | |
3099 Node* hsize = _gvn.transform( new(C, 3) URShiftINode(layout_val, hss) ); | |
3100 hsize = _gvn.transform( new(C, 3) AndINode(hsize, hsm) ); | |
3101 Node* mask = intcon(round_mask); | |
3102 header_size = _gvn.transform( new(C, 3) AddINode(hsize, mask) ); | |
3103 } | |
3104 | |
3105 Node* elem_shift = NULL; | |
3106 if (layout_is_con) { | |
3107 int eshift = Klass::layout_helper_log2_element_size(layout_con); | |
3108 if (eshift != 0) | |
3109 elem_shift = intcon(eshift); | |
3110 } else { | |
3111 // There is no need to mask or shift this value. | |
3112 // The semantics of LShiftINode include an implicit mask to 0x1F. | |
3113 assert(Klass::_lh_log2_element_size_shift == 0, "use shift in place"); | |
3114 elem_shift = layout_val; | |
3115 } | |
3116 | |
3117 // Transition to native address size for all offset calculations: | |
3118 Node* lengthx = ConvI2X(length); | |
3119 Node* headerx = ConvI2X(header_size); | |
3120 #ifdef _LP64 | |
3121 { const TypeLong* tllen = _gvn.find_long_type(lengthx); | |
3122 if (tllen != NULL && tllen->_lo < 0) { | |
3123 // Add a manual constraint to a positive range. Cf. array_element_address. | |
3124 jlong size_max = arrayOopDesc::max_array_length(T_BYTE); | |
3125 if (size_max > tllen->_hi) size_max = tllen->_hi; | |
3126 const TypeLong* tlcon = TypeLong::make(CONST64(0), size_max, Type::WidenMin); | |
3127 lengthx = _gvn.transform( new (C, 2) ConvI2LNode(length, tlcon)); | |
3128 } | |
3129 } | |
3130 #endif | |
3131 | |
3132 // Combine header size (plus rounding) and body size. Then round down. | |
3133 // This computation cannot overflow, because it is used only in two | |
3134 // places, one where the length is sharply limited, and the other | |
3135 // after a successful allocation. | |
3136 Node* abody = lengthx; | |
3137 if (elem_shift != NULL) | |
3138 abody = _gvn.transform( new(C, 3) LShiftXNode(lengthx, elem_shift) ); | |
3139 Node* size = _gvn.transform( new(C, 3) AddXNode(headerx, abody) ); | |
3140 if (round_mask != 0) { | |
3141 Node* mask = MakeConX(~round_mask); | |
3142 size = _gvn.transform( new(C, 3) AndXNode(size, mask) ); | |
3143 } | |
3144 // else if round_mask == 0, the size computation is self-rounding | |
3145 | |
3146 if (return_size_val != NULL) { | |
3147 // This is the size | |
3148 (*return_size_val) = size; | |
3149 } | |
3150 | |
3151 // Now generate allocation code | |
74
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
63
diff
changeset
|
3152 |
565
7fe62bb75bf4
6799693: Server compiler leads to data corruption when expression throws an Exception
kvn
parents:
563
diff
changeset
|
3153 // 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
|
3154 // since GC and deoptimization can happened. |
7fe62bb75bf4
6799693: Server compiler leads to data corruption when expression throws an Exception
kvn
parents:
563
diff
changeset
|
3155 Node *mem = reset_memory(); |
7fe62bb75bf4
6799693: Server compiler leads to data corruption when expression throws an Exception
kvn
parents:
563
diff
changeset
|
3156 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
|
3157 |
0 | 3158 // Create the AllocateArrayNode and its result projections |
3159 AllocateArrayNode* alloc | |
3160 = new (C, AllocateArrayNode::ParmLimit) | |
3161 AllocateArrayNode(C, AllocateArrayNode::alloc_type(), | |
74
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
63
diff
changeset
|
3162 control(), mem, i_o(), |
0 | 3163 size, klass_node, |
3164 initial_slow_test, | |
3165 length); | |
3166 | |
3167 // Cast to correct type. Note that the klass_node may be constant or not, | |
3168 // and in the latter case the actual array type will be inexact also. | |
3169 // (This happens via a non-constant argument to inline_native_newArray.) | |
3170 // In any case, the value of klass_node provides the desired array type. | |
3171 const TypeInt* length_type = _gvn.find_int_type(length); | |
3172 const TypeOopPtr* ary_type = _gvn.type(klass_node)->is_klassptr()->as_instance_type(); | |
3173 if (ary_type->isa_aryptr() && length_type != NULL) { | |
3174 // Try to get a better type than POS for the size | |
3175 ary_type = ary_type->is_aryptr()->cast_to_size(length_type); | |
3176 } | |
3177 | |
3178 Node* javaoop = set_output_for_allocation(alloc, ary_type, raw_mem_only); | |
3179 | |
366
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
332
diff
changeset
|
3180 // 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
|
3181 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
|
3182 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
|
3183 if (ccast != length) { |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
332
diff
changeset
|
3184 _gvn.set_type_bottom(ccast); |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
332
diff
changeset
|
3185 record_for_igvn(ccast); |
0 | 3186 replace_in_map(length, ccast); |
3187 } | |
3188 } | |
3189 | |
3190 return javaoop; | |
3191 } | |
3192 | |
3193 // The following "Ideal_foo" functions are placed here because they recognize | |
3194 // the graph shapes created by the functions immediately above. | |
3195 | |
3196 //---------------------------Ideal_allocation---------------------------------- | |
3197 // Given an oop pointer or raw pointer, see if it feeds from an AllocateNode. | |
3198 AllocateNode* AllocateNode::Ideal_allocation(Node* ptr, PhaseTransform* phase) { | |
3199 if (ptr == NULL) { // reduce dumb test in callers | |
3200 return NULL; | |
3201 } | |
3202 if (ptr->is_CheckCastPP()) { // strip a raw-to-oop cast | |
3203 ptr = ptr->in(1); | |
3204 if (ptr == NULL) return NULL; | |
3205 } | |
3206 if (ptr->is_Proj()) { | |
3207 Node* allo = ptr->in(0); | |
3208 if (allo != NULL && allo->is_Allocate()) { | |
3209 return allo->as_Allocate(); | |
3210 } | |
3211 } | |
3212 // Report failure to match. | |
3213 return NULL; | |
3214 } | |
3215 | |
3216 // Fancy version which also strips off an offset (and reports it to caller). | |
3217 AllocateNode* AllocateNode::Ideal_allocation(Node* ptr, PhaseTransform* phase, | |
3218 intptr_t& offset) { | |
3219 Node* base = AddPNode::Ideal_base_and_offset(ptr, phase, offset); | |
3220 if (base == NULL) return NULL; | |
3221 return Ideal_allocation(base, phase); | |
3222 } | |
3223 | |
3224 // Trace Initialize <- Proj[Parm] <- Allocate | |
3225 AllocateNode* InitializeNode::allocation() { | |
3226 Node* rawoop = in(InitializeNode::RawAddress); | |
3227 if (rawoop->is_Proj()) { | |
3228 Node* alloc = rawoop->in(0); | |
3229 if (alloc->is_Allocate()) { | |
3230 return alloc->as_Allocate(); | |
3231 } | |
3232 } | |
3233 return NULL; | |
3234 } | |
3235 | |
3236 // Trace Allocate -> Proj[Parm] -> Initialize | |
3237 InitializeNode* AllocateNode::initialization() { | |
3238 ProjNode* rawoop = proj_out(AllocateNode::RawAddress); | |
3239 if (rawoop == NULL) return NULL; | |
3240 for (DUIterator_Fast imax, i = rawoop->fast_outs(imax); i < imax; i++) { | |
3241 Node* init = rawoop->fast_out(i); | |
3242 if (init->is_Initialize()) { | |
3243 assert(init->as_Initialize()->allocation() == this, "2-way link"); | |
3244 return init->as_Initialize(); | |
3245 } | |
3246 } | |
3247 return NULL; | |
3248 } | |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3249 |
851
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3250 //----------------------------- store barriers ---------------------------- |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3251 #define __ ideal. |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3252 |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3253 void GraphKit::sync_kit(IdealKit& ideal) { |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3254 // Final sync IdealKit and graphKit. |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3255 __ drain_delay_transform(); |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3256 set_all_memory(__ merged_memory()); |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3257 set_control(__ ctrl()); |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3258 } |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3259 |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3260 // vanilla/CMS post barrier |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3261 // 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
|
3262 // 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
|
3263 void GraphKit::write_barrier_post(Node* oop_store, |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3264 Node* obj, |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3265 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
|
3266 uint adr_idx, |
851
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3267 Node* val, |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3268 bool use_precise) { |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3269 // 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
|
3270 // (latter case is probably a string constant). The concurrent |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3271 // 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
|
3272 // oop updates flagged via card-marks. |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3273 if (val != NULL && val->is_Con()) { |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3274 // must be either an oop or NULL |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3275 const Type* t = val->bottom_type(); |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3276 if (t == TypePtr::NULL_PTR || t == Type::TOP) |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3277 // stores of null never (?) need barriers |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3278 return; |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3279 ciObject* con = t->is_oopptr()->const_oop(); |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3280 if (con != NULL |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3281 && con->is_perm() |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3282 && Universe::heap()->can_elide_permanent_oop_store_barriers()) |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3283 // 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
|
3284 return; |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3285 } |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3286 |
1027
39b01ab7035a
6888898: CMS: ReduceInitialCardMarks unsafe in the presence of cms precleaning
ysr
parents:
985
diff
changeset
|
3287 if (use_ReduceInitialCardMarks() |
39b01ab7035a
6888898: CMS: ReduceInitialCardMarks unsafe in the presence of cms precleaning
ysr
parents:
985
diff
changeset
|
3288 && obj == just_allocated_object(control())) { |
39b01ab7035a
6888898: CMS: ReduceInitialCardMarks unsafe in the presence of cms precleaning
ysr
parents:
985
diff
changeset
|
3289 // We can skip marks on a freshly-allocated object in Eden. |
1166 | 3290 // Keep this code in sync with new_store_pre_barrier() in runtime.cpp. |
3291 // That routine informs GC to take appropriate compensating steps, | |
3292 // upon a slow-path allocation, so as to make this card-mark | |
3293 // elision safe. | |
1027
39b01ab7035a
6888898: CMS: ReduceInitialCardMarks unsafe in the presence of cms precleaning
ysr
parents:
985
diff
changeset
|
3294 return; |
39b01ab7035a
6888898: CMS: ReduceInitialCardMarks unsafe in the presence of cms precleaning
ysr
parents:
985
diff
changeset
|
3295 } |
39b01ab7035a
6888898: CMS: ReduceInitialCardMarks unsafe in the presence of cms precleaning
ysr
parents:
985
diff
changeset
|
3296 |
851
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3297 if (!use_precise) { |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3298 // 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
|
3299 adr = obj; |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3300 } |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3301 // (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
|
3302 assert(adr != NULL, ""); |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3303 |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3304 IdealKit ideal(gvn(), control(), merged_memory(), true); |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3305 |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3306 // 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
|
3307 Node* cast = __ CastPX(__ ctrl(), adr); |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3308 |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3309 // Divide by card size |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3310 assert(Universe::heap()->barrier_set()->kind() == BarrierSet::CardTableModRef, |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3311 "Only one we handle so far."); |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3312 Node* card_offset = __ URShiftX( cast, __ ConI(CardTableModRefBS::card_shift) ); |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3313 |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3314 // Combine card table base and card offset |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3315 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
|
3316 |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3317 // Get the alias_index for raw card-mark memory |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3318 int adr_type = Compile::AliasIdxRaw; |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3319 // Smash zero into card |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3320 Node* zero = __ ConI(0); |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3321 BasicType bt = T_BYTE; |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3322 if( !UseConcMarkSweepGC ) { |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3323 __ store(__ ctrl(), card_adr, zero, bt, adr_type); |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3324 } else { |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3325 // 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
|
3326 __ 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
|
3327 } |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3328 |
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 sync_kit(ideal); |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3331 } |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3332 |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3333 // G1 pre/post barriers |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3334 void GraphKit::g1_write_barrier_pre(Node* obj, |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3335 Node* adr, |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3336 uint alias_idx, |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3337 Node* val, |
825 | 3338 const TypeOopPtr* val_type, |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3339 BasicType bt) { |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3340 IdealKit ideal(gvn(), control(), merged_memory(), true); |
851
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3341 |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3342 Node* tls = __ thread(); // ThreadLocalStorage |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3343 |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3344 Node* no_ctrl = NULL; |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3345 Node* no_base = __ top(); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3346 Node* zero = __ ConI(0); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3347 |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3348 float likely = PROB_LIKELY(0.999); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3349 float unlikely = PROB_UNLIKELY(0.999); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3350 |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3351 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
|
3352 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
|
3353 |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3354 // Offsets into the thread |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3355 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
|
3356 PtrQueue::byte_offset_of_active()); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3357 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
|
3358 PtrQueue::byte_offset_of_index()); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3359 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
|
3360 PtrQueue::byte_offset_of_buf()); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3361 // Now the actual pointers into the thread |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3362 |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3363 // set_control( ctl); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3364 |
851
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3365 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
|
3366 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
|
3367 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
|
3368 |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3369 // Now some of the values |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3370 |
544
82a980778b92
6793828: G1: invariant: queues are empty when activated
never
parents:
372
diff
changeset
|
3371 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
|
3372 |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3373 // if (!marking) |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3374 __ if_then(marking, BoolTest::ne, zero); { |
544
82a980778b92
6793828: G1: invariant: queues are empty when activated
never
parents:
372
diff
changeset
|
3375 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
|
3376 |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3377 const Type* t1 = adr->bottom_type(); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3378 const Type* t2 = val->bottom_type(); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3379 |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3380 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
|
3381 // if (orig != NULL) |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3382 __ if_then(orig, BoolTest::ne, null()); { |
544
82a980778b92
6793828: G1: invariant: queues are empty when activated
never
parents:
372
diff
changeset
|
3383 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
|
3384 |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3385 // load original value |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3386 // alias_idx correct?? |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3387 |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3388 // is the queue for this thread full? |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3389 __ if_then(index, BoolTest::ne, zero, likely); { |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3390 |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3391 // decrement the index |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3392 Node* next_index = __ SubI(index, __ ConI(sizeof(intptr_t))); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3393 Node* next_indexX = next_index; |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3394 #ifdef _LP64 |
851
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3395 // 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
|
3396 // 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
|
3397 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
|
3398 #endif |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3399 |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3400 // 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
|
3401 Node *log_addr = __ AddP(no_base, buffer, next_indexX); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3402 __ store(__ ctrl(), log_addr, orig, T_OBJECT, Compile::AliasIdxRaw); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3403 |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3404 // update the index |
851
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3405 __ 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
|
3406 |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3407 } __ else_(); { |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3408 |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3409 // logging buffer is full, call the runtime |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3410 const TypeFunc *tf = OptoRuntime::g1_wb_pre_Type(); |
851
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3411 __ 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
|
3412 } __ end_if(); // (!index) |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3413 } __ end_if(); // (orig != NULL) |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3414 } __ end_if(); // (!marking) |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3415 |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3416 // Final sync IdealKit and GraphKit. |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3417 sync_kit(ideal); |
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 |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3420 // |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3421 // 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
|
3422 // |
851
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3423 void GraphKit::g1_mark_card(IdealKit& ideal, |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3424 Node* card_adr, |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3425 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
|
3426 uint oop_alias_idx, |
851
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3427 Node* index, |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3428 Node* index_adr, |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3429 Node* buffer, |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3430 const TypeFunc* tf) { |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3431 |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3432 Node* zero = __ ConI(0); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3433 Node* no_base = __ top(); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3434 BasicType card_bt = T_BYTE; |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3435 // 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
|
3436 __ 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
|
3437 |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3438 // Now do the queue work |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3439 __ if_then(index, BoolTest::ne, zero); { |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3440 |
851
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3441 Node* next_index = __ SubI(index, __ ConI(sizeof(intptr_t))); |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3442 Node* next_indexX = next_index; |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3443 #ifdef _LP64 |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3444 // We could refine the type for what it's worth |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3445 // 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
|
3446 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
|
3447 #endif // _LP64 |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3448 Node* log_addr = __ AddP(no_base, buffer, next_indexX); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3449 |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3450 __ store(__ ctrl(), log_addr, card_adr, T_ADDRESS, Compile::AliasIdxRaw); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3451 __ store(__ ctrl(), index_adr, next_index, T_INT, Compile::AliasIdxRaw); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3452 |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3453 } __ else_(); { |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3454 __ 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
|
3455 } __ end_if(); |
851
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3456 |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3457 } |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3458 |
851
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3459 void GraphKit::g1_write_barrier_post(Node* oop_store, |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3460 Node* obj, |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3461 Node* adr, |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3462 uint alias_idx, |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3463 Node* val, |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3464 BasicType bt, |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3465 bool use_precise) { |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3466 // 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
|
3467 |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3468 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
|
3469 // Must be NULL |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3470 const Type* t = val->bottom_type(); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3471 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
|
3472 // No post barrier if writing NULLx |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3473 return; |
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 |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3476 if (!use_precise) { |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3477 // 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
|
3478 adr = obj; |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3479 } |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3480 // (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
|
3481 assert(adr != NULL, ""); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3482 |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3483 IdealKit ideal(gvn(), control(), merged_memory(), true); |
851
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3484 |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3485 Node* tls = __ thread(); // ThreadLocalStorage |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3486 |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3487 Node* no_base = __ top(); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3488 float likely = PROB_LIKELY(0.999); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3489 float unlikely = PROB_UNLIKELY(0.999); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3490 Node* zero = __ ConI(0); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3491 Node* zeroX = __ ConX(0); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3492 |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3493 // Get the alias_index for raw card-mark memory |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3494 const TypePtr* card_type = TypeRawPtr::BOTTOM; |
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 const TypeFunc *tf = OptoRuntime::g1_wb_post_Type(); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3497 |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3498 // Offsets into the thread |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3499 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
|
3500 PtrQueue::byte_offset_of_index()); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3501 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
|
3502 PtrQueue::byte_offset_of_buf()); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3503 |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3504 // Pointers into the thread |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3505 |
851
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3506 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
|
3507 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
|
3508 |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3509 // Now some values |
1593
2458a1f25356
6953058: G1: A bigapp crashes with SIGSEGV in compiled code
johnc
parents:
1397
diff
changeset
|
3510 // 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
|
3511 // potentially reset these fields in the JavaThread. |
2458a1f25356
6953058: G1: A bigapp crashes with SIGSEGV in compiled code
johnc
parents:
1397
diff
changeset
|
3512 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
|
3513 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
|
3514 |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3515 // 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
|
3516 // 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
|
3517 Node* cast = __ CastPX(__ ctrl(), adr); |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3518 |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3519 // Divide pointer by card size |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3520 Node* card_offset = __ URShiftX( cast, __ ConI(CardTableModRefBS::card_shift) ); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3521 |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3522 // Combine card table base and card offset |
851
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3523 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
|
3524 |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3525 // 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
|
3526 |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3527 if (val != NULL) { |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3528 // Does the store cause us to cross regions? |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3529 |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3530 // 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
|
3531 // and extra shift. Do we have an unsigned compare?? |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3532 // Node* region_size = __ ConI(1 << HeapRegion::LogOfHRGrainBytes); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3533 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
|
3534 |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3535 // if (xor_res == 0) same region so skip |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3536 __ if_then(xor_res, BoolTest::ne, zeroX); { |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3537 |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3538 // No barrier if we are storing a NULL |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3539 __ if_then(val, BoolTest::ne, null(), unlikely); { |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3540 |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3541 // Ok must mark the card if not already dirty |
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 // load the original value of the card |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3544 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
|
3545 |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3546 __ 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
|
3547 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
|
3548 } __ end_if(); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3549 } __ end_if(); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3550 } __ end_if(); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3551 } else { |
851
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3552 // 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
|
3553 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
|
3554 } |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3555 |
851
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3556 // Final sync IdealKit and GraphKit. |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3557 sync_kit(ideal); |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
827
diff
changeset
|
3558 } |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
3559 #undef __ |