1 /*
2 * Copyright (c) 2015, 2019, Red Hat, Inc. All rights reserved.
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 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26
27 #include "classfile/javaClasses.hpp"
28 #include "gc/shenandoah/c2/shenandoahSupport.hpp"
29 #include "gc/shenandoah/c2/shenandoahBarrierSetC2.hpp"
30 #include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp"
31 #include "gc/shenandoah/shenandoahForwarding.hpp"
32 #include "gc/shenandoah/shenandoahHeap.hpp"
33 #include "gc/shenandoah/shenandoahHeapRegion.hpp"
34 #include "gc/shenandoah/shenandoahRuntime.hpp"
35 #include "gc/shenandoah/shenandoahThreadLocalData.hpp"
36 #include "opto/arraycopynode.hpp"
37 #include "opto/block.hpp"
38 #include "opto/callnode.hpp"
39 #include "opto/castnode.hpp"
40 #include "opto/movenode.hpp"
41 #include "opto/phaseX.hpp"
42 #include "opto/rootnode.hpp"
43 #include "opto/runtime.hpp"
44 #include "opto/subnode.hpp"
45
46 bool ShenandoahBarrierC2Support::expand(Compile* C, PhaseIterGVN& igvn) {
47 ShenandoahBarrierSetC2State* state = ShenandoahBarrierSetC2::bsc2()->state();
48 if ((state->enqueue_barriers_count() +
49 state->load_reference_barriers_count()) > 0) {
50 bool attempt_more_loopopts = ShenandoahLoopOptsAfterExpansion;
51 C->clear_major_progress();
52 PhaseIdealLoop ideal_loop(igvn, LoopOptsShenandoahExpand);
53 if (C->failing()) return false;
54 PhaseIdealLoop::verify(igvn);
55 DEBUG_ONLY(verify_raw_mem(C->root());)
56 if (attempt_more_loopopts) {
57 C->set_major_progress();
58 if (!C->optimize_loops(igvn, LoopOptsShenandoahPostExpand)) {
59 return false;
60 }
61 C->clear_major_progress();
62 if (C->range_check_cast_count() > 0) {
63 // No more loop optimizations. Remove all range check dependent CastIINodes.
64 C->remove_range_check_casts(igvn);
65 igvn.optimize();
66 }
67 }
68 }
69 return true;
70 }
71
72 bool ShenandoahBarrierC2Support::is_gc_state_test(Node* iff, int mask) {
73 if (!UseShenandoahGC) {
74 return false;
75 }
76 assert(iff->is_If(), "bad input");
77 if (iff->Opcode() != Op_If) {
78 return false;
79 }
80 Node* bol = iff->in(1);
81 if (!bol->is_Bool() || bol->as_Bool()->_test._test != BoolTest::ne) {
82 return false;
83 }
84 Node* cmp = bol->in(1);
85 if (cmp->Opcode() != Op_CmpI) {
86 return false;
87 }
88 Node* in1 = cmp->in(1);
89 Node* in2 = cmp->in(2);
90 if (in2->find_int_con(-1) != 0) {
91 return false;
92 }
93 if (in1->Opcode() != Op_AndI) {
94 return false;
95 }
96 in2 = in1->in(2);
97 if (in2->find_int_con(-1) != mask) {
98 return false;
99 }
100 in1 = in1->in(1);
101
102 return is_gc_state_load(in1);
103 }
104
105 bool ShenandoahBarrierC2Support::is_heap_stable_test(Node* iff) {
106 return is_gc_state_test(iff, ShenandoahHeap::HAS_FORWARDED);
107 }
108
109 bool ShenandoahBarrierC2Support::is_gc_state_load(Node *n) {
110 if (!UseShenandoahGC) {
111 return false;
112 }
113 if (n->Opcode() != Op_LoadB && n->Opcode() != Op_LoadUB) {
114 return false;
115 }
116 Node* addp = n->in(MemNode::Address);
117 if (!addp->is_AddP()) {
118 return false;
119 }
120 Node* base = addp->in(AddPNode::Address);
121 Node* off = addp->in(AddPNode::Offset);
122 if (base->Opcode() != Op_ThreadLocal) {
123 return false;
124 }
125 if (off->find_intptr_t_con(-1) != in_bytes(ShenandoahThreadLocalData::gc_state_offset())) {
126 return false;
127 }
128 return true;
129 }
130
131 bool ShenandoahBarrierC2Support::has_safepoint_between(Node* start, Node* stop, PhaseIdealLoop *phase) {
132 assert(phase->is_dominator(stop, start), "bad inputs");
133 ResourceMark rm;
134 Unique_Node_List wq;
135 wq.push(start);
136 for (uint next = 0; next < wq.size(); next++) {
137 Node *m = wq.at(next);
138 if (m == stop) {
139 continue;
140 }
141 if (m->is_SafePoint() && !m->is_CallLeaf()) {
142 return true;
143 }
144 if (m->is_Region()) {
145 for (uint i = 1; i < m->req(); i++) {
146 wq.push(m->in(i));
147 }
148 } else {
149 wq.push(m->in(0));
150 }
151 }
152 return false;
153 }
154
155 #ifdef ASSERT
156 bool ShenandoahBarrierC2Support::verify_helper(Node* in, Node_Stack& phis, VectorSet& visited, verify_type t, bool trace, Unique_Node_List& barriers_used) {
157 assert(phis.size() == 0, "");
158
159 while (true) {
160 if (in->bottom_type() == TypePtr::NULL_PTR) {
161 if (trace) {tty->print_cr("NULL");}
162 } else if (!in->bottom_type()->make_ptr()->make_oopptr()) {
163 if (trace) {tty->print_cr("Non oop");}
164 } else {
165 if (in->is_ConstraintCast()) {
166 in = in->in(1);
167 continue;
168 } else if (in->is_AddP()) {
169 assert(!in->in(AddPNode::Address)->is_top(), "no raw memory access");
170 in = in->in(AddPNode::Address);
171 continue;
172 } else if (in->is_Con()) {
173 if (trace) {
174 tty->print("Found constant");
175 in->dump();
176 }
177 } else if (in->Opcode() == Op_Parm) {
178 if (trace) {
179 tty->print("Found argument");
180 }
181 } else if (in->Opcode() == Op_CreateEx) {
182 if (trace) {
183 tty->print("Found create-exception");
184 }
185 } else if (in->Opcode() == Op_LoadP && in->adr_type() == TypeRawPtr::BOTTOM) {
186 if (trace) {
187 tty->print("Found raw LoadP (OSR argument?)");
188 }
189 } else if (in->Opcode() == Op_ShenandoahLoadReferenceBarrier) {
190 if (t == ShenandoahOopStore) {
191 uint i = 0;
192 for (; i < phis.size(); i++) {
193 Node* n = phis.node_at(i);
194 if (n->Opcode() == Op_ShenandoahEnqueueBarrier) {
195 break;
196 }
197 }
198 if (i == phis.size()) {
199 return false;
200 }
201 }
202 barriers_used.push(in);
203 if (trace) {tty->print("Found barrier"); in->dump();}
204 } else if (in->Opcode() == Op_ShenandoahEnqueueBarrier) {
205 if (t != ShenandoahOopStore) {
206 in = in->in(1);
207 continue;
208 }
209 if (trace) {tty->print("Found enqueue barrier"); in->dump();}
210 phis.push(in, in->req());
211 in = in->in(1);
212 continue;
213 } else if (in->is_Proj() && in->in(0)->is_Allocate()) {
214 if (trace) {
215 tty->print("Found alloc");
216 in->in(0)->dump();
217 }
218 } else if (in->is_Proj() && (in->in(0)->Opcode() == Op_CallStaticJava || in->in(0)->Opcode() == Op_CallDynamicJava)) {
219 if (trace) {
220 tty->print("Found Java call");
221 }
222 } else if (in->is_Phi()) {
223 if (!visited.test_set(in->_idx)) {
224 if (trace) {tty->print("Pushed phi:"); in->dump();}
225 phis.push(in, 2);
226 in = in->in(1);
227 continue;
228 }
229 if (trace) {tty->print("Already seen phi:"); in->dump();}
230 } else if (in->Opcode() == Op_CMoveP || in->Opcode() == Op_CMoveN) {
231 if (!visited.test_set(in->_idx)) {
232 if (trace) {tty->print("Pushed cmovep:"); in->dump();}
233 phis.push(in, CMoveNode::IfTrue);
234 in = in->in(CMoveNode::IfFalse);
235 continue;
236 }
237 if (trace) {tty->print("Already seen cmovep:"); in->dump();}
238 } else if (in->Opcode() == Op_EncodeP || in->Opcode() == Op_DecodeN) {
239 in = in->in(1);
240 continue;
241 } else {
242 return false;
243 }
244 }
245 bool cont = false;
246 while (phis.is_nonempty()) {
247 uint idx = phis.index();
248 Node* phi = phis.node();
249 if (idx >= phi->req()) {
250 if (trace) {tty->print("Popped phi:"); phi->dump();}
251 phis.pop();
252 continue;
253 }
254 if (trace) {tty->print("Next entry(%d) for phi:", idx); phi->dump();}
255 in = phi->in(idx);
256 phis.set_index(idx+1);
257 cont = true;
258 break;
259 }
260 if (!cont) {
261 break;
262 }
263 }
264 return true;
265 }
266
267 void ShenandoahBarrierC2Support::report_verify_failure(const char* msg, Node* n1, Node* n2) {
268 if (n1 != NULL) {
269 n1->dump(+10);
270 }
271 if (n2 != NULL) {
272 n2->dump(+10);
273 }
274 fatal("%s", msg);
275 }
276
277 void ShenandoahBarrierC2Support::verify(RootNode* root) {
278 ResourceMark rm;
279 Unique_Node_List wq;
280 GrowableArray<Node*> barriers;
281 Unique_Node_List barriers_used;
282 Node_Stack phis(0);
283 VectorSet visited;
284 const bool trace = false;
285 const bool verify_no_useless_barrier = false;
286
287 wq.push(root);
288 for (uint next = 0; next < wq.size(); next++) {
289 Node *n = wq.at(next);
290 if (n->is_Load()) {
291 const bool trace = false;
292 if (trace) {tty->print("Verifying"); n->dump();}
293 if (n->Opcode() == Op_LoadRange || n->Opcode() == Op_LoadKlass || n->Opcode() == Op_LoadNKlass) {
294 if (trace) {tty->print_cr("Load range/klass");}
295 } else {
296 const TypePtr* adr_type = n->as_Load()->adr_type();
297
298 if (adr_type->isa_oopptr() && adr_type->is_oopptr()->offset() == oopDesc::mark_offset_in_bytes()) {
299 if (trace) {tty->print_cr("Mark load");}
300 } else if (adr_type->isa_instptr() &&
301 adr_type->is_instptr()->klass()->is_subtype_of(Compile::current()->env()->Reference_klass()) &&
302 adr_type->is_instptr()->offset() == java_lang_ref_Reference::referent_offset()) {
303 if (trace) {tty->print_cr("Reference.get()");}
304 } else if (!verify_helper(n->in(MemNode::Address), phis, visited, ShenandoahLoad, trace, barriers_used)) {
305 report_verify_failure("Shenandoah verification: Load should have barriers", n);
306 }
307 }
308 } else if (n->is_Store()) {
309 const bool trace = false;
310
311 if (trace) {tty->print("Verifying"); n->dump();}
312 if (n->in(MemNode::ValueIn)->bottom_type()->make_oopptr()) {
313 Node* adr = n->in(MemNode::Address);
314 bool verify = true;
315
316 if (adr->is_AddP() && adr->in(AddPNode::Base)->is_top()) {
317 adr = adr->in(AddPNode::Address);
318 if (adr->is_AddP()) {
319 assert(adr->in(AddPNode::Base)->is_top(), "");
320 adr = adr->in(AddPNode::Address);
321 if (adr->Opcode() == Op_LoadP &&
322 adr->in(MemNode::Address)->in(AddPNode::Base)->is_top() &&
323 adr->in(MemNode::Address)->in(AddPNode::Address)->Opcode() == Op_ThreadLocal &&
324 adr->in(MemNode::Address)->in(AddPNode::Offset)->find_intptr_t_con(-1) == in_bytes(ShenandoahThreadLocalData::satb_mark_queue_buffer_offset())) {
325 if (trace) {tty->print_cr("SATB prebarrier");}
326 verify = false;
327 }
328 }
329 }
330
331 if (verify && !verify_helper(n->in(MemNode::ValueIn), phis, visited, ShenandoahStoreValEnqueueBarrier ? ShenandoahOopStore : ShenandoahValue, trace, barriers_used)) {
332 report_verify_failure("Shenandoah verification: Store should have barriers", n);
333 }
334 }
335 if (!verify_helper(n->in(MemNode::Address), phis, visited, ShenandoahStore, trace, barriers_used)) {
336 report_verify_failure("Shenandoah verification: Store (address) should have barriers", n);
337 }
338 } else if (n->Opcode() == Op_CmpP) {
339 const bool trace = false;
340
341 Node* in1 = n->in(1);
342 Node* in2 = n->in(2);
343 if (in1->bottom_type()->isa_oopptr()) {
344 if (trace) {tty->print("Verifying"); n->dump();}
345
346 bool mark_inputs = false;
347 if (in1->bottom_type() == TypePtr::NULL_PTR || in2->bottom_type() == TypePtr::NULL_PTR ||
348 (in1->is_Con() || in2->is_Con())) {
349 if (trace) {tty->print_cr("Comparison against a constant");}
350 mark_inputs = true;
351 } else if ((in1->is_CheckCastPP() && in1->in(1)->is_Proj() && in1->in(1)->in(0)->is_Allocate()) ||
352 (in2->is_CheckCastPP() && in2->in(1)->is_Proj() && in2->in(1)->in(0)->is_Allocate())) {
353 if (trace) {tty->print_cr("Comparison with newly alloc'ed object");}
354 mark_inputs = true;
355 } else {
356 assert(in2->bottom_type()->isa_oopptr(), "");
357
358 if (!verify_helper(in1, phis, visited, ShenandoahStore, trace, barriers_used) ||
359 !verify_helper(in2, phis, visited, ShenandoahStore, trace, barriers_used)) {
360 report_verify_failure("Shenandoah verification: Cmp should have barriers", n);
361 }
362 }
363 if (verify_no_useless_barrier &&
364 mark_inputs &&
365 (!verify_helper(in1, phis, visited, ShenandoahValue, trace, barriers_used) ||
366 !verify_helper(in2, phis, visited, ShenandoahValue, trace, barriers_used))) {
367 phis.clear();
368 visited.reset();
369 }
370 }
371 } else if (n->is_LoadStore()) {
372 if (n->in(MemNode::ValueIn)->bottom_type()->make_ptr() &&
373 !verify_helper(n->in(MemNode::ValueIn), phis, visited, ShenandoahStoreValEnqueueBarrier ? ShenandoahOopStore : ShenandoahValue, trace, barriers_used)) {
374 report_verify_failure("Shenandoah verification: LoadStore (value) should have barriers", n);
375 }
376
377 if (n->in(MemNode::Address)->bottom_type()->make_oopptr() && !verify_helper(n->in(MemNode::Address), phis, visited, ShenandoahStore, trace, barriers_used)) {
378 report_verify_failure("Shenandoah verification: LoadStore (address) should have barriers", n);
379 }
380 } else if (n->Opcode() == Op_CallLeafNoFP || n->Opcode() == Op_CallLeaf) {
381 CallNode* call = n->as_Call();
382
383 static struct {
384 const char* name;
385 struct {
386 int pos;
387 verify_type t;
388 } args[6];
389 } calls[] = {
390 "aescrypt_encryptBlock",
391 { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+1, ShenandoahStore }, { TypeFunc::Parms+2, ShenandoahLoad },
392 { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} },
393 "aescrypt_decryptBlock",
394 { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+1, ShenandoahStore }, { TypeFunc::Parms+2, ShenandoahLoad },
395 { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} },
396 "multiplyToLen",
397 { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+2, ShenandoahLoad }, { TypeFunc::Parms+4, ShenandoahStore },
398 { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} },
399 "squareToLen",
400 { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+2, ShenandoahLoad }, { -1, ShenandoahNone},
401 { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} },
402 "montgomery_multiply",
403 { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+1, ShenandoahLoad }, { TypeFunc::Parms+2, ShenandoahLoad },
404 { TypeFunc::Parms+6, ShenandoahStore }, { -1, ShenandoahNone}, { -1, ShenandoahNone} },
405 "montgomery_square",
406 { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+1, ShenandoahLoad }, { TypeFunc::Parms+5, ShenandoahStore },
407 { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} },
408 "mulAdd",
409 { { TypeFunc::Parms, ShenandoahStore }, { TypeFunc::Parms+1, ShenandoahLoad }, { -1, ShenandoahNone},
410 { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} },
411 "vectorizedMismatch",
412 { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+1, ShenandoahLoad }, { -1, ShenandoahNone},
413 { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} },
414 "updateBytesCRC32",
415 { { TypeFunc::Parms+1, ShenandoahLoad }, { -1, ShenandoahNone}, { -1, ShenandoahNone},
416 { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} },
417 "updateBytesAdler32",
418 { { TypeFunc::Parms+1, ShenandoahLoad }, { -1, ShenandoahNone}, { -1, ShenandoahNone},
419 { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} },
420 "updateBytesCRC32C",
421 { { TypeFunc::Parms+1, ShenandoahLoad }, { TypeFunc::Parms+3, ShenandoahLoad}, { -1, ShenandoahNone},
422 { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} },
423 "counterMode_AESCrypt",
424 { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+1, ShenandoahStore }, { TypeFunc::Parms+2, ShenandoahLoad },
425 { TypeFunc::Parms+3, ShenandoahStore }, { TypeFunc::Parms+5, ShenandoahStore }, { TypeFunc::Parms+6, ShenandoahStore } },
426 "cipherBlockChaining_encryptAESCrypt",
427 { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+1, ShenandoahStore }, { TypeFunc::Parms+2, ShenandoahLoad },
428 { TypeFunc::Parms+3, ShenandoahLoad }, { -1, ShenandoahNone}, { -1, ShenandoahNone} },
429 "cipherBlockChaining_decryptAESCrypt",
430 { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+1, ShenandoahStore }, { TypeFunc::Parms+2, ShenandoahLoad },
431 { TypeFunc::Parms+3, ShenandoahLoad }, { -1, ShenandoahNone}, { -1, ShenandoahNone} },
432 "shenandoah_clone_barrier",
433 { { TypeFunc::Parms, ShenandoahLoad }, { -1, ShenandoahNone}, { -1, ShenandoahNone},
434 { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} },
435 "ghash_processBlocks",
436 { { TypeFunc::Parms, ShenandoahStore }, { TypeFunc::Parms+1, ShenandoahLoad }, { TypeFunc::Parms+2, ShenandoahLoad },
437 { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} },
438 "sha1_implCompress",
439 { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+1, ShenandoahStore }, { -1, ShenandoahNone },
440 { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} },
441 "sha256_implCompress",
442 { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+1, ShenandoahStore }, { -1, ShenandoahNone },
443 { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} },
444 "sha512_implCompress",
445 { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+1, ShenandoahStore }, { -1, ShenandoahNone },
446 { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} },
447 "sha1_implCompressMB",
448 { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+1, ShenandoahStore }, { -1, ShenandoahNone },
449 { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} },
450 "sha256_implCompressMB",
451 { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+1, ShenandoahStore }, { -1, ShenandoahNone },
452 { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} },
453 "sha512_implCompressMB",
454 { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+1, ShenandoahStore }, { -1, ShenandoahNone },
455 { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} },
456 "encodeBlock",
457 { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+3, ShenandoahStore }, { -1, ShenandoahNone },
458 { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} },
459 };
460
461 if (call->is_call_to_arraycopystub()) {
462 Node* dest = NULL;
463 const TypeTuple* args = n->as_Call()->_tf->domain_sig();
464 for (uint i = TypeFunc::Parms, j = 0; i < args->cnt(); i++) {
465 if (args->field_at(i)->isa_ptr()) {
466 j++;
467 if (j == 2) {
468 dest = n->in(i);
469 break;
470 }
471 }
472 }
473 if (!verify_helper(n->in(TypeFunc::Parms), phis, visited, ShenandoahLoad, trace, barriers_used) ||
474 !verify_helper(dest, phis, visited, ShenandoahStore, trace, barriers_used)) {
475 report_verify_failure("Shenandoah verification: ArrayCopy should have barriers", n);
476 }
477 } else if (strlen(call->_name) > 5 &&
478 !strcmp(call->_name + strlen(call->_name) - 5, "_fill")) {
479 if (!verify_helper(n->in(TypeFunc::Parms), phis, visited, ShenandoahStore, trace, barriers_used)) {
480 report_verify_failure("Shenandoah verification: _fill should have barriers", n);
481 }
482 } else if (!strcmp(call->_name, "shenandoah_wb_pre")) {
483 // skip
484 } else {
485 const int calls_len = sizeof(calls) / sizeof(calls[0]);
486 int i = 0;
487 for (; i < calls_len; i++) {
488 if (!strcmp(calls[i].name, call->_name)) {
489 break;
490 }
491 }
492 if (i != calls_len) {
493 const uint args_len = sizeof(calls[0].args) / sizeof(calls[0].args[0]);
494 for (uint j = 0; j < args_len; j++) {
495 int pos = calls[i].args[j].pos;
496 if (pos == -1) {
497 break;
498 }
499 if (!verify_helper(call->in(pos), phis, visited, calls[i].args[j].t, trace, barriers_used)) {
500 report_verify_failure("Shenandoah verification: intrinsic calls should have barriers", n);
501 }
502 }
503 for (uint j = TypeFunc::Parms; j < call->req(); j++) {
504 if (call->in(j)->bottom_type()->make_ptr() &&
505 call->in(j)->bottom_type()->make_ptr()->isa_oopptr()) {
506 uint k = 0;
507 for (; k < args_len && calls[i].args[k].pos != (int)j; k++);
508 if (k == args_len) {
509 fatal("arg %d for call %s not covered", j, call->_name);
510 }
511 }
512 }
513 } else {
514 for (uint j = TypeFunc::Parms; j < call->req(); j++) {
515 if (call->in(j)->bottom_type()->make_ptr() &&
516 call->in(j)->bottom_type()->make_ptr()->isa_oopptr()) {
517 fatal("%s not covered", call->_name);
518 }
519 }
520 }
521 }
522 } else if (n->Opcode() == Op_ShenandoahEnqueueBarrier || n->Opcode() == Op_ShenandoahLoadReferenceBarrier) {
523 // skip
524 } else if (n->is_AddP()
525 || n->is_Phi()
526 || n->is_ConstraintCast()
527 || n->Opcode() == Op_Return
528 || n->Opcode() == Op_CMoveP
529 || n->Opcode() == Op_CMoveN
530 || n->Opcode() == Op_Rethrow
531 || n->is_MemBar()
532 || n->Opcode() == Op_Conv2B
533 || n->Opcode() == Op_SafePoint
534 || n->is_CallJava()
535 || n->Opcode() == Op_Unlock
536 || n->Opcode() == Op_EncodeP
537 || n->Opcode() == Op_DecodeN) {
538 // nothing to do
539 } else {
540 static struct {
541 int opcode;
542 struct {
543 int pos;
544 verify_type t;
545 } inputs[2];
546 } others[] = {
547 Op_FastLock,
548 { { 1, ShenandoahLoad }, { -1, ShenandoahNone} },
549 Op_Lock,
550 { { TypeFunc::Parms, ShenandoahLoad }, { -1, ShenandoahNone} },
551 Op_ArrayCopy,
552 { { ArrayCopyNode::Src, ShenandoahLoad }, { ArrayCopyNode::Dest, ShenandoahStore } },
553 Op_StrCompressedCopy,
554 { { 2, ShenandoahLoad }, { 3, ShenandoahStore } },
555 Op_StrInflatedCopy,
556 { { 2, ShenandoahLoad }, { 3, ShenandoahStore } },
557 Op_AryEq,
558 { { 2, ShenandoahLoad }, { 3, ShenandoahLoad } },
559 Op_StrIndexOf,
560 { { 2, ShenandoahLoad }, { 4, ShenandoahLoad } },
561 Op_StrComp,
562 { { 2, ShenandoahLoad }, { 4, ShenandoahLoad } },
563 Op_StrEquals,
564 { { 2, ShenandoahLoad }, { 3, ShenandoahLoad } },
565 Op_EncodeISOArray,
566 { { 2, ShenandoahLoad }, { 3, ShenandoahStore } },
567 Op_HasNegatives,
568 { { 2, ShenandoahLoad }, { -1, ShenandoahNone} },
569 Op_CastP2X,
570 { { 1, ShenandoahLoad }, { -1, ShenandoahNone} },
571 Op_StrIndexOfChar,
572 { { 2, ShenandoahLoad }, { -1, ShenandoahNone } },
573 };
574
575 const int others_len = sizeof(others) / sizeof(others[0]);
576 int i = 0;
577 for (; i < others_len; i++) {
578 if (others[i].opcode == n->Opcode()) {
579 break;
580 }
581 }
582 uint stop = n->is_Call() ? n->as_Call()->tf()->domain_sig()->cnt() : n->req();
583 if (i != others_len) {
584 const uint inputs_len = sizeof(others[0].inputs) / sizeof(others[0].inputs[0]);
585 for (uint j = 0; j < inputs_len; j++) {
586 int pos = others[i].inputs[j].pos;
587 if (pos == -1) {
588 break;
589 }
590 if (!verify_helper(n->in(pos), phis, visited, others[i].inputs[j].t, trace, barriers_used)) {
591 report_verify_failure("Shenandoah verification: intrinsic calls should have barriers", n);
592 }
593 }
594 for (uint j = 1; j < stop; j++) {
595 if (n->in(j) != NULL && n->in(j)->bottom_type()->make_ptr() &&
596 n->in(j)->bottom_type()->make_ptr()->make_oopptr()) {
597 uint k = 0;
598 for (; k < inputs_len && others[i].inputs[k].pos != (int)j; k++);
599 if (k == inputs_len) {
600 fatal("arg %d for node %s not covered", j, n->Name());
601 }
602 }
603 }
604 } else {
605 for (uint j = 1; j < stop; j++) {
606 if (n->in(j) != NULL && n->in(j)->bottom_type()->make_ptr() &&
607 n->in(j)->bottom_type()->make_ptr()->make_oopptr()) {
608 fatal("%s not covered", n->Name());
609 }
610 }
611 }
612 }
613
614 if (n->is_SafePoint()) {
615 SafePointNode* sfpt = n->as_SafePoint();
616 if (verify_no_useless_barrier && sfpt->jvms() != NULL) {
617 for (uint i = sfpt->jvms()->scloff(); i < sfpt->jvms()->endoff(); i++) {
618 if (!verify_helper(sfpt->in(i), phis, visited, ShenandoahLoad, trace, barriers_used)) {
619 phis.clear();
620 visited.reset();
621 }
622 }
623 }
624 }
625 }
626
627 if (verify_no_useless_barrier) {
628 for (int i = 0; i < barriers.length(); i++) {
629 Node* n = barriers.at(i);
630 if (!barriers_used.member(n)) {
631 tty->print("XXX useless barrier"); n->dump(-2);
632 ShouldNotReachHere();
633 }
634 }
635 }
636 }
637 #endif
638
639 bool ShenandoahBarrierC2Support::is_dominator_same_ctrl(Node* c, Node* d, Node* n, PhaseIdealLoop* phase) {
640 // That both nodes have the same control is not sufficient to prove
641 // domination, verify that there's no path from d to n
642 ResourceMark rm;
643 Unique_Node_List wq;
644 wq.push(d);
645 for (uint next = 0; next < wq.size(); next++) {
646 Node *m = wq.at(next);
647 if (m == n) {
648 return false;
649 }
650 if (m->is_Phi() && m->in(0)->is_Loop()) {
651 assert(phase->ctrl_or_self(m->in(LoopNode::EntryControl)) != c, "following loop entry should lead to new control");
652 } else {
653 if (m->is_Store() || m->is_LoadStore()) {
654 // Take anti-dependencies into account
655 Node* mem = m->in(MemNode::Memory);
656 for (DUIterator_Fast imax, i = mem->fast_outs(imax); i < imax; i++) {
657 Node* u = mem->fast_out(i);
658 if (u->is_Load() && phase->C->can_alias(m->adr_type(), phase->C->get_alias_index(u->adr_type())) &&
659 phase->ctrl_or_self(u) == c) {
660 wq.push(u);
661 }
662 }
663 }
664 for (uint i = 0; i < m->req(); i++) {
665 if (m->in(i) != NULL && phase->ctrl_or_self(m->in(i)) == c) {
666 wq.push(m->in(i));
667 }
668 }
669 }
670 }
671 return true;
672 }
673
674 bool ShenandoahBarrierC2Support::is_dominator(Node* d_c, Node* n_c, Node* d, Node* n, PhaseIdealLoop* phase) {
675 if (d_c != n_c) {
676 return phase->is_dominator(d_c, n_c);
677 }
678 return is_dominator_same_ctrl(d_c, d, n, phase);
679 }
680
681 Node* next_mem(Node* mem, int alias) {
682 Node* res = NULL;
683 if (mem->is_Proj()) {
684 res = mem->in(0);
685 } else if (mem->is_SafePoint() || mem->is_MemBar()) {
686 res = mem->in(TypeFunc::Memory);
687 } else if (mem->is_Phi()) {
688 res = mem->in(1);
689 } else if (mem->is_MergeMem()) {
690 res = mem->as_MergeMem()->memory_at(alias);
691 } else if (mem->is_Store() || mem->is_LoadStore() || mem->is_ClearArray()) {
692 assert(alias = Compile::AliasIdxRaw, "following raw memory can't lead to a barrier");
693 res = mem->in(MemNode::Memory);
694 } else {
695 #ifdef ASSERT
696 mem->dump();
697 #endif
698 ShouldNotReachHere();
699 }
700 return res;
701 }
702
703 Node* ShenandoahBarrierC2Support::no_branches(Node* c, Node* dom, bool allow_one_proj, PhaseIdealLoop* phase) {
704 Node* iffproj = NULL;
705 while (c != dom) {
706 Node* next = phase->idom(c);
707 assert(next->unique_ctrl_out() == c || c->is_Proj() || c->is_Region(), "multiple control flow out but no proj or region?");
708 if (c->is_Region()) {
709 ResourceMark rm;
710 Unique_Node_List wq;
711 wq.push(c);
712 for (uint i = 0; i < wq.size(); i++) {
713 Node *n = wq.at(i);
714 if (n == next) {
715 continue;
716 }
717 if (n->is_Region()) {
718 for (uint j = 1; j < n->req(); j++) {
719 wq.push(n->in(j));
720 }
721 } else {
722 wq.push(n->in(0));
723 }
724 }
725 for (uint i = 0; i < wq.size(); i++) {
726 Node *n = wq.at(i);
727 assert(n->is_CFG(), "");
728 if (n->is_Multi()) {
729 for (DUIterator_Fast jmax, j = n->fast_outs(jmax); j < jmax; j++) {
730 Node* u = n->fast_out(j);
731 if (u->is_CFG()) {
732 if (!wq.member(u) && !u->as_Proj()->is_uncommon_trap_proj(Deoptimization::Reason_none)) {
733 return NodeSentinel;
734 }
735 }
736 }
737 }
738 }
739 } else if (c->is_Proj()) {
740 if (c->is_IfProj()) {
741 if (c->as_Proj()->is_uncommon_trap_if_pattern(Deoptimization::Reason_none) != NULL) {
742 // continue;
743 } else {
744 if (!allow_one_proj) {
745 return NodeSentinel;
746 }
747 if (iffproj == NULL) {
748 iffproj = c;
749 } else {
750 return NodeSentinel;
751 }
752 }
753 } else if (c->Opcode() == Op_JumpProj) {
754 return NodeSentinel; // unsupported
755 } else if (c->Opcode() == Op_CatchProj) {
756 return NodeSentinel; // unsupported
757 } else if (c->Opcode() == Op_CProj && next->Opcode() == Op_NeverBranch) {
758 return NodeSentinel; // unsupported
759 } else {
760 assert(next->unique_ctrl_out() == c, "unsupported branch pattern");
761 }
762 }
763 c = next;
764 }
765 return iffproj;
766 }
767
768 Node* ShenandoahBarrierC2Support::dom_mem(Node* mem, Node* ctrl, int alias, Node*& mem_ctrl, PhaseIdealLoop* phase) {
769 ResourceMark rm;
770 VectorSet wq;
771 wq.set(mem->_idx);
772 mem_ctrl = phase->ctrl_or_self(mem);
773 while (!phase->is_dominator(mem_ctrl, ctrl) || mem_ctrl == ctrl) {
774 mem = next_mem(mem, alias);
775 if (wq.test_set(mem->_idx)) {
776 return NULL;
777 }
778 mem_ctrl = phase->ctrl_or_self(mem);
779 }
780 if (mem->is_MergeMem()) {
781 mem = mem->as_MergeMem()->memory_at(alias);
782 mem_ctrl = phase->ctrl_or_self(mem);
783 }
784 return mem;
785 }
786
787 Node* ShenandoahBarrierC2Support::find_bottom_mem(Node* ctrl, PhaseIdealLoop* phase) {
788 Node* mem = NULL;
789 Node* c = ctrl;
790 do {
791 if (c->is_Region()) {
792 for (DUIterator_Fast imax, i = c->fast_outs(imax); i < imax && mem == NULL; i++) {
793 Node* u = c->fast_out(i);
794 if (u->is_Phi() && u->bottom_type() == Type::MEMORY) {
795 if (u->adr_type() == TypePtr::BOTTOM) {
796 mem = u;
797 }
798 }
799 }
800 } else {
801 if (c->is_Call() && c->as_Call()->adr_type() != NULL) {
802 CallProjections* projs = c->as_Call()->extract_projections(true, false);
803 if (projs->fallthrough_memproj != NULL) {
804 if (projs->fallthrough_memproj->adr_type() == TypePtr::BOTTOM) {
805 if (projs->catchall_memproj == NULL) {
806 mem = projs->fallthrough_memproj;
807 } else {
808 if (phase->is_dominator(projs->fallthrough_catchproj, ctrl)) {
809 mem = projs->fallthrough_memproj;
810 } else {
811 assert(phase->is_dominator(projs->catchall_catchproj, ctrl), "one proj must dominate barrier");
812 mem = projs->catchall_memproj;
813 }
814 }
815 }
816 } else {
817 Node* proj = c->as_Call()->proj_out(TypeFunc::Memory);
818 if (proj != NULL &&
819 proj->adr_type() == TypePtr::BOTTOM) {
820 mem = proj;
821 }
822 }
823 } else {
824 for (DUIterator_Fast imax, i = c->fast_outs(imax); i < imax; i++) {
825 Node* u = c->fast_out(i);
826 if (u->is_Proj() &&
827 u->bottom_type() == Type::MEMORY &&
828 u->adr_type() == TypePtr::BOTTOM) {
829 assert(c->is_SafePoint() || c->is_MemBar() || c->is_Start(), "");
830 assert(mem == NULL, "only one proj");
831 mem = u;
832 }
833 }
834 assert(!c->is_Call() || c->as_Call()->adr_type() != NULL || mem == NULL, "no mem projection expected");
835 }
836 }
837 c = phase->idom(c);
838 } while (mem == NULL);
839 return mem;
840 }
841
842 void ShenandoahBarrierC2Support::follow_barrier_uses(Node* n, Node* ctrl, Unique_Node_List& uses, PhaseIdealLoop* phase) {
843 for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
844 Node* u = n->fast_out(i);
845 if (!u->is_CFG() && phase->get_ctrl(u) == ctrl && (!u->is_Phi() || !u->in(0)->is_Loop() || u->in(LoopNode::LoopBackControl) != n)) {
846 uses.push(u);
847 }
848 }
849 }
850
851 static void hide_strip_mined_loop(OuterStripMinedLoopNode* outer, CountedLoopNode* inner, PhaseIdealLoop* phase) {
852 OuterStripMinedLoopEndNode* le = inner->outer_loop_end();
853 Node* new_outer = new LoopNode(outer->in(LoopNode::EntryControl), outer->in(LoopNode::LoopBackControl));
854 phase->register_control(new_outer, phase->get_loop(outer), outer->in(LoopNode::EntryControl));
855 Node* new_le = new IfNode(le->in(0), le->in(1), le->_prob, le->_fcnt);
856 phase->register_control(new_le, phase->get_loop(le), le->in(0));
857 phase->lazy_replace(outer, new_outer);
858 phase->lazy_replace(le, new_le);
859 inner->clear_strip_mined();
860 }
861
862 void ShenandoahBarrierC2Support::test_gc_state(Node*& ctrl, Node* raw_mem, Node*& test_fail_ctrl,
863 PhaseIdealLoop* phase, int flags) {
864 PhaseIterGVN& igvn = phase->igvn();
865 Node* old_ctrl = ctrl;
866
867 Node* thread = new ThreadLocalNode();
868 Node* gc_state_offset = igvn.MakeConX(in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
869 Node* gc_state_addr = new AddPNode(phase->C->top(), thread, gc_state_offset);
870 Node* gc_state = new LoadBNode(old_ctrl, raw_mem, gc_state_addr,
871 DEBUG_ONLY(phase->C->get_adr_type(Compile::AliasIdxRaw)) NOT_DEBUG(NULL),
872 TypeInt::BYTE, MemNode::unordered);
873 Node* gc_state_and = new AndINode(gc_state, igvn.intcon(flags));
874 Node* gc_state_cmp = new CmpINode(gc_state_and, igvn.zerocon(T_INT));
875 Node* gc_state_bool = new BoolNode(gc_state_cmp, BoolTest::ne);
876
877 IfNode* gc_state_iff = new IfNode(old_ctrl, gc_state_bool, PROB_UNLIKELY(0.999), COUNT_UNKNOWN);
878 ctrl = new IfTrueNode(gc_state_iff);
879 test_fail_ctrl = new IfFalseNode(gc_state_iff);
880
881 IdealLoopTree* loop = phase->get_loop(old_ctrl);
882 phase->register_control(gc_state_iff, loop, old_ctrl);
883 phase->register_control(ctrl, loop, gc_state_iff);
884 phase->register_control(test_fail_ctrl, loop, gc_state_iff);
885
886 phase->register_new_node(thread, old_ctrl);
887 phase->register_new_node(gc_state_addr, old_ctrl);
888 phase->register_new_node(gc_state, old_ctrl);
889 phase->register_new_node(gc_state_and, old_ctrl);
890 phase->register_new_node(gc_state_cmp, old_ctrl);
891 phase->register_new_node(gc_state_bool, old_ctrl);
892
893 phase->set_ctrl(gc_state_offset, phase->C->root());
894
895 assert(is_gc_state_test(gc_state_iff, flags), "Should match the shape");
896 }
897
898 void ShenandoahBarrierC2Support::test_null(Node*& ctrl, Node* val, Node*& null_ctrl, PhaseIdealLoop* phase) {
899 Node* old_ctrl = ctrl;
900 PhaseIterGVN& igvn = phase->igvn();
901
902 const Type* val_t = igvn.type(val);
903 if (val_t->meet(TypePtr::NULL_PTR) == val_t) {
904 Node* null_cmp = new CmpPNode(val, igvn.zerocon(T_OBJECT));
905 Node* null_test = new BoolNode(null_cmp, BoolTest::ne);
906
907 IfNode* null_iff = new IfNode(old_ctrl, null_test, PROB_LIKELY(0.999), COUNT_UNKNOWN);
908 ctrl = new IfTrueNode(null_iff);
909 null_ctrl = new IfFalseNode(null_iff);
910
911 IdealLoopTree* loop = phase->get_loop(old_ctrl);
912 phase->register_control(null_iff, loop, old_ctrl);
913 phase->register_control(ctrl, loop, null_iff);
914 phase->register_control(null_ctrl, loop, null_iff);
915
916 phase->register_new_node(null_cmp, old_ctrl);
917 phase->register_new_node(null_test, old_ctrl);
918 }
919 }
920
921 void ShenandoahBarrierC2Support::test_in_cset(Node*& ctrl, Node*& not_cset_ctrl, Node* val, Node* raw_mem, PhaseIdealLoop* phase) {
922 Node* old_ctrl = ctrl;
923 PhaseIterGVN& igvn = phase->igvn();
924
925 Node* raw_val = new CastP2XNode(old_ctrl, val);
926 Node* cset_idx = new URShiftXNode(raw_val, igvn.intcon(ShenandoahHeapRegion::region_size_bytes_shift_jint()));
927
928 // Figure out the target cset address with raw pointer math.
929 // This avoids matching AddP+LoadB that would emit inefficient code.
930 // See JDK-8245465.
931 Node* cset_addr_ptr = igvn.makecon(TypeRawPtr::make(ShenandoahHeap::in_cset_fast_test_addr()));
932 Node* cset_addr = new CastP2XNode(old_ctrl, cset_addr_ptr);
933 Node* cset_load_addr = new AddXNode(cset_addr, cset_idx);
934 Node* cset_load_ptr = new CastX2PNode(cset_load_addr);
935
936 Node* cset_load = new LoadBNode(old_ctrl, raw_mem, cset_load_ptr,
937 DEBUG_ONLY(phase->C->get_adr_type(Compile::AliasIdxRaw)) NOT_DEBUG(NULL),
938 TypeInt::BYTE, MemNode::unordered);
939 Node* cset_cmp = new CmpINode(cset_load, igvn.zerocon(T_INT));
940 Node* cset_bool = new BoolNode(cset_cmp, BoolTest::ne);
941
942 IfNode* cset_iff = new IfNode(old_ctrl, cset_bool, PROB_UNLIKELY(0.999), COUNT_UNKNOWN);
943 ctrl = new IfTrueNode(cset_iff);
944 not_cset_ctrl = new IfFalseNode(cset_iff);
945
946 IdealLoopTree *loop = phase->get_loop(old_ctrl);
947 phase->register_control(cset_iff, loop, old_ctrl);
948 phase->register_control(ctrl, loop, cset_iff);
949 phase->register_control(not_cset_ctrl, loop, cset_iff);
950
951 phase->set_ctrl(cset_addr_ptr, phase->C->root());
952
953 phase->register_new_node(raw_val, old_ctrl);
954 phase->register_new_node(cset_idx, old_ctrl);
955 phase->register_new_node(cset_addr, old_ctrl);
956 phase->register_new_node(cset_load_addr, old_ctrl);
957 phase->register_new_node(cset_load_ptr, old_ctrl);
958 phase->register_new_node(cset_load, old_ctrl);
959 phase->register_new_node(cset_cmp, old_ctrl);
960 phase->register_new_node(cset_bool, old_ctrl);
961 }
962
963 void ShenandoahBarrierC2Support::call_lrb_stub(Node*& ctrl, Node*& val, Node* load_addr, Node*& result_mem, Node* raw_mem, bool is_native, PhaseIdealLoop* phase) {
964 IdealLoopTree*loop = phase->get_loop(ctrl);
965 const TypePtr* obj_type = phase->igvn().type(val)->is_oopptr();
966
967 // The slow path stub consumes and produces raw memory in addition
968 // to the existing memory edges
969 Node* base = find_bottom_mem(ctrl, phase);
970 MergeMemNode* mm = MergeMemNode::make(base);
971 mm->set_memory_at(Compile::AliasIdxRaw, raw_mem);
972 phase->register_new_node(mm, ctrl);
973
974 address target = LP64_ONLY(UseCompressedOops) NOT_LP64(false) ?
975 CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_narrow) :
976 CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier);
977
978 address calladdr = is_native ? CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_native)
979 : target;
980 const char* name = is_native ? "load_reference_barrier_native" : "load_reference_barrier";
981 Node* call = new CallLeafNode(ShenandoahBarrierSetC2::shenandoah_load_reference_barrier_Type(), calladdr, name, TypeRawPtr::BOTTOM);
982
983 call->init_req(TypeFunc::Control, ctrl);
984 call->init_req(TypeFunc::I_O, phase->C->top());
985 call->init_req(TypeFunc::Memory, mm);
986 call->init_req(TypeFunc::FramePtr, phase->C->top());
987 call->init_req(TypeFunc::ReturnAdr, phase->C->top());
988 call->init_req(TypeFunc::Parms, val);
989 call->init_req(TypeFunc::Parms+1, load_addr);
990 phase->register_control(call, loop, ctrl);
991 ctrl = new ProjNode(call, TypeFunc::Control);
992 phase->register_control(ctrl, loop, call);
993 result_mem = new ProjNode(call, TypeFunc::Memory);
994 phase->register_new_node(result_mem, call);
995 val = new ProjNode(call, TypeFunc::Parms);
996 phase->register_new_node(val, call);
997 val = new CheckCastPPNode(ctrl, val, obj_type);
998 phase->register_new_node(val, ctrl);
999 }
1000
1001 void ShenandoahBarrierC2Support::fix_ctrl(Node* barrier, Node* region, const MemoryGraphFixer& fixer, Unique_Node_List& uses, Unique_Node_List& uses_to_ignore, uint last, PhaseIdealLoop* phase) {
1002 Node* ctrl = phase->get_ctrl(barrier);
1003 Node* init_raw_mem = fixer.find_mem(ctrl, barrier);
1004
1005 // Update the control of all nodes that should be after the
1006 // barrier control flow
1007 uses.clear();
1008 // Every node that is control dependent on the barrier's input
1009 // control will be after the expanded barrier. The raw memory (if
1010 // its memory is control dependent on the barrier's input control)
1011 // must stay above the barrier.
1012 uses_to_ignore.clear();
1013 if (phase->has_ctrl(init_raw_mem) && phase->get_ctrl(init_raw_mem) == ctrl && !init_raw_mem->is_Phi()) {
1014 uses_to_ignore.push(init_raw_mem);
1015 }
1016 for (uint next = 0; next < uses_to_ignore.size(); next++) {
1017 Node *n = uses_to_ignore.at(next);
1018 for (uint i = 0; i < n->req(); i++) {
1019 Node* in = n->in(i);
1020 if (in != NULL && phase->has_ctrl(in) && phase->get_ctrl(in) == ctrl) {
1021 uses_to_ignore.push(in);
1022 }
1023 }
1024 }
1025 for (DUIterator_Fast imax, i = ctrl->fast_outs(imax); i < imax; i++) {
1026 Node* u = ctrl->fast_out(i);
1027 if (u->_idx < last &&
1028 u != barrier &&
1029 !uses_to_ignore.member(u) &&
1030 (u->in(0) != ctrl || (!u->is_Region() && !u->is_Phi())) &&
1031 (ctrl->Opcode() != Op_CatchProj || u->Opcode() != Op_CreateEx)) {
1032 Node* old_c = phase->ctrl_or_self(u);
1033 Node* c = old_c;
1034 if (c != ctrl ||
1035 is_dominator_same_ctrl(old_c, barrier, u, phase) ||
1036 ShenandoahBarrierSetC2::is_shenandoah_state_load(u)) {
1037 phase->igvn().rehash_node_delayed(u);
1038 int nb = u->replace_edge(ctrl, region);
1039 if (u->is_CFG()) {
1040 if (phase->idom(u) == ctrl) {
1041 phase->set_idom(u, region, phase->dom_depth(region));
1042 }
1043 } else if (phase->get_ctrl(u) == ctrl) {
1044 assert(u != init_raw_mem, "should leave input raw mem above the barrier");
1045 uses.push(u);
1046 }
1047 assert(nb == 1, "more than 1 ctrl input?");
1048 --i, imax -= nb;
1049 }
1050 }
1051 }
1052 }
1053
1054 static Node* create_phis_on_call_return(Node* ctrl, Node* c, Node* n, Node* n_clone, const CallProjections* projs, PhaseIdealLoop* phase) {
1055 Node* region = NULL;
1056 while (c != ctrl) {
1057 if (c->is_Region()) {
1058 region = c;
1059 }
1060 c = phase->idom(c);
1061 }
1062 assert(region != NULL, "");
1063 Node* phi = new PhiNode(region, n->bottom_type());
1064 for (uint j = 1; j < region->req(); j++) {
1065 Node* in = region->in(j);
1066 if (phase->is_dominator(projs->fallthrough_catchproj, in)) {
1067 phi->init_req(j, n);
1068 } else if (phase->is_dominator(projs->catchall_catchproj, in)) {
1069 phi->init_req(j, n_clone);
1070 } else {
1071 phi->init_req(j, create_phis_on_call_return(ctrl, in, n, n_clone, projs, phase));
1072 }
1073 }
1074 phase->register_new_node(phi, region);
1075 return phi;
1076 }
1077
1078 void ShenandoahBarrierC2Support::pin_and_expand(PhaseIdealLoop* phase) {
1079 ShenandoahBarrierSetC2State* state = ShenandoahBarrierSetC2::bsc2()->state();
1080
1081 Unique_Node_List uses;
1082 for (int i = 0; i < state->enqueue_barriers_count(); i++) {
1083 Node* barrier = state->enqueue_barrier(i);
1084 Node* ctrl = phase->get_ctrl(barrier);
1085 IdealLoopTree* loop = phase->get_loop(ctrl);
1086 Node* head = loop->head();
1087 if (head->is_OuterStripMinedLoop()) {
1088 // Expanding a barrier here will break loop strip mining
1089 // verification. Transform the loop so the loop nest doesn't
1090 // appear as strip mined.
1091 OuterStripMinedLoopNode* outer = head->as_OuterStripMinedLoop();
1092 hide_strip_mined_loop(outer, outer->unique_ctrl_out()->as_CountedLoop(), phase);
1093 }
1094 }
1095
1096 Node_Stack stack(0);
1097 Node_List clones;
1098 for (int i = state->load_reference_barriers_count() - 1; i >= 0; i--) {
1099 ShenandoahLoadReferenceBarrierNode* lrb = state->load_reference_barrier(i);
1100
1101 Node* ctrl = phase->get_ctrl(lrb);
1102 Node* val = lrb->in(ShenandoahLoadReferenceBarrierNode::ValueIn);
1103
1104 CallStaticJavaNode* unc = NULL;
1105 Node* unc_ctrl = NULL;
1106 Node* uncasted_val = val;
1107
1108 for (DUIterator_Fast imax, i = lrb->fast_outs(imax); i < imax; i++) {
1109 Node* u = lrb->fast_out(i);
1110 if (u->Opcode() == Op_CastPP &&
1111 u->in(0) != NULL &&
1112 phase->is_dominator(u->in(0), ctrl)) {
1113 const Type* u_t = phase->igvn().type(u);
1114
1115 if (u_t->meet(TypePtr::NULL_PTR) != u_t &&
1116 u->in(0)->Opcode() == Op_IfTrue &&
1117 u->in(0)->as_Proj()->is_uncommon_trap_if_pattern(Deoptimization::Reason_none) &&
1118 u->in(0)->in(0)->is_If() &&
1119 u->in(0)->in(0)->in(1)->Opcode() == Op_Bool &&
1120 u->in(0)->in(0)->in(1)->as_Bool()->_test._test == BoolTest::ne &&
1121 u->in(0)->in(0)->in(1)->in(1)->Opcode() == Op_CmpP &&
1122 u->in(0)->in(0)->in(1)->in(1)->in(1) == val &&
1123 u->in(0)->in(0)->in(1)->in(1)->in(2)->bottom_type() == TypePtr::NULL_PTR) {
1124 IdealLoopTree* loop = phase->get_loop(ctrl);
1125 IdealLoopTree* unc_loop = phase->get_loop(u->in(0));
1126
1127 if (!unc_loop->is_member(loop)) {
1128 continue;
1129 }
1130
1131 Node* branch = no_branches(ctrl, u->in(0), false, phase);
1132 assert(branch == NULL || branch == NodeSentinel, "was not looking for a branch");
1133 if (branch == NodeSentinel) {
1134 continue;
1135 }
1136
1137 Node* iff = u->in(0)->in(0);
1138 Node* bol = iff->in(1)->clone();
1139 Node* cmp = bol->in(1)->clone();
1140 cmp->set_req(1, lrb);
1141 bol->set_req(1, cmp);
1142 phase->igvn().replace_input_of(iff, 1, bol);
1143 phase->set_ctrl(lrb, iff->in(0));
1144 phase->register_new_node(cmp, iff->in(0));
1145 phase->register_new_node(bol, iff->in(0));
1146 break;
1147 }
1148 }
1149 }
1150 if ((ctrl->is_Proj() && ctrl->in(0)->is_CallJava()) || ctrl->is_CallJava()) {
1151 CallNode* call = ctrl->is_Proj() ? ctrl->in(0)->as_CallJava() : ctrl->as_CallJava();
1152 if (call->entry_point() == OptoRuntime::rethrow_stub()) {
1153 // The rethrow call may have too many projections to be
1154 // properly handled here. Given there's no reason for a
1155 // barrier to depend on the call, move it above the call
1156 stack.push(lrb, 0);
1157 do {
1158 Node* n = stack.node();
1159 uint idx = stack.index();
1160 if (idx < n->req()) {
1161 Node* in = n->in(idx);
1162 stack.set_index(idx+1);
1163 if (in != NULL) {
1164 if (phase->has_ctrl(in)) {
1165 if (phase->is_dominator(call, phase->get_ctrl(in))) {
1166 #ifdef ASSERT
1167 for (uint i = 0; i < stack.size(); i++) {
1168 assert(stack.node_at(i) != in, "node shouldn't have been seen yet");
1169 }
1170 #endif
1171 stack.push(in, 0);
1172 }
1173 } else {
1174 assert(phase->is_dominator(in, call->in(0)), "no dependency on the call");
1175 }
1176 }
1177 } else {
1178 phase->set_ctrl(n, call->in(0));
1179 stack.pop();
1180 }
1181 } while(stack.size() > 0);
1182 continue;
1183 }
1184 CallProjections* projs = call->extract_projections(false, false);
1185 #ifdef ASSERT
1186 VectorSet cloned;
1187 #endif
1188 Node* lrb_clone = lrb->clone();
1189 phase->register_new_node(lrb_clone, projs->catchall_catchproj);
1190 phase->set_ctrl(lrb, projs->fallthrough_catchproj);
1191
1192 stack.push(lrb, 0);
1193 clones.push(lrb_clone);
1194
1195 do {
1196 assert(stack.size() == clones.size(), "");
1197 Node* n = stack.node();
1198 #ifdef ASSERT
1199 if (n->is_Load()) {
1200 Node* mem = n->in(MemNode::Memory);
1201 for (DUIterator_Fast jmax, j = mem->fast_outs(jmax); j < jmax; j++) {
1202 Node* u = mem->fast_out(j);
1203 assert(!u->is_Store() || !u->is_LoadStore() || phase->get_ctrl(u) != ctrl, "anti dependent store?");
1204 }
1205 }
1206 #endif
1207 uint idx = stack.index();
1208 Node* n_clone = clones.at(clones.size()-1);
1209 if (idx < n->outcnt()) {
1210 Node* u = n->raw_out(idx);
1211 Node* c = phase->ctrl_or_self(u);
1212 if (phase->is_dominator(call, c) && phase->is_dominator(c, projs->fallthrough_proj)) {
1213 stack.set_index(idx+1);
1214 assert(!u->is_CFG(), "");
1215 stack.push(u, 0);
1216 assert(!cloned.test_set(u->_idx), "only one clone");
1217 Node* u_clone = u->clone();
1218 int nb = u_clone->replace_edge(n, n_clone);
1219 assert(nb > 0, "should have replaced some uses");
1220 phase->register_new_node(u_clone, projs->catchall_catchproj);
1221 clones.push(u_clone);
1222 phase->set_ctrl(u, projs->fallthrough_catchproj);
1223 } else {
1224 bool replaced = false;
1225 if (u->is_Phi()) {
1226 for (uint k = 1; k < u->req(); k++) {
1227 if (u->in(k) == n) {
1228 if (phase->is_dominator(projs->catchall_catchproj, u->in(0)->in(k))) {
1229 phase->igvn().replace_input_of(u, k, n_clone);
1230 replaced = true;
1231 } else if (!phase->is_dominator(projs->fallthrough_catchproj, u->in(0)->in(k))) {
1232 phase->igvn().replace_input_of(u, k, create_phis_on_call_return(ctrl, u->in(0)->in(k), n, n_clone, projs, phase));
1233 replaced = true;
1234 }
1235 }
1236 }
1237 } else {
1238 if (phase->is_dominator(projs->catchall_catchproj, c)) {
1239 phase->igvn().rehash_node_delayed(u);
1240 int nb = u->replace_edge(n, n_clone);
1241 assert(nb > 0, "should have replaced some uses");
1242 replaced = true;
1243 } else if (!phase->is_dominator(projs->fallthrough_catchproj, c)) {
1244 if (u->is_If()) {
1245 // Can't break If/Bool/Cmp chain
1246 assert(n->is_Bool(), "unexpected If shape");
1247 assert(stack.node_at(stack.size()-2)->is_Cmp(), "unexpected If shape");
1248 assert(n_clone->is_Bool(), "unexpected clone");
1249 assert(clones.at(clones.size()-2)->is_Cmp(), "unexpected clone");
1250 Node* bol_clone = n->clone();
1251 Node* cmp_clone = stack.node_at(stack.size()-2)->clone();
1252 bol_clone->set_req(1, cmp_clone);
1253
1254 Node* nn = stack.node_at(stack.size()-3);
1255 Node* nn_clone = clones.at(clones.size()-3);
1256 assert(nn->Opcode() == nn_clone->Opcode(), "mismatch");
1257
1258 int nb = cmp_clone->replace_edge(nn, create_phis_on_call_return(ctrl, c, nn, nn_clone, projs, phase));
1259 assert(nb > 0, "should have replaced some uses");
1260
1261 phase->register_new_node(bol_clone, u->in(0));
1262 phase->register_new_node(cmp_clone, u->in(0));
1263
1264 phase->igvn().replace_input_of(u, 1, bol_clone);
1265
1266 } else {
1267 phase->igvn().rehash_node_delayed(u);
1268 int nb = u->replace_edge(n, create_phis_on_call_return(ctrl, c, n, n_clone, projs, phase));
1269 assert(nb > 0, "should have replaced some uses");
1270 }
1271 replaced = true;
1272 }
1273 }
1274 if (!replaced) {
1275 stack.set_index(idx+1);
1276 }
1277 }
1278 } else {
1279 stack.pop();
1280 clones.pop();
1281 }
1282 } while (stack.size() > 0);
1283 assert(stack.size() == 0 && clones.size() == 0, "");
1284 }
1285 }
1286
1287 for (int i = 0; i < state->load_reference_barriers_count(); i++) {
1288 ShenandoahLoadReferenceBarrierNode* lrb = state->load_reference_barrier(i);
1289 Node* ctrl = phase->get_ctrl(lrb);
1290 IdealLoopTree* loop = phase->get_loop(ctrl);
1291 Node* head = loop->head();
1292 if (head->is_OuterStripMinedLoop()) {
1293 // Expanding a barrier here will break loop strip mining
1294 // verification. Transform the loop so the loop nest doesn't
1295 // appear as strip mined.
1296 OuterStripMinedLoopNode* outer = head->as_OuterStripMinedLoop();
1297 hide_strip_mined_loop(outer, outer->unique_ctrl_out()->as_CountedLoop(), phase);
1298 }
1299 }
1300
1301 // Expand load-reference-barriers
1302 MemoryGraphFixer fixer(Compile::AliasIdxRaw, true, phase);
1303 Unique_Node_List uses_to_ignore;
1304 for (int i = state->load_reference_barriers_count() - 1; i >= 0; i--) {
1305 ShenandoahLoadReferenceBarrierNode* lrb = state->load_reference_barrier(i);
1306 uint last = phase->C->unique();
1307 Node* ctrl = phase->get_ctrl(lrb);
1308 Node* val = lrb->in(ShenandoahLoadReferenceBarrierNode::ValueIn);
1309
1310
1311 Node* orig_ctrl = ctrl;
1312
1313 Node* raw_mem = fixer.find_mem(ctrl, lrb);
1314 Node* init_raw_mem = raw_mem;
1315 Node* raw_mem_for_ctrl = fixer.find_mem(ctrl, NULL);
1316
1317 IdealLoopTree *loop = phase->get_loop(ctrl);
1318
1319 Node* heap_stable_ctrl = NULL;
1320 Node* null_ctrl = NULL;
1321
1322 assert(val->bottom_type()->make_oopptr(), "need oop");
1323 assert(val->bottom_type()->make_oopptr()->const_oop() == NULL, "expect non-constant");
1324
1325 enum { _heap_stable = 1, _not_cset, _evac_path, PATH_LIMIT };
1326 Node* region = new RegionNode(PATH_LIMIT);
1327 Node* val_phi = new PhiNode(region, val->bottom_type()->is_oopptr());
1328 Node* raw_mem_phi = PhiNode::make(region, raw_mem, Type::MEMORY, TypeRawPtr::BOTTOM);
1329
1330 // Stable path.
1331 test_gc_state(ctrl, raw_mem, heap_stable_ctrl, phase, ShenandoahHeap::HAS_FORWARDED);
1332 IfNode* heap_stable_iff = heap_stable_ctrl->in(0)->as_If();
1333
1334 // Heap stable case
1335 region->init_req(_heap_stable, heap_stable_ctrl);
1336 val_phi->init_req(_heap_stable, val);
1337 raw_mem_phi->init_req(_heap_stable, raw_mem);
1338
1339 // Test for in-cset.
1340 // Wires !in_cset(obj) to slot 2 of region and phis
1341 Node* not_cset_ctrl = NULL;
1342 test_in_cset(ctrl, not_cset_ctrl, val, raw_mem, phase);
1343 if (not_cset_ctrl != NULL) {
1344 region->init_req(_not_cset, not_cset_ctrl);
1345 val_phi->init_req(_not_cset, val);
1346 raw_mem_phi->init_req(_not_cset, raw_mem);
1347 }
1348
1349 // Resolve object when orig-value is in cset.
1350 // Make the unconditional resolve for fwdptr.
1351
1352 // Call lrb-stub and wire up that path in slots 4
1353 Node* result_mem = NULL;
1354
1355 Node* addr;
1356 if (ShenandoahSelfFixing) {
1357 VectorSet visited;
1358 addr = get_load_addr(phase, visited, lrb);
1359 } else {
1360 addr = phase->igvn().zerocon(T_OBJECT);
1361 }
1362 if (addr->Opcode() == Op_AddP) {
1363 Node* orig_base = addr->in(AddPNode::Base);
1364 Node* base = new CheckCastPPNode(ctrl, orig_base, orig_base->bottom_type(), true);
1365 phase->register_new_node(base, ctrl);
1366 if (addr->in(AddPNode::Base) == addr->in((AddPNode::Address))) {
1367 // Field access
1368 addr = addr->clone();
1369 addr->set_req(AddPNode::Base, base);
1370 addr->set_req(AddPNode::Address, base);
1371 phase->register_new_node(addr, ctrl);
1372 } else {
1373 Node* addr2 = addr->in(AddPNode::Address);
1374 if (addr2->Opcode() == Op_AddP && addr2->in(AddPNode::Base) == addr2->in(AddPNode::Address) &&
1375 addr2->in(AddPNode::Base) == orig_base) {
1376 addr2 = addr2->clone();
1377 addr2->set_req(AddPNode::Base, base);
1378 addr2->set_req(AddPNode::Address, base);
1379 phase->register_new_node(addr2, ctrl);
1380 addr = addr->clone();
1381 addr->set_req(AddPNode::Base, base);
1382 addr->set_req(AddPNode::Address, addr2);
1383 phase->register_new_node(addr, ctrl);
1384 }
1385 }
1386 }
1387 call_lrb_stub(ctrl, val, addr, result_mem, raw_mem, lrb->is_native(), phase);
1388 region->init_req(_evac_path, ctrl);
1389 val_phi->init_req(_evac_path, val);
1390 raw_mem_phi->init_req(_evac_path, result_mem);
1391
1392 phase->register_control(region, loop, heap_stable_iff);
1393 Node* out_val = val_phi;
1394 phase->register_new_node(val_phi, region);
1395 phase->register_new_node(raw_mem_phi, region);
1396
1397 fix_ctrl(lrb, region, fixer, uses, uses_to_ignore, last, phase);
1398
1399 ctrl = orig_ctrl;
1400
1401 phase->igvn().replace_node(lrb, out_val);
1402
1403 follow_barrier_uses(out_val, ctrl, uses, phase);
1404
1405 for(uint next = 0; next < uses.size(); next++ ) {
1406 Node *n = uses.at(next);
1407 assert(phase->get_ctrl(n) == ctrl, "bad control");
1408 assert(n != init_raw_mem, "should leave input raw mem above the barrier");
1409 phase->set_ctrl(n, region);
1410 follow_barrier_uses(n, ctrl, uses, phase);
1411 }
1412
1413 // The slow path call produces memory: hook the raw memory phi
1414 // from the expanded load reference barrier with the rest of the graph
1415 // which may require adding memory phis at every post dominated
1416 // region and at enclosing loop heads. Use the memory state
1417 // collected in memory_nodes to fix the memory graph. Update that
1418 // memory state as we go.
1419 fixer.fix_mem(ctrl, region, init_raw_mem, raw_mem_for_ctrl, raw_mem_phi, uses);
1420 }
1421 // Done expanding load-reference-barriers.
1422 assert(ShenandoahBarrierSetC2::bsc2()->state()->load_reference_barriers_count() == 0, "all load reference barrier nodes should have been replaced");
1423
1424 for (int i = state->enqueue_barriers_count() - 1; i >= 0; i--) {
1425 Node* barrier = state->enqueue_barrier(i);
1426 Node* pre_val = barrier->in(1);
1427
1428 if (phase->igvn().type(pre_val)->higher_equal(TypePtr::NULL_PTR)) {
1429 ShouldNotReachHere();
1430 continue;
1431 }
1432
1433 Node* ctrl = phase->get_ctrl(barrier);
1434
1435 if (ctrl->is_Proj() && ctrl->in(0)->is_CallJava()) {
1436 assert(is_dominator(phase->get_ctrl(pre_val), ctrl->in(0)->in(0), pre_val, ctrl->in(0), phase), "can't move");
1437 ctrl = ctrl->in(0)->in(0);
1438 phase->set_ctrl(barrier, ctrl);
1439 } else if (ctrl->is_CallRuntime()) {
1440 assert(is_dominator(phase->get_ctrl(pre_val), ctrl->in(0), pre_val, ctrl, phase), "can't move");
1441 ctrl = ctrl->in(0);
1442 phase->set_ctrl(barrier, ctrl);
1443 }
1444
1445 Node* init_ctrl = ctrl;
1446 IdealLoopTree* loop = phase->get_loop(ctrl);
1447 Node* raw_mem = fixer.find_mem(ctrl, barrier);
1448 Node* init_raw_mem = raw_mem;
1449 Node* raw_mem_for_ctrl = fixer.find_mem(ctrl, NULL);
1450 Node* heap_stable_ctrl = NULL;
1451 Node* null_ctrl = NULL;
1452 uint last = phase->C->unique();
1453
1454 enum { _heap_stable = 1, _heap_unstable, PATH_LIMIT };
1455 Node* region = new RegionNode(PATH_LIMIT);
1456 Node* phi = PhiNode::make(region, raw_mem, Type::MEMORY, TypeRawPtr::BOTTOM);
1457
1458 enum { _fast_path = 1, _slow_path, _null_path, PATH_LIMIT2 };
1459 Node* region2 = new RegionNode(PATH_LIMIT2);
1460 Node* phi2 = PhiNode::make(region2, raw_mem, Type::MEMORY, TypeRawPtr::BOTTOM);
1461
1462 // Stable path.
1463 test_gc_state(ctrl, raw_mem, heap_stable_ctrl, phase, ShenandoahHeap::MARKING);
1464 region->init_req(_heap_stable, heap_stable_ctrl);
1465 phi->init_req(_heap_stable, raw_mem);
1466
1467 // Null path
1468 Node* reg2_ctrl = NULL;
1469 test_null(ctrl, pre_val, null_ctrl, phase);
1470 if (null_ctrl != NULL) {
1471 reg2_ctrl = null_ctrl->in(0);
1472 region2->init_req(_null_path, null_ctrl);
1473 phi2->init_req(_null_path, raw_mem);
1474 } else {
1475 region2->del_req(_null_path);
1476 phi2->del_req(_null_path);
1477 }
1478
1479 const int index_offset = in_bytes(ShenandoahThreadLocalData::satb_mark_queue_index_offset());
1480 const int buffer_offset = in_bytes(ShenandoahThreadLocalData::satb_mark_queue_buffer_offset());
1481 Node* thread = new ThreadLocalNode();
1482 phase->register_new_node(thread, ctrl);
1483 Node* buffer_adr = new AddPNode(phase->C->top(), thread, phase->igvn().MakeConX(buffer_offset));
1484 phase->register_new_node(buffer_adr, ctrl);
1485 Node* index_adr = new AddPNode(phase->C->top(), thread, phase->igvn().MakeConX(index_offset));
1486 phase->register_new_node(index_adr, ctrl);
1487
1488 BasicType index_bt = TypeX_X->basic_type();
1489 assert(sizeof(size_t) == type2aelembytes(index_bt), "Loading G1 SATBMarkQueue::_index with wrong size.");
1490 const TypePtr* adr_type = TypeRawPtr::BOTTOM;
1491 Node* index = new LoadXNode(ctrl, raw_mem, index_adr, adr_type, TypeX_X, MemNode::unordered);
1492 phase->register_new_node(index, ctrl);
1493 Node* index_cmp = new CmpXNode(index, phase->igvn().MakeConX(0));
1494 phase->register_new_node(index_cmp, ctrl);
1495 Node* index_test = new BoolNode(index_cmp, BoolTest::ne);
1496 phase->register_new_node(index_test, ctrl);
1497 IfNode* queue_full_iff = new IfNode(ctrl, index_test, PROB_LIKELY(0.999), COUNT_UNKNOWN);
1498 if (reg2_ctrl == NULL) reg2_ctrl = queue_full_iff;
1499 phase->register_control(queue_full_iff, loop, ctrl);
1500 Node* not_full = new IfTrueNode(queue_full_iff);
1501 phase->register_control(not_full, loop, queue_full_iff);
1502 Node* full = new IfFalseNode(queue_full_iff);
1503 phase->register_control(full, loop, queue_full_iff);
1504
1505 ctrl = not_full;
1506
1507 Node* next_index = new SubXNode(index, phase->igvn().MakeConX(sizeof(intptr_t)));
1508 phase->register_new_node(next_index, ctrl);
1509
1510 Node* buffer = new LoadPNode(ctrl, raw_mem, buffer_adr, adr_type, TypeRawPtr::NOTNULL, MemNode::unordered);
1511 phase->register_new_node(buffer, ctrl);
1512 Node *log_addr = new AddPNode(phase->C->top(), buffer, next_index);
1513 phase->register_new_node(log_addr, ctrl);
1514 Node* log_store = new StorePNode(ctrl, raw_mem, log_addr, adr_type, pre_val, MemNode::unordered);
1515 phase->register_new_node(log_store, ctrl);
1516 // update the index
1517 Node* index_update = new StoreXNode(ctrl, log_store, index_adr, adr_type, next_index, MemNode::unordered);
1518 phase->register_new_node(index_update, ctrl);
1519
1520 // Fast-path case
1521 region2->init_req(_fast_path, ctrl);
1522 phi2->init_req(_fast_path, index_update);
1523
1524 ctrl = full;
1525
1526 Node* base = find_bottom_mem(ctrl, phase);
1527
1528 MergeMemNode* mm = MergeMemNode::make(base);
1529 mm->set_memory_at(Compile::AliasIdxRaw, raw_mem);
1530 phase->register_new_node(mm, ctrl);
1531
1532 Node* call = new CallLeafNode(ShenandoahBarrierSetC2::write_ref_field_pre_entry_Type(), CAST_FROM_FN_PTR(address, ShenandoahRuntime::write_ref_field_pre_entry), "shenandoah_wb_pre", TypeRawPtr::BOTTOM);
1533 call->init_req(TypeFunc::Control, ctrl);
1534 call->init_req(TypeFunc::I_O, phase->C->top());
1535 call->init_req(TypeFunc::Memory, mm);
1536 call->init_req(TypeFunc::FramePtr, phase->C->top());
1537 call->init_req(TypeFunc::ReturnAdr, phase->C->top());
1538 call->init_req(TypeFunc::Parms, pre_val);
1539 call->init_req(TypeFunc::Parms+1, thread);
1540 phase->register_control(call, loop, ctrl);
1541
1542 Node* ctrl_proj = new ProjNode(call, TypeFunc::Control);
1543 phase->register_control(ctrl_proj, loop, call);
1544 Node* mem_proj = new ProjNode(call, TypeFunc::Memory);
1545 phase->register_new_node(mem_proj, call);
1546
1547 // Slow-path case
1548 region2->init_req(_slow_path, ctrl_proj);
1549 phi2->init_req(_slow_path, mem_proj);
1550
1551 phase->register_control(region2, loop, reg2_ctrl);
1552 phase->register_new_node(phi2, region2);
1553
1554 region->init_req(_heap_unstable, region2);
1555 phi->init_req(_heap_unstable, phi2);
1556
1557 phase->register_control(region, loop, heap_stable_ctrl->in(0));
1558 phase->register_new_node(phi, region);
1559
1560 fix_ctrl(barrier, region, fixer, uses, uses_to_ignore, last, phase);
1561 for(uint next = 0; next < uses.size(); next++ ) {
1562 Node *n = uses.at(next);
1563 assert(phase->get_ctrl(n) == init_ctrl, "bad control");
1564 assert(n != init_raw_mem, "should leave input raw mem above the barrier");
1565 phase->set_ctrl(n, region);
1566 follow_barrier_uses(n, init_ctrl, uses, phase);
1567 }
1568 fixer.fix_mem(init_ctrl, region, init_raw_mem, raw_mem_for_ctrl, phi, uses);
1569
1570 phase->igvn().replace_node(barrier, pre_val);
1571 }
1572 assert(state->enqueue_barriers_count() == 0, "all enqueue barrier nodes should have been replaced");
1573
1574 }
1575
1576 Node* ShenandoahBarrierC2Support::get_load_addr(PhaseIdealLoop* phase, VectorSet& visited, Node* in) {
1577 if (visited.test_set(in->_idx)) {
1578 return NULL;
1579 }
1580 switch (in->Opcode()) {
1581 case Op_Proj:
1582 return get_load_addr(phase, visited, in->in(0));
1583 case Op_CastPP:
1584 case Op_CheckCastPP:
1585 case Op_DecodeN:
1586 case Op_EncodeP:
1587 return get_load_addr(phase, visited, in->in(1));
1588 case Op_LoadN:
1589 case Op_LoadP:
1590 return in->in(MemNode::Address);
1591 case Op_CompareAndExchangeN:
1592 case Op_CompareAndExchangeP:
1593 case Op_GetAndSetN:
1594 case Op_GetAndSetP:
1595 case Op_ShenandoahCompareAndExchangeP:
1596 case Op_ShenandoahCompareAndExchangeN:
1597 // Those instructions would just have stored a different
1598 // value into the field. No use to attempt to fix it at this point.
1599 return phase->igvn().zerocon(T_OBJECT);
1600 case Op_CMoveP:
1601 case Op_CMoveN: {
1602 Node* t = get_load_addr(phase, visited, in->in(CMoveNode::IfTrue));
1603 Node* f = get_load_addr(phase, visited, in->in(CMoveNode::IfFalse));
1604 // Handle unambiguous cases: single address reported on both branches.
1605 if (t != NULL && f == NULL) return t;
1606 if (t == NULL && f != NULL) return f;
1607 if (t != NULL && t == f) return t;
1608 // Ambiguity.
1609 return phase->igvn().zerocon(T_OBJECT);
1610 }
1611 case Op_Phi: {
1612 Node* addr = NULL;
1613 for (uint i = 1; i < in->req(); i++) {
1614 Node* addr1 = get_load_addr(phase, visited, in->in(i));
1615 if (addr == NULL) {
1616 addr = addr1;
1617 }
1618 if (addr != addr1) {
1619 return phase->igvn().zerocon(T_OBJECT);
1620 }
1621 }
1622 return addr;
1623 }
1624 case Op_ShenandoahLoadReferenceBarrier:
1625 return get_load_addr(phase, visited, in->in(ShenandoahLoadReferenceBarrierNode::ValueIn));
1626 case Op_ShenandoahEnqueueBarrier:
1627 return get_load_addr(phase, visited, in->in(1));
1628 case Op_CallDynamicJava:
1629 case Op_CallLeaf:
1630 case Op_CallStaticJava:
1631 case Op_ConN:
1632 case Op_ConP:
1633 case Op_Parm:
1634 case Op_CreateEx:
1635 return phase->igvn().zerocon(T_OBJECT);
1636 default:
1637 #ifdef ASSERT
1638 fatal("Unknown node in get_load_addr: %s", NodeClassNames[in->Opcode()]);
1639 #endif
1640 return phase->igvn().zerocon(T_OBJECT);
1641 }
1642
1643 }
1644
1645 void ShenandoahBarrierC2Support::move_gc_state_test_out_of_loop(IfNode* iff, PhaseIdealLoop* phase) {
1646 IdealLoopTree *loop = phase->get_loop(iff);
1647 Node* loop_head = loop->_head;
1648 Node* entry_c = loop_head->in(LoopNode::EntryControl);
1649
1650 Node* bol = iff->in(1);
1651 Node* cmp = bol->in(1);
1652 Node* andi = cmp->in(1);
1653 Node* load = andi->in(1);
1654
1655 assert(is_gc_state_load(load), "broken");
1656 if (!phase->is_dominator(load->in(0), entry_c)) {
1657 Node* mem_ctrl = NULL;
1658 Node* mem = dom_mem(load->in(MemNode::Memory), loop_head, Compile::AliasIdxRaw, mem_ctrl, phase);
1659 load = load->clone();
1660 load->set_req(MemNode::Memory, mem);
1661 load->set_req(0, entry_c);
1662 phase->register_new_node(load, entry_c);
1663 andi = andi->clone();
1664 andi->set_req(1, load);
1665 phase->register_new_node(andi, entry_c);
1666 cmp = cmp->clone();
1667 cmp->set_req(1, andi);
1668 phase->register_new_node(cmp, entry_c);
1669 bol = bol->clone();
1670 bol->set_req(1, cmp);
1671 phase->register_new_node(bol, entry_c);
1672
1673 phase->igvn().replace_input_of(iff, 1, bol);
1674 }
1675 }
1676
1677 bool ShenandoahBarrierC2Support::identical_backtoback_ifs(Node* n, PhaseIdealLoop* phase) {
1678 if (!n->is_If() || n->is_CountedLoopEnd()) {
1679 return false;
1680 }
1681 Node* region = n->in(0);
1682
1683 if (!region->is_Region()) {
1684 return false;
1685 }
1686 Node* dom = phase->idom(region);
1687 if (!dom->is_If()) {
1688 return false;
1689 }
1690
1691 if (!is_heap_stable_test(n) || !is_heap_stable_test(dom)) {
1692 return false;
1693 }
1694
1695 IfNode* dom_if = dom->as_If();
1696 Node* proj_true = dom_if->proj_out(1);
1697 Node* proj_false = dom_if->proj_out(0);
1698
1699 for (uint i = 1; i < region->req(); i++) {
1700 if (phase->is_dominator(proj_true, region->in(i))) {
1701 continue;
1702 }
1703 if (phase->is_dominator(proj_false, region->in(i))) {
1704 continue;
1705 }
1706 return false;
1707 }
1708
1709 return true;
1710 }
1711
1712 void ShenandoahBarrierC2Support::merge_back_to_back_tests(Node* n, PhaseIdealLoop* phase) {
1713 assert(is_heap_stable_test(n), "no other tests");
1714 if (identical_backtoback_ifs(n, phase)) {
1715 Node* n_ctrl = n->in(0);
1716 if (phase->can_split_if(n_ctrl)) {
1717 IfNode* dom_if = phase->idom(n_ctrl)->as_If();
1718 if (is_heap_stable_test(n)) {
1719 Node* gc_state_load = n->in(1)->in(1)->in(1)->in(1);
1720 assert(is_gc_state_load(gc_state_load), "broken");
1721 Node* dom_gc_state_load = dom_if->in(1)->in(1)->in(1)->in(1);
1722 assert(is_gc_state_load(dom_gc_state_load), "broken");
1723 if (gc_state_load != dom_gc_state_load) {
1724 phase->igvn().replace_node(gc_state_load, dom_gc_state_load);
1725 }
1726 }
1727 PhiNode* bolphi = PhiNode::make_blank(n_ctrl, n->in(1));
1728 Node* proj_true = dom_if->proj_out(1);
1729 Node* proj_false = dom_if->proj_out(0);
1730 Node* con_true = phase->igvn().makecon(TypeInt::ONE);
1731 Node* con_false = phase->igvn().makecon(TypeInt::ZERO);
1732
1733 for (uint i = 1; i < n_ctrl->req(); i++) {
1734 if (phase->is_dominator(proj_true, n_ctrl->in(i))) {
1735 bolphi->init_req(i, con_true);
1736 } else {
1737 assert(phase->is_dominator(proj_false, n_ctrl->in(i)), "bad if");
1738 bolphi->init_req(i, con_false);
1739 }
1740 }
1741 phase->register_new_node(bolphi, n_ctrl);
1742 phase->igvn().replace_input_of(n, 1, bolphi);
1743 phase->do_split_if(n);
1744 }
1745 }
1746 }
1747
1748 IfNode* ShenandoahBarrierC2Support::find_unswitching_candidate(const IdealLoopTree* loop, PhaseIdealLoop* phase) {
1749 // Find first invariant test that doesn't exit the loop
1750 LoopNode *head = loop->_head->as_Loop();
1751 IfNode* unswitch_iff = NULL;
1752 Node* n = head->in(LoopNode::LoopBackControl);
1753 int loop_has_sfpts = -1;
1754 while (n != head) {
1755 Node* n_dom = phase->idom(n);
1756 if (n->is_Region()) {
1757 if (n_dom->is_If()) {
1758 IfNode* iff = n_dom->as_If();
1759 if (iff->in(1)->is_Bool()) {
1760 BoolNode* bol = iff->in(1)->as_Bool();
1761 if (bol->in(1)->is_Cmp()) {
1762 // If condition is invariant and not a loop exit,
1763 // then found reason to unswitch.
1764 if (is_heap_stable_test(iff) &&
1765 (loop_has_sfpts == -1 || loop_has_sfpts == 0)) {
1766 assert(!loop->is_loop_exit(iff), "both branches should be in the loop");
1767 if (loop_has_sfpts == -1) {
1768 for(uint i = 0; i < loop->_body.size(); i++) {
1769 Node *m = loop->_body[i];
1770 if (m->is_SafePoint() && !m->is_CallLeaf()) {
1771 loop_has_sfpts = 1;
1772 break;
1773 }
1774 }
1775 if (loop_has_sfpts == -1) {
1776 loop_has_sfpts = 0;
1777 }
1778 }
1779 if (!loop_has_sfpts) {
1780 unswitch_iff = iff;
1781 }
1782 }
1783 }
1784 }
1785 }
1786 }
1787 n = n_dom;
1788 }
1789 return unswitch_iff;
1790 }
1791
1792
1793 void ShenandoahBarrierC2Support::optimize_after_expansion(VectorSet &visited, Node_Stack &stack, Node_List &old_new, PhaseIdealLoop* phase) {
1794 Node_List heap_stable_tests;
1795 stack.push(phase->C->start(), 0);
1796 do {
1797 Node* n = stack.node();
1798 uint i = stack.index();
1799
1800 if (i < n->outcnt()) {
1801 Node* u = n->raw_out(i);
1802 stack.set_index(i+1);
1803 if (!visited.test_set(u->_idx)) {
1804 stack.push(u, 0);
1805 }
1806 } else {
1807 stack.pop();
1808 if (n->is_If() && is_heap_stable_test(n)) {
1809 heap_stable_tests.push(n);
1810 }
1811 }
1812 } while (stack.size() > 0);
1813
1814 for (uint i = 0; i < heap_stable_tests.size(); i++) {
1815 Node* n = heap_stable_tests.at(i);
1816 assert(is_heap_stable_test(n), "only evacuation test");
1817 merge_back_to_back_tests(n, phase);
1818 }
1819
1820 if (!phase->C->major_progress()) {
1821 VectorSet seen;
1822 for (uint i = 0; i < heap_stable_tests.size(); i++) {
1823 Node* n = heap_stable_tests.at(i);
1824 IdealLoopTree* loop = phase->get_loop(n);
1825 if (loop != phase->ltree_root() &&
1826 loop->_child == NULL &&
1827 !loop->_irreducible) {
1828 Node* head = loop->_head;
1829 if (head->is_Loop() &&
1830 (!head->is_CountedLoop() || head->as_CountedLoop()->is_main_loop() || head->as_CountedLoop()->is_normal_loop()) &&
1831 !seen.test_set(head->_idx)) {
1832 IfNode* iff = find_unswitching_candidate(loop, phase);
1833 if (iff != NULL) {
1834 Node* bol = iff->in(1);
1835 if (head->as_Loop()->is_strip_mined()) {
1836 head->as_Loop()->verify_strip_mined(0);
1837 }
1838 move_gc_state_test_out_of_loop(iff, phase);
1839
1840 AutoNodeBudget node_budget(phase);
1841
1842 if (loop->policy_unswitching(phase)) {
1843 if (head->as_Loop()->is_strip_mined()) {
1844 OuterStripMinedLoopNode* outer = head->as_CountedLoop()->outer_loop();
1845 hide_strip_mined_loop(outer, head->as_CountedLoop(), phase);
1846 }
1847 phase->do_unswitching(loop, old_new);
1848 } else {
1849 // Not proceeding with unswitching. Move load back in
1850 // the loop.
1851 phase->igvn().replace_input_of(iff, 1, bol);
1852 }
1853 }
1854 }
1855 }
1856 }
1857 }
1858 }
1859
1860 #ifdef ASSERT
1861 void ShenandoahBarrierC2Support::verify_raw_mem(RootNode* root) {
1862 const bool trace = false;
1863 ResourceMark rm;
1864 Unique_Node_List nodes;
1865 Unique_Node_List controls;
1866 Unique_Node_List memories;
1867
1868 nodes.push(root);
1869 for (uint next = 0; next < nodes.size(); next++) {
1870 Node *n = nodes.at(next);
1871 if (ShenandoahBarrierSetC2::is_shenandoah_lrb_call(n)) {
1872 controls.push(n);
1873 if (trace) { tty->print("XXXXXX verifying"); n->dump(); }
1874 for (uint next2 = 0; next2 < controls.size(); next2++) {
1875 Node *m = controls.at(next2);
1876 for (DUIterator_Fast imax, i = m->fast_outs(imax); i < imax; i++) {
1877 Node* u = m->fast_out(i);
1878 if (u->is_CFG() && !u->is_Root() &&
1879 !(u->Opcode() == Op_CProj && u->in(0)->Opcode() == Op_NeverBranch && u->as_Proj()->_con == 1) &&
1880 !(u->is_Region() && u->unique_ctrl_out()->Opcode() == Op_Halt)) {
1881 if (trace) { tty->print("XXXXXX pushing control"); u->dump(); }
1882 controls.push(u);
1883 }
1884 }
1885 }
1886 memories.push(n->as_Call()->proj_out(TypeFunc::Memory));
1887 for (uint next2 = 0; next2 < memories.size(); next2++) {
1888 Node *m = memories.at(next2);
1889 assert(m->bottom_type() == Type::MEMORY, "");
1890 for (DUIterator_Fast imax, i = m->fast_outs(imax); i < imax; i++) {
1891 Node* u = m->fast_out(i);
1892 if (u->bottom_type() == Type::MEMORY && (u->is_Mem() || u->is_ClearArray())) {
1893 if (trace) { tty->print("XXXXXX pushing memory"); u->dump(); }
1894 memories.push(u);
1895 } else if (u->is_LoadStore()) {
1896 if (trace) { tty->print("XXXXXX pushing memory"); u->find_out_with(Op_SCMemProj)->dump(); }
1897 memories.push(u->find_out_with(Op_SCMemProj));
1898 } else if (u->is_MergeMem() && u->as_MergeMem()->memory_at(Compile::AliasIdxRaw) == m) {
1899 if (trace) { tty->print("XXXXXX pushing memory"); u->dump(); }
1900 memories.push(u);
1901 } else if (u->is_Phi()) {
1902 assert(u->bottom_type() == Type::MEMORY, "");
1903 if (u->adr_type() == TypeRawPtr::BOTTOM || u->adr_type() == TypePtr::BOTTOM) {
1904 assert(controls.member(u->in(0)), "");
1905 if (trace) { tty->print("XXXXXX pushing memory"); u->dump(); }
1906 memories.push(u);
1907 }
1908 } else if (u->is_SafePoint() || u->is_MemBar()) {
1909 for (DUIterator_Fast jmax, j = u->fast_outs(jmax); j < jmax; j++) {
1910 Node* uu = u->fast_out(j);
1911 if (uu->bottom_type() == Type::MEMORY) {
1912 if (trace) { tty->print("XXXXXX pushing memory"); uu->dump(); }
1913 memories.push(uu);
1914 }
1915 }
1916 }
1917 }
1918 }
1919 for (uint next2 = 0; next2 < controls.size(); next2++) {
1920 Node *m = controls.at(next2);
1921 if (m->is_Region()) {
1922 bool all_in = true;
1923 for (uint i = 1; i < m->req(); i++) {
1924 if (!controls.member(m->in(i))) {
1925 all_in = false;
1926 break;
1927 }
1928 }
1929 if (trace) { tty->print("XXX verifying %s", all_in ? "all in" : ""); m->dump(); }
1930 bool found_phi = false;
1931 for (DUIterator_Fast jmax, j = m->fast_outs(jmax); j < jmax && !found_phi; j++) {
1932 Node* u = m->fast_out(j);
1933 if (u->is_Phi() && memories.member(u)) {
1934 found_phi = true;
1935 for (uint i = 1; i < u->req() && found_phi; i++) {
1936 Node* k = u->in(i);
1937 if (memories.member(k) != controls.member(m->in(i))) {
1938 found_phi = false;
1939 }
1940 }
1941 }
1942 }
1943 assert(found_phi || all_in, "");
1944 }
1945 }
1946 controls.clear();
1947 memories.clear();
1948 }
1949 for( uint i = 0; i < n->len(); ++i ) {
1950 Node *m = n->in(i);
1951 if (m != NULL) {
1952 nodes.push(m);
1953 }
1954 }
1955 }
1956 }
1957 #endif
1958
1959 ShenandoahEnqueueBarrierNode::ShenandoahEnqueueBarrierNode(Node* val) : Node(NULL, val) {
1960 ShenandoahBarrierSetC2::bsc2()->state()->add_enqueue_barrier(this);
1961 }
1962
1963 const Type* ShenandoahEnqueueBarrierNode::bottom_type() const {
1964 if (in(1) == NULL || in(1)->is_top()) {
1965 return Type::TOP;
1966 }
1967 const Type* t = in(1)->bottom_type();
1968 if (t == TypePtr::NULL_PTR) {
1969 return t;
1970 }
1971 return t->is_oopptr();
1972 }
1973
1974 const Type* ShenandoahEnqueueBarrierNode::Value(PhaseGVN* phase) const {
1975 if (in(1) == NULL) {
1976 return Type::TOP;
1977 }
1978 const Type* t = phase->type(in(1));
1979 if (t == Type::TOP) {
1980 return Type::TOP;
1981 }
1982 if (t == TypePtr::NULL_PTR) {
1983 return t;
1984 }
1985 return t->is_oopptr();
1986 }
1987
1988 int ShenandoahEnqueueBarrierNode::needed(Node* n) {
1989 if (n == NULL ||
1990 n->is_Allocate() ||
1991 n->Opcode() == Op_ShenandoahEnqueueBarrier ||
1992 n->bottom_type() == TypePtr::NULL_PTR ||
1993 (n->bottom_type()->make_oopptr() != NULL && n->bottom_type()->make_oopptr()->const_oop() != NULL)) {
1994 return NotNeeded;
1995 }
1996 if (n->is_Phi() ||
1997 n->is_CMove()) {
1998 return MaybeNeeded;
1999 }
2000 return Needed;
2001 }
2002
2003 Node* ShenandoahEnqueueBarrierNode::next(Node* n) {
2004 for (;;) {
2005 if (n == NULL) {
2006 return n;
2007 } else if (n->bottom_type() == TypePtr::NULL_PTR) {
2008 return n;
2009 } else if (n->bottom_type()->make_oopptr() != NULL && n->bottom_type()->make_oopptr()->const_oop() != NULL) {
2010 return n;
2011 } else if (n->is_ConstraintCast() ||
2012 n->Opcode() == Op_DecodeN ||
2013 n->Opcode() == Op_EncodeP) {
2014 n = n->in(1);
2015 } else if (n->is_Proj()) {
2016 n = n->in(0);
2017 } else {
2018 return n;
2019 }
2020 }
2021 ShouldNotReachHere();
2022 return NULL;
2023 }
2024
2025 Node* ShenandoahEnqueueBarrierNode::Identity(PhaseGVN* phase) {
2026 PhaseIterGVN* igvn = phase->is_IterGVN();
2027
2028 Node* n = next(in(1));
2029
2030 int cont = needed(n);
2031
2032 if (cont == NotNeeded) {
2033 return in(1);
2034 } else if (cont == MaybeNeeded) {
2035 if (igvn == NULL) {
2036 phase->record_for_igvn(this);
2037 return this;
2038 } else {
2039 ResourceMark rm;
2040 Unique_Node_List wq;
2041 uint wq_i = 0;
2042
2043 for (;;) {
2044 if (n->is_Phi()) {
2045 for (uint i = 1; i < n->req(); i++) {
2046 Node* m = n->in(i);
2047 if (m != NULL) {
2048 wq.push(m);
2049 }
2050 }
2051 } else {
2052 assert(n->is_CMove(), "nothing else here");
2053 Node* m = n->in(CMoveNode::IfFalse);
2054 wq.push(m);
2055 m = n->in(CMoveNode::IfTrue);
2056 wq.push(m);
2057 }
2058 Node* orig_n = NULL;
2059 do {
2060 if (wq_i >= wq.size()) {
2061 return in(1);
2062 }
2063 n = wq.at(wq_i);
2064 wq_i++;
2065 orig_n = n;
2066 n = next(n);
2067 cont = needed(n);
2068 if (cont == Needed) {
2069 return this;
2070 }
2071 } while (cont != MaybeNeeded || (orig_n != n && wq.member(n)));
2072 }
2073 }
2074 }
2075
2076 return this;
2077 }
2078
2079 #ifdef ASSERT
2080 static bool has_never_branch(Node* root) {
2081 for (uint i = 1; i < root->req(); i++) {
2082 Node* in = root->in(i);
2083 if (in != NULL && in->Opcode() == Op_Halt && in->in(0)->is_Proj() && in->in(0)->in(0)->Opcode() == Op_NeverBranch) {
2084 return true;
2085 }
2086 }
2087 return false;
2088 }
2089 #endif
2090
2091 void MemoryGraphFixer::collect_memory_nodes() {
2092 Node_Stack stack(0);
2093 VectorSet visited;
2094 Node_List regions;
2095
2096 // Walk the raw memory graph and create a mapping from CFG node to
2097 // memory node. Exclude phis for now.
2098 stack.push(_phase->C->root(), 1);
2099 do {
2100 Node* n = stack.node();
2101 int opc = n->Opcode();
2102 uint i = stack.index();
2103 if (i < n->req()) {
2104 Node* mem = NULL;
2105 if (opc == Op_Root) {
2106 Node* in = n->in(i);
2107 int in_opc = in->Opcode();
2108 if (in_opc == Op_Return || in_opc == Op_Rethrow) {
2109 mem = in->in(TypeFunc::Memory);
2110 } else if (in_opc == Op_Halt) {
2111 if (in->in(0)->is_Region()) {
2112 Node* r = in->in(0);
2113 for (uint j = 1; j < r->req(); j++) {
2114 assert(r->in(j)->Opcode() != Op_NeverBranch, "");
2115 }
2116 } else {
2117 Node* proj = in->in(0);
2118 assert(proj->is_Proj(), "");
2119 Node* in = proj->in(0);
2120 assert(in->is_CallStaticJava() || in->Opcode() == Op_NeverBranch || in->Opcode() == Op_Catch || proj->is_IfProj(), "");
2121 if (in->is_CallStaticJava()) {
2122 mem = in->in(TypeFunc::Memory);
2123 } else if (in->Opcode() == Op_Catch) {
2124 Node* call = in->in(0)->in(0);
2125 assert(call->is_Call(), "");
2126 mem = call->in(TypeFunc::Memory);
2127 } else if (in->Opcode() == Op_NeverBranch) {
2128 Node* head = in->in(0);
2129 assert(head->is_Region(), "unexpected infinite loop graph shape");
2130
2131 Node* phi_mem = NULL;
2132 for (DUIterator_Fast jmax, j = head->fast_outs(jmax); j < jmax; j++) {
2133 Node* u = head->fast_out(j);
2134 if (u->is_Phi() && u->bottom_type() == Type::MEMORY) {
2135 if (_phase->C->get_alias_index(u->adr_type()) == _alias) {
2136 assert(phi_mem == NULL || phi_mem->adr_type() == TypePtr::BOTTOM, "");
2137 phi_mem = u;
2138 } else if (u->adr_type() == TypePtr::BOTTOM) {
2139 assert(phi_mem == NULL || _phase->C->get_alias_index(phi_mem->adr_type()) == _alias, "");
2140 if (phi_mem == NULL) {
2141 phi_mem = u;
2142 }
2143 }
2144 }
2145 }
2146 if (phi_mem == NULL) {
2147 for (uint j = 1; j < head->req(); j++) {
2148 Node* tail = head->in(j);
2149 if (!_phase->is_dominator(head, tail)) {
2150 continue;
2151 }
2152 Node* c = tail;
2153 while (c != head) {
2154 if (c->is_SafePoint() && !c->is_CallLeaf()) {
2155 Node* m =c->in(TypeFunc::Memory);
2156 if (m->is_MergeMem()) {
2157 m = m->as_MergeMem()->memory_at(_alias);
2158 }
2159 assert(mem == NULL || mem == m, "several memory states");
2160 mem = m;
2161 }
2162 c = _phase->idom(c);
2163 }
2164 assert(mem != NULL, "should have found safepoint");
2165 }
2166 assert(mem != NULL, "should have found safepoint");
2167 } else {
2168 mem = phi_mem;
2169 }
2170 }
2171 }
2172 } else {
2173 #ifdef ASSERT
2174 n->dump();
2175 in->dump();
2176 #endif
2177 ShouldNotReachHere();
2178 }
2179 } else {
2180 assert(n->is_Phi() && n->bottom_type() == Type::MEMORY, "");
2181 assert(n->adr_type() == TypePtr::BOTTOM || _phase->C->get_alias_index(n->adr_type()) == _alias, "");
2182 mem = n->in(i);
2183 }
2184 i++;
2185 stack.set_index(i);
2186 if (mem == NULL) {
2187 continue;
2188 }
2189 for (;;) {
2190 if (visited.test_set(mem->_idx) || mem->is_Start()) {
2191 break;
2192 }
2193 if (mem->is_Phi()) {
2194 stack.push(mem, 2);
2195 mem = mem->in(1);
2196 } else if (mem->is_Proj()) {
2197 stack.push(mem, mem->req());
2198 mem = mem->in(0);
2199 } else if (mem->is_SafePoint() || mem->is_MemBar()) {
2200 mem = mem->in(TypeFunc::Memory);
2201 } else if (mem->is_MergeMem()) {
2202 MergeMemNode* mm = mem->as_MergeMem();
2203 mem = mm->memory_at(_alias);
2204 } else if (mem->is_Store() || mem->is_LoadStore() || mem->is_ClearArray()) {
2205 assert(_alias == Compile::AliasIdxRaw, "");
2206 stack.push(mem, mem->req());
2207 mem = mem->in(MemNode::Memory);
2208 } else {
2209 #ifdef ASSERT
2210 mem->dump();
2211 #endif
2212 ShouldNotReachHere();
2213 }
2214 }
2215 } else {
2216 if (n->is_Phi()) {
2217 // Nothing
2218 } else if (!n->is_Root()) {
2219 Node* c = get_ctrl(n);
2220 _memory_nodes.map(c->_idx, n);
2221 }
2222 stack.pop();
2223 }
2224 } while(stack.is_nonempty());
2225
2226 // Iterate over CFG nodes in rpo and propagate memory state to
2227 // compute memory state at regions, creating new phis if needed.
2228 Node_List rpo_list;
2229 visited.clear();
2230 _phase->rpo(_phase->C->root(), stack, visited, rpo_list);
2231 Node* root = rpo_list.pop();
2232 assert(root == _phase->C->root(), "");
2233
2234 const bool trace = false;
2235 #ifdef ASSERT
2236 if (trace) {
2237 for (int i = rpo_list.size() - 1; i >= 0; i--) {
2238 Node* c = rpo_list.at(i);
2239 if (_memory_nodes[c->_idx] != NULL) {
2240 tty->print("X %d", c->_idx); _memory_nodes[c->_idx]->dump();
2241 }
2242 }
2243 }
2244 #endif
2245 uint last = _phase->C->unique();
2246
2247 #ifdef ASSERT
2248 uint8_t max_depth = 0;
2249 for (LoopTreeIterator iter(_phase->ltree_root()); !iter.done(); iter.next()) {
2250 IdealLoopTree* lpt = iter.current();
2251 max_depth = MAX2(max_depth, lpt->_nest);
2252 }
2253 #endif
2254
2255 bool progress = true;
2256 int iteration = 0;
2257 Node_List dead_phis;
2258 while (progress) {
2259 progress = false;
2260 iteration++;
2261 assert(iteration <= 2+max_depth || _phase->C->has_irreducible_loop() || has_never_branch(_phase->C->root()), "");
2262 if (trace) { tty->print_cr("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"); }
2263
2264 for (int i = rpo_list.size() - 1; i >= 0; i--) {
2265 Node* c = rpo_list.at(i);
2266
2267 Node* prev_mem = _memory_nodes[c->_idx];
2268 if (c->is_Region() && (_include_lsm || !c->is_OuterStripMinedLoop())) {
2269 Node* prev_region = regions[c->_idx];
2270 Node* unique = NULL;
2271 for (uint j = 1; j < c->req() && unique != NodeSentinel; j++) {
2272 Node* m = _memory_nodes[c->in(j)->_idx];
2273 assert(m != NULL || (c->is_Loop() && j == LoopNode::LoopBackControl && iteration == 1) || _phase->C->has_irreducible_loop() || has_never_branch(_phase->C->root()), "expect memory state");
2274 if (m != NULL) {
2275 if (m == prev_region && ((c->is_Loop() && j == LoopNode::LoopBackControl) || (prev_region->is_Phi() && prev_region->in(0) == c))) {
2276 assert(c->is_Loop() && j == LoopNode::LoopBackControl || _phase->C->has_irreducible_loop() || has_never_branch(_phase->C->root()), "");
2277 // continue
2278 } else if (unique == NULL) {
2279 unique = m;
2280 } else if (m == unique) {
2281 // continue
2282 } else {
2283 unique = NodeSentinel;
2284 }
2285 }
2286 }
2287 assert(unique != NULL, "empty phi???");
2288 if (unique != NodeSentinel) {
2289 if (prev_region != NULL && prev_region->is_Phi() && prev_region->in(0) == c) {
2290 dead_phis.push(prev_region);
2291 }
2292 regions.map(c->_idx, unique);
2293 } else {
2294 Node* phi = NULL;
2295 if (prev_region != NULL && prev_region->is_Phi() && prev_region->in(0) == c && prev_region->_idx >= last) {
2296 phi = prev_region;
2297 for (uint k = 1; k < c->req(); k++) {
2298 Node* m = _memory_nodes[c->in(k)->_idx];
2299 assert(m != NULL, "expect memory state");
2300 phi->set_req(k, m);
2301 }
2302 } else {
2303 for (DUIterator_Fast jmax, j = c->fast_outs(jmax); j < jmax && phi == NULL; j++) {
2304 Node* u = c->fast_out(j);
2305 if (u->is_Phi() && u->bottom_type() == Type::MEMORY &&
2306 (u->adr_type() == TypePtr::BOTTOM || _phase->C->get_alias_index(u->adr_type()) == _alias)) {
2307 phi = u;
2308 for (uint k = 1; k < c->req() && phi != NULL; k++) {
2309 Node* m = _memory_nodes[c->in(k)->_idx];
2310 assert(m != NULL, "expect memory state");
2311 if (u->in(k) != m) {
2312 phi = NULL;
2313 }
2314 }
2315 }
2316 }
2317 if (phi == NULL) {
2318 phi = new PhiNode(c, Type::MEMORY, _phase->C->get_adr_type(_alias));
2319 for (uint k = 1; k < c->req(); k++) {
2320 Node* m = _memory_nodes[c->in(k)->_idx];
2321 assert(m != NULL, "expect memory state");
2322 phi->init_req(k, m);
2323 }
2324 }
2325 }
2326 assert(phi != NULL, "");
2327 regions.map(c->_idx, phi);
2328 }
2329 Node* current_region = regions[c->_idx];
2330 if (current_region != prev_region) {
2331 progress = true;
2332 if (prev_region == prev_mem) {
2333 _memory_nodes.map(c->_idx, current_region);
2334 }
2335 }
2336 } else if (prev_mem == NULL || prev_mem->is_Phi() || ctrl_or_self(prev_mem) != c) {
2337 Node* m = _memory_nodes[_phase->idom(c)->_idx];
2338 assert(m != NULL, "expect memory state");
2339 if (m != prev_mem) {
2340 _memory_nodes.map(c->_idx, m);
2341 progress = true;
2342 }
2343 }
2344 #ifdef ASSERT
2345 if (trace) { tty->print("X %d", c->_idx); _memory_nodes[c->_idx]->dump(); }
2346 #endif
2347 }
2348 }
2349
2350 // Replace existing phi with computed memory state for that region
2351 // if different (could be a new phi or a dominating memory node if
2352 // that phi was found to be useless).
2353 while (dead_phis.size() > 0) {
2354 Node* n = dead_phis.pop();
2355 n->replace_by(_phase->C->top());
2356 n->destruct();
2357 }
2358 for (int i = rpo_list.size() - 1; i >= 0; i--) {
2359 Node* c = rpo_list.at(i);
2360 if (c->is_Region() && (_include_lsm || !c->is_OuterStripMinedLoop())) {
2361 Node* n = regions[c->_idx];
2362 if (n->is_Phi() && n->_idx >= last && n->in(0) == c) {
2363 _phase->register_new_node(n, c);
2364 }
2365 }
2366 }
2367 for (int i = rpo_list.size() - 1; i >= 0; i--) {
2368 Node* c = rpo_list.at(i);
2369 if (c->is_Region() && (_include_lsm || !c->is_OuterStripMinedLoop())) {
2370 Node* n = regions[c->_idx];
2371 for (DUIterator_Fast imax, i = c->fast_outs(imax); i < imax; i++) {
2372 Node* u = c->fast_out(i);
2373 if (u->is_Phi() && u->bottom_type() == Type::MEMORY &&
2374 u != n) {
2375 if (u->adr_type() == TypePtr::BOTTOM) {
2376 fix_memory_uses(u, n, n, c);
2377 } else if (_phase->C->get_alias_index(u->adr_type()) == _alias) {
2378 _phase->lazy_replace(u, n);
2379 --i; --imax;
2380 }
2381 }
2382 }
2383 }
2384 }
2385 }
2386
2387 Node* MemoryGraphFixer::get_ctrl(Node* n) const {
2388 Node* c = _phase->get_ctrl(n);
2389 if (n->is_Proj() && n->in(0) != NULL && n->in(0)->is_Call()) {
2390 assert(c == n->in(0), "");
2391 CallNode* call = c->as_Call();
2392 CallProjections* projs = call->extract_projections(true, false);
2393 if (projs->catchall_memproj != NULL) {
2394 if (projs->fallthrough_memproj == n) {
2395 c = projs->fallthrough_catchproj;
2396 } else {
2397 assert(projs->catchall_memproj == n, "");
2398 c = projs->catchall_catchproj;
2399 }
2400 }
2401 }
2402 return c;
2403 }
2404
2405 Node* MemoryGraphFixer::ctrl_or_self(Node* n) const {
2406 if (_phase->has_ctrl(n))
2407 return get_ctrl(n);
2408 else {
2409 assert (n->is_CFG(), "must be a CFG node");
2410 return n;
2411 }
2412 }
2413
2414 bool MemoryGraphFixer::mem_is_valid(Node* m, Node* c) const {
2415 return m != NULL && get_ctrl(m) == c;
2416 }
2417
2418 Node* MemoryGraphFixer::find_mem(Node* ctrl, Node* n) const {
2419 assert(n == NULL || _phase->ctrl_or_self(n) == ctrl, "");
2420 Node* mem = _memory_nodes[ctrl->_idx];
2421 Node* c = ctrl;
2422 while (!mem_is_valid(mem, c) &&
2423 (!c->is_CatchProj() || mem == NULL || c->in(0)->in(0)->in(0) != get_ctrl(mem))) {
2424 c = _phase->idom(c);
2425 mem = _memory_nodes[c->_idx];
2426 }
2427 if (n != NULL && mem_is_valid(mem, c)) {
2428 while (!ShenandoahBarrierC2Support::is_dominator_same_ctrl(c, mem, n, _phase) && _phase->ctrl_or_self(mem) == ctrl) {
2429 mem = next_mem(mem, _alias);
2430 }
2431 if (mem->is_MergeMem()) {
2432 mem = mem->as_MergeMem()->memory_at(_alias);
2433 }
2434 if (!mem_is_valid(mem, c)) {
2435 do {
2436 c = _phase->idom(c);
2437 mem = _memory_nodes[c->_idx];
2438 } while (!mem_is_valid(mem, c) &&
2439 (!c->is_CatchProj() || mem == NULL || c->in(0)->in(0)->in(0) != get_ctrl(mem)));
2440 }
2441 }
2442 assert(mem->bottom_type() == Type::MEMORY, "");
2443 return mem;
2444 }
2445
2446 bool MemoryGraphFixer::has_mem_phi(Node* region) const {
2447 for (DUIterator_Fast imax, i = region->fast_outs(imax); i < imax; i++) {
2448 Node* use = region->fast_out(i);
2449 if (use->is_Phi() && use->bottom_type() == Type::MEMORY &&
2450 (_phase->C->get_alias_index(use->adr_type()) == _alias)) {
2451 return true;
2452 }
2453 }
2454 return false;
2455 }
2456
2457 void MemoryGraphFixer::fix_mem(Node* ctrl, Node* new_ctrl, Node* mem, Node* mem_for_ctrl, Node* new_mem, Unique_Node_List& uses) {
2458 assert(_phase->ctrl_or_self(new_mem) == new_ctrl, "");
2459 const bool trace = false;
2460 DEBUG_ONLY(if (trace) { tty->print("ZZZ control is"); ctrl->dump(); });
2461 DEBUG_ONLY(if (trace) { tty->print("ZZZ mem is"); mem->dump(); });
2462 GrowableArray<Node*> phis;
2463 if (mem_for_ctrl != mem) {
2464 Node* old = mem_for_ctrl;
2465 Node* prev = NULL;
2466 while (old != mem) {
2467 prev = old;
2468 if (old->is_Store() || old->is_ClearArray() || old->is_LoadStore()) {
2469 assert(_alias == Compile::AliasIdxRaw, "");
2470 old = old->in(MemNode::Memory);
2471 } else if (old->Opcode() == Op_SCMemProj) {
2472 assert(_alias == Compile::AliasIdxRaw, "");
2473 old = old->in(0);
2474 } else {
2475 ShouldNotReachHere();
2476 }
2477 }
2478 assert(prev != NULL, "");
2479 if (new_ctrl != ctrl) {
2480 _memory_nodes.map(ctrl->_idx, mem);
2481 _memory_nodes.map(new_ctrl->_idx, mem_for_ctrl);
2482 }
2483 uint input = (uint)MemNode::Memory;
2484 _phase->igvn().replace_input_of(prev, input, new_mem);
2485 } else {
2486 uses.clear();
2487 _memory_nodes.map(new_ctrl->_idx, new_mem);
2488 uses.push(new_ctrl);
2489 for(uint next = 0; next < uses.size(); next++ ) {
2490 Node *n = uses.at(next);
2491 assert(n->is_CFG(), "");
2492 DEBUG_ONLY(if (trace) { tty->print("ZZZ ctrl"); n->dump(); });
2493 for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
2494 Node* u = n->fast_out(i);
2495 if (!u->is_Root() && u->is_CFG() && u != n) {
2496 Node* m = _memory_nodes[u->_idx];
2497 if (u->is_Region() && (!u->is_OuterStripMinedLoop() || _include_lsm) &&
2498 !has_mem_phi(u) &&
2499 u->unique_ctrl_out()->Opcode() != Op_Halt) {
2500 DEBUG_ONLY(if (trace) { tty->print("ZZZ region"); u->dump(); });
2501 DEBUG_ONLY(if (trace && m != NULL) { tty->print("ZZZ mem"); m->dump(); });
2502
2503 if (!mem_is_valid(m, u) || !m->is_Phi()) {
2504 bool push = true;
2505 bool create_phi = true;
2506 if (_phase->is_dominator(new_ctrl, u)) {
2507 create_phi = false;
2508 }
2509 if (create_phi) {
2510 Node* phi = new PhiNode(u, Type::MEMORY, _phase->C->get_adr_type(_alias));
2511 _phase->register_new_node(phi, u);
2512 phis.push(phi);
2513 DEBUG_ONLY(if (trace) { tty->print("ZZZ new phi"); phi->dump(); });
2514 if (!mem_is_valid(m, u)) {
2515 DEBUG_ONLY(if (trace) { tty->print("ZZZ setting mem"); phi->dump(); });
2516 _memory_nodes.map(u->_idx, phi);
2517 } else {
2518 DEBUG_ONLY(if (trace) { tty->print("ZZZ NOT setting mem"); m->dump(); });
2519 for (;;) {
2520 assert(m->is_Mem() || m->is_LoadStore() || m->is_Proj(), "");
2521 Node* next = NULL;
2522 if (m->is_Proj()) {
2523 next = m->in(0);
2524 } else {
2525 assert(m->is_Mem() || m->is_LoadStore(), "");
2526 assert(_alias == Compile::AliasIdxRaw, "");
2527 next = m->in(MemNode::Memory);
2528 }
2529 if (_phase->get_ctrl(next) != u) {
2530 break;
2531 }
2532 if (next->is_MergeMem()) {
2533 assert(_phase->get_ctrl(next->as_MergeMem()->memory_at(_alias)) != u, "");
2534 break;
2535 }
2536 if (next->is_Phi()) {
2537 assert(next->adr_type() == TypePtr::BOTTOM && next->in(0) == u, "");
2538 break;
2539 }
2540 m = next;
2541 }
2542
2543 DEBUG_ONLY(if (trace) { tty->print("ZZZ setting to phi"); m->dump(); });
2544 assert(m->is_Mem() || m->is_LoadStore(), "");
2545 uint input = (uint)MemNode::Memory;
2546 _phase->igvn().replace_input_of(m, input, phi);
2547 push = false;
2548 }
2549 } else {
2550 DEBUG_ONLY(if (trace) { tty->print("ZZZ skipping region"); u->dump(); });
2551 }
2552 if (push) {
2553 uses.push(u);
2554 }
2555 }
2556 } else if (!mem_is_valid(m, u) &&
2557 !(u->Opcode() == Op_CProj && u->in(0)->Opcode() == Op_NeverBranch && u->as_Proj()->_con == 1)) {
2558 uses.push(u);
2559 }
2560 }
2561 }
2562 }
2563 for (int i = 0; i < phis.length(); i++) {
2564 Node* n = phis.at(i);
2565 Node* r = n->in(0);
2566 DEBUG_ONLY(if (trace) { tty->print("ZZZ fixing new phi"); n->dump(); });
2567 for (uint j = 1; j < n->req(); j++) {
2568 Node* m = find_mem(r->in(j), NULL);
2569 _phase->igvn().replace_input_of(n, j, m);
2570 DEBUG_ONLY(if (trace) { tty->print("ZZZ fixing new phi: %d", j); m->dump(); });
2571 }
2572 }
2573 }
2574 uint last = _phase->C->unique();
2575 MergeMemNode* mm = NULL;
2576 int alias = _alias;
2577 DEBUG_ONLY(if (trace) { tty->print("ZZZ raw mem is"); mem->dump(); });
2578 // Process loads first to not miss an anti-dependency: if the memory
2579 // edge of a store is updated before a load is processed then an
2580 // anti-dependency may be missed.
2581 for (DUIterator i = mem->outs(); mem->has_out(i); i++) {
2582 Node* u = mem->out(i);
2583 if (u->_idx < last && u->is_Load() && _phase->C->get_alias_index(u->adr_type()) == alias) {
2584 Node* m = find_mem(_phase->get_ctrl(u), u);
2585 if (m != mem) {
2586 DEBUG_ONLY(if (trace) { tty->print("ZZZ setting memory of use"); u->dump(); });
2587 _phase->igvn().replace_input_of(u, MemNode::Memory, m);
2588 --i;
2589 }
2590 }
2591 }
2592 for (DUIterator i = mem->outs(); mem->has_out(i); i++) {
2593 Node* u = mem->out(i);
2594 if (u->_idx < last) {
2595 if (u->is_Mem()) {
2596 if (_phase->C->get_alias_index(u->adr_type()) == alias) {
2597 Node* m = find_mem(_phase->get_ctrl(u), u);
2598 if (m != mem) {
2599 DEBUG_ONLY(if (trace) { tty->print("ZZZ setting memory of use"); u->dump(); });
2600 _phase->igvn().replace_input_of(u, MemNode::Memory, m);
2601 --i;
2602 }
2603 }
2604 } else if (u->is_MergeMem()) {
2605 MergeMemNode* u_mm = u->as_MergeMem();
2606 if (u_mm->memory_at(alias) == mem) {
2607 MergeMemNode* newmm = NULL;
2608 for (DUIterator_Fast jmax, j = u->fast_outs(jmax); j < jmax; j++) {
2609 Node* uu = u->fast_out(j);
2610 assert(!uu->is_MergeMem(), "chain of MergeMems?");
2611 if (uu->is_Phi()) {
2612 assert(uu->adr_type() == TypePtr::BOTTOM, "");
2613 Node* region = uu->in(0);
2614 int nb = 0;
2615 for (uint k = 1; k < uu->req(); k++) {
2616 if (uu->in(k) == u) {
2617 Node* m = find_mem(region->in(k), NULL);
2618 if (m != mem) {
2619 DEBUG_ONLY(if (trace) { tty->print("ZZZ setting memory of phi %d", k); uu->dump(); });
2620 newmm = clone_merge_mem(u, mem, m, _phase->ctrl_or_self(m), i);
2621 if (newmm != u) {
2622 _phase->igvn().replace_input_of(uu, k, newmm);
2623 nb++;
2624 --jmax;
2625 }
2626 }
2627 }
2628 }
2629 if (nb > 0) {
2630 --j;
2631 }
2632 } else {
2633 Node* m = find_mem(_phase->ctrl_or_self(uu), uu);
2634 if (m != mem) {
2635 DEBUG_ONLY(if (trace) { tty->print("ZZZ setting memory of use"); uu->dump(); });
2636 newmm = clone_merge_mem(u, mem, m, _phase->ctrl_or_self(m), i);
2637 if (newmm != u) {
2638 _phase->igvn().replace_input_of(uu, uu->find_edge(u), newmm);
2639 --j, --jmax;
2640 }
2641 }
2642 }
2643 }
2644 }
2645 } else if (u->is_Phi()) {
2646 assert(u->bottom_type() == Type::MEMORY, "what else?");
2647 if (_phase->C->get_alias_index(u->adr_type()) == alias || u->adr_type() == TypePtr::BOTTOM) {
2648 Node* region = u->in(0);
2649 bool replaced = false;
2650 for (uint j = 1; j < u->req(); j++) {
2651 if (u->in(j) == mem) {
2652 Node* m = find_mem(region->in(j), NULL);
2653 Node* nnew = m;
2654 if (m != mem) {
2655 if (u->adr_type() == TypePtr::BOTTOM) {
2656 mm = allocate_merge_mem(mem, m, _phase->ctrl_or_self(m));
2657 nnew = mm;
2658 }
2659 DEBUG_ONLY(if (trace) { tty->print("ZZZ setting memory of phi %d", j); u->dump(); });
2660 _phase->igvn().replace_input_of(u, j, nnew);
2661 replaced = true;
2662 }
2663 }
2664 }
2665 if (replaced) {
2666 --i;
2667 }
2668 }
2669 } else if ((u->adr_type() == TypePtr::BOTTOM && u->Opcode() != Op_StrInflatedCopy) ||
2670 u->adr_type() == NULL) {
2671 assert(u->adr_type() != NULL ||
2672 u->Opcode() == Op_Rethrow ||
2673 u->Opcode() == Op_Return ||
2674 u->Opcode() == Op_SafePoint ||
2675 (u->is_CallStaticJava() && u->as_CallStaticJava()->uncommon_trap_request() != 0) ||
2676 (u->is_CallStaticJava() && u->as_CallStaticJava()->_entry_point == OptoRuntime::rethrow_stub()) ||
2677 u->Opcode() == Op_CallLeaf, "");
2678 Node* m = find_mem(_phase->ctrl_or_self(u), u);
2679 if (m != mem) {
2680 mm = allocate_merge_mem(mem, m, _phase->get_ctrl(m));
2681 _phase->igvn().replace_input_of(u, u->find_edge(mem), mm);
2682 --i;
2683 }
2684 } else if (_phase->C->get_alias_index(u->adr_type()) == alias) {
2685 Node* m = find_mem(_phase->ctrl_or_self(u), u);
2686 if (m != mem) {
2687 DEBUG_ONLY(if (trace) { tty->print("ZZZ setting memory of use"); u->dump(); });
2688 _phase->igvn().replace_input_of(u, u->find_edge(mem), m);
2689 --i;
2690 }
2691 } else if (u->adr_type() != TypePtr::BOTTOM &&
2692 _memory_nodes[_phase->ctrl_or_self(u)->_idx] == u) {
2693 Node* m = find_mem(_phase->ctrl_or_self(u), u);
2694 assert(m != mem, "");
2695 // u is on the wrong slice...
2696 assert(u->is_ClearArray(), "");
2697 DEBUG_ONLY(if (trace) { tty->print("ZZZ setting memory of use"); u->dump(); });
2698 _phase->igvn().replace_input_of(u, u->find_edge(mem), m);
2699 --i;
2700 }
2701 }
2702 }
2703 #ifdef ASSERT
2704 assert(new_mem->outcnt() > 0, "");
2705 for (int i = 0; i < phis.length(); i++) {
2706 Node* n = phis.at(i);
2707 assert(n->outcnt() > 0, "new phi must have uses now");
2708 }
2709 #endif
2710 }
2711
2712 MergeMemNode* MemoryGraphFixer::allocate_merge_mem(Node* mem, Node* rep_proj, Node* rep_ctrl) const {
2713 MergeMemNode* mm = MergeMemNode::make(mem);
2714 mm->set_memory_at(_alias, rep_proj);
2715 _phase->register_new_node(mm, rep_ctrl);
2716 return mm;
2717 }
2718
2719 MergeMemNode* MemoryGraphFixer::clone_merge_mem(Node* u, Node* mem, Node* rep_proj, Node* rep_ctrl, DUIterator& i) const {
2720 MergeMemNode* newmm = NULL;
2721 MergeMemNode* u_mm = u->as_MergeMem();
2722 Node* c = _phase->get_ctrl(u);
2723 if (_phase->is_dominator(c, rep_ctrl)) {
2724 c = rep_ctrl;
2725 } else {
2726 assert(_phase->is_dominator(rep_ctrl, c), "one must dominate the other");
2727 }
2728 if (u->outcnt() == 1) {
2729 if (u->req() > (uint)_alias && u->in(_alias) == mem) {
2730 _phase->igvn().replace_input_of(u, _alias, rep_proj);
2731 --i;
2732 } else {
2733 _phase->igvn().rehash_node_delayed(u);
2734 u_mm->set_memory_at(_alias, rep_proj);
2735 }
2736 newmm = u_mm;
2737 _phase->set_ctrl_and_loop(u, c);
2738 } else {
2739 // can't simply clone u and then change one of its input because
2740 // it adds and then removes an edge which messes with the
2741 // DUIterator
2742 newmm = MergeMemNode::make(u_mm->base_memory());
2743 for (uint j = 0; j < u->req(); j++) {
2744 if (j < newmm->req()) {
2745 if (j == (uint)_alias) {
2746 newmm->set_req(j, rep_proj);
2747 } else if (newmm->in(j) != u->in(j)) {
2748 newmm->set_req(j, u->in(j));
2749 }
2750 } else if (j == (uint)_alias) {
2751 newmm->add_req(rep_proj);
2752 } else {
2753 newmm->add_req(u->in(j));
2754 }
2755 }
2756 if ((uint)_alias >= u->req()) {
2757 newmm->set_memory_at(_alias, rep_proj);
2758 }
2759 _phase->register_new_node(newmm, c);
2760 }
2761 return newmm;
2762 }
2763
2764 bool MemoryGraphFixer::should_process_phi(Node* phi) const {
2765 if (phi->adr_type() == TypePtr::BOTTOM) {
2766 Node* region = phi->in(0);
2767 for (DUIterator_Fast jmax, j = region->fast_outs(jmax); j < jmax; j++) {
2768 Node* uu = region->fast_out(j);
2769 if (uu->is_Phi() && uu != phi && uu->bottom_type() == Type::MEMORY && _phase->C->get_alias_index(uu->adr_type()) == _alias) {
2770 return false;
2771 }
2772 }
2773 return true;
2774 }
2775 return _phase->C->get_alias_index(phi->adr_type()) == _alias;
2776 }
2777
2778 void MemoryGraphFixer::fix_memory_uses(Node* mem, Node* replacement, Node* rep_proj, Node* rep_ctrl) const {
2779 uint last = _phase-> C->unique();
2780 MergeMemNode* mm = NULL;
2781 assert(mem->bottom_type() == Type::MEMORY, "");
2782 for (DUIterator i = mem->outs(); mem->has_out(i); i++) {
2783 Node* u = mem->out(i);
2784 if (u != replacement && u->_idx < last) {
2785 if (u->is_MergeMem()) {
2786 MergeMemNode* u_mm = u->as_MergeMem();
2787 if (u_mm->memory_at(_alias) == mem) {
2788 MergeMemNode* newmm = NULL;
2789 for (DUIterator_Fast jmax, j = u->fast_outs(jmax); j < jmax; j++) {
2790 Node* uu = u->fast_out(j);
2791 assert(!uu->is_MergeMem(), "chain of MergeMems?");
2792 if (uu->is_Phi()) {
2793 if (should_process_phi(uu)) {
2794 Node* region = uu->in(0);
2795 int nb = 0;
2796 for (uint k = 1; k < uu->req(); k++) {
2797 if (uu->in(k) == u && _phase->is_dominator(rep_ctrl, region->in(k))) {
2798 if (newmm == NULL) {
2799 newmm = clone_merge_mem(u, mem, rep_proj, rep_ctrl, i);
2800 }
2801 if (newmm != u) {
2802 _phase->igvn().replace_input_of(uu, k, newmm);
2803 nb++;
2804 --jmax;
2805 }
2806 }
2807 }
2808 if (nb > 0) {
2809 --j;
2810 }
2811 }
2812 } else {
2813 if (rep_ctrl != uu && ShenandoahBarrierC2Support::is_dominator(rep_ctrl, _phase->ctrl_or_self(uu), replacement, uu, _phase)) {
2814 if (newmm == NULL) {
2815 newmm = clone_merge_mem(u, mem, rep_proj, rep_ctrl, i);
2816 }
2817 if (newmm != u) {
2818 _phase->igvn().replace_input_of(uu, uu->find_edge(u), newmm);
2819 --j, --jmax;
2820 }
2821 }
2822 }
2823 }
2824 }
2825 } else if (u->is_Phi()) {
2826 assert(u->bottom_type() == Type::MEMORY, "what else?");
2827 Node* region = u->in(0);
2828 if (should_process_phi(u)) {
2829 bool replaced = false;
2830 for (uint j = 1; j < u->req(); j++) {
2831 if (u->in(j) == mem && _phase->is_dominator(rep_ctrl, region->in(j))) {
2832 Node* nnew = rep_proj;
2833 if (u->adr_type() == TypePtr::BOTTOM) {
2834 if (mm == NULL) {
2835 mm = allocate_merge_mem(mem, rep_proj, rep_ctrl);
2836 }
2837 nnew = mm;
2838 }
2839 _phase->igvn().replace_input_of(u, j, nnew);
2840 replaced = true;
2841 }
2842 }
2843 if (replaced) {
2844 --i;
2845 }
2846
2847 }
2848 } else if ((u->adr_type() == TypePtr::BOTTOM && u->Opcode() != Op_StrInflatedCopy) ||
2849 u->adr_type() == NULL) {
2850 assert(u->adr_type() != NULL ||
2851 u->Opcode() == Op_Rethrow ||
2852 u->Opcode() == Op_Return ||
2853 u->Opcode() == Op_SafePoint ||
2854 u->Opcode() == Op_StoreIConditional ||
2855 u->Opcode() == Op_StoreLConditional ||
2856 (u->is_CallStaticJava() && u->as_CallStaticJava()->uncommon_trap_request() != 0) ||
2857 (u->is_CallStaticJava() && u->as_CallStaticJava()->_entry_point == OptoRuntime::rethrow_stub()) ||
2858 u->Opcode() == Op_CallLeaf, "%s", u->Name());
2859 if (ShenandoahBarrierC2Support::is_dominator(rep_ctrl, _phase->ctrl_or_self(u), replacement, u, _phase)) {
2860 if (mm == NULL) {
2861 mm = allocate_merge_mem(mem, rep_proj, rep_ctrl);
2862 }
2863 _phase->igvn().replace_input_of(u, u->find_edge(mem), mm);
2864 --i;
2865 }
2866 } else if (_phase->C->get_alias_index(u->adr_type()) == _alias) {
2867 if (ShenandoahBarrierC2Support::is_dominator(rep_ctrl, _phase->ctrl_or_self(u), replacement, u, _phase)) {
2868 _phase->igvn().replace_input_of(u, u->find_edge(mem), rep_proj);
2869 --i;
2870 }
2871 }
2872 }
2873 }
2874 }
2875
2876 ShenandoahLoadReferenceBarrierNode::ShenandoahLoadReferenceBarrierNode(Node* ctrl, Node* obj, bool native)
2877 : Node(ctrl, obj), _native(native) {
2878 ShenandoahBarrierSetC2::bsc2()->state()->add_load_reference_barrier(this);
2879 }
2880
2881 bool ShenandoahLoadReferenceBarrierNode::is_native() const {
2882 return _native;
2883 }
2884
2885 uint ShenandoahLoadReferenceBarrierNode::size_of() const {
2886 return sizeof(*this);
2887 }
2888
2889 uint ShenandoahLoadReferenceBarrierNode::hash() const {
2890 return Node::hash() + (_native ? 1 : 0);
2891 }
2892
2893 bool ShenandoahLoadReferenceBarrierNode::cmp( const Node &n ) const {
2894 return Node::cmp(n) && n.Opcode() == Op_ShenandoahLoadReferenceBarrier &&
2895 _native == ((const ShenandoahLoadReferenceBarrierNode&)n)._native;
2896 }
2897
2898 const Type* ShenandoahLoadReferenceBarrierNode::bottom_type() const {
2899 if (in(ValueIn) == NULL || in(ValueIn)->is_top()) {
2900 return Type::TOP;
2901 }
2902 const Type* t = in(ValueIn)->bottom_type();
2903 if (t == TypePtr::NULL_PTR) {
2904 return t;
2905 }
2906 return t->is_oopptr();
2907 }
2908
2909 const Type* ShenandoahLoadReferenceBarrierNode::Value(PhaseGVN* phase) const {
2910 // Either input is TOP ==> the result is TOP
2911 const Type *t2 = phase->type(in(ValueIn));
2912 if( t2 == Type::TOP ) return Type::TOP;
2913
2914 if (t2 == TypePtr::NULL_PTR) {
2915 return t2;
2916 }
2917
2918 const Type* type = t2->is_oopptr();
2919 return type;
2920 }
2921
2922 Node* ShenandoahLoadReferenceBarrierNode::Identity(PhaseGVN* phase) {
2923 Node* value = in(ValueIn);
2924 if (!needs_barrier(phase, value)) {
2925 return value;
2926 }
2927 return this;
2928 }
2929
2930 bool ShenandoahLoadReferenceBarrierNode::needs_barrier(PhaseGVN* phase, Node* n) {
2931 Unique_Node_List visited;
2932 return needs_barrier_impl(phase, n, visited);
2933 }
2934
2935 bool ShenandoahLoadReferenceBarrierNode::needs_barrier_impl(PhaseGVN* phase, Node* n, Unique_Node_List &visited) {
2936 if (n == NULL) return false;
2937 if (visited.member(n)) {
2938 return false; // Been there.
2939 }
2940 visited.push(n);
2941
2942 if (n->is_Allocate()) {
2943 // tty->print_cr("optimize barrier on alloc");
2944 return false;
2945 }
2946 if (n->is_Call()) {
2947 // tty->print_cr("optimize barrier on call");
2948 return false;
2949 }
2950
2951 const Type* type = phase->type(n);
2952 if (type == Type::TOP) {
2953 return false;
2954 }
2955 if (type->make_ptr()->higher_equal(TypePtr::NULL_PTR)) {
2956 // tty->print_cr("optimize barrier on null");
2957 return false;
2958 }
2959 if (type->make_oopptr() && type->make_oopptr()->const_oop() != NULL) {
2960 // tty->print_cr("optimize barrier on constant");
2961 return false;
2962 }
2963
2964 switch (n->Opcode()) {
2965 case Op_AddP:
2966 return true; // TODO: Can refine?
2967 case Op_LoadP:
2968 case Op_ShenandoahCompareAndExchangeN:
2969 case Op_ShenandoahCompareAndExchangeP:
2970 case Op_CompareAndExchangeN:
2971 case Op_CompareAndExchangeP:
2972 case Op_GetAndSetN:
2973 case Op_GetAndSetP:
2974 return true;
2975 case Op_Phi: {
2976 for (uint i = 1; i < n->req(); i++) {
2977 if (needs_barrier_impl(phase, n->in(i), visited)) return true;
2978 }
2979 return false;
2980 }
2981 case Op_CheckCastPP:
2982 case Op_CastPP:
2983 return needs_barrier_impl(phase, n->in(1), visited);
2984 case Op_Proj:
2985 return needs_barrier_impl(phase, n->in(0), visited);
2986 case Op_ShenandoahLoadReferenceBarrier:
2987 // tty->print_cr("optimize barrier on barrier");
2988 return false;
2989 case Op_Parm:
2990 // tty->print_cr("optimize barrier on input arg");
2991 return false;
2992 case Op_DecodeN:
2993 case Op_EncodeP:
2994 return needs_barrier_impl(phase, n->in(1), visited);
2995 case Op_LoadN:
2996 return true;
2997 case Op_CMoveN:
2998 case Op_CMoveP:
2999 return needs_barrier_impl(phase, n->in(2), visited) ||
3000 needs_barrier_impl(phase, n->in(3), visited);
3001 case Op_ShenandoahEnqueueBarrier:
3002 return needs_barrier_impl(phase, n->in(1), visited);
3003 case Op_CreateEx:
3004 return false;
3005 default:
3006 break;
3007 }
3008 #ifdef ASSERT
3009 tty->print("need barrier on?: ");
3010 tty->print_cr("ins:");
3011 n->dump(2);
3012 tty->print_cr("outs:");
3013 n->dump(-2);
3014 ShouldNotReachHere();
3015 #endif
3016 return true;
3017 }