1 /* 2 * Copyright (c) 2015, Red Hat, Inc. and/or its affiliates. 3 * 4 * This code is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU General Public License version 2 only, as 6 * published by the Free Software Foundation. 7 * 8 * This code is distributed in the hope that it will be useful, but WITHOUT 9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 11 * version 2 for more details (a copy is included in the LICENSE file that 12 * accompanied this code). 13 * 14 * You should have received a copy of the GNU General Public License version 15 * 2 along with this work; if not, write to the Free Software Foundation, 16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 17 * 18 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 19 * or visit www.oracle.com if you need additional information or have any 20 * questions. 21 * 22 */ 23 24 #include "precompiled.hpp" 25 #include "gc/shenandoah/brooksPointer.hpp" 26 #include "gc/shenandoah/shenandoahHeap.hpp" 27 #include "gc/shenandoah/shenandoahHeapRegion.hpp" 28 #include "opto/arraycopynode.hpp" 29 #include "opto/block.hpp" 30 #include "opto/callnode.hpp" 31 #include "opto/castnode.hpp" 32 #include "opto/movenode.hpp" 33 #include "opto/phaseX.hpp" 34 #include "opto/rootnode.hpp" 35 #include "opto/runtime.hpp" 36 #include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp" 37 #include "gc/shenandoah/c2/shenandoahSupport.hpp" 38 #include "gc/shenandoah/c2/shenandoahBarrierSetC2.hpp" 39 #include "opto/subnode.hpp" 40 41 Node* ShenandoahBarrierNode::skip_through_barrier(Node* n) { 42 if (n == NULL) { 43 return NULL; 44 } else if (n->is_ShenandoahBarrier()) { 45 return n->in(ValueIn); 46 } else if (n->is_Phi() && 47 n->req() == 3 && 48 n->in(1) != NULL && 49 n->in(1)->is_ShenandoahBarrier() && 50 n->in(2) != NULL && 51 n->in(2)->bottom_type() == TypePtr::NULL_PTR && 52 n->in(0) != NULL && 53 n->in(0)->in(1) != NULL && 54 n->in(0)->in(1)->is_IfProj() && 55 n->in(0)->in(2) != NULL && 56 n->in(0)->in(2)->is_IfProj() && 57 n->in(0)->in(1)->in(0) != NULL && 58 n->in(0)->in(1)->in(0) == n->in(0)->in(2)->in(0) && 59 n->in(1)->in(ValueIn)->Opcode() == Op_CastPP) { 60 Node* iff = n->in(0)->in(1)->in(0); 61 Node* res = n->in(1)->in(ValueIn)->in(1); 62 if (iff->is_If() && 63 iff->in(1) != NULL && 64 iff->in(1)->is_Bool() && 65 iff->in(1)->as_Bool()->_test._test == BoolTest::ne && 66 iff->in(1)->in(1) != NULL && 67 iff->in(1)->in(1)->Opcode() == Op_CmpP && 68 iff->in(1)->in(1)->in(1) != NULL && 69 iff->in(1)->in(1)->in(1) == res && 70 iff->in(1)->in(1)->in(2) != NULL && 71 iff->in(1)->in(1)->in(2)->bottom_type() == TypePtr::NULL_PTR) { 72 return res; 73 } 74 } 75 return n; 76 } 77 78 bool ShenandoahBarrierNode::needs_barrier(PhaseGVN* phase, ShenandoahBarrierNode* orig, Node* n, Node* rb_mem, bool allow_fromspace) { 79 Unique_Node_List visited; 80 return needs_barrier_impl(phase, orig, n, rb_mem, allow_fromspace, visited); 81 } 82 83 bool ShenandoahBarrierNode::needs_barrier_impl(PhaseGVN* phase, ShenandoahBarrierNode* orig, Node* n, Node* rb_mem, bool allow_fromspace, Unique_Node_List &visited) { 84 85 if (visited.member(n)) { 86 return false; // Been there. 87 } 88 visited.push(n); 89 90 if (n->is_Allocate()) { 91 // tty->print_cr("killed barrier for newly allocated object"); 92 return false; 93 } 94 95 if (n->is_CallJava() || n->Opcode() == Op_CallLeafNoFP) { 96 return true; 97 } 98 99 const Type* type = phase->type(n); 100 if (type == Type::TOP) { 101 return false; 102 } 103 if (type->make_ptr()->higher_equal(TypePtr::NULL_PTR)) { 104 // tty->print_cr("killed barrier for NULL object"); 105 return false; 106 } 107 if (type->make_oopptr() && type->make_oopptr()->const_oop() != NULL) { 108 // tty->print_cr("killed barrier for constant object"); 109 return ShenandoahBarriersForConst; 110 } 111 112 if (ShenandoahOptimizeStableFinals) { 113 const TypeAryPtr* ary = type->isa_aryptr(); 114 if (ary && ary->is_stable() && allow_fromspace) { 115 return false; 116 } 117 } 118 119 if (n->is_CheckCastPP() || n->is_ConstraintCast()) { 120 return needs_barrier_impl(phase, orig, n->in(1), rb_mem, allow_fromspace, visited); 121 } 122 if (n->is_Parm()) { 123 return true; 124 } 125 if (n->is_Proj()) { 126 return needs_barrier_impl(phase, orig, n->in(0), rb_mem, allow_fromspace, visited); 127 } 128 if (n->is_Phi()) { 129 bool need_barrier = false; 130 for (uint i = 1; i < n->req() && ! need_barrier; i++) { 131 Node* input = n->in(i); 132 if (input == NULL) { 133 need_barrier = true; // Phi not complete yet? 134 } else if (needs_barrier_impl(phase, orig, input, rb_mem, allow_fromspace, visited)) { 135 need_barrier = true; 136 } 137 } 138 return need_barrier; 139 } 140 if (n->is_CMove()) { 141 return needs_barrier_impl(phase, orig, n->in(CMoveNode::IfFalse), rb_mem, allow_fromspace, visited) || 142 needs_barrier_impl(phase, orig, n->in(CMoveNode::IfTrue ), rb_mem, allow_fromspace, visited); 143 } 144 if (n->Opcode() == Op_CreateEx) { 145 return true; 146 } 147 if (n->Opcode() == Op_ShenandoahWriteBarrier) { 148 // tty->print_cr("skipped barrier for chained write barrier object"); 149 return false; 150 } 151 if (n->Opcode() == Op_ShenandoahReadBarrier) { 152 if (rb_mem == n->in(Memory)) { 153 // tty->print_cr("Eliminated chained read barrier"); 154 return false; 155 } else { 156 return true; 157 } 158 } 159 160 if (n->Opcode() == Op_LoadP || 161 n->Opcode() == Op_LoadN || 162 n->Opcode() == Op_GetAndSetP || 163 n->Opcode() == Op_CompareAndExchangeP || 164 n->Opcode() == Op_GetAndSetN || 165 n->Opcode() == Op_CompareAndExchangeN) { 166 return true; 167 } 168 if (n->Opcode() == Op_DecodeN || 169 n->Opcode() == Op_EncodeP) { 170 return needs_barrier_impl(phase, orig, n->in(1), rb_mem, allow_fromspace, visited); 171 } 172 173 #ifdef ASSERT 174 tty->print("need barrier on?: "); n->dump(); 175 ShouldNotReachHere(); 176 #endif 177 return true; 178 } 179 180 /** 181 * In Shenandoah, we need barriers on acmp (and similar instructions that compare two 182 * oops) to avoid false negatives. If it compares a from-space and a to-space 183 * copy of an object, a regular acmp would return false, even though both are 184 * the same. The acmp barrier compares the two objects, and when they are 185 * *not equal* it does a read-barrier on both, and compares them again. When it 186 * failed because of different copies of the object, we know that the object 187 * must already have been evacuated (and therefore doesn't require a write-barrier). 188 */ 189 void ShenandoahBarrierNode::do_cmpp_if(GraphKit& kit, Node*& taken_branch, Node*& untaken_branch, Node*& taken_memory, Node*& untaken_memory) { 190 assert(taken_memory == NULL && untaken_memory == NULL, "unexpected memory inputs"); 191 if (!UseShenandoahGC || !ShenandoahAcmpBarrier || ShenandoahVerifyOptoBarriers) { 192 return; 193 } 194 if (taken_branch->is_top() || untaken_branch->is_top()) { 195 // one of the branches is known to be untaken 196 return; 197 } 198 assert(taken_branch->is_IfProj() && untaken_branch->is_IfProj(), "if projections only"); 199 assert(taken_branch->in(0) == untaken_branch->in(0), "should come from same if"); 200 IfNode* iff = taken_branch->in(0)->as_If(); 201 BoolNode* bol = iff->in(1)->as_Bool(); 202 Node* cmp = bol->in(1); 203 if (cmp->Opcode() != Op_CmpP) { 204 return; 205 } 206 Node* a = cmp->in(1); 207 Node* b = cmp->in(2); 208 const Type* a_type = kit.gvn().type(a); 209 const Type* b_type = kit.gvn().type(b); 210 if (a_type->higher_equal(TypePtr::NULL_PTR) || b_type->higher_equal(TypePtr::NULL_PTR)) { 211 // We know one arg is gonna be null. No need for barriers. 212 return; 213 } 214 215 const TypePtr* a_adr_type = ShenandoahBarrierNode::brooks_pointer_type(a_type); 216 const TypePtr* b_adr_type = ShenandoahBarrierNode::brooks_pointer_type(b_type); 217 if ((! ShenandoahBarrierNode::needs_barrier(&kit.gvn(), NULL, a, kit.memory(a_adr_type), false)) && 218 (! ShenandoahBarrierNode::needs_barrier(&kit.gvn(), NULL, b, kit.memory(b_adr_type), false))) { 219 // We know both args are in to-space already. No acmp barrier needed. 220 return; 221 } 222 223 Node* equal_path = iff->proj_out(true); 224 Node* not_equal_path = iff->proj_out(false); 225 226 if (bol->_test._test == BoolTest::ne) { 227 swap(equal_path, not_equal_path); 228 } 229 230 Node* init_equal_path = equal_path; 231 Node* init_not_equal_path = not_equal_path; 232 233 uint alias_a = kit.C->get_alias_index(a_adr_type); 234 uint alias_b = kit.C->get_alias_index(b_adr_type); 235 236 Node* equal_memory = NULL; 237 Node* not_equal_memory = NULL; 238 239 RegionNode* region = new RegionNode(3); 240 region->init_req(1, equal_path); 241 PhiNode* mem_phi = NULL; 242 if (alias_a == alias_b) { 243 mem_phi = PhiNode::make(region, kit.memory(alias_a), Type::MEMORY, kit.C->get_adr_type(alias_a)); 244 } else { 245 Node* mem = kit.reset_memory(); 246 mem_phi = PhiNode::make(region, mem, Type::MEMORY, TypePtr::BOTTOM); 247 kit.set_all_memory(mem); 248 } 249 250 kit.set_control(not_equal_path); 251 252 Node* mb = NULL; 253 if (alias_a == alias_b) { 254 Node* mem = kit.reset_memory(); 255 mb = MemBarNode::make(kit.C, Op_MemBarAcquire, alias_a); 256 mb->init_req(TypeFunc::Control, kit.control()); 257 mb->init_req(TypeFunc::Memory, mem); 258 Node* membar = kit.gvn().transform(mb); 259 kit.set_control(kit.gvn().transform(new ProjNode(membar, TypeFunc::Control))); 260 Node* newmem = kit.gvn().transform(new ProjNode(membar, TypeFunc::Memory)); 261 kit.set_all_memory(mem); 262 kit.set_memory(newmem, alias_a); 263 } else { 264 mb = kit.insert_mem_bar(Op_MemBarAcquire); 265 } 266 267 ShenandoahBarrierSetC2* bs = (ShenandoahBarrierSetC2*) BarrierSet::barrier_set()->barrier_set_c2(); 268 a = bs->shenandoah_read_barrier_acmp(&kit, a); 269 b = bs->shenandoah_read_barrier_acmp(&kit, b); 270 271 Node* cmp2 = kit.gvn().transform(new CmpPNode(a, b)); 272 Node* bol2 = bol->clone(); 273 bol2->set_req(1, cmp2); 274 bol2 = kit.gvn().transform(bol2); 275 Node* iff2 = iff->clone(); 276 iff2->set_req(0, kit.control()); 277 iff2->set_req(1, bol2); 278 kit.gvn().set_type(iff2, kit.gvn().type(iff)); 279 Node* equal_path2 = equal_path->clone(); 280 equal_path2->set_req(0, iff2); 281 equal_path2 = kit.gvn().transform(equal_path2); 282 Node* not_equal_path2 = not_equal_path->clone(); 283 not_equal_path2->set_req(0, iff2); 284 not_equal_path2 = kit.gvn().transform(not_equal_path2); 285 286 region->init_req(2, equal_path2); 287 not_equal_memory = kit.reset_memory(); 288 not_equal_path = not_equal_path2; 289 290 kit.set_all_memory(not_equal_memory); 291 292 if (alias_a == alias_b) { 293 mem_phi->init_req(2, kit.memory(alias_a)); 294 kit.set_memory(mem_phi, alias_a); 295 } else { 296 mem_phi->init_req(2, kit.reset_memory()); 297 } 298 299 kit.record_for_igvn(mem_phi); 300 kit.gvn().set_type(mem_phi, Type::MEMORY); 301 302 if (alias_a == alias_b) { 303 equal_memory = kit.reset_memory(); 304 } else { 305 equal_memory = mem_phi; 306 } 307 308 assert(kit.map()->memory() == NULL, "no live memory state"); 309 equal_path = kit.gvn().transform(region); 310 311 if (taken_branch == init_equal_path) { 312 assert(untaken_branch == init_not_equal_path, "inconsistent"); 313 taken_branch = equal_path; 314 untaken_branch = not_equal_path; 315 taken_memory = equal_memory; 316 untaken_memory = not_equal_memory; 317 } else { 318 assert(taken_branch == init_not_equal_path, "inconsistent"); 319 assert(untaken_branch == init_equal_path, "inconsistent"); 320 taken_branch = not_equal_path; 321 untaken_branch = equal_path; 322 taken_memory = not_equal_memory; 323 untaken_memory = equal_memory; 324 } 325 } 326 327 bool ShenandoahReadBarrierNode::dominates_memory_rb_impl(PhaseGVN* phase, 328 Node* b1, 329 Node* b2, 330 Node* current, 331 bool linear) { 332 ResourceMark rm; 333 VectorSet visited(Thread::current()->resource_area()); 334 Node_Stack phis(0); 335 336 for(int i = 0; i < 10; i++) { 337 if (current == NULL) { 338 return false; 339 } else if (visited.test_set(current->_idx) || current->is_top() || current == b1) { 340 current = NULL; 341 while (phis.is_nonempty() && current == NULL) { 342 uint idx = phis.index(); 343 Node* phi = phis.node(); 344 if (idx >= phi->req()) { 345 phis.pop(); 346 } else { 347 current = phi->in(idx); 348 phis.set_index(idx+1); 349 } 350 } 351 if (current == NULL) { 352 return true; 353 } 354 } else if (current == phase->C->immutable_memory()) { 355 return false; 356 } else if (current->isa_Phi()) { 357 if (!linear) { 358 return false; 359 } 360 phis.push(current, 2); 361 current = current->in(1); 362 } else if (current->Opcode() == Op_ShenandoahWriteBarrier) { 363 const Type* in_type = current->bottom_type(); 364 const Type* this_type = b2->bottom_type(); 365 if (is_independent(in_type, this_type)) { 366 current = current->in(Memory); 367 } else { 368 return false; 369 } 370 } else if (current->Opcode() == Op_ShenandoahWBMemProj) { 371 current = current->in(0); 372 } else if (current->is_Proj()) { 373 current = current->in(0); 374 } else if (current->is_Call()) { 375 return false; // TODO: Maybe improve by looking at the call's memory effects? 376 } else if (current->is_MemBar()) { 377 return false; // TODO: Do we need to stop at *any* membar? 378 } else if (current->is_MergeMem()) { 379 // if (true) return false; 380 // tty->print_cr("current == mergemem: "); current->dump(); 381 const TypePtr* adr_type = brooks_pointer_type(phase->type(b2)); 382 uint alias_idx = phase->C->get_alias_index(adr_type); 383 current = current->as_MergeMem()->memory_at(alias_idx); 384 } else { 385 // tty->print_cr("what else can we see here:"); 386 #ifdef ASSERT 387 current->dump(); 388 #endif 389 ShouldNotReachHere(); 390 return false; 391 } 392 } 393 return false; 394 } 395 396 bool ShenandoahReadBarrierNode::is_independent(Node* mem) { 397 if (mem->is_Phi() || mem->is_Proj() || mem->is_MergeMem()) { 398 return true; 399 } else if (mem->Opcode() == Op_ShenandoahWriteBarrier) { 400 const Type* mem_type = mem->bottom_type(); 401 const Type* this_type = bottom_type(); 402 if (is_independent(mem_type, this_type)) { 403 return true; 404 } else { 405 return false; 406 } 407 } else if (mem->is_Call() || mem->is_MemBar()) { 408 return false; 409 } 410 #ifdef ASSERT 411 mem->dump(); 412 #endif 413 ShouldNotReachHere(); 414 return true; 415 } 416 417 418 bool ShenandoahReadBarrierNode::dominates_memory_rb(PhaseGVN* phase, Node* b1, Node* b2, bool linear) { 419 return dominates_memory_rb_impl(phase, b1->in(Memory), b2, b2->in(Memory), linear); 420 } 421 422 bool ShenandoahReadBarrierNode::is_independent(const Type* in_type, const Type* this_type) { 423 assert(in_type->isa_oopptr(), "expect oop ptr"); 424 assert(this_type->isa_oopptr(), "expect oop ptr"); 425 /* 426 if ((! in_type->isa_oopptr()) || (! this_type->isa_oopptr())) { 427 #ifdef ASSERT 428 tty->print_cr("not oopptr"); 429 tty->print("in: "); in_type->dump(); tty->print_cr(" "); 430 tty->print("this: "); this_type->dump(); tty->print_cr(" "); 431 #endif 432 return false; 433 } 434 */ 435 436 ciKlass* in_kls = in_type->is_oopptr()->klass(); 437 ciKlass* this_kls = this_type->is_oopptr()->klass(); 438 if (in_kls != NULL && this_kls != NULL && 439 in_kls->is_loaded() && this_kls->is_loaded() && 440 (!in_kls->is_subclass_of(this_kls)) && 441 (!this_kls->is_subclass_of(in_kls))) { 442 #ifdef ASSERT 443 // tty->print_cr("independent: "); 444 // tty->print("in: "); in_kls->print(); tty->print_cr(" "); 445 // tty->print("this: "); this_kls->print(); tty->print_cr(" "); 446 #endif 447 return true; 448 } 449 #ifdef ASSERT 450 // tty->print_cr("possibly dependend?"); 451 // tty->print("in: "); in_type->dump(); tty->print_cr(" "); 452 // tty->print("this: "); this_type->dump(); tty->print_cr(" "); 453 #endif 454 return false; 455 } 456 457 Node* ShenandoahReadBarrierNode::Ideal(PhaseGVN *phase, bool can_reshape) { 458 459 if (! can_reshape) { 460 return NULL; 461 } 462 463 if (in(Memory) == phase->C->immutable_memory()) return NULL; 464 465 // If memory input is a MergeMem, take the appropriate slice out of it. 466 Node* mem_in = in(Memory); 467 if (mem_in->isa_MergeMem()) { 468 const TypePtr* adr_type = brooks_pointer_type(bottom_type()); 469 uint alias_idx = phase->C->get_alias_index(adr_type); 470 mem_in = mem_in->as_MergeMem()->memory_at(alias_idx); 471 set_req(Memory, mem_in); 472 return this; 473 } 474 475 Node* input = in(Memory); 476 if (input->Opcode() == Op_ShenandoahWBMemProj) { 477 Node* wb = input->in(0); 478 const Type* in_type = phase->type(wb); 479 // is_top() test not sufficient here: we can come here after CCP 480 // in a dead branch of the graph that has not yet been removed. 481 if (in_type == Type::TOP) return NULL; // Dead path. 482 assert(wb->Opcode() == Op_ShenandoahWriteBarrier, "expect write barrier"); 483 if (is_independent(in_type, _type)) { 484 phase->igvn_rehash_node_delayed(wb); 485 set_req(Memory, wb->in(Memory)); 486 if (can_reshape && input->outcnt() == 0) { 487 phase->is_IterGVN()->_worklist.push(input); 488 } 489 return this; 490 } 491 } 492 return NULL; 493 } 494 495 ShenandoahWriteBarrierNode::ShenandoahWriteBarrierNode(Compile* C, Node* ctrl, Node* mem, Node* obj) 496 : ShenandoahBarrierNode(ctrl, mem, obj, false) { 497 assert(UseShenandoahGC && ShenandoahWriteBarrier, "should be enabled"); 498 ShenandoahBarrierSetC2::bsc2()->state()->add_shenandoah_barrier(this); 499 } 500 501 Node* ShenandoahWriteBarrierNode::Identity(PhaseGVN* phase) { 502 assert(in(0) != NULL, "should have control"); 503 PhaseIterGVN* igvn = phase->is_IterGVN(); 504 Node* mem_in = in(Memory); 505 Node* mem_proj = NULL; 506 507 if (igvn != NULL) { 508 mem_proj = find_out_with(Op_ShenandoahWBMemProj); 509 if (mem_proj == NULL || mem_in == mem_proj) { 510 return this; 511 } 512 } 513 514 Node* replacement = Identity_impl(phase); 515 if (igvn != NULL) { 516 if (replacement != NULL && replacement != this) { 517 igvn->replace_node(mem_proj, mem_in); 518 } 519 } 520 return replacement; 521 } 522 523 524 Node* ShenandoahWriteBarrierNode::Ideal(PhaseGVN *phase, bool can_reshape) { 525 assert(in(0) != NULL, "should have control"); 526 if (!can_reshape) { 527 return NULL; 528 } 529 530 PhaseIterGVN* igvn = phase->is_IterGVN(); 531 Node* mem_proj = find_out_with(Op_ShenandoahWBMemProj); 532 Node* mem_in = in(Memory); 533 534 if (mem_in == phase->C->immutable_memory()) return NULL; 535 536 if (mem_in->isa_MergeMem()) { 537 const TypePtr* adr_type = brooks_pointer_type(bottom_type()); 538 uint alias_idx = phase->C->get_alias_index(adr_type); 539 mem_in = mem_in->as_MergeMem()->memory_at(alias_idx); 540 set_req(Memory, mem_in); 541 return this; 542 } 543 544 return NULL; 545 } 546 547 bool ShenandoahWriteBarrierNode::expand(Compile* C, PhaseIterGVN& igvn, int& loop_opts_cnt) { 548 if (UseShenandoahGC && ShenandoahWriteBarrierToIR) { 549 if (ShenandoahBarrierSetC2::bsc2()->state()->shenandoah_barriers_count() > 0) { 550 bool attempt_more_loopopts = ShenandoahLoopOptsAfterExpansion; 551 C->clear_major_progress(); 552 PhaseIdealLoop ideal_loop(igvn, LoopOptsShenandoahExpand); 553 if (C->failing()) return false; 554 PhaseIdealLoop::verify(igvn); 555 DEBUG_ONLY(ShenandoahBarrierNode::verify_raw_mem(C->root());) 556 if (attempt_more_loopopts) { 557 C->set_major_progress(); 558 if (!C->optimize_loops(loop_opts_cnt, igvn, LoopOptsShenandoahPostExpand)) { 559 return false; 560 } 561 C->clear_major_progress(); 562 } 563 } 564 } 565 return true; 566 } 567 568 bool ShenandoahWriteBarrierNode::is_heap_state_test(Node* iff, int mask) { 569 if (!UseShenandoahGC) { 570 return false; 571 } 572 assert(iff->is_If(), "bad input"); 573 if (iff->Opcode() != Op_If) { 574 return false; 575 } 576 Node* bol = iff->in(1); 577 if (!bol->is_Bool() || bol->as_Bool()->_test._test != BoolTest::ne) { 578 return false; 579 } 580 Node* cmp = bol->in(1); 581 if (cmp->Opcode() != Op_CmpI) { 582 return false; 583 } 584 Node* in1 = cmp->in(1); 585 Node* in2 = cmp->in(2); 586 if (in2->find_int_con(-1) != 0) { 587 return false; 588 } 589 if (in1->Opcode() != Op_AndI) { 590 return false; 591 } 592 in2 = in1->in(2); 593 if (in2->find_int_con(-1) != mask) { 594 return false; 595 } 596 in1 = in1->in(1); 597 598 return is_gc_state_load(in1); 599 } 600 601 602 bool ShenandoahWriteBarrierNode::is_evacuation_in_progress_test(Node* iff) { 603 return is_heap_state_test(iff, ShenandoahHeap::EVACUATION | ShenandoahHeap::TRAVERSAL); 604 } 605 606 bool ShenandoahWriteBarrierNode::is_heap_stable_test(Node* iff) { 607 if (!UseShenandoahGC) { 608 return false; 609 } 610 assert(iff->is_If(), "bad input"); 611 if (iff->Opcode() != Op_If) { 612 return false; 613 } 614 Node* bol = iff->in(1); 615 if (bol == NULL || !bol->is_Bool() || bol->as_Bool()->_test._test != BoolTest::ne) { 616 return false; 617 } 618 Node* cmp = bol->in(1); 619 if (cmp->Opcode() != Op_CmpI) { 620 return false; 621 } 622 Node* in1 = cmp->in(1); 623 Node* in2 = cmp->in(2); 624 if (in2->find_int_con(-1) != 0) { 625 return false; 626 } 627 return is_gc_state_load(in1); 628 } 629 630 bool ShenandoahWriteBarrierNode::is_gc_state_load(Node *n) { 631 if (!UseShenandoahGC) { 632 return false; 633 } 634 if (n->Opcode() != Op_LoadB) { 635 return false; 636 } 637 Node* addp = n->in(MemNode::Address); 638 if (!addp->is_AddP()) { 639 return false; 640 } 641 Node* base = addp->in(AddPNode::Address); 642 Node* off = addp->in(AddPNode::Offset); 643 if (base->Opcode() != Op_ThreadLocal) { 644 return false; 645 } 646 if (off->find_intptr_t_con(-1) != in_bytes(ShenandoahThreadLocalData::gc_state_offset())) { 647 return false; 648 } 649 return true; 650 } 651 652 bool ShenandoahWriteBarrierNode::has_safepoint_between(Node* start, Node* stop, PhaseIdealLoop *phase) { 653 assert(phase->is_dominator(stop, start), "bad inputs"); 654 ResourceMark rm; 655 Unique_Node_List wq; 656 wq.push(start); 657 for (uint next = 0; next < wq.size(); next++) { 658 Node *m = wq.at(next); 659 if (m == stop) { 660 continue; 661 } 662 if (m->is_SafePoint() && !m->is_CallLeaf()) { 663 return true; 664 } 665 if (m->is_Region()) { 666 for (uint i = 1; i < m->req(); i++) { 667 wq.push(m->in(i)); 668 } 669 } else { 670 wq.push(m->in(0)); 671 } 672 } 673 return false; 674 } 675 676 bool ShenandoahWriteBarrierNode::try_common_gc_state_load(Node *n, PhaseIdealLoop *phase) { 677 assert(is_gc_state_load(n), "inconsistent"); 678 Node* addp = n->in(MemNode::Address); 679 Node* dominator = NULL; 680 for (DUIterator_Fast imax, i = addp->fast_outs(imax); i < imax; i++) { 681 Node* u = addp->fast_out(i); 682 assert(is_gc_state_load(u), "inconsistent"); 683 if (u != n && phase->is_dominator(u->in(0), n->in(0))) { 684 if (dominator == NULL) { 685 dominator = u; 686 } else { 687 if (phase->dom_depth(u->in(0)) < phase->dom_depth(dominator->in(0))) { 688 dominator = u; 689 } 690 } 691 } 692 } 693 if (dominator == NULL || has_safepoint_between(n->in(0), dominator->in(0), phase)) { 694 return false; 695 } 696 phase->igvn().replace_node(n, dominator); 697 698 return true; 699 } 700 701 Node* ShenandoahWriteBarrierNode::evacuation_in_progress_test_ctrl(Node* iff) { 702 assert(is_evacuation_in_progress_test(iff), "bad input"); 703 return iff->in(0); 704 } 705 706 bool ShenandoahBarrierNode::dominates_memory_impl(PhaseGVN* phase, 707 Node* b1, 708 Node* b2, 709 Node* current, 710 bool linear) { 711 ResourceMark rm; 712 VectorSet visited(Thread::current()->resource_area()); 713 Node_Stack phis(0); 714 715 716 for(int i = 0; i < 10; i++) { 717 if (current == NULL) { 718 return false; 719 } else if (visited.test_set(current->_idx) || current->is_top() || current == b1) { 720 current = NULL; 721 while (phis.is_nonempty() && current == NULL) { 722 uint idx = phis.index(); 723 Node* phi = phis.node(); 724 if (idx >= phi->req()) { 725 phis.pop(); 726 } else { 727 current = phi->in(idx); 728 phis.set_index(idx+1); 729 } 730 } 731 if (current == NULL) { 732 return true; 733 } 734 } else if (current == b2) { 735 return false; 736 } else if (current == phase->C->immutable_memory()) { 737 return false; 738 } else if (current->isa_Phi()) { 739 if (!linear) { 740 return false; 741 } 742 phis.push(current, 2); 743 current = current->in(1); 744 } else if (current->Opcode() == Op_ShenandoahWriteBarrier) { 745 current = current->in(Memory); 746 } else if (current->Opcode() == Op_ShenandoahWBMemProj) { 747 current = current->in(0); 748 } else if (current->is_Proj()) { 749 current = current->in(0); 750 } else if (current->is_Call()) { 751 current = current->in(TypeFunc::Memory); 752 } else if (current->is_MemBar()) { 753 current = current->in(TypeFunc::Memory); 754 } else if (current->is_MergeMem()) { 755 const TypePtr* adr_type = brooks_pointer_type(phase->type(b2)); 756 uint alias_idx = phase->C->get_alias_index(adr_type); 757 current = current->as_MergeMem()->memory_at(alias_idx); 758 } else { 759 #ifdef ASSERT 760 current->dump(); 761 #endif 762 ShouldNotReachHere(); 763 return false; 764 } 765 } 766 return false; 767 } 768 769 /** 770 * Determines if b1 dominates b2 through memory inputs. It returns true if: 771 * - b1 can be reached by following each branch in b2's memory input (through phis, etc) 772 * - or we get back to b2 (i.e. through a loop) without seeing b1 773 * In all other cases, (in particular, if we reach immutable_memory without having seen b1) 774 * we return false. 775 */ 776 bool ShenandoahBarrierNode::dominates_memory(PhaseGVN* phase, Node* b1, Node* b2, bool linear) { 777 return dominates_memory_impl(phase, b1, b2, b2->in(Memory), linear); 778 } 779 780 Node* ShenandoahBarrierNode::Identity_impl(PhaseGVN* phase) { 781 Node* n = in(ValueIn); 782 783 Node* rb_mem = Opcode() == Op_ShenandoahReadBarrier ? in(Memory) : NULL; 784 if (! needs_barrier(phase, this, n, rb_mem, _allow_fromspace)) { 785 return n; 786 } 787 788 // tty->print_cr("find sibling for: "); dump(2); 789 // Try to find a write barrier sibling with identical inputs that we can fold into. 790 for (DUIterator i = n->outs(); n->has_out(i); i++) { 791 Node* sibling = n->out(i); 792 if (sibling == this) { 793 continue; 794 } 795 /* 796 assert(sibling->Opcode() != Op_ShenandoahWriteBarrier || 797 Opcode() != Op_ShenandoahWriteBarrier || hash() == sibling->hash(), 798 "if this is a write barrier, then sibling can't be write barrier too"); 799 */ 800 if (sibling->Opcode() != Op_ShenandoahWriteBarrier) { 801 continue; 802 } 803 /* 804 if (sibling->outcnt() == 0) { 805 // Some dead node. 806 continue; 807 } 808 */ 809 assert(sibling->in(ValueIn) == in(ValueIn), "sanity"); 810 assert(sibling->Opcode() == Op_ShenandoahWriteBarrier, "sanity"); 811 // tty->print_cr("candidate: "); sibling->dump(); 812 813 if (dominates_memory(phase, sibling, this, phase->is_IterGVN() == NULL)) { 814 815 /* 816 tty->print_cr("matched barrier:"); 817 sibling->dump(); 818 tty->print_cr("for: "); 819 dump(); 820 */ 821 return sibling; 822 } 823 824 /* 825 tty->print_cr("couldn't match candidate:"); 826 sibling->dump(2); 827 */ 828 } 829 /* 830 tty->print_cr("couldn't match barrier to any:"); 831 dump(); 832 */ 833 return this; 834 } 835 836 #ifndef PRODUCT 837 void ShenandoahBarrierNode::dump_spec(outputStream *st) const { 838 const TypePtr* adr = adr_type(); 839 if (adr == NULL) { 840 return; 841 } 842 st->print(" @"); 843 adr->dump_on(st); 844 st->print(" ("); 845 Compile::current()->alias_type(adr)->adr_type()->dump_on(st); 846 st->print(") "); 847 } 848 #endif 849 850 Node* ShenandoahReadBarrierNode::Identity(PhaseGVN* phase) { 851 852 // if (true) return this; 853 854 // tty->print("optimizing rb: "); dump(); 855 Node* id = Identity_impl(phase); 856 857 if (id == this && phase->is_IterGVN()) { 858 Node* n = in(ValueIn); 859 // No success in super call. Try to combine identical read barriers. 860 for (DUIterator i = n->outs(); n->has_out(i); i++) { 861 Node* sibling = n->out(i); 862 if (sibling == this || sibling->Opcode() != Op_ShenandoahReadBarrier) { 863 continue; 864 } 865 assert(sibling->in(ValueIn) == in(ValueIn), "sanity"); 866 if (phase->is_IterGVN()->hash_find(sibling) && 867 sibling->bottom_type() == bottom_type() && 868 sibling->in(Control) == in(Control) && 869 dominates_memory_rb(phase, sibling, this, phase->is_IterGVN() == NULL)) { 870 /* 871 if (in(Memory) != sibling->in(Memory)) { 872 tty->print_cr("interesting rb-fold"); 873 dump(); 874 sibling->dump(); 875 } 876 */ 877 return sibling; 878 } 879 } 880 } 881 return id; 882 } 883 884 const Type* ShenandoahBarrierNode::Value(PhaseGVN* phase) const { 885 // Either input is TOP ==> the result is TOP 886 const Type *t1 = phase->type(in(Memory)); 887 if (t1 == Type::TOP) return Type::TOP; 888 const Type *t2 = phase->type(in(ValueIn)); 889 if( t2 == Type::TOP ) return Type::TOP; 890 891 Node* input = in(ValueIn); 892 const Type* type = phase->type(input)->is_oopptr()->cast_to_nonconst(); 893 return type; 894 } 895 896 uint ShenandoahBarrierNode::hash() const { 897 return TypeNode::hash() + _allow_fromspace; 898 } 899 900 uint ShenandoahBarrierNode::cmp(const Node& n) const { 901 return _allow_fromspace == ((ShenandoahBarrierNode&) n)._allow_fromspace 902 && TypeNode::cmp(n); 903 } 904 905 uint ShenandoahBarrierNode::size_of() const { 906 return sizeof(*this); 907 } 908 909 Node* ShenandoahWBMemProjNode::Identity(PhaseGVN* phase) { 910 911 Node* wb = in(0); 912 if (wb->is_top()) return phase->C->top(); // Dead path. 913 914 assert(wb->Opcode() == Op_ShenandoahWriteBarrier, "expect write barrier"); 915 PhaseIterGVN* igvn = phase->is_IterGVN(); 916 // We can't do the below unless the graph is fully constructed. 917 if (igvn == NULL) { 918 return this; 919 } 920 921 // If the mem projection has no barrier users, it's not needed anymore. 922 Unique_Node_List visited; 923 if (wb->outcnt() == 1) { 924 return wb->in(ShenandoahBarrierNode::Memory); 925 } 926 927 return this; 928 } 929 930 #ifdef ASSERT 931 bool ShenandoahBarrierNode::verify_helper(Node* in, Node_Stack& phis, VectorSet& visited, verify_type t, bool trace, Unique_Node_List& barriers_used) { 932 assert(phis.size() == 0, ""); 933 934 while (true) { 935 if (!in->bottom_type()->make_ptr()->make_oopptr()) { 936 if (trace) {tty->print_cr("Non oop");} 937 } else if (t == ShenandoahLoad && ShenandoahOptimizeStableFinals && 938 in->bottom_type()->make_ptr()->isa_aryptr() && 939 in->bottom_type()->make_ptr()->is_aryptr()->is_stable()) { 940 if (trace) {tty->print_cr("Stable array load");} 941 } else { 942 if (in->is_ConstraintCast()) { 943 in = in->in(1); 944 continue; 945 } else if (in->is_AddP()) { 946 assert(!in->in(AddPNode::Address)->is_top(), "no raw memory access"); 947 in = in->in(AddPNode::Address); 948 continue; 949 } else if (in->is_Con() && !ShenandoahBarriersForConst) { 950 if (trace) {tty->print("Found constant"); in->dump();} 951 } else if (in->is_ShenandoahBarrier()) { 952 if (t == ShenandoahStore && in->Opcode() != Op_ShenandoahWriteBarrier) { 953 return false; 954 } 955 barriers_used.push(in); 956 if (trace) {tty->print("Found barrier"); in->dump();} 957 } else if (in->is_Proj() && in->in(0)->is_Allocate()) { 958 if (trace) {tty->print("Found alloc"); in->in(0)->dump();} 959 } else if (in->is_Phi()) { 960 if (!visited.test_set(in->_idx)) { 961 if (trace) {tty->print("Pushed phi:"); in->dump();} 962 phis.push(in, 2); 963 in = in->in(1); 964 continue; 965 } 966 if (trace) {tty->print("Already seen phi:"); in->dump();} 967 } else if (in->Opcode() == Op_CMoveP || in->Opcode() == Op_CMoveN) { 968 if (!visited.test_set(in->_idx)) { 969 if (trace) {tty->print("Pushed cmovep:"); in->dump();} 970 phis.push(in, CMoveNode::IfTrue); 971 in = in->in(CMoveNode::IfFalse); 972 continue; 973 } 974 if (trace) {tty->print("Already seen cmovep:"); in->dump();} 975 } else if (in->Opcode() == Op_EncodeP || in->Opcode() == Op_DecodeN) { 976 in = in->in(1); 977 continue; 978 } else { 979 return false; 980 } 981 } 982 bool cont = false; 983 while (phis.is_nonempty()) { 984 uint idx = phis.index(); 985 Node* phi = phis.node(); 986 if (idx >= phi->req()) { 987 if (trace) {tty->print("Popped phi:"); phi->dump();} 988 phis.pop(); 989 continue; 990 } 991 if (trace) {tty->print("Next entry(%d) for phi:", idx); phi->dump();} 992 in = phi->in(idx); 993 phis.set_index(idx+1); 994 cont = true; 995 break; 996 } 997 if (!cont) { 998 break; 999 } 1000 } 1001 return true; 1002 } 1003 1004 void ShenandoahBarrierNode::report_verify_failure(const char *msg, Node *n1, Node *n2) { 1005 if (n1 != NULL) { 1006 n1->dump(+10); 1007 } 1008 if (n2 != NULL) { 1009 n2->dump(+10); 1010 } 1011 fatal("%s", msg); 1012 } 1013 1014 void ShenandoahBarrierNode::verify(RootNode* root) { 1015 ResourceMark rm; 1016 Unique_Node_List wq; 1017 GrowableArray<Node*> barriers; 1018 Unique_Node_List barriers_used; 1019 Node_Stack phis(0); 1020 VectorSet visited(Thread::current()->resource_area()); 1021 const bool trace = false; 1022 const bool verify_no_useless_barrier = false; 1023 1024 wq.push(root); 1025 for (uint next = 0; next < wq.size(); next++) { 1026 Node *n = wq.at(next); 1027 if (n->is_Load()) { 1028 const bool trace = false; 1029 if (trace) {tty->print("Verifying"); n->dump();} 1030 if (n->Opcode() == Op_LoadRange || n->Opcode() == Op_LoadKlass || n->Opcode() == Op_LoadNKlass) { 1031 if (trace) {tty->print_cr("Load range/klass");} 1032 } else { 1033 const TypePtr* adr_type = n->as_Load()->adr_type(); 1034 1035 if (adr_type->isa_oopptr() && adr_type->is_oopptr()->offset() == oopDesc::mark_offset_in_bytes()) { 1036 if (trace) {tty->print_cr("Mark load");} 1037 } else if (adr_type->isa_instptr() && 1038 adr_type->is_instptr()->klass()->is_subtype_of(Compile::current()->env()->Reference_klass()) && 1039 adr_type->is_instptr()->offset() == java_lang_ref_Reference::referent_offset) { 1040 if (trace) {tty->print_cr("Reference.get()");} 1041 } else { 1042 bool verify = true; 1043 if (adr_type->isa_instptr()) { 1044 const TypeInstPtr* tinst = adr_type->is_instptr(); 1045 ciKlass* k = tinst->klass(); 1046 assert(k->is_instance_klass(), ""); 1047 ciInstanceKlass* ik = (ciInstanceKlass*)k; 1048 int offset = adr_type->offset(); 1049 1050 if ((ik->debug_final_field_at(offset) && ShenandoahOptimizeInstanceFinals) || 1051 (ik->debug_stable_field_at(offset) && ShenandoahOptimizeStableFinals)) { 1052 if (trace) {tty->print_cr("Final/stable");} 1053 verify = false; 1054 } else if (k == ciEnv::current()->Class_klass() && 1055 tinst->const_oop() != NULL && 1056 tinst->offset() >= (ik->size_helper() * wordSize)) { 1057 ciInstanceKlass* k = tinst->const_oop()->as_instance()->java_lang_Class_klass()->as_instance_klass(); 1058 ciField* field = k->get_field_by_offset(tinst->offset(), true); 1059 if ((ShenandoahOptimizeStaticFinals && field->is_final()) || 1060 (ShenandoahOptimizeStableFinals && field->is_stable())) { 1061 verify = false; 1062 } 1063 } 1064 } 1065 1066 if (verify && !ShenandoahBarrierNode::verify_helper(n->in(MemNode::Address), phis, visited, ShenandoahLoad, trace, barriers_used)) { 1067 report_verify_failure("Shenandoah verification: Load should have barriers", n); 1068 } 1069 } 1070 } 1071 } else if (n->is_Store()) { 1072 const bool trace = false; 1073 1074 if (trace) {tty->print("Verifying"); n->dump();} 1075 if (n->in(MemNode::ValueIn)->bottom_type()->make_oopptr()) { 1076 Node* adr = n->in(MemNode::Address); 1077 bool verify = true; 1078 1079 if (adr->is_AddP() && adr->in(AddPNode::Base)->is_top()) { 1080 adr = adr->in(AddPNode::Address); 1081 if (adr->is_AddP()) { 1082 assert(adr->in(AddPNode::Base)->is_top(), ""); 1083 adr = adr->in(AddPNode::Address); 1084 if (adr->Opcode() == Op_LoadP && 1085 adr->in(MemNode::Address)->in(AddPNode::Base)->is_top() && 1086 adr->in(MemNode::Address)->in(AddPNode::Address)->Opcode() == Op_ThreadLocal && 1087 adr->in(MemNode::Address)->in(AddPNode::Offset)->find_intptr_t_con(-1) == in_bytes(ShenandoahThreadLocalData::satb_mark_queue_buffer_offset())) { 1088 if (trace) {tty->print_cr("SATB prebarrier");} 1089 verify = false; 1090 } 1091 } 1092 } 1093 1094 if (verify && !ShenandoahBarrierNode::verify_helper(n->in(MemNode::ValueIn), phis, visited, ShenandoahValue, trace, barriers_used)) { 1095 report_verify_failure("Shenandoah verification: Store should have barriers", n); 1096 } 1097 } 1098 if (!ShenandoahBarrierNode::verify_helper(n->in(MemNode::Address), phis, visited, ShenandoahStore, trace, barriers_used)) { 1099 report_verify_failure("Shenandoah verification: Store (address) should have barriers", n); 1100 } 1101 } else if (n->Opcode() == Op_CmpP) { 1102 const bool trace = false; 1103 1104 Node* in1 = n->in(1); 1105 Node* in2 = n->in(2); 1106 if (in1->bottom_type()->isa_oopptr()) { 1107 if (trace) {tty->print("Verifying"); n->dump();} 1108 1109 bool mark_inputs = false; 1110 if (in1->bottom_type() == TypePtr::NULL_PTR || in2->bottom_type() == TypePtr::NULL_PTR || 1111 ((in1->is_Con() || in2->is_Con()) && !ShenandoahBarriersForConst)) { 1112 if (trace) {tty->print_cr("Comparison against a constant");} 1113 mark_inputs = true; 1114 } else if ((in1->is_CheckCastPP() && in1->in(1)->is_Proj() && in1->in(1)->in(0)->is_Allocate()) || 1115 (in2->is_CheckCastPP() && in2->in(1)->is_Proj() && in2->in(1)->in(0)->is_Allocate())) { 1116 if (trace) {tty->print_cr("Comparison with newly alloc'ed object");} 1117 mark_inputs = true; 1118 } else { 1119 assert(in2->bottom_type()->isa_oopptr(), ""); 1120 1121 if (!ShenandoahBarrierNode::verify_helper(in1, phis, visited, ShenandoahStore, trace, barriers_used) || 1122 !ShenandoahBarrierNode::verify_helper(in2, phis, visited, ShenandoahStore, trace, barriers_used)) { 1123 report_verify_failure("Shenandoah verification: Cmp should have barriers", n); 1124 } 1125 } 1126 if (verify_no_useless_barrier && 1127 mark_inputs && 1128 (!ShenandoahBarrierNode::verify_helper(in1, phis, visited, ShenandoahValue, trace, barriers_used) || 1129 !ShenandoahBarrierNode::verify_helper(in2, phis, visited, ShenandoahValue, trace, barriers_used))) { 1130 phis.clear(); 1131 visited.Reset(); 1132 } 1133 } 1134 } else if (n->is_LoadStore()) { 1135 if (n->in(MemNode::ValueIn)->bottom_type()->isa_ptr() && 1136 !ShenandoahBarrierNode::verify_helper(n->in(MemNode::ValueIn), phis, visited, ShenandoahLoad, trace, barriers_used)) { 1137 report_verify_failure("Shenandoah verification: LoadStore (value) should have barriers", n); 1138 } 1139 1140 if (n->in(MemNode::Address)->bottom_type()->isa_oopptr() && !ShenandoahBarrierNode::verify_helper(n->in(MemNode::Address), phis, visited, ShenandoahStore, trace, barriers_used)) { 1141 report_verify_failure("Shenandoah verification: LoadStore (address) should have barriers", n); 1142 } 1143 } else if (n->Opcode() == Op_CallLeafNoFP || n->Opcode() == Op_CallLeaf) { 1144 CallNode* call = n->as_Call(); 1145 1146 static struct { 1147 const char* name; 1148 struct { 1149 int pos; 1150 verify_type t; 1151 } args[6]; 1152 } calls[] = { 1153 "aescrypt_encryptBlock", 1154 { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+1, ShenandoahStore }, { TypeFunc::Parms+2, ShenandoahLoad }, 1155 { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, 1156 "aescrypt_decryptBlock", 1157 { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+1, ShenandoahStore }, { TypeFunc::Parms+2, ShenandoahLoad }, 1158 { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, 1159 "multiplyToLen", 1160 { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+2, ShenandoahLoad }, { TypeFunc::Parms+4, ShenandoahStore }, 1161 { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, 1162 "squareToLen", 1163 { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+2, ShenandoahLoad }, { -1, ShenandoahNone}, 1164 { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, 1165 "montgomery_multiply", 1166 { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+1, ShenandoahLoad }, { TypeFunc::Parms+2, ShenandoahLoad }, 1167 { TypeFunc::Parms+6, ShenandoahStore }, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, 1168 "montgomery_square", 1169 { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+1, ShenandoahLoad }, { TypeFunc::Parms+5, ShenandoahStore }, 1170 { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, 1171 "mulAdd", 1172 { { TypeFunc::Parms, ShenandoahStore }, { TypeFunc::Parms+1, ShenandoahLoad }, { -1, ShenandoahNone}, 1173 { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, 1174 "vectorizedMismatch", 1175 { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+1, ShenandoahLoad }, { -1, ShenandoahNone}, 1176 { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, 1177 "updateBytesCRC32", 1178 { { TypeFunc::Parms+1, ShenandoahLoad }, { -1, ShenandoahNone}, { -1, ShenandoahNone}, 1179 { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, 1180 "updateBytesAdler32", 1181 { { TypeFunc::Parms+1, ShenandoahLoad }, { -1, ShenandoahNone}, { -1, ShenandoahNone}, 1182 { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, 1183 "updateBytesCRC32C", 1184 { { TypeFunc::Parms+1, ShenandoahLoad }, { TypeFunc::Parms+3, ShenandoahLoad}, { -1, ShenandoahNone}, 1185 { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, 1186 "counterMode_AESCrypt", 1187 { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+1, ShenandoahStore }, { TypeFunc::Parms+2, ShenandoahLoad }, 1188 { TypeFunc::Parms+3, ShenandoahStore }, { TypeFunc::Parms+5, ShenandoahStore }, { TypeFunc::Parms+6, ShenandoahStore } }, 1189 "cipherBlockChaining_encryptAESCrypt", 1190 { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+1, ShenandoahStore }, { TypeFunc::Parms+2, ShenandoahLoad }, 1191 { TypeFunc::Parms+3, ShenandoahLoad }, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, 1192 "cipherBlockChaining_decryptAESCrypt", 1193 { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+1, ShenandoahStore }, { TypeFunc::Parms+2, ShenandoahLoad }, 1194 { TypeFunc::Parms+3, ShenandoahLoad }, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, 1195 "shenandoah_clone_barrier", 1196 { { TypeFunc::Parms, ShenandoahLoad }, { -1, ShenandoahNone}, { -1, ShenandoahNone}, 1197 { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, 1198 "ghash_processBlocks", 1199 { { TypeFunc::Parms, ShenandoahStore }, { TypeFunc::Parms+1, ShenandoahLoad }, { TypeFunc::Parms+2, ShenandoahLoad }, 1200 { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, 1201 "sha1_implCompress", 1202 { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+1, ShenandoahStore }, { -1, ShenandoahNone }, 1203 { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, 1204 "sha256_implCompress", 1205 { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+1, ShenandoahStore }, { -1, ShenandoahNone }, 1206 { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, 1207 "sha512_implCompress", 1208 { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+1, ShenandoahStore }, { -1, ShenandoahNone }, 1209 { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, 1210 "sha1_implCompressMB", 1211 { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+1, ShenandoahStore }, { -1, ShenandoahNone }, 1212 { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, 1213 "sha256_implCompressMB", 1214 { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+1, ShenandoahStore }, { -1, ShenandoahNone }, 1215 { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, 1216 "sha512_implCompressMB", 1217 { { TypeFunc::Parms, ShenandoahLoad }, { TypeFunc::Parms+1, ShenandoahStore }, { -1, ShenandoahNone }, 1218 { -1, ShenandoahNone}, { -1, ShenandoahNone}, { -1, ShenandoahNone} }, 1219 }; 1220 1221 if (call->is_call_to_arraycopystub()) { 1222 Node* dest = NULL; 1223 const TypeTuple* args = n->as_Call()->_tf->domain(); 1224 for (uint i = TypeFunc::Parms, j = 0; i < args->cnt(); i++) { 1225 if (args->field_at(i)->isa_ptr()) { 1226 j++; 1227 if (j == 2) { 1228 dest = n->in(i); 1229 break; 1230 } 1231 } 1232 } 1233 if (!ShenandoahBarrierNode::verify_helper(n->in(TypeFunc::Parms), phis, visited, ShenandoahLoad, trace, barriers_used) || 1234 !ShenandoahBarrierNode::verify_helper(dest, phis, visited, ShenandoahStore, trace, barriers_used)) { 1235 report_verify_failure("Shenandoah verification: ArrayCopy should have barriers", n); 1236 } 1237 } else if (strlen(call->_name) > 5 && 1238 !strcmp(call->_name + strlen(call->_name) - 5, "_fill")) { 1239 if (!ShenandoahBarrierNode::verify_helper(n->in(TypeFunc::Parms), phis, visited, ShenandoahStore, trace, barriers_used)) { 1240 report_verify_failure("Shenandoah verification: _fill should have barriers", n); 1241 } 1242 } else if (!strcmp(call->_name, "g1_wb_pre")) { 1243 // skip 1244 } else { 1245 const int calls_len = sizeof(calls) / sizeof(calls[0]); 1246 int i = 0; 1247 for (; i < calls_len; i++) { 1248 if (!strcmp(calls[i].name, call->_name)) { 1249 break; 1250 } 1251 } 1252 if (i != calls_len) { 1253 const uint args_len = sizeof(calls[0].args) / sizeof(calls[0].args[0]); 1254 for (uint j = 0; j < args_len; j++) { 1255 int pos = calls[i].args[j].pos; 1256 if (pos == -1) { 1257 break; 1258 } 1259 if (!ShenandoahBarrierNode::verify_helper(call->in(pos), phis, visited, calls[i].args[j].t, trace, barriers_used)) { 1260 report_verify_failure("Shenandoah verification: intrinsic calls should have barriers", n); 1261 } 1262 } 1263 for (uint j = TypeFunc::Parms; j < call->req(); j++) { 1264 if (call->in(j)->bottom_type()->make_ptr() && 1265 call->in(j)->bottom_type()->make_ptr()->isa_oopptr()) { 1266 uint k = 0; 1267 for (; k < args_len && calls[i].args[k].pos != (int)j; k++); 1268 if (k == args_len) { 1269 fatal("arg %d for call %s not covered", j, call->_name); 1270 } 1271 } 1272 } 1273 } else { 1274 for (uint j = TypeFunc::Parms; j < call->req(); j++) { 1275 if (call->in(j)->bottom_type()->make_ptr() && 1276 call->in(j)->bottom_type()->make_ptr()->isa_oopptr()) { 1277 fatal("%s not covered", call->_name); 1278 } 1279 } 1280 } 1281 } 1282 } else if (n->is_ShenandoahBarrier()) { 1283 assert(!barriers.contains(n), ""); 1284 assert(n->Opcode() != Op_ShenandoahWriteBarrier || n->find_out_with(Op_ShenandoahWBMemProj) != NULL, "bad shenandoah write barrier"); 1285 assert(n->Opcode() != Op_ShenandoahWriteBarrier || n->outcnt() > 1, "bad shenandoah write barrier"); 1286 barriers.push(n); 1287 } else if (n->is_AddP() 1288 || n->is_Phi() 1289 || n->is_ConstraintCast() 1290 || n->Opcode() == Op_Return 1291 || n->Opcode() == Op_CMoveP 1292 || n->Opcode() == Op_CMoveN 1293 || n->Opcode() == Op_Rethrow 1294 || n->is_MemBar() 1295 || n->Opcode() == Op_Conv2B 1296 || n->Opcode() == Op_SafePoint 1297 || n->is_CallJava() 1298 || n->Opcode() == Op_Unlock 1299 || n->Opcode() == Op_EncodeP 1300 || n->Opcode() == Op_DecodeN) { 1301 // nothing to do 1302 } else { 1303 static struct { 1304 int opcode; 1305 struct { 1306 int pos; 1307 verify_type t; 1308 } inputs[2]; 1309 } others[] = { 1310 Op_FastLock, 1311 { { 1, ShenandoahLoad }, { -1, ShenandoahNone} }, 1312 Op_Lock, 1313 { { TypeFunc::Parms, ShenandoahLoad }, { -1, ShenandoahNone} }, 1314 Op_ArrayCopy, 1315 { { ArrayCopyNode::Src, ShenandoahLoad }, { ArrayCopyNode::Dest, ShenandoahStore } }, 1316 Op_StrCompressedCopy, 1317 { { 2, ShenandoahLoad }, { 3, ShenandoahStore } }, 1318 Op_StrInflatedCopy, 1319 { { 2, ShenandoahLoad }, { 3, ShenandoahStore } }, 1320 Op_AryEq, 1321 { { 2, ShenandoahLoad }, { 3, ShenandoahLoad } }, 1322 Op_StrIndexOf, 1323 { { 2, ShenandoahLoad }, { 4, ShenandoahLoad } }, 1324 Op_StrComp, 1325 { { 2, ShenandoahLoad }, { 4, ShenandoahLoad } }, 1326 Op_StrEquals, 1327 { { 2, ShenandoahLoad }, { 3, ShenandoahLoad } }, 1328 Op_EncodeISOArray, 1329 { { 2, ShenandoahLoad }, { 3, ShenandoahStore } }, 1330 Op_HasNegatives, 1331 { { 2, ShenandoahLoad }, { -1, ShenandoahNone} }, 1332 Op_CastP2X, 1333 { { 1, ShenandoahLoad }, { -1, ShenandoahNone} }, 1334 Op_StrIndexOfChar, 1335 { { 2, ShenandoahLoad }, { -1, ShenandoahNone } }, 1336 }; 1337 1338 const int others_len = sizeof(others) / sizeof(others[0]); 1339 int i = 0; 1340 for (; i < others_len; i++) { 1341 if (others[i].opcode == n->Opcode()) { 1342 break; 1343 } 1344 } 1345 uint stop = n->is_Call() ? n->as_Call()->tf()->domain()->cnt() : n->req(); 1346 if (i != others_len) { 1347 const uint inputs_len = sizeof(others[0].inputs) / sizeof(others[0].inputs[0]); 1348 for (uint j = 0; j < inputs_len; j++) { 1349 int pos = others[i].inputs[j].pos; 1350 if (pos == -1) { 1351 break; 1352 } 1353 if (!ShenandoahBarrierNode::verify_helper(n->in(pos), phis, visited, others[i].inputs[j].t, trace, barriers_used)) { 1354 report_verify_failure("Shenandoah verification: intrinsic calls should have barriers", n); 1355 } 1356 } 1357 for (uint j = 1; j < stop; j++) { 1358 if (n->in(j) != NULL && n->in(j)->bottom_type()->make_ptr() && 1359 n->in(j)->bottom_type()->make_ptr()->make_oopptr()) { 1360 uint k = 0; 1361 for (; k < inputs_len && others[i].inputs[k].pos != (int)j; k++); 1362 if (k == inputs_len) { 1363 fatal("arg %d for node %s not covered", j, n->Name()); 1364 } 1365 } 1366 } 1367 } else { 1368 for (uint j = 1; j < stop; j++) { 1369 if (n->in(j) != NULL && n->in(j)->bottom_type()->make_ptr() && 1370 n->in(j)->bottom_type()->make_ptr()->make_oopptr()) { 1371 fatal("%s not covered", n->Name()); 1372 } 1373 } 1374 } 1375 } 1376 1377 if (n->is_SafePoint()) { 1378 SafePointNode* sfpt = n->as_SafePoint(); 1379 if (verify_no_useless_barrier && sfpt->jvms() != NULL) { 1380 for (uint i = sfpt->jvms()->scloff(); i < sfpt->jvms()->endoff(); i++) { 1381 if (!ShenandoahBarrierNode::verify_helper(sfpt->in(i), phis, visited, ShenandoahLoad, trace, barriers_used)) { 1382 phis.clear(); 1383 visited.Reset(); 1384 } 1385 } 1386 } 1387 } 1388 for( uint i = 0; i < n->len(); ++i ) { 1389 Node *m = n->in(i); 1390 if (m == NULL) continue; 1391 1392 // In most cases, inputs should be known to be non null. If it's 1393 // not the case, it could be a missing cast_not_null() in an 1394 // intrinsic or support might be needed in AddPNode::Ideal() to 1395 // avoid a NULL+offset input. 1396 if (!(n->is_Phi() || 1397 (n->is_SafePoint() && (!n->is_CallRuntime() || !strcmp(n->as_Call()->_name, "g1_wb_pre") || !strcmp(n->as_Call()->_name, "unsafe_arraycopy"))) || 1398 n->Opcode() == Op_CmpP || 1399 n->Opcode() == Op_CmpN || 1400 (n->Opcode() == Op_StoreP && i == StoreNode::ValueIn) || 1401 (n->Opcode() == Op_StoreN && i == StoreNode::ValueIn) || 1402 n->is_ConstraintCast() || 1403 n->Opcode() == Op_Return || 1404 n->Opcode() == Op_Conv2B || 1405 n->is_AddP() || 1406 n->Opcode() == Op_CMoveP || 1407 n->Opcode() == Op_CMoveN || 1408 n->Opcode() == Op_Rethrow || 1409 n->is_MemBar() || 1410 n->is_Mem() || 1411 n->Opcode() == Op_AryEq || 1412 n->Opcode() == Op_SCMemProj || 1413 n->Opcode() == Op_EncodeP || 1414 n->Opcode() == Op_DecodeN)) { 1415 if (m->bottom_type()->make_oopptr() && m->bottom_type()->make_oopptr()->meet(TypePtr::NULL_PTR) == m->bottom_type()) { 1416 report_verify_failure("Shenandoah verification: null input", n, m); 1417 } 1418 } 1419 1420 wq.push(m); 1421 } 1422 } 1423 1424 if (verify_no_useless_barrier) { 1425 for (int i = 0; i < barriers.length(); i++) { 1426 Node* n = barriers.at(i); 1427 if (!barriers_used.member(n)) { 1428 tty->print("XXX useless barrier"); n->dump(-2); 1429 ShouldNotReachHere(); 1430 } 1431 } 1432 } 1433 } 1434 #endif 1435 1436 MergeMemNode* ShenandoahWriteBarrierNode::allocate_merge_mem(Node* mem, int alias, Node* rep_proj, Node* rep_ctrl, PhaseIdealLoop* phase) { 1437 MergeMemNode* mm = MergeMemNode::make(mem); 1438 mm->set_memory_at(alias, rep_proj); 1439 phase->register_new_node(mm, rep_ctrl); 1440 return mm; 1441 } 1442 1443 MergeMemNode* ShenandoahWriteBarrierNode::clone_merge_mem(Node* u, Node* mem, int alias, Node* rep_proj, Node* rep_ctrl, DUIterator& i, PhaseIdealLoop* phase) { 1444 MergeMemNode* newmm = NULL; 1445 MergeMemNode* u_mm = u->as_MergeMem(); 1446 Node* c = phase->get_ctrl(u); 1447 if (phase->is_dominator(c, rep_ctrl)) { 1448 c = rep_ctrl; 1449 } else { 1450 assert(phase->is_dominator(rep_ctrl, c), "one must dominate the other"); 1451 } 1452 if (u->outcnt() == 1) { 1453 if (u->req() > (uint)alias && u->in(alias) == mem) { 1454 phase->igvn().replace_input_of(u, alias, rep_proj); 1455 --i; 1456 } else { 1457 phase->igvn().rehash_node_delayed(u); 1458 u_mm->set_memory_at(alias, rep_proj); 1459 } 1460 newmm = u_mm; 1461 phase->set_ctrl_and_loop(u, c); 1462 } else { 1463 // can't simply clone u and then change one of its input because 1464 // it adds and then removes an edge which messes with the 1465 // DUIterator 1466 newmm = MergeMemNode::make(u_mm->base_memory()); 1467 for (uint j = 0; j < u->req(); j++) { 1468 if (j < newmm->req()) { 1469 if (j == (uint)alias) { 1470 newmm->set_req(j, rep_proj); 1471 } else if (newmm->in(j) != u->in(j)) { 1472 newmm->set_req(j, u->in(j)); 1473 } 1474 } else if (j == (uint)alias) { 1475 newmm->add_req(rep_proj); 1476 } else { 1477 newmm->add_req(u->in(j)); 1478 } 1479 } 1480 if ((uint)alias >= u->req()) { 1481 newmm->set_memory_at(alias, rep_proj); 1482 } 1483 phase->register_new_node(newmm, c); 1484 } 1485 return newmm; 1486 } 1487 1488 bool ShenandoahWriteBarrierNode::should_process_phi(Node* phi, int alias, Compile* C) { 1489 if (phi->adr_type() == TypePtr::BOTTOM) { 1490 Node* region = phi->in(0); 1491 for (DUIterator_Fast jmax, j = region->fast_outs(jmax); j < jmax; j++) { 1492 Node* uu = region->fast_out(j); 1493 if (uu->is_Phi() && uu != phi && uu->bottom_type() == Type::MEMORY && C->get_alias_index(uu->adr_type()) == alias) { 1494 return false; 1495 } 1496 } 1497 return true; 1498 } 1499 return C->get_alias_index(phi->adr_type()) == alias; 1500 } 1501 1502 bool ShenandoahBarrierNode::is_dominator_same_ctrl(Node*c, Node* d, Node* n, PhaseIdealLoop* phase) { 1503 // That both nodes have the same control is not sufficient to prove 1504 // domination, verify that there's no path from d to n 1505 ResourceMark rm; 1506 Unique_Node_List wq; 1507 wq.push(d); 1508 for (uint next = 0; next < wq.size(); next++) { 1509 Node *m = wq.at(next); 1510 if (m == n) { 1511 return false; 1512 } 1513 if (m->is_Phi() && m->in(0)->is_Loop()) { 1514 assert(phase->ctrl_or_self(m->in(LoopNode::EntryControl)) != c, "following loop entry should lead to new control"); 1515 } else { 1516 for (uint i = 0; i < m->req(); i++) { 1517 if (m->in(i) != NULL && phase->ctrl_or_self(m->in(i)) == c) { 1518 wq.push(m->in(i)); 1519 } 1520 } 1521 } 1522 } 1523 return true; 1524 } 1525 1526 bool ShenandoahBarrierNode::is_dominator(Node *d_c, Node *n_c, Node* d, Node* n, PhaseIdealLoop* phase) { 1527 if (d_c != n_c) { 1528 return phase->is_dominator(d_c, n_c); 1529 } 1530 return is_dominator_same_ctrl(d_c, d, n, phase); 1531 } 1532 1533 Node* next_mem(Node* mem, int alias) { 1534 Node* res = NULL; 1535 if (mem->is_Proj()) { 1536 res = mem->in(0); 1537 } else if (mem->is_SafePoint() || mem->is_MemBar()) { 1538 res = mem->in(TypeFunc::Memory); 1539 } else if (mem->is_Phi()) { 1540 res = mem->in(1); 1541 } else if (mem->is_ShenandoahBarrier()) { 1542 res = mem->in(ShenandoahBarrierNode::Memory); 1543 } else if (mem->is_MergeMem()) { 1544 res = mem->as_MergeMem()->memory_at(alias); 1545 } else if (mem->is_Store() || mem->is_LoadStore() || mem->is_ClearArray()) { 1546 assert(alias = Compile::AliasIdxRaw, "following raw memory can't lead to a barrier"); 1547 res = mem->in(MemNode::Memory); 1548 } else { 1549 #ifdef ASSERT 1550 mem->dump(); 1551 #endif 1552 ShouldNotReachHere(); 1553 } 1554 return res; 1555 } 1556 1557 bool suitable_mem(Node* mem, Node* old_mem, Node* rep_proj) { 1558 for (DUIterator_Fast imax, i = mem->fast_outs(imax); i < imax; i++) { 1559 Node* u = mem->fast_out(i); 1560 if (u->is_MergeMem()) { 1561 if (u->has_out_with(Op_MergeMem)) { 1562 // too complicated for now 1563 return false; 1564 } 1565 if (old_mem == u && rep_proj->has_out_with(Op_MergeMem)) { 1566 return false; 1567 } 1568 } 1569 if (u->Opcode() == Op_Unlock && mem->is_Proj() && mem->in(0)->Opcode() == Op_MemBarReleaseLock) { 1570 // would require a merge mem between unlock and the 1571 // preceding membar. Would confuse logic that eliminates 1572 // lock/unlock nodes. 1573 return false; 1574 } 1575 } 1576 return true; 1577 } 1578 1579 void ShenandoahWriteBarrierNode::fix_memory_uses(Node* mem, Node* replacement, Node* rep_proj, Node* rep_ctrl, int alias, PhaseIdealLoop* phase) { 1580 uint last =phase-> C->unique(); 1581 MergeMemNode* mm = NULL; 1582 assert(mem->bottom_type() == Type::MEMORY, ""); 1583 for (DUIterator i = mem->outs(); mem->has_out(i); i++) { 1584 Node* u = mem->out(i); 1585 if (u != replacement && u->_idx < last) { 1586 if (u->is_ShenandoahBarrier() && alias != Compile::AliasIdxRaw) { 1587 if (phase->C->get_alias_index(u->adr_type()) == alias && is_dominator(rep_ctrl, phase->ctrl_or_self(u), replacement, u, phase)) { 1588 phase->igvn().replace_input_of(u, u->find_edge(mem), rep_proj); 1589 assert(u->find_edge(mem) == -1, "only one edge"); 1590 --i; 1591 } 1592 } else if (u->is_Mem()) { 1593 if (phase->C->get_alias_index(u->adr_type()) == alias && is_dominator(rep_ctrl, phase->ctrl_or_self(u), replacement, u, phase)) { 1594 assert(alias == Compile::AliasIdxRaw , "only raw memory can lead to a memory operation"); 1595 phase->igvn().replace_input_of(u, u->find_edge(mem), rep_proj); 1596 assert(u->find_edge(mem) == -1, "only one edge"); 1597 --i; 1598 } 1599 } else if (u->is_MergeMem()) { 1600 MergeMemNode* u_mm = u->as_MergeMem(); 1601 if (u_mm->memory_at(alias) == mem) { 1602 MergeMemNode* newmm = NULL; 1603 for (DUIterator_Fast jmax, j = u->fast_outs(jmax); j < jmax; j++) { 1604 Node* uu = u->fast_out(j); 1605 assert(!uu->is_MergeMem(), "chain of MergeMems?"); 1606 if (uu->is_Phi()) { 1607 if (should_process_phi(uu, alias, phase->C)) { 1608 Node* region = uu->in(0); 1609 int nb = 0; 1610 for (uint k = 1; k < uu->req(); k++) { 1611 if (uu->in(k) == u && phase->is_dominator(rep_ctrl, region->in(k))) { 1612 if (newmm == NULL) { 1613 newmm = clone_merge_mem(u, mem, alias, rep_proj, rep_ctrl, i, phase); 1614 } 1615 if (newmm != u) { 1616 phase->igvn().replace_input_of(uu, k, newmm); 1617 nb++; 1618 --jmax; 1619 } 1620 } 1621 } 1622 if (nb > 0) { 1623 --j; 1624 } 1625 } 1626 } else { 1627 if (rep_ctrl != uu && is_dominator(rep_ctrl, phase->ctrl_or_self(uu), replacement, uu, phase)) { 1628 if (newmm == NULL) { 1629 newmm = clone_merge_mem(u, mem, alias, rep_proj, rep_ctrl, i, phase); 1630 } 1631 if (newmm != u) { 1632 phase->igvn().replace_input_of(uu, uu->find_edge(u), newmm); 1633 --j, --jmax; 1634 } 1635 } 1636 } 1637 } 1638 } 1639 } else if (u->is_Phi()) { 1640 assert(u->bottom_type() == Type::MEMORY, "what else?"); 1641 Node* region = u->in(0); 1642 if (should_process_phi(u, alias, phase->C)) { 1643 bool replaced = false; 1644 for (uint j = 1; j < u->req(); j++) { 1645 if (u->in(j) == mem && phase->is_dominator(rep_ctrl, region->in(j))) { 1646 Node* nnew = rep_proj; 1647 if (u->adr_type() == TypePtr::BOTTOM) { 1648 if (mm == NULL) { 1649 mm = allocate_merge_mem(mem, alias, rep_proj, rep_ctrl, phase); 1650 } 1651 nnew = mm; 1652 } 1653 phase->igvn().replace_input_of(u, j, nnew); 1654 replaced = true; 1655 } 1656 } 1657 if (replaced) { 1658 --i; 1659 } 1660 1661 } 1662 } else if ((u->adr_type() == TypePtr::BOTTOM && u->Opcode() != Op_StrInflatedCopy) || 1663 u->adr_type() == NULL) { 1664 assert(u->adr_type() != NULL || 1665 u->Opcode() == Op_Rethrow || 1666 u->Opcode() == Op_Return || 1667 u->Opcode() == Op_SafePoint || 1668 (u->is_CallStaticJava() && u->as_CallStaticJava()->uncommon_trap_request() != 0) || 1669 (u->is_CallStaticJava() && u->as_CallStaticJava()->_entry_point == OptoRuntime::rethrow_stub()) || 1670 u->Opcode() == Op_CallLeaf, ""); 1671 if (is_dominator(rep_ctrl, phase->ctrl_or_self(u), replacement, u, phase)) { 1672 if (mm == NULL) { 1673 mm = allocate_merge_mem(mem, alias, rep_proj, rep_ctrl, phase); 1674 } 1675 phase->igvn().replace_input_of(u, u->find_edge(mem), mm); 1676 --i; 1677 } 1678 } else if (phase->C->get_alias_index(u->adr_type()) == alias) { 1679 if (is_dominator(rep_ctrl, phase->ctrl_or_self(u), replacement, u, phase)) { 1680 phase->igvn().replace_input_of(u, u->find_edge(mem), rep_proj); 1681 --i; 1682 } 1683 } 1684 } 1685 } 1686 } 1687 1688 Node* ShenandoahBarrierNode::no_branches(Node* c, Node* dom, bool allow_one_proj, PhaseIdealLoop* phase) { 1689 Node* iffproj = NULL; 1690 while (c != dom) { 1691 Node* next = phase->idom(c); 1692 assert(next->unique_ctrl_out() == c || c->is_Proj() || c->is_Region(), "multiple control flow out but no proj or region?"); 1693 if (c->is_Region()) { 1694 ResourceMark rm; 1695 Unique_Node_List wq; 1696 wq.push(c); 1697 for (uint i = 0; i < wq.size(); i++) { 1698 Node *n = wq.at(i); 1699 if (n->is_Region()) { 1700 for (uint j = 1; j < n->req(); j++) { 1701 if (n->in(j) != next) { 1702 wq.push(n->in(j)); 1703 } 1704 } 1705 } else { 1706 if (n->in(0) != next) { 1707 wq.push(n->in(0)); 1708 } 1709 } 1710 } 1711 for (DUIterator_Fast imax, i = next->fast_outs(imax); i < imax; i++) { 1712 Node* u = next->fast_out(i); 1713 if (u->is_CFG()) { 1714 if (!wq.member(u)) { 1715 return NodeSentinel; 1716 } 1717 } 1718 } 1719 1720 } else if (c->is_Proj()) { 1721 if (c->is_IfProj()) { 1722 if (c->as_Proj()->is_uncommon_trap_if_pattern(Deoptimization::Reason_none) != NULL) { 1723 // continue; 1724 } else { 1725 if (!allow_one_proj) { 1726 return NodeSentinel; 1727 } 1728 if (iffproj == NULL) { 1729 iffproj = c; 1730 } else { 1731 return NodeSentinel; 1732 } 1733 } 1734 } else if (c->Opcode() == Op_JumpProj) { 1735 return NodeSentinel; // unsupported 1736 } else if (c->Opcode() == Op_CatchProj) { 1737 return NodeSentinel; // unsupported 1738 } else if (c->Opcode() == Op_CProj && next->Opcode() == Op_NeverBranch) { 1739 return NodeSentinel; // unsupported 1740 } else { 1741 assert(next->unique_ctrl_out() == c, "unsupported branch pattern"); 1742 } 1743 } 1744 c = next; 1745 } 1746 return iffproj; 1747 } 1748 1749 #ifdef ASSERT 1750 void ShenandoahWriteBarrierNode::memory_dominates_all_paths_helper(Node* c, Node* rep_ctrl, Unique_Node_List& controls, PhaseIdealLoop* phase) { 1751 const bool trace = false; 1752 if (trace) { tty->print("X control is"); c->dump(); } 1753 1754 uint start = controls.size(); 1755 controls.push(c); 1756 for (uint i = start; i < controls.size(); i++) { 1757 Node *n = controls.at(i); 1758 1759 if (trace) { tty->print("X from"); n->dump(); } 1760 1761 if (n == rep_ctrl) { 1762 continue; 1763 } 1764 1765 if (n->is_Proj()) { 1766 Node* n_dom = n->in(0); 1767 IdealLoopTree* n_dom_loop = phase->get_loop(n_dom); 1768 if (n->is_IfProj() && n_dom->outcnt() == 2) { 1769 n_dom_loop = phase->get_loop(n_dom->as_If()->proj_out(n->as_Proj()->_con == 0 ? 1 : 0)); 1770 } 1771 if (n_dom_loop != phase->ltree_root()) { 1772 Node* tail = n_dom_loop->tail(); 1773 if (tail->is_Region()) { 1774 for (uint j = 1; j < tail->req(); j++) { 1775 if (phase->is_dominator(n_dom, tail->in(j)) && !phase->is_dominator(n, tail->in(j))) { 1776 assert(phase->is_dominator(rep_ctrl, tail->in(j)), "why are we here?"); 1777 // entering loop from below, mark backedge 1778 if (trace) { tty->print("X pushing backedge"); tail->in(j)->dump(); } 1779 controls.push(tail->in(j)); 1780 //assert(n->in(0) == n_dom, "strange flow control"); 1781 } 1782 } 1783 } else if (phase->get_loop(n) != n_dom_loop && phase->is_dominator(n_dom, tail)) { 1784 // entering loop from below, mark backedge 1785 if (trace) { tty->print("X pushing backedge"); tail->dump(); } 1786 controls.push(tail); 1787 //assert(n->in(0) == n_dom, "strange flow control"); 1788 } 1789 } 1790 } 1791 1792 if (n->is_Loop()) { 1793 Node* c = n->in(LoopNode::EntryControl); 1794 if (trace) { tty->print("X pushing"); c->dump(); } 1795 controls.push(c); 1796 } else if (n->is_Region()) { 1797 for (uint i = 1; i < n->req(); i++) { 1798 Node* c = n->in(i); 1799 if (trace) { tty->print("X pushing"); c->dump(); } 1800 controls.push(c); 1801 } 1802 } else { 1803 Node* c = n->in(0); 1804 if (trace) { tty->print("X pushing"); c->dump(); } 1805 controls.push(c); 1806 } 1807 } 1808 } 1809 1810 bool ShenandoahWriteBarrierNode::memory_dominates_all_paths(Node* mem, Node* rep_ctrl, int alias, PhaseIdealLoop* phase) { 1811 const bool trace = false; 1812 if (trace) { 1813 tty->print("XXX mem is"); mem->dump(); 1814 tty->print("XXX rep ctrl is"); rep_ctrl->dump(); 1815 tty->print_cr("XXX alias is %d", alias); 1816 } 1817 ResourceMark rm; 1818 Unique_Node_List wq; 1819 Unique_Node_List controls; 1820 wq.push(mem); 1821 for (uint next = 0; next < wq.size(); next++) { 1822 Node *nn = wq.at(next); 1823 if (trace) { tty->print("XX from mem"); nn->dump(); } 1824 assert(nn->bottom_type() == Type::MEMORY, "memory only"); 1825 1826 if (nn->is_Phi()) { 1827 Node* r = nn->in(0); 1828 for (DUIterator_Fast jmax, j = r->fast_outs(jmax); j < jmax; j++) { 1829 Node* u = r->fast_out(j); 1830 if (u->is_Phi() && u->bottom_type() == Type::MEMORY && u != nn && 1831 (u->adr_type() == TypePtr::BOTTOM || phase->C->get_alias_index(u->adr_type()) == alias)) { 1832 if (trace) { tty->print("XX Next mem (other phi)"); u->dump(); } 1833 wq.push(u); 1834 } 1835 } 1836 } 1837 1838 for (DUIterator_Fast imax, i = nn->fast_outs(imax); i < imax; i++) { 1839 Node* use = nn->fast_out(i); 1840 1841 if (trace) { tty->print("XX use %p", use->adr_type()); use->dump(); } 1842 if (use->is_CFG()) { 1843 assert(use->in(TypeFunc::Memory) == nn, "bad cfg node"); 1844 Node* c = use->in(0); 1845 if (phase->is_dominator(rep_ctrl, c)) { 1846 memory_dominates_all_paths_helper(c, rep_ctrl, controls, phase); 1847 } else if (use->is_CallStaticJava() && use->as_CallStaticJava()->uncommon_trap_request() != 0 && c->is_Region()) { 1848 Node* region = c; 1849 if (trace) { tty->print("XX unc region"); region->dump(); } 1850 for (uint j = 1; j < region->req(); j++) { 1851 if (phase->is_dominator(rep_ctrl, region->in(j))) { 1852 if (trace) { tty->print("XX unc follows"); region->in(j)->dump(); } 1853 memory_dominates_all_paths_helper(region->in(j), rep_ctrl, controls, phase); 1854 } 1855 } 1856 } 1857 //continue; 1858 } else if (use->is_Phi()) { 1859 assert(use->bottom_type() == Type::MEMORY, "bad phi"); 1860 if ((use->adr_type() == TypePtr::BOTTOM /*&& !shenandoah_has_alias_phi(C, use, alias)*/) || 1861 phase->C->get_alias_index(use->adr_type()) == alias) { 1862 for (uint j = 1; j < use->req(); j++) { 1863 if (use->in(j) == nn) { 1864 Node* c = use->in(0)->in(j); 1865 if (phase->is_dominator(rep_ctrl, c)) { 1866 memory_dominates_all_paths_helper(c, rep_ctrl, controls, phase); 1867 } 1868 } 1869 } 1870 } 1871 // continue; 1872 } 1873 1874 if (use->is_MergeMem()) { 1875 if (use->as_MergeMem()->memory_at(alias) == nn) { 1876 if (trace) { tty->print("XX Next mem"); use->dump(); } 1877 // follow the memory edges 1878 wq.push(use); 1879 } 1880 } else if (use->is_Phi()) { 1881 assert(use->bottom_type() == Type::MEMORY, "bad phi"); 1882 if ((use->adr_type() == TypePtr::BOTTOM /*&& !shenandoah_has_alias_phi(C, use, alias)*/) || 1883 phase->C->get_alias_index(use->adr_type()) == alias) { 1884 if (trace) { tty->print("XX Next mem"); use->dump(); } 1885 // follow the memory edges 1886 wq.push(use); 1887 } 1888 } else if (use->bottom_type() == Type::MEMORY && 1889 (use->adr_type() == TypePtr::BOTTOM || phase->C->get_alias_index(use->adr_type()) == alias)) { 1890 if (trace) { tty->print("XX Next mem"); use->dump(); } 1891 // follow the memory edges 1892 wq.push(use); 1893 } else if ((use->is_SafePoint() || use->is_MemBar()) && 1894 (use->adr_type() == TypePtr::BOTTOM || phase->C->get_alias_index(use->adr_type()) == alias)) { 1895 for (DUIterator_Fast jmax, j = use->fast_outs(jmax); j < jmax; j++) { 1896 Node* u = use->fast_out(j); 1897 if (u->bottom_type() == Type::MEMORY) { 1898 if (trace) { tty->print("XX Next mem"); u->dump(); } 1899 // follow the memory edges 1900 wq.push(u); 1901 } 1902 } 1903 } else if (use->Opcode() == Op_ShenandoahWriteBarrier && phase->C->get_alias_index(use->adr_type()) == alias) { 1904 Node* m = use->find_out_with(Op_ShenandoahWBMemProj); 1905 if (m != NULL) { 1906 if (trace) { tty->print("XX Next mem"); m->dump(); } 1907 // follow the memory edges 1908 wq.push(m); 1909 } 1910 } 1911 } 1912 } 1913 1914 if (controls.size() == 0) { 1915 return false; 1916 } 1917 1918 for (uint i = 0; i < controls.size(); i++) { 1919 Node *n = controls.at(i); 1920 1921 if (trace) { tty->print("X checking"); n->dump(); } 1922 1923 if (n->unique_ctrl_out() != NULL) { 1924 continue; 1925 } 1926 1927 if (n->Opcode() == Op_NeverBranch) { 1928 Node* taken = n->as_Multi()->proj_out(0); 1929 if (!controls.member(taken)) { 1930 if (trace) { tty->print("X not seen"); taken->dump(); } 1931 return false; 1932 } 1933 continue; 1934 } 1935 1936 for (DUIterator_Fast jmax, j = n->fast_outs(jmax); j < jmax; j++) { 1937 Node* u = n->fast_out(j); 1938 1939 if (u->is_CFG()) { 1940 if (!controls.member(u)) { 1941 if (u->is_Proj() && u->as_Proj()->is_uncommon_trap_proj(Deoptimization::Reason_none)) { 1942 if (trace) { tty->print("X not seen but unc"); u->dump(); } 1943 } else { 1944 Node* c = u; 1945 do { 1946 c = c->unique_ctrl_out(); 1947 } while (c != NULL && c->is_Region()); 1948 if (c != NULL && c->Opcode() == Op_Halt) { 1949 if (trace) { tty->print("X not seen but halt"); c->dump(); } 1950 } else { 1951 if (trace) { tty->print("X not seen"); u->dump(); } 1952 return false; 1953 } 1954 } 1955 } else { 1956 if (trace) { tty->print("X seen"); u->dump(); } 1957 } 1958 } 1959 } 1960 } 1961 return true; 1962 } 1963 #endif 1964 1965 static bool has_mem_phi(Compile* C, Node* region, int alias) { 1966 for (DUIterator_Fast imax, i = region->fast_outs(imax); i < imax; i++) { 1967 Node* use = region->fast_out(i); 1968 if (use->is_Phi() && use->bottom_type() == Type::MEMORY && 1969 (C->get_alias_index(use->adr_type()) == alias)) { 1970 return true; 1971 } 1972 } 1973 return false; 1974 } 1975 1976 bool ShenandoahWriteBarrierNode::fix_mem_phis_helper(Node* c, Node* mem, Node* mem_ctrl, Node* rep_ctrl, int alias, VectorSet& controls, GrowableArray<Node*>& regions, PhaseIdealLoop* phase) { 1977 const bool trace = false; 1978 Node_List wq; 1979 wq.push(c); 1980 1981 #ifdef ASSERT 1982 if (trace) { tty->print("YYY from"); c->dump(); } 1983 if (trace) { tty->print("YYY with mem"); mem->dump(); } 1984 #endif 1985 1986 while(wq.size() > 0) { 1987 c = wq.pop(); 1988 1989 while (!c->is_Region() || c->is_Loop()) { 1990 #ifdef ASSERT 1991 if (trace) { tty->print("YYY"); c->dump(); } 1992 #endif 1993 assert(c->is_CFG(), "node should be control node"); 1994 if (c == mem_ctrl || phase->is_dominator(c, rep_ctrl)) { 1995 c = NULL; 1996 break; 1997 } else if (c->is_Loop()) { 1998 c = c->in(LoopNode::EntryControl); 1999 } else { 2000 c = c->in(0); 2001 } 2002 } 2003 if (c == NULL) { 2004 continue; 2005 } 2006 2007 #ifdef ASSERT 2008 if (trace) { tty->print("YYY new region"); c->dump(); } 2009 #endif 2010 2011 bool has_phi = has_mem_phi(phase->C, c, alias); 2012 if (!has_phi) { 2013 2014 Node* m_ctrl = NULL; 2015 Node* m = dom_mem(mem, c, alias, m_ctrl, phase); 2016 if (m == NULL) { 2017 return false; 2018 } 2019 2020 #ifdef ASSERT 2021 if (trace) { tty->print("YYY mem "); m->dump(); } 2022 #endif 2023 2024 if (controls.test(c->_idx)) { 2025 int i; 2026 for (i = 0; i < regions.length() && regions.at(i) != c; i+=2) { 2027 // deliberately empty, rolling over the regions 2028 } 2029 assert(i < regions.length(), "missing region"); 2030 Node* prev_m = regions.at(i+1); 2031 if (prev_m == m) { 2032 continue; 2033 } 2034 #ifdef ASSERT 2035 if (trace) { tty->print("YYY prev mem "); prev_m->dump(); } 2036 #endif 2037 Node* prev_m_ctrl = phase->ctrl_or_self(prev_m); 2038 assert(is_dominator(m_ctrl, prev_m_ctrl, m, prev_m, phase) || 2039 is_dominator(prev_m_ctrl, m_ctrl, prev_m, m, phase), "one should dominate the other"); 2040 if (is_dominator(m_ctrl, prev_m_ctrl, m, prev_m, phase)) { 2041 continue; 2042 } 2043 #ifdef ASSERT 2044 if (trace) { tty->print("YYY Fixing "); c->dump(); } 2045 #endif 2046 regions.at_put(i+1, m); 2047 } else { 2048 #ifdef ASSERT 2049 if (trace) { tty->print("YYY Pushing "); c->dump(); } 2050 #endif 2051 regions.push(c); 2052 regions.push(m); 2053 } 2054 } else { 2055 continue; 2056 } 2057 2058 controls.set(c->_idx); 2059 2060 for (uint i = 1; i < c->req(); i++) { 2061 wq.push(c->in(i)); 2062 } 2063 } 2064 return true; 2065 } 2066 2067 2068 bool ShenandoahWriteBarrierNode::fix_mem_phis(Node* mem, Node* mem_ctrl, Node* rep_ctrl, int alias, PhaseIdealLoop* phase) { 2069 GrowableArray<Node*> regions; 2070 VectorSet controls(Thread::current()->resource_area()); 2071 const bool trace = false; 2072 2073 #ifdef ASSERT 2074 if (trace) { tty->print("YYY mem is "); mem->dump(); } 2075 if (trace) { tty->print("YYY mem ctrl is "); mem_ctrl->dump(); } 2076 if (trace) { tty->print("YYY rep ctrl is "); rep_ctrl->dump(); } 2077 if (trace) { tty->print_cr("YYY alias is %d", alias); } 2078 #endif 2079 2080 // Walk memory edges from mem until we hit a memory point where 2081 // control is known then follow the control up looking for regions 2082 // with no memory Phi for alias 2083 Unique_Node_List wq; 2084 wq.push(mem); 2085 2086 for (uint next = 0; next < wq.size(); next++) { 2087 Node *n = wq.at(next); 2088 #ifdef ASSERT 2089 if (trace) { tty->print("YYY from (2) "); n->dump(); } 2090 #endif 2091 for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) { 2092 Node* u = n->fast_out(i); 2093 #ifdef ASSERT 2094 if (trace) { tty->print("YYY processing "); u->dump(); } 2095 #endif 2096 if (u->is_Phi()) { 2097 assert(u->bottom_type() == Type::MEMORY, "strange memory graph"); 2098 if (should_process_phi(u, alias, phase->C)) { 2099 for (uint j = 1; j < u->req(); j++) { 2100 if (u->in(j) == n) { 2101 Node *c = u->in(0)->in(j); 2102 if (!fix_mem_phis_helper(c, n, mem_ctrl, rep_ctrl, alias, controls, regions, phase)) { 2103 return false; 2104 } 2105 } 2106 } 2107 } 2108 #ifdef ASSERT 2109 } else if (u->is_CallStaticJava() && u->as_CallStaticJava()->uncommon_trap_request() != 0) { 2110 if (!fix_mem_phis_helper(u->in(0), n, mem_ctrl, rep_ctrl, alias, controls, regions, phase)) { 2111 return false; 2112 } 2113 #endif 2114 } else if ((u->is_CFG() && u->adr_type() == TypePtr::BOTTOM) || u->Opcode() == Op_Rethrow || u->Opcode() == Op_Return) { 2115 if (!fix_mem_phis_helper(u->in(0), n, mem_ctrl, rep_ctrl, alias, controls, regions, phase)) { 2116 return false; 2117 } 2118 } else if (u->is_MergeMem() && u->as_MergeMem()->memory_at(alias) == n) { 2119 wq.push(u); 2120 } else if (u->Opcode() == Op_ShenandoahWriteBarrier && phase->C->get_alias_index(u->adr_type()) == alias) { 2121 Node* m = u->find_out_with(Op_ShenandoahWBMemProj); 2122 if (m != NULL) { 2123 wq.push(m); 2124 } 2125 } 2126 } 2127 } 2128 #ifdef ASSERT 2129 if (trace) { 2130 tty->print_cr("XXXXXXXXXXXXXXXXXXXX"); 2131 for (int i = 0; i < regions.length(); i++) { 2132 Node* r = regions.at(i); 2133 tty->print("%d", i); r->dump(); 2134 } 2135 tty->print_cr("XXXXXXXXXXXXXXXXXXXX"); 2136 } 2137 #endif 2138 2139 if (regions.length() == 0) { 2140 return true; 2141 } 2142 2143 { 2144 int i = 0; 2145 for (; i < regions.length(); i+=2) { 2146 Node* region = regions.at(i); 2147 bool has_phi = false; 2148 for (DUIterator_Fast jmax, j = region->fast_outs(jmax); j < jmax && !has_phi; j++) { 2149 Node* u = region->fast_out(j); 2150 if (u->is_Phi() && u->bottom_type() == Type::MEMORY && 2151 (u->adr_type() == TypePtr::BOTTOM || phase->C->get_alias_index(u->adr_type()) == alias)) { 2152 has_phi = true; 2153 } 2154 } 2155 if (!has_phi) { 2156 break; 2157 } 2158 } 2159 if (i == regions.length()) { 2160 return true; 2161 } 2162 } 2163 2164 // Try to restrict the update to path that post dominates rep_ctrl 2165 int k = 0; 2166 int start = 0; 2167 int end = 0; 2168 do { 2169 start = end; 2170 end = k; 2171 for (int i = end; i < regions.length(); i+=2) { 2172 Node* r = regions.at(i); 2173 int prev = k; 2174 for (uint j = 1; j < r->req() && prev == k; j++) { 2175 if (end == 0) { 2176 if (phase->is_dominator(rep_ctrl, r->in(j))) { 2177 Node* mem = regions.at(i+1); 2178 regions.at_put(i, regions.at(k)); 2179 regions.at_put(i+1, regions.at(k+1)); 2180 regions.at_put(k, r); 2181 regions.at_put(k+1, mem); 2182 k+=2; 2183 } 2184 } else { 2185 for (int l = start; l < end && prev == k; l+=2) { 2186 Node* r2 = regions.at(l); 2187 if (phase->is_dominator(r2, r->in(j))) { 2188 Node* mem = regions.at(i+1); 2189 regions.at_put(i, regions.at(k)); 2190 regions.at_put(i+1, regions.at(k+1)); 2191 regions.at_put(k, r); 2192 regions.at_put(k+1, mem); 2193 k+=2; 2194 } 2195 } 2196 } 2197 } 2198 } 2199 #ifdef ASSERT 2200 if (trace) { tty->print_cr("k = %d start = %d end = %d", k, start, end); } 2201 #endif 2202 } while(k != end); 2203 2204 #ifdef ASSERT 2205 if (end != regions.length()) { 2206 if (trace) { tty->print_cr("Compacting %d -> %d", regions.length(), end); } 2207 } 2208 #endif 2209 regions.trunc_to(end); 2210 2211 #ifdef ASSERT 2212 if (trace) { 2213 tty->print_cr("XXXXXXXXXXXXXXXXXXXX"); 2214 for (int i = 0; i < regions.length(); i++) { 2215 Node* r = regions.at(i); 2216 tty->print("%d", i); r->dump(); 2217 } 2218 tty->print_cr("XXXXXXXXXXXXXXXXXXXX"); 2219 } 2220 #endif 2221 2222 // Creating new phis must be done in post order 2223 while (regions.length() > 0) { 2224 int i = 0; 2225 for (; i < regions.length(); i+=2) { 2226 Node* r1 = regions.at(i); 2227 bool is_dom = false; 2228 for (int j = 0; j < regions.length() && !is_dom; j+=2) { 2229 if (i != j) { 2230 Node* r2 = regions.at(j); 2231 for (uint k = 1; k < r2->req() && !is_dom; k++) { 2232 if (phase->is_dominator(r1, r2->in(k))) { 2233 is_dom = true; 2234 } 2235 } 2236 } 2237 } 2238 if (!is_dom) { 2239 break; 2240 } 2241 } 2242 assert(i < regions.length(), "need one"); 2243 Node* r = regions.at(i); 2244 Node* m = regions.at(i+1); 2245 regions.delete_at(i+1); 2246 regions.delete_at(i); 2247 2248 if (!suitable_mem(m, NULL, NULL)) { 2249 return false; 2250 } 2251 Node* phi = PhiNode::make(r, m, Type::MEMORY, phase->C->get_adr_type(alias)); 2252 #ifdef ASSERT 2253 if (trace) { tty->print("YYY Adding new mem phi "); phi->dump(); } 2254 #endif 2255 phase->register_new_node(phi, r); 2256 2257 fix_memory_uses(m, phi, phi, r, phase->C->get_alias_index(phi->adr_type()), phase); 2258 assert(phi->outcnt() != 0, "new proj should have uses"); 2259 if (phi->outcnt() == 0) { 2260 phase->igvn().remove_dead_node(phi); 2261 } 2262 } 2263 2264 return true; 2265 } 2266 2267 Node* ShenandoahBarrierNode::dom_mem(Node* mem, Node*& mem_ctrl, Node* n, Node* rep_ctrl, int alias, PhaseIdealLoop* phase) { 2268 ResourceMark rm; 2269 VectorSet wq(Thread::current()->resource_area()); 2270 wq.set(mem->_idx); 2271 mem_ctrl = phase->get_ctrl(mem); 2272 while (!is_dominator(mem_ctrl, rep_ctrl, mem, n, phase)) { 2273 mem = next_mem(mem, alias); 2274 if (wq.test_set(mem->_idx)) { 2275 return NULL; // hit an unexpected loop 2276 } 2277 mem_ctrl = phase->ctrl_or_self(mem); 2278 } 2279 if (mem->is_MergeMem()) { 2280 mem = mem->as_MergeMem()->memory_at(alias); 2281 mem_ctrl = phase->ctrl_or_self(mem); 2282 } 2283 return mem; 2284 } 2285 2286 Node* ShenandoahBarrierNode::dom_mem(Node* mem, Node* ctrl, int alias, Node*& mem_ctrl, PhaseIdealLoop* phase) { 2287 ResourceMark rm; 2288 VectorSet wq(Thread::current()->resource_area()); 2289 wq.set(mem->_idx); 2290 mem_ctrl = phase->ctrl_or_self(mem); 2291 while (!phase->is_dominator(mem_ctrl, ctrl) || mem_ctrl == ctrl) { 2292 mem = next_mem(mem, alias); 2293 if (wq.test_set(mem->_idx)) { 2294 return NULL; 2295 } 2296 mem_ctrl = phase->ctrl_or_self(mem); 2297 } 2298 if (mem->is_MergeMem()) { 2299 mem = mem->as_MergeMem()->memory_at(alias); 2300 mem_ctrl = phase->ctrl_or_self(mem); 2301 } 2302 return mem; 2303 } 2304 2305 Node* ShenandoahBarrierNode::try_common(Node *n_ctrl, PhaseIdealLoop* phase) { 2306 if (!phase->C->has_irreducible_loop()) { 2307 // We look for a write barrier whose memory edge dominates n 2308 // Either the replacement write barrier dominates n or we have, 2309 // for instance: 2310 // if ( ) { 2311 // read barrier n 2312 // } else { 2313 // write barrier 2314 // } 2315 // in which case replacing n by the write barrier causes the write 2316 // barrier to move above the if() and the memory Phi that merges 2317 // the memory state for both branches must be updated so both 2318 // inputs become the write barrier's memory projection (and the 2319 // Phi is optimized out) otherwise we risk loosing a memory 2320 // dependency. 2321 // Once we find a replacement write barrier, the code below fixes 2322 // the memory graph in cases like the one above. 2323 Node* val = in(ValueIn); 2324 Node* val_ctrl = phase->get_ctrl(val); 2325 Node* n_proj = find_out_with(Op_ShenandoahWBMemProj); 2326 Node* replacement = NULL; 2327 int alias = phase->C->get_alias_index(adr_type()); 2328 Node* rep_ctrl = NULL; 2329 for (DUIterator_Fast imax, i = val->fast_outs(imax); i < imax && replacement == NULL; i++) { 2330 Node* u = val->fast_out(i); 2331 if (u != this && u->Opcode() == Op_ShenandoahWriteBarrier) { 2332 Node* u_mem = u->in(Memory); 2333 Node* u_proj = u->find_out_with(Op_ShenandoahWBMemProj); 2334 Node* u_ctrl = phase->get_ctrl(u); 2335 Node* u_mem_ctrl = phase->get_ctrl(u_mem); 2336 IdealLoopTree* n_loop = phase->get_loop(n_ctrl); 2337 IdealLoopTree* u_loop = phase->get_loop(u_ctrl); 2338 2339 Node* ctrl = phase->dom_lca(u_ctrl, n_ctrl); 2340 2341 if (ctrl->is_Proj() && 2342 ctrl->in(0)->is_Call() && 2343 ctrl->unique_ctrl_out() != NULL && 2344 ctrl->unique_ctrl_out()->Opcode() == Op_Catch && 2345 !phase->is_dominator(val_ctrl, ctrl->in(0)->in(0))) { 2346 continue; 2347 } 2348 2349 if (Opcode() == Op_ShenandoahWriteBarrier && u_proj == NULL && n_proj != NULL) { 2350 continue; 2351 } 2352 2353 IdealLoopTree* loop = phase->get_loop(ctrl); 2354 2355 // We don't want to move a write barrier in a loop 2356 // If the LCA is in a inner loop, try a control out of loop if possible 2357 bool loop_ok = true; 2358 while (!loop->is_member(u_loop) && (Opcode() != Op_ShenandoahWriteBarrier || !loop->is_member(n_loop))) { 2359 ctrl = phase->idom(ctrl); 2360 if (ctrl != val_ctrl && phase->is_dominator(ctrl, val_ctrl)) { 2361 loop_ok = false; 2362 break; 2363 } 2364 loop = phase->get_loop(ctrl); 2365 } 2366 2367 if (loop_ok) { 2368 if (ShenandoahDontIncreaseWBFreq) { 2369 Node* u_iffproj = no_branches(u_ctrl, ctrl, true, phase); 2370 if (Opcode() == Op_ShenandoahWriteBarrier) { 2371 Node* n_iffproj = no_branches(n_ctrl, ctrl, true, phase); 2372 if (u_iffproj == NULL || n_iffproj == NULL) { 2373 replacement = u; 2374 rep_ctrl = ctrl; 2375 } else if (u_iffproj != NodeSentinel && n_iffproj != NodeSentinel && u_iffproj->in(0) == n_iffproj->in(0)) { 2376 replacement = u; 2377 rep_ctrl = ctrl; 2378 } 2379 } else if (u_iffproj == NULL) { 2380 replacement = u; 2381 rep_ctrl = ctrl; 2382 } 2383 } else { 2384 replacement = u; 2385 rep_ctrl = ctrl; 2386 } 2387 } 2388 } 2389 } 2390 if (replacement != NULL) { 2391 if (rep_ctrl->is_Proj() && 2392 rep_ctrl->in(0)->is_Call() && 2393 rep_ctrl->unique_ctrl_out() != NULL && 2394 rep_ctrl->unique_ctrl_out()->Opcode() == Op_Catch) { 2395 rep_ctrl = rep_ctrl->in(0)->in(0); 2396 assert(phase->is_dominator(val_ctrl, rep_ctrl), "bad control"); 2397 } else { 2398 LoopNode* c = ShenandoahWriteBarrierNode::try_move_before_pre_loop(rep_ctrl, val_ctrl, phase); 2399 if (c != NULL) { 2400 rep_ctrl = ShenandoahWriteBarrierNode::move_above_predicates(c, val_ctrl, phase); 2401 } else { 2402 while (rep_ctrl->is_IfProj()) { 2403 CallStaticJavaNode* unc = rep_ctrl->as_Proj()->is_uncommon_trap_if_pattern(Deoptimization::Reason_none); 2404 if (unc != NULL) { 2405 int req = unc->uncommon_trap_request(); 2406 Deoptimization::DeoptReason trap_reason = Deoptimization::trap_request_reason(req); 2407 if ((trap_reason == Deoptimization::Reason_loop_limit_check || 2408 trap_reason == Deoptimization::Reason_predicate || 2409 trap_reason == Deoptimization::Reason_profile_predicate) && 2410 phase->is_dominator(val_ctrl, rep_ctrl->in(0)->in(0))) { 2411 rep_ctrl = rep_ctrl->in(0)->in(0); 2412 continue; 2413 } 2414 } 2415 break; 2416 } 2417 } 2418 } 2419 2420 Node* mem = replacement->in(Memory); 2421 Node* old_mem = mem; 2422 Node* rep_proj = replacement->find_out_with(Op_ShenandoahWBMemProj); 2423 { 2424 Node* mem_ctrl = NULL; 2425 2426 mem = dom_mem(mem, mem_ctrl, this, rep_ctrl, alias, phase); 2427 if (mem == NULL) { 2428 return NULL; 2429 } 2430 2431 // Add a memory Phi for the slice of the write barrier to any 2432 // region that post dominates rep_ctrl and doesn't have one 2433 // already. 2434 if (rep_proj != NULL && !ShenandoahWriteBarrierNode::fix_mem_phis(mem, mem_ctrl, rep_ctrl, alias, phase)) { 2435 return NULL; 2436 } 2437 2438 assert(!ShenandoahVerifyOptoBarriers || ShenandoahWriteBarrierNode::memory_dominates_all_paths(mem, rep_ctrl, alias, phase), "can't fix the memory graph"); 2439 } 2440 assert(phase->igvn().type(mem) == Type::MEMORY, "not memory"); 2441 2442 if (rep_proj != NULL) { 2443 Node* old_mem = replacement->in(Memory); 2444 if (!suitable_mem(mem, old_mem, rep_proj)) { 2445 return NULL; 2446 } 2447 2448 if (replacement->in(Memory) != mem) { 2449 // tty->print("XXX setting memory of"); replacement->dump(); 2450 // tty->print("XXX to"); mem->dump(); 2451 for (DUIterator_Last imin, i = rep_proj->last_outs(imin); i >= imin; ) { 2452 Node* u = rep_proj->last_out(i); 2453 phase->igvn().rehash_node_delayed(u); 2454 int uses_found = u->replace_edge(rep_proj, old_mem); 2455 i -= uses_found; 2456 } 2457 phase->igvn().replace_input_of(replacement, Memory, mem); 2458 } 2459 phase->set_ctrl_and_loop(replacement, rep_ctrl); 2460 phase->igvn().replace_input_of(replacement, Control, rep_ctrl); 2461 2462 ShenandoahWriteBarrierNode::fix_memory_uses(mem, replacement, rep_proj, rep_ctrl, phase->C->get_alias_index(replacement->adr_type()), phase); 2463 assert(rep_proj->outcnt() != 0, "new proj should have uses"); 2464 } else { 2465 if (replacement->in(Memory) != mem) { 2466 phase->igvn()._worklist.push(replacement->in(Memory)); 2467 phase->igvn().replace_input_of(replacement, Memory, mem); 2468 } 2469 phase->set_ctrl_and_loop(replacement, rep_ctrl); 2470 phase->igvn().replace_input_of(replacement, Control, rep_ctrl); 2471 } 2472 if (Opcode() == Op_ShenandoahWriteBarrier) { 2473 if (n_proj != NULL) { 2474 phase->lazy_replace(n_proj, in(Memory)); 2475 } 2476 } 2477 phase->lazy_replace(this, replacement); 2478 if (rep_proj != NULL) { 2479 phase->set_ctrl_and_loop(rep_proj, rep_ctrl); 2480 } 2481 return replacement; 2482 } 2483 } 2484 2485 return NULL; 2486 } 2487 2488 const TypePtr* ShenandoahBarrierNode::fix_addp_type(const TypePtr* res, Node* base) { 2489 if (UseShenandoahGC && ShenandoahBarriersForConst) { 2490 // With barriers on constant oops, if a field being accessed is a 2491 // static field, correct alias analysis requires that we look 2492 // beyond the barriers (that hide the constant) to find the actual 2493 // java class mirror constant. 2494 const TypeInstPtr* ti = res->isa_instptr(); 2495 if (ti != NULL && 2496 ti->const_oop() == NULL && 2497 ti->klass() == ciEnv::current()->Class_klass() && 2498 ti->offset() >= (ti->klass()->as_instance_klass()->size_helper() * wordSize)) { 2499 ResourceMark rm; 2500 Unique_Node_List wq; 2501 ciObject* const_oop = NULL; 2502 wq.push(base); 2503 for (uint i = 0; i < wq.size(); i++) { 2504 Node *n = wq.at(i); 2505 if (n->is_ShenandoahBarrier() || 2506 (n->is_Mach() && n->as_Mach()->ideal_Opcode() == Op_ShenandoahReadBarrier)) { 2507 Node* m = n->in(ShenandoahBarrierNode::ValueIn); 2508 if (m != NULL) { 2509 wq.push(m); 2510 } 2511 } else if (n->is_Phi()) { 2512 for (uint j = 1; j < n->req(); j++) { 2513 Node* m = n->in(j); 2514 if (m != NULL) { 2515 wq.push(m); 2516 } 2517 } 2518 } else if (n->is_ConstraintCast() || (n->is_Mach() && n->as_Mach()->ideal_Opcode() == Op_CheckCastPP)) { 2519 Node* m = n->in(1); 2520 if (m != NULL) { 2521 wq.push(m); 2522 } 2523 } else { 2524 const TypeInstPtr* tn = n->bottom_type()->isa_instptr(); 2525 if (tn != NULL) { 2526 if (tn->const_oop() != NULL) { 2527 if (const_oop == NULL) { 2528 const_oop = tn->const_oop(); 2529 } else if (const_oop != tn->const_oop()) { 2530 const_oop = NULL; 2531 break; 2532 } 2533 } else { 2534 if (n->is_Proj()) { 2535 if (n->in(0)->Opcode() == Op_CallLeafNoFP) { 2536 if (n->in(0)->as_Call()->entry_point() != ShenandoahBarrierSetAssembler::shenandoah_wb_C()) { 2537 const_oop = NULL; 2538 break; 2539 } 2540 } else if (n->in(0)->is_MachCallLeaf()) { 2541 if (n->in(0)->as_MachCall()->entry_point() != ShenandoahBarrierSetAssembler::shenandoah_wb_C()) { 2542 const_oop = NULL; 2543 break; 2544 } 2545 } 2546 } else { 2547 fatal("2 different static fields being accessed with a single AddP"); 2548 const_oop = NULL; 2549 break; 2550 } 2551 } 2552 } else { 2553 assert(n->bottom_type() == Type::TOP, "not an instance ptr?"); 2554 } 2555 } 2556 } 2557 if (const_oop != NULL) { 2558 res = ti->cast_to_const(const_oop); 2559 } 2560 } 2561 } 2562 return res; 2563 } 2564 2565 static void disconnect_barrier_mem(Node* wb, PhaseIterGVN& igvn) { 2566 Node* mem_in = wb->in(ShenandoahBarrierNode::Memory); 2567 Node* proj = wb->find_out_with(Op_ShenandoahWBMemProj); 2568 2569 for (DUIterator_Last imin, i = proj->last_outs(imin); i >= imin; ) { 2570 Node* u = proj->last_out(i); 2571 igvn.rehash_node_delayed(u); 2572 int nb = u->replace_edge(proj, mem_in); 2573 assert(nb > 0, "no replacement?"); 2574 i -= nb; 2575 } 2576 } 2577 2578 Node* ShenandoahWriteBarrierNode::move_above_predicates(LoopNode* cl, Node* val_ctrl, PhaseIdealLoop* phase) { 2579 Node* entry = cl->skip_strip_mined()->in(LoopNode::EntryControl); 2580 Node* above_pred = phase->skip_all_loop_predicates(entry); 2581 Node* ctrl = entry; 2582 while (ctrl != above_pred) { 2583 Node* next = ctrl->in(0); 2584 if (!phase->is_dominator(val_ctrl, next)) { 2585 break; 2586 } 2587 ctrl = next; 2588 } 2589 return ctrl; 2590 } 2591 2592 Node* ShenandoahWriteBarrierNode::try_move_before_loop_helper(LoopNode* cl, Node* val_ctrl, Node* mem, PhaseIdealLoop* phase) { 2593 assert(cl->is_Loop(), "bad control"); 2594 Node* ctrl = move_above_predicates(cl, val_ctrl, phase); 2595 Node* mem_ctrl = NULL; 2596 int alias = phase->C->get_alias_index(adr_type()); 2597 mem = dom_mem(mem, mem_ctrl, this, ctrl, alias, phase); 2598 if (mem == NULL) { 2599 return NULL; 2600 } 2601 2602 Node* old_mem = in(Memory); 2603 Node* proj = find_out_with(Op_ShenandoahWBMemProj); 2604 if (old_mem != mem && !suitable_mem(mem, old_mem, proj)) { 2605 return NULL; 2606 } 2607 2608 assert(!ShenandoahVerifyOptoBarriers || memory_dominates_all_paths(mem, ctrl, alias, phase), "can't fix the memory graph"); 2609 phase->set_ctrl_and_loop(this, ctrl); 2610 phase->igvn().replace_input_of(this, Control, ctrl); 2611 if (old_mem != mem) { 2612 if (proj != NULL) { 2613 disconnect_barrier_mem(this, phase->igvn()); 2614 fix_memory_uses(mem, this, proj, ctrl, phase->C->get_alias_index(adr_type()), phase); 2615 assert(proj->outcnt() > 0, "disconnected write barrier"); 2616 } 2617 phase->igvn().replace_input_of(this, Memory, mem); 2618 } 2619 if (proj != NULL) { 2620 phase->set_ctrl_and_loop(proj, ctrl); 2621 } 2622 return this; 2623 } 2624 2625 LoopNode* ShenandoahWriteBarrierNode::try_move_before_pre_loop(Node* c, Node* val_ctrl, PhaseIdealLoop* phase) { 2626 // A write barrier between a pre and main loop can get in the way of 2627 // vectorization. Move it above the pre loop if possible 2628 CountedLoopNode* cl = NULL; 2629 if (c->is_IfFalse() && 2630 c->in(0)->is_CountedLoopEnd()) { 2631 cl = c->in(0)->as_CountedLoopEnd()->loopnode(); 2632 } else if (c->is_IfProj() && 2633 c->in(0)->is_If() && 2634 c->in(0)->in(0)->is_IfFalse() && 2635 c->in(0)->in(0)->in(0)->is_CountedLoopEnd()) { 2636 cl = c->in(0)->in(0)->in(0)->as_CountedLoopEnd()->loopnode(); 2637 } 2638 if (cl != NULL && 2639 cl->is_pre_loop() && 2640 val_ctrl != cl && 2641 phase->is_dominator(val_ctrl, cl)) { 2642 return cl; 2643 } 2644 return NULL; 2645 } 2646 2647 Node* ShenandoahWriteBarrierNode::try_move_before_loop(Node *n_ctrl, PhaseIdealLoop* phase) { 2648 IdealLoopTree *n_loop = phase->get_loop(n_ctrl); 2649 Node* val = in(ValueIn); 2650 Node* val_ctrl = phase->get_ctrl(val); 2651 if (n_loop != phase->ltree_root() && !n_loop->_irreducible) { 2652 IdealLoopTree *val_loop = phase->get_loop(val_ctrl); 2653 Node* mem = in(Memory); 2654 IdealLoopTree *mem_loop = phase->get_loop(phase->get_ctrl(mem)); 2655 if (!n_loop->is_member(val_loop) && 2656 n_loop->is_member(mem_loop)) { 2657 Node* n_loop_head = n_loop->_head; 2658 2659 if (n_loop_head->is_Loop()) { 2660 LoopNode* loop = n_loop_head->as_Loop(); 2661 if (n_loop_head->is_CountedLoop() && n_loop_head->as_CountedLoop()->is_main_loop()) { 2662 LoopNode* res = try_move_before_pre_loop(n_loop_head->in(LoopNode::EntryControl), val_ctrl, phase); 2663 if (res != NULL) { 2664 loop = res; 2665 } 2666 } 2667 2668 return try_move_before_loop_helper(loop, val_ctrl, mem, phase); 2669 } 2670 } 2671 } 2672 LoopNode* ctrl = try_move_before_pre_loop(in(0), val_ctrl, phase); 2673 if (ctrl != NULL) { 2674 return try_move_before_loop_helper(ctrl, val_ctrl, in(Memory), phase); 2675 } 2676 return NULL; 2677 } 2678 2679 void ShenandoahReadBarrierNode::try_move(Node *n_ctrl, PhaseIdealLoop* phase) { 2680 Node* mem = in(MemNode::Memory); 2681 int alias = phase->C->get_alias_index(adr_type()); 2682 const bool trace = false; 2683 2684 #ifdef ASSERT 2685 if (trace) { tty->print("Trying to move mem of"); dump(); } 2686 #endif 2687 2688 Node* new_mem = mem; 2689 2690 ResourceMark rm; 2691 VectorSet seen(Thread::current()->resource_area()); 2692 Node_List phis; 2693 2694 for (;;) { 2695 #ifdef ASSERT 2696 if (trace) { tty->print("Looking for dominator from"); mem->dump(); } 2697 #endif 2698 if (mem->is_Proj() && mem->in(0)->is_Start()) { 2699 if (new_mem != in(MemNode::Memory)) { 2700 #ifdef ASSERT 2701 if (trace) { tty->print("XXX Setting mem to"); new_mem->dump(); tty->print(" for "); dump(); } 2702 #endif 2703 phase->igvn().replace_input_of(this, MemNode::Memory, new_mem); 2704 } 2705 return; 2706 } 2707 2708 Node* candidate = mem; 2709 do { 2710 if (!is_independent(mem)) { 2711 if (trace) { tty->print_cr("Not independent"); } 2712 if (new_mem != in(MemNode::Memory)) { 2713 #ifdef ASSERT 2714 if (trace) { tty->print("XXX Setting mem to"); new_mem->dump(); tty->print(" for "); dump(); } 2715 #endif 2716 phase->igvn().replace_input_of(this, MemNode::Memory, new_mem); 2717 } 2718 return; 2719 } 2720 if (seen.test_set(mem->_idx)) { 2721 if (trace) { tty->print_cr("Already seen"); } 2722 ShouldNotReachHere(); 2723 // Strange graph 2724 if (new_mem != in(MemNode::Memory)) { 2725 #ifdef ASSERT 2726 if (trace) { tty->print("XXX Setting mem to"); new_mem->dump(); tty->print(" for "); dump(); } 2727 #endif 2728 phase->igvn().replace_input_of(this, MemNode::Memory, new_mem); 2729 } 2730 return; 2731 } 2732 if (mem->is_Phi()) { 2733 phis.push(mem); 2734 } 2735 mem = next_mem(mem, alias); 2736 if (mem->bottom_type() == Type::MEMORY) { 2737 candidate = mem; 2738 } 2739 assert(is_dominator(phase->ctrl_or_self(mem), n_ctrl, mem, this, phase) == phase->is_dominator(phase->ctrl_or_self(mem), n_ctrl), "strange dominator"); 2740 #ifdef ASSERT 2741 if (trace) { tty->print("Next mem is"); mem->dump(); } 2742 #endif 2743 } while (mem->bottom_type() != Type::MEMORY || !phase->is_dominator(phase->ctrl_or_self(mem), n_ctrl)); 2744 2745 assert(mem->bottom_type() == Type::MEMORY, "bad mem"); 2746 2747 bool not_dom = false; 2748 for (uint i = 0; i < phis.size() && !not_dom; i++) { 2749 Node* nn = phis.at(i); 2750 2751 #ifdef ASSERT 2752 if (trace) { tty->print("Looking from phi"); nn->dump(); } 2753 #endif 2754 assert(nn->is_Phi(), "phis only"); 2755 for (uint j = 2; j < nn->req() && !not_dom; j++) { 2756 Node* m = nn->in(j); 2757 #ifdef ASSERT 2758 if (trace) { tty->print("Input %d is", j); m->dump(); } 2759 #endif 2760 while (m != mem && !seen.test_set(m->_idx)) { 2761 if (is_dominator(phase->ctrl_or_self(m), phase->ctrl_or_self(mem), m, mem, phase)) { 2762 not_dom = true; 2763 // Scheduling anomaly 2764 #ifdef ASSERT 2765 if (trace) { tty->print("Giving up"); m->dump(); } 2766 #endif 2767 break; 2768 } 2769 if (!is_independent(m)) { 2770 if (trace) { tty->print_cr("Not independent"); } 2771 if (new_mem != in(MemNode::Memory)) { 2772 #ifdef ASSERT 2773 if (trace) { tty->print("XXX Setting mem to"); new_mem->dump(); tty->print(" for "); dump(); } 2774 #endif 2775 phase->igvn().replace_input_of(this, MemNode::Memory, new_mem); 2776 } 2777 return; 2778 } 2779 if (m->is_Phi()) { 2780 phis.push(m); 2781 } 2782 m = next_mem(m, alias); 2783 #ifdef ASSERT 2784 if (trace) { tty->print("Next mem is"); m->dump(); } 2785 #endif 2786 } 2787 } 2788 } 2789 if (!not_dom) { 2790 new_mem = mem; 2791 phis.clear(); 2792 } else { 2793 seen.Clear(); 2794 } 2795 } 2796 } 2797 2798 CallStaticJavaNode* ShenandoahWriteBarrierNode::pin_and_expand_null_check(PhaseIterGVN& igvn) { 2799 Node* val = in(ValueIn); 2800 2801 #ifdef ASSERT 2802 const Type* val_t = igvn.type(val); 2803 assert(val_t->meet(TypePtr::NULL_PTR) != val_t, "should be not null"); 2804 #endif 2805 2806 if (val->Opcode() == Op_CastPP && 2807 val->in(0) != NULL && 2808 val->in(0)->Opcode() == Op_IfTrue && 2809 val->in(0)->as_Proj()->is_uncommon_trap_if_pattern(Deoptimization::Reason_none) && 2810 val->in(0)->in(0)->is_If() && 2811 val->in(0)->in(0)->in(1)->Opcode() == Op_Bool && 2812 val->in(0)->in(0)->in(1)->as_Bool()->_test._test == BoolTest::ne && 2813 val->in(0)->in(0)->in(1)->in(1)->Opcode() == Op_CmpP && 2814 val->in(0)->in(0)->in(1)->in(1)->in(1) == val->in(1) && 2815 val->in(0)->in(0)->in(1)->in(1)->in(2)->bottom_type() == TypePtr::NULL_PTR) { 2816 assert(val->in(0)->in(0)->in(1)->in(1)->in(1) == val->in(1), ""); 2817 CallStaticJavaNode* unc = val->in(0)->as_Proj()->is_uncommon_trap_if_pattern(Deoptimization::Reason_none); 2818 return unc; 2819 } 2820 return NULL; 2821 } 2822 2823 void ShenandoahWriteBarrierNode::pin_and_expand_move_barrier(PhaseIdealLoop* phase, Unique_Node_List& uses) { 2824 Node* unc = pin_and_expand_null_check(phase->igvn()); 2825 Node* val = in(ValueIn); 2826 2827 if (unc != NULL) { 2828 Node* ctrl = phase->get_ctrl(this); 2829 Node* unc_ctrl = val->in(0); 2830 2831 // Don't move write barrier in a loop 2832 IdealLoopTree* loop = phase->get_loop(ctrl); 2833 IdealLoopTree* unc_loop = phase->get_loop(unc_ctrl); 2834 2835 if (!unc_loop->is_member(loop)) { 2836 return; 2837 } 2838 2839 Node* branch = no_branches(ctrl, unc_ctrl, false, phase); 2840 assert(branch == NULL || branch == NodeSentinel, "was not looking for a branch"); 2841 if (branch == NodeSentinel) { 2842 return; 2843 } 2844 2845 2846 RegionNode* r = new RegionNode(3); 2847 IfNode* iff = unc_ctrl->in(0)->as_If(); 2848 2849 Node* ctrl_use = unc_ctrl->unique_ctrl_out(); 2850 Node* c = unc_ctrl; 2851 Node* new_cast = clone_null_check(c, val, unc_ctrl, r, 1, phase); 2852 2853 phase->igvn().rehash_node_delayed(ctrl_use); 2854 int nb = ctrl_use->replace_edge(unc_ctrl, c); 2855 assert(nb == 1, "no update?"); 2856 if (phase->idom(ctrl_use) == unc_ctrl) { 2857 phase->set_idom(ctrl_use, c, phase->dom_depth(ctrl_use)); 2858 } 2859 2860 IfNode* new_iff = new_cast->in(0)->in(0)->as_If(); 2861 fix_null_check(iff, unc, unc_ctrl, r, uses, phase); 2862 Node* iff_proj = iff->proj_out(0); 2863 r->init_req(2, iff_proj); 2864 2865 Node* new_bol = new_iff->in(1)->clone(); 2866 Node* new_cmp = new_bol->in(1)->clone(); 2867 assert(new_cmp->Opcode() == Op_CmpP, "broken"); 2868 assert(new_cmp->in(1) == val->in(1), "broken"); 2869 new_bol->set_req(1, new_cmp); 2870 new_cmp->set_req(1, this); 2871 phase->register_new_node(new_bol, new_iff->in(0)); 2872 phase->register_new_node(new_cmp, new_iff->in(0)); 2873 phase->igvn().replace_input_of(new_iff, 1, new_bol); 2874 phase->igvn().replace_input_of(new_cast, 1, this); 2875 2876 for (DUIterator_Fast imax, i = this->fast_outs(imax); i < imax; i++) { 2877 Node* u = this->fast_out(i); 2878 if (u == new_cast || u->Opcode() == Op_ShenandoahWBMemProj || u == new_cmp) { 2879 continue; 2880 } 2881 phase->igvn().rehash_node_delayed(u); 2882 int nb = u->replace_edge(this, new_cast); 2883 assert(nb > 0, "no update?"); 2884 --i; imax -= nb; 2885 } 2886 2887 for (DUIterator_Fast imax, i = val->fast_outs(imax); i < imax; i++) { 2888 Node* u = val->fast_out(i); 2889 if (u == this) { 2890 continue; 2891 } 2892 phase->igvn().rehash_node_delayed(u); 2893 int nb = u->replace_edge(val, new_cast); 2894 assert(nb > 0, "no update?"); 2895 --i; imax -= nb; 2896 } 2897 2898 uses.clear(); 2899 uses.push(new_cast); 2900 for (uint next = 0; next < uses.size(); next++) { 2901 Node *n = uses.at(next); 2902 for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) { 2903 Node* u = n->fast_out(i); 2904 if (phase->has_ctrl(u) && phase->get_ctrl(u) == unc_ctrl) { 2905 phase->set_ctrl(u, c); 2906 if (u->in(0) == unc_ctrl) { 2907 phase->igvn().replace_input_of(u, 0, c); 2908 } 2909 uses.push(u); 2910 } 2911 } 2912 } 2913 2914 Node* new_ctrl = unc_ctrl; 2915 2916 Node* mem = in(Memory); 2917 Node* old_mem = mem; 2918 2919 Node* mem_ctrl = NULL; 2920 int alias = phase->C->get_alias_index(adr_type()); 2921 mem = dom_mem(mem, mem_ctrl, this, new_ctrl, alias, phase); 2922 if (mem == NULL) { 2923 return; 2924 } 2925 2926 Node* proj = find_out_with(Op_ShenandoahWBMemProj); 2927 if (!fix_mem_phis(mem, mem_ctrl, new_ctrl, alias, phase)) { 2928 return; 2929 } 2930 2931 assert(mem == old_mem || memory_dominates_all_paths(mem, new_ctrl, alias, phase), "can't fix the memory graph"); 2932 phase->set_ctrl_and_loop(this, new_ctrl); 2933 if (in(Control) != NULL) { 2934 phase->igvn().replace_input_of(this, Control, new_ctrl); 2935 } 2936 disconnect_barrier_mem(this, phase->igvn()); 2937 fix_memory_uses(mem, this, proj, new_ctrl, phase->C->get_alias_index(adr_type()), phase); 2938 assert(proj->outcnt() > 0, "disconnected write barrier"); 2939 phase->igvn().replace_input_of(this, Memory, mem); 2940 phase->set_ctrl_and_loop(proj, new_ctrl); 2941 } 2942 } 2943 2944 void ShenandoahWriteBarrierNode::pin_and_expand_helper(PhaseIdealLoop* phase) { 2945 Node* val = in(ValueIn); 2946 CallStaticJavaNode* unc = pin_and_expand_null_check(phase->igvn()); 2947 Node* rep = this; 2948 Node* ctrl = phase->get_ctrl(this); 2949 if (unc != NULL && val->in(0) == ctrl) { 2950 Node* unc_ctrl = val->in(0); 2951 IfNode* other_iff = unc_ctrl->unique_ctrl_out()->as_If(); 2952 ProjNode* other_unc_ctrl = other_iff->proj_out(1); 2953 Node* cast = other_unc_ctrl->find_out_with(Op_CastPP); 2954 assert(cast != NULL, "missing cast"); 2955 assert(cast->in(1) == this, "bad cast"); 2956 assert(other_unc_ctrl->is_uncommon_trap_if_pattern(Deoptimization::Reason_none) == unc, "broken"); 2957 rep = cast; 2958 } 2959 2960 // Replace all uses of barrier's input that are dominated by ctrl 2961 // with the value returned by the barrier: no need to keep both 2962 // live. 2963 for (DUIterator_Fast imax, i = val->fast_outs(imax); i < imax; i++) { 2964 Node* u = val->fast_out(i); 2965 if (u != this) { 2966 if (u->is_Phi()) { 2967 int nb = 0; 2968 for (uint j = 1; j < u->req(); j++) { 2969 if (u->in(j) == val) { 2970 Node* c = u->in(0)->in(j); 2971 if (phase->is_dominator(ctrl, c)) { 2972 phase->igvn().replace_input_of(u, j, rep); 2973 nb++; 2974 } 2975 } 2976 } 2977 if (nb > 0) { 2978 imax -= nb; 2979 --i; 2980 } 2981 } else { 2982 Node* c = phase->ctrl_or_self(u); 2983 if (is_dominator(ctrl, c, this, u, phase)) { 2984 phase->igvn().rehash_node_delayed(u); 2985 int nb = u->replace_edge(val, rep); 2986 assert(nb > 0, "no update?"); 2987 --i, imax -= nb; 2988 } 2989 } 2990 } 2991 } 2992 } 2993 2994 Node* ShenandoahWriteBarrierNode::pick_phi(Node* phi1, Node* phi2, Node_Stack& phis, VectorSet& visited, PhaseIdealLoop* phase) { 2995 assert(phis.size() == 0, "stack needs to be empty"); 2996 uint i = 1; 2997 int phi_dominates = -1; 2998 for (;;) { 2999 assert(phi1->req() == phi2->req(), "strange pair of phis"); 3000 assert(phis.size() % 2 == 0, ""); 3001 Node* in1 = phi1->in(i); 3002 Node* in2 = phi2->in(i); 3003 3004 if (in1->is_MergeMem()) { 3005 in1 = in1->as_MergeMem()->base_memory(); 3006 } 3007 if (in2->is_MergeMem()) { 3008 in2 = in2->as_MergeMem()->base_memory(); 3009 } 3010 3011 if (in1 == in2) { 3012 //continue 3013 } else if (in1->is_Phi() && in2->is_Phi() && in1->in(0) == in2->in(0)) { 3014 assert(!visited.test_set(in1->_idx), "no loop"); 3015 assert(!visited.test_set(in2->_idx), "no loop"); 3016 phis.push(phi1, i+1); 3017 phis.push(phi2, i+1); 3018 phi1 = in1; 3019 phi2 = in2; 3020 i = 1; 3021 } else { 3022 Node* in1_c = phase->get_ctrl(in1); 3023 Node* in2_c = phase->get_ctrl(in2); 3024 if (is_dominator(in1_c, in2_c, in1, in2, phase)) { 3025 assert(!is_dominator(in2_c, in1_c, in2, in1, phase), "one has to dominate the other"); 3026 assert(phi_dominates == -1 || phi_dominates == 1, "all inputs must dominate"); 3027 phi_dominates = 1; 3028 } else { 3029 assert(is_dominator(in2_c, in1_c, in2, in1, phase), "one must dominate the other"); 3030 assert(!is_dominator(in1_c, in2_c, in1, in2, phase), "one has to dominate the other"); 3031 assert(phi_dominates == -1 || phi_dominates == 2, "all inputs must dominate"); 3032 phi_dominates = 2; 3033 } 3034 } 3035 i++; 3036 3037 while (i >= phi1->req() && phis.size() > 0) { 3038 i = phis.index(); 3039 phi2 = phis.node(); 3040 phis.pop(); 3041 phi1 = phis.node(); 3042 phis.pop(); 3043 } 3044 3045 if (i >= phi1->req() && phis.size() == 0) { 3046 Node* phi = NULL; 3047 if (phi_dominates == 1) { 3048 return phi2; 3049 } else if (phi_dominates == 2) { 3050 return phi1; 3051 } else { 3052 return phi1; 3053 } 3054 } 3055 } 3056 return NULL; 3057 } 3058 3059 bool ShenandoahWriteBarrierNode::mem_is_valid(Node* m, Node* c, PhaseIdealLoop* phase) { 3060 return m != NULL && get_ctrl(m, phase) == c; 3061 } 3062 3063 Node* ShenandoahWriteBarrierNode::find_raw_mem(Node* ctrl, Node* n, const Node_List& memory_nodes, PhaseIdealLoop* phase) { 3064 assert(n == NULL || phase->ctrl_or_self(n) == ctrl, ""); 3065 Node* raw_mem = memory_nodes[ctrl->_idx]; 3066 Node* c = ctrl; 3067 while (!mem_is_valid(raw_mem, c, phase) && 3068 (!c->is_CatchProj() || raw_mem == NULL || c->in(0)->in(0)->in(0) != get_ctrl(raw_mem, phase))) { 3069 c = phase->idom(c); 3070 raw_mem = memory_nodes[c->_idx]; 3071 } 3072 if (n != NULL && mem_is_valid(raw_mem, c, phase)) { 3073 while (!is_dominator_same_ctrl(c, raw_mem, n, phase) && phase->ctrl_or_self(raw_mem) == ctrl) { 3074 raw_mem = next_mem(raw_mem, Compile::AliasIdxRaw); 3075 } 3076 if (raw_mem->is_MergeMem()) { 3077 raw_mem = raw_mem->as_MergeMem()->memory_at(Compile::AliasIdxRaw); 3078 } 3079 if (!mem_is_valid(raw_mem, c, phase)) { 3080 do { 3081 c = phase->idom(c); 3082 raw_mem = memory_nodes[c->_idx]; 3083 } while (!mem_is_valid(raw_mem, c, phase) && 3084 (!c->is_CatchProj() || raw_mem == NULL || c->in(0)->in(0)->in(0) != get_ctrl(raw_mem, phase))); 3085 } 3086 } 3087 assert(raw_mem->bottom_type() == Type::MEMORY, ""); 3088 return raw_mem; 3089 } 3090 3091 Node* ShenandoahWriteBarrierNode::find_bottom_mem(Node* ctrl, PhaseIdealLoop* phase) { 3092 Node* mem = NULL; 3093 Node* c = ctrl; 3094 do { 3095 if (c->is_Region()) { 3096 Node* phi_bottom = NULL; 3097 for (DUIterator_Fast imax, i = c->fast_outs(imax); i < imax; i++) { 3098 Node* u = c->fast_out(i); 3099 if (u->is_Phi() && u->bottom_type() == Type::MEMORY) { 3100 if (u->adr_type() == TypePtr::BOTTOM) { 3101 if (phi_bottom != NULL) { 3102 phi_bottom = NodeSentinel; 3103 } else { 3104 phi_bottom = u; 3105 } 3106 } 3107 } 3108 } 3109 if (phi_bottom != NULL) { 3110 if (phi_bottom != NodeSentinel) { 3111 mem = phi_bottom; 3112 } else { 3113 Node* phi = NULL; 3114 ResourceMark rm; 3115 Node_Stack phis(0); 3116 VectorSet visited(Thread::current()->resource_area()); 3117 for (DUIterator_Fast imax, i = c->fast_outs(imax); i < imax; i++) { 3118 Node* u = c->fast_out(i); 3119 if (u->is_Phi() && u->bottom_type() == Type::MEMORY && u->adr_type() == TypePtr::BOTTOM) { 3120 if (phi == NULL) { 3121 phi = u; 3122 } else { 3123 phi = pick_phi(phi, u, phis, visited, phase); 3124 } 3125 } 3126 } 3127 mem = phi; 3128 } 3129 } 3130 } else { 3131 if (c->is_Call() && c->as_Call()->adr_type() != NULL) { 3132 CallProjections projs; 3133 c->as_Call()->extract_projections(&projs, true, false); 3134 if (projs.fallthrough_memproj != NULL) { 3135 if (projs.fallthrough_memproj->adr_type() == TypePtr::BOTTOM) { 3136 if (projs.catchall_memproj == NULL) { 3137 mem = projs.fallthrough_memproj; 3138 } else { 3139 if (phase->is_dominator(projs.fallthrough_catchproj, ctrl)) { 3140 mem = projs.fallthrough_memproj; 3141 } else { 3142 assert(phase->is_dominator(projs.catchall_catchproj, ctrl), "one proj must dominate barrier"); 3143 mem = projs.catchall_memproj; 3144 } 3145 } 3146 } 3147 } else { 3148 Node* proj = c->as_Call()->proj_out(TypeFunc::Memory); 3149 if (proj != NULL && 3150 proj->adr_type() == TypePtr::BOTTOM) { 3151 mem = proj; 3152 } 3153 } 3154 } else { 3155 for (DUIterator_Fast imax, i = c->fast_outs(imax); i < imax; i++) { 3156 Node* u = c->fast_out(i); 3157 if (u->is_Proj() && 3158 u->bottom_type() == Type::MEMORY && 3159 u->adr_type() == TypePtr::BOTTOM) { 3160 assert(c->is_SafePoint() || c->is_MemBar() || c->is_Start(), ""); 3161 assert(mem == NULL, "only one proj"); 3162 mem = u; 3163 } 3164 } 3165 assert(!c->is_Call() || c->as_Call()->adr_type() != NULL || mem == NULL, "no mem projection expected"); 3166 } 3167 } 3168 c = phase->idom(c); 3169 } while (mem == NULL); 3170 return mem; 3171 } 3172 3173 void ShenandoahWriteBarrierNode::follow_barrier_uses(Node* n, Node* ctrl, Unique_Node_List& uses, PhaseIdealLoop* phase) { 3174 for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) { 3175 Node* u = n->fast_out(i); 3176 if (!u->is_CFG() && phase->get_ctrl(u) == ctrl && (!u->is_Phi() || !u->in(0)->is_Loop() || u->in(LoopNode::LoopBackControl) != n)) { 3177 uses.push(u); 3178 } 3179 } 3180 } 3181 3182 Node* ShenandoahWriteBarrierNode::get_ctrl(Node* n, PhaseIdealLoop* phase) { 3183 Node* c = phase->get_ctrl(n); 3184 if (n->is_Proj() && n->in(0)->is_Call()) { 3185 assert(c == n->in(0), ""); 3186 CallNode* call = c->as_Call(); 3187 CallProjections projs; 3188 call->extract_projections(&projs, true, false); 3189 if (projs.catchall_memproj != NULL) { 3190 if (projs.fallthrough_memproj == n) { 3191 c = projs.fallthrough_catchproj; 3192 } else { 3193 assert(projs.catchall_memproj == n, ""); 3194 c = projs.catchall_catchproj; 3195 } 3196 } 3197 } 3198 return c; 3199 } 3200 3201 Node* ShenandoahWriteBarrierNode::ctrl_or_self(Node* n, PhaseIdealLoop* phase) { 3202 if (phase->has_ctrl(n)) 3203 return get_ctrl(n, phase); 3204 else { 3205 assert (n->is_CFG(), "must be a CFG node"); 3206 return n; 3207 } 3208 } 3209 3210 #ifdef ASSERT 3211 static bool has_never_branch(Node* root) { 3212 for (uint i = 1; i < root->req(); i++) { 3213 Node* in = root->in(i); 3214 if (in != NULL && in->Opcode() == Op_Halt && in->in(0)->is_Proj() && in->in(0)->in(0)->Opcode() == Op_NeverBranch) { 3215 return true; 3216 } 3217 } 3218 return false; 3219 } 3220 #endif 3221 3222 void ShenandoahWriteBarrierNode::collect_memory_nodes(int alias, Node_List& memory_nodes, PhaseIdealLoop* phase) { 3223 Node_Stack stack(0); 3224 VectorSet visited(Thread::current()->resource_area()); 3225 Node_List regions; 3226 3227 // Walk the raw memory graph and create a mapping from CFG node to 3228 // memory node. Exclude phis for now. 3229 stack.push(phase->C->root(), 1); 3230 do { 3231 Node* n = stack.node(); 3232 int opc = n->Opcode(); 3233 uint i = stack.index(); 3234 if (i < n->req()) { 3235 Node* mem = NULL; 3236 if (opc == Op_Root) { 3237 Node* in = n->in(i); 3238 int in_opc = in->Opcode(); 3239 if (in_opc == Op_Return || in_opc == Op_Rethrow) { 3240 mem = in->in(TypeFunc::Memory); 3241 } else if (in_opc == Op_Halt) { 3242 if (!in->in(0)->is_Region()) { 3243 Node* proj = in->in(0); 3244 assert(proj->is_Proj(), ""); 3245 Node* in = proj->in(0); 3246 assert(in->is_CallStaticJava() || in->Opcode() == Op_NeverBranch || in->Opcode() == Op_Catch || proj->is_IfProj(), ""); 3247 if (in->is_CallStaticJava()) { 3248 mem = in->in(TypeFunc::Memory); 3249 } else if (in->Opcode() == Op_Catch) { 3250 Node* call = in->in(0)->in(0); 3251 assert(call->is_Call(), ""); 3252 mem = call->in(TypeFunc::Memory); 3253 } 3254 } 3255 } else { 3256 #ifdef ASSERT 3257 n->dump(); 3258 in->dump(); 3259 #endif 3260 ShouldNotReachHere(); 3261 } 3262 } else { 3263 assert(n->is_Phi() && n->bottom_type() == Type::MEMORY, ""); 3264 assert(n->adr_type() == TypePtr::BOTTOM || phase->C->get_alias_index(n->adr_type()) == alias, ""); 3265 mem = n->in(i); 3266 } 3267 i++; 3268 stack.set_index(i); 3269 if (mem == NULL) { 3270 continue; 3271 } 3272 for (;;) { 3273 if (visited.test_set(mem->_idx) || mem->is_Start()) { 3274 break; 3275 } 3276 if (mem->is_Phi()) { 3277 stack.push(mem, 2); 3278 mem = mem->in(1); 3279 } else if (mem->is_Proj()) { 3280 stack.push(mem, mem->req()); 3281 mem = mem->in(0); 3282 } else if (mem->is_SafePoint() || mem->is_MemBar()) { 3283 mem = mem->in(TypeFunc::Memory); 3284 } else if (mem->is_MergeMem()) { 3285 mem = mem->as_MergeMem()->memory_at(alias); 3286 } else if (mem->is_Store() || mem->is_LoadStore() || mem->is_ClearArray()) { 3287 stack.push(mem, mem->req()); 3288 mem = mem->in(MemNode::Memory); 3289 } else { 3290 #ifdef ASSERT 3291 mem->dump(); 3292 #endif 3293 ShouldNotReachHere(); 3294 } 3295 } 3296 } else { 3297 if (n->is_Phi()) { 3298 // Nothing 3299 } else if (!n->is_Root()) { 3300 Node* c = get_ctrl(n, phase); 3301 memory_nodes.map(c->_idx, n); 3302 } 3303 stack.pop(); 3304 } 3305 } while(stack.is_nonempty()); 3306 3307 // Iterate over CFG nodes in rpo and propagate memory state to 3308 // compute memory state at regions, creating new phis if needed. 3309 Node_List rpo_list; 3310 visited.Clear(); 3311 phase->rpo(phase->C->root(), stack, visited, rpo_list); 3312 Node* root = rpo_list.pop(); 3313 assert(root == phase->C->root(), ""); 3314 3315 const bool trace = false; 3316 #ifdef ASSERT 3317 if (trace) { 3318 for (int i = rpo_list.size() - 1; i >= 0; i--) { 3319 Node* c = rpo_list.at(i); 3320 if (memory_nodes[c->_idx] != NULL) { 3321 tty->print("X %d", c->_idx); memory_nodes[c->_idx]->dump(); 3322 } 3323 } 3324 } 3325 #endif 3326 uint last = phase->C->unique(); 3327 3328 #ifdef ASSERT 3329 uint8_t max_depth = 0; 3330 for (LoopTreeIterator iter(phase->ltree_root()); !iter.done(); iter.next()) { 3331 IdealLoopTree* lpt = iter.current(); 3332 max_depth = MAX2(max_depth, lpt->_nest); 3333 } 3334 #endif 3335 3336 bool progress = true; 3337 int iteration = 0; 3338 Node_List dead_phis; 3339 while (progress) { 3340 progress = false; 3341 iteration++; 3342 assert(iteration <= 2+max_depth || phase->C->has_irreducible_loop(), ""); 3343 if (trace) { tty->print_cr("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"); } 3344 IdealLoopTree* last_updated_ilt = NULL; 3345 for (int i = rpo_list.size() - 1; i >= 0; i--) { 3346 Node* c = rpo_list.at(i); 3347 3348 Node* prev_mem = memory_nodes[c->_idx]; 3349 if (c->is_Region()) { 3350 Node* prev_region = regions[c->_idx]; 3351 Node* unique = NULL; 3352 for (uint j = 1; j < c->req() && unique != NodeSentinel; j++) { 3353 Node* m = memory_nodes[c->in(j)->_idx]; 3354 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"); 3355 if (m != NULL) { 3356 if (m == prev_region && ((c->is_Loop() && j == LoopNode::LoopBackControl) || (prev_region->is_Phi() && prev_region->in(0) == c))) { 3357 assert(c->is_Loop() && j == LoopNode::LoopBackControl || phase->C->has_irreducible_loop(), ""); 3358 // continue 3359 } else if (unique == NULL) { 3360 unique = m; 3361 } else if (m == unique) { 3362 // continue 3363 } else { 3364 unique = NodeSentinel; 3365 } 3366 } 3367 } 3368 assert(unique != NULL, "empty phi???"); 3369 if (unique != NodeSentinel) { 3370 if (prev_region != NULL && prev_region->is_Phi() && prev_region->in(0) == c) { 3371 dead_phis.push(prev_region); 3372 } 3373 regions.map(c->_idx, unique); 3374 } else { 3375 Node* phi = NULL; 3376 if (prev_region != NULL && prev_region->is_Phi() && prev_region->in(0) == c && prev_region->_idx >= last) { 3377 phi = prev_region; 3378 for (uint k = 1; k < c->req(); k++) { 3379 Node* m = memory_nodes[c->in(k)->_idx]; 3380 assert(m != NULL, "expect memory state"); 3381 phi->set_req(k, m); 3382 } 3383 } else { 3384 for (DUIterator_Fast jmax, j = c->fast_outs(jmax); j < jmax && phi == NULL; j++) { 3385 Node* u = c->fast_out(j); 3386 if (u->is_Phi() && u->bottom_type() == Type::MEMORY && 3387 (u->adr_type() == TypePtr::BOTTOM || phase->C->get_alias_index(u->adr_type()) == alias)) { 3388 phi = u; 3389 for (uint k = 1; k < c->req() && phi != NULL; k++) { 3390 Node* m = memory_nodes[c->in(k)->_idx]; 3391 assert(m != NULL, "expect memory state"); 3392 if (u->in(k) != m) { 3393 phi = NULL; 3394 } 3395 } 3396 } 3397 } 3398 if (phi == NULL) { 3399 phi = new PhiNode(c, Type::MEMORY, phase->C->get_adr_type(alias)); 3400 for (uint k = 1; k < c->req(); k++) { 3401 Node* m = memory_nodes[c->in(k)->_idx]; 3402 assert(m != NULL, "expect memory state"); 3403 phi->init_req(k, m); 3404 } 3405 } 3406 } 3407 assert(phi != NULL, ""); 3408 regions.map(c->_idx, phi); 3409 } 3410 Node* current_region = regions[c->_idx]; 3411 if (current_region != prev_region) { 3412 progress = true; 3413 if (prev_region == prev_mem) { 3414 memory_nodes.map(c->_idx, current_region); 3415 } 3416 } 3417 } else if (prev_mem == NULL || prev_mem->is_Phi() || ctrl_or_self(prev_mem, phase) != c) { 3418 Node* m = memory_nodes[phase->idom(c)->_idx]; 3419 assert(m != NULL, "expect memory state"); 3420 if (m != prev_mem) { 3421 memory_nodes.map(c->_idx, m); 3422 progress = true; 3423 } 3424 } 3425 #ifdef ASSERT 3426 if (trace) { tty->print("X %d", c->_idx); memory_nodes[c->_idx]->dump(); } 3427 #endif 3428 } 3429 } 3430 3431 // Replace existing phi with computed memory state for that region 3432 // if different (could be a new phi or a dominating memory node if 3433 // that phi was found to be useless). 3434 while (dead_phis.size() > 0) { 3435 Node* n = dead_phis.pop(); 3436 n->replace_by(phase->C->top()); 3437 n->destruct(); 3438 } 3439 for (int i = rpo_list.size() - 1; i >= 0; i--) { 3440 Node* c = rpo_list.at(i); 3441 if (c->is_Region()) { 3442 Node* n = regions[c->_idx]; 3443 if (n->is_Phi() && n->_idx >= last && n->in(0) == c) { 3444 phase->register_new_node(n, c); 3445 } 3446 } 3447 } 3448 for (int i = rpo_list.size() - 1; i >= 0; i--) { 3449 Node* c = rpo_list.at(i); 3450 if (c->is_Region()) { 3451 Node* n = regions[c->_idx]; 3452 for (DUIterator_Fast imax, i = c->fast_outs(imax); i < imax; i++) { 3453 Node* u = c->fast_out(i); 3454 if (u->is_Phi() && u->bottom_type() == Type::MEMORY && 3455 u != n) { 3456 if (u->adr_type() == TypePtr::BOTTOM) { 3457 fix_memory_uses(u, n, n, c, alias, phase); 3458 } else if (phase->C->get_alias_index(u->adr_type()) == alias) { 3459 phase->lazy_replace(u, n); 3460 --i; --imax; 3461 } 3462 } 3463 } 3464 } 3465 } 3466 } 3467 3468 void ShenandoahWriteBarrierNode::fix_raw_mem(Node* ctrl, Node* region, Node* raw_mem, Node* raw_mem_for_ctrl, Node* raw_mem_phi, 3469 Node_List& memory_nodes, Unique_Node_List& uses, PhaseIdealLoop* phase) { 3470 const bool trace = false; 3471 DEBUG_ONLY(if (trace) { tty->print("ZZZ control is"); ctrl->dump(); }); 3472 DEBUG_ONLY(if (trace) { tty->print("ZZZ mem is"); raw_mem->dump(); }); 3473 GrowableArray<Node*> phis; 3474 if (raw_mem_for_ctrl != raw_mem) { 3475 Node* old = raw_mem_for_ctrl; 3476 Node* prev = NULL; 3477 while (old != raw_mem) { 3478 assert(old->is_Store() || old->is_LoadStore() || old->is_ClearArray(), ""); 3479 prev = old; 3480 old = old->in(MemNode::Memory); 3481 } 3482 assert(prev != NULL, ""); 3483 memory_nodes.map(ctrl->_idx, raw_mem); 3484 memory_nodes.map(region->_idx, raw_mem_for_ctrl); 3485 phase->igvn().replace_input_of(prev, MemNode::Memory, raw_mem_phi); 3486 } else { 3487 memory_nodes.map(region->_idx, raw_mem_phi); 3488 uses.clear(); 3489 uses.push(region); 3490 for(uint next = 0; next < uses.size(); next++ ) { 3491 Node *n = uses.at(next); 3492 assert(n->is_CFG(), ""); 3493 DEBUG_ONLY(if (trace) { tty->print("ZZZ ctrl"); n->dump(); }); 3494 for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) { 3495 Node* u = n->fast_out(i); 3496 if (!u->is_Root() && u->is_CFG() && u != n) { 3497 Node* m = memory_nodes[u->_idx]; 3498 if (u->is_Region() && !has_mem_phi(phase->C, u, Compile::AliasIdxRaw) && 3499 u->unique_ctrl_out()->Opcode() != Op_Halt) { 3500 DEBUG_ONLY(if (trace) { tty->print("ZZZ region"); u->dump(); }); 3501 DEBUG_ONLY(if (trace && m != NULL) { tty->print("ZZZ mem"); m->dump(); }); 3502 3503 if (!mem_is_valid(m, u, phase) || !m->is_Phi()) { 3504 bool push = true; 3505 bool create_phi = true; 3506 if (phase->is_dominator(region, u)) { 3507 create_phi = false; 3508 } else if (!phase->C->has_irreducible_loop()) { 3509 IdealLoopTree* loop = phase->get_loop(ctrl); 3510 bool do_check = true; 3511 IdealLoopTree* l = loop; 3512 create_phi = false; 3513 while (l != phase->ltree_root()) { 3514 if (phase->is_dominator(l->_head, u) && phase->is_dominator(phase->idom(u), l->_head)) { 3515 create_phi = true; 3516 do_check = false; 3517 break; 3518 } 3519 l = l->_parent; 3520 } 3521 3522 if (do_check) { 3523 assert(!create_phi, ""); 3524 IdealLoopTree* u_loop = phase->get_loop(u); 3525 if (u_loop != phase->ltree_root() && u_loop->is_member(loop)) { 3526 Node* c = ctrl; 3527 while (!phase->is_dominator(c, u_loop->tail())) { 3528 c = phase->idom(c); 3529 } 3530 if (!phase->is_dominator(c, u)) { 3531 do_check = false; 3532 } 3533 } 3534 } 3535 3536 if (do_check && phase->is_dominator(phase->idom(u), region)) { 3537 create_phi = true; 3538 } 3539 } 3540 if (create_phi) { 3541 Node* phi = new PhiNode(u, Type::MEMORY, TypeRawPtr::BOTTOM); 3542 phase->register_new_node(phi, u); 3543 phis.push(phi); 3544 DEBUG_ONLY(if (trace) { tty->print("ZZZ new phi"); phi->dump(); }); 3545 if (!mem_is_valid(m, u, phase)) { 3546 DEBUG_ONLY(if (trace) { tty->print("ZZZ setting mem"); phi->dump(); }); 3547 memory_nodes.map(u->_idx, phi); 3548 } else { 3549 DEBUG_ONLY(if (trace) { tty->print("ZZZ NOT setting mem"); m->dump(); }); 3550 for (;;) { 3551 assert(m->is_Mem() || m->is_LoadStore() || m->is_Proj() /*|| m->is_MergeMem()*/, ""); 3552 Node* next = NULL; 3553 if (m->is_Proj()) { 3554 next = m->in(0); 3555 } else { 3556 next = m->in(MemNode::Memory); 3557 } 3558 if (phase->get_ctrl(next) != u) { 3559 break; 3560 } 3561 if (next->is_MergeMem()) { 3562 assert(phase->get_ctrl(next->as_MergeMem()->memory_at(Compile::AliasIdxRaw)) != u, ""); 3563 break; 3564 } 3565 if (next->is_Phi()) { 3566 assert(next->adr_type() == TypePtr::BOTTOM && next->in(0) == u, ""); 3567 break; 3568 } 3569 m = next; 3570 } 3571 3572 DEBUG_ONLY(if (trace) { tty->print("ZZZ setting to phi"); m->dump(); }); 3573 assert(m->is_Mem() || m->is_LoadStore(), ""); 3574 phase->igvn().replace_input_of(m, MemNode::Memory, phi); 3575 push = false; 3576 } 3577 } else { 3578 DEBUG_ONLY(if (trace) { tty->print("ZZZ skipping region"); u->dump(); }); 3579 } 3580 if (push) { 3581 uses.push(u); 3582 } 3583 } 3584 } else if (!mem_is_valid(m, u, phase) && 3585 !(u->Opcode() == Op_CProj && u->in(0)->Opcode() == Op_NeverBranch && u->as_Proj()->_con == 1)) { 3586 uses.push(u); 3587 } 3588 } 3589 } 3590 } 3591 for (int i = 0; i < phis.length(); i++) { 3592 Node* n = phis.at(i); 3593 Node* r = n->in(0); 3594 DEBUG_ONLY(if (trace) { tty->print("ZZZ fixing new phi"); n->dump(); }); 3595 for (uint j = 1; j < n->req(); j++) { 3596 Node* m = find_raw_mem(r->in(j), NULL, memory_nodes, phase); 3597 phase->igvn().replace_input_of(n, j, m); 3598 DEBUG_ONLY(if (trace) { tty->print("ZZZ fixing new phi: %d", j); m->dump(); }); 3599 } 3600 } 3601 } 3602 uint last = phase->C->unique(); 3603 MergeMemNode* mm = NULL; 3604 int alias = Compile::AliasIdxRaw; 3605 DEBUG_ONLY(if (trace) { tty->print("ZZZ raw mem is"); raw_mem->dump(); }); 3606 for (DUIterator i = raw_mem->outs(); raw_mem->has_out(i); i++) { 3607 Node* u = raw_mem->out(i); 3608 if (u->_idx < last) { 3609 if (u->is_Mem()) { 3610 if (phase->C->get_alias_index(u->adr_type()) == alias) { 3611 Node* m = find_raw_mem(phase->get_ctrl(u), u, memory_nodes, phase); 3612 if (m != raw_mem) { 3613 DEBUG_ONLY(if (trace) { tty->print("ZZZ setting memory of use"); u->dump(); }); 3614 phase->igvn().replace_input_of(u, MemNode::Memory, m); 3615 --i; 3616 } 3617 } 3618 } else if (u->is_MergeMem()) { 3619 MergeMemNode* u_mm = u->as_MergeMem(); 3620 if (u_mm->memory_at(alias) == raw_mem) { 3621 MergeMemNode* newmm = NULL; 3622 for (DUIterator_Fast jmax, j = u->fast_outs(jmax); j < jmax; j++) { 3623 Node* uu = u->fast_out(j); 3624 assert(!uu->is_MergeMem(), "chain of MergeMems?"); 3625 if (uu->is_Phi()) { 3626 assert(uu->adr_type() == TypePtr::BOTTOM, ""); 3627 Node* region = uu->in(0); 3628 int nb = 0; 3629 for (uint k = 1; k < uu->req(); k++) { 3630 if (uu->in(k) == u) { 3631 Node* m = find_raw_mem(region->in(k), NULL, memory_nodes, phase); 3632 if (m != raw_mem) { 3633 DEBUG_ONLY(if (trace) { tty->print("ZZZ setting memory of phi %d", k); uu->dump(); }); 3634 if (newmm == NULL || 1) { 3635 newmm = clone_merge_mem(u, raw_mem, alias, m, phase->ctrl_or_self(m), i, phase); 3636 } 3637 if (newmm != u) { 3638 phase->igvn().replace_input_of(uu, k, newmm); 3639 nb++; 3640 --jmax; 3641 } 3642 } 3643 } 3644 } 3645 if (nb > 0) { 3646 --j; 3647 } 3648 } else { 3649 Node* m = find_raw_mem(phase->ctrl_or_self(uu), uu, memory_nodes, phase); 3650 if (m != raw_mem) { 3651 DEBUG_ONLY(if (trace) { tty->print("ZZZ setting memory of use"); uu->dump(); }); 3652 if (newmm == NULL || 1) { 3653 newmm = clone_merge_mem(u, raw_mem, alias, m, phase->ctrl_or_self(m), i, phase); 3654 } 3655 if (newmm != u) { 3656 phase->igvn().replace_input_of(uu, uu->find_edge(u), newmm); 3657 --j, --jmax; 3658 } 3659 } 3660 } 3661 } 3662 } 3663 } else if (u->is_Phi()) { 3664 assert(u->bottom_type() == Type::MEMORY, "what else?"); 3665 if (u->adr_type() == TypeRawPtr::BOTTOM || u->adr_type() == TypePtr::BOTTOM) { 3666 Node* region = u->in(0); 3667 bool replaced = false; 3668 for (uint j = 1; j < u->req(); j++) { 3669 if (u->in(j) == raw_mem) { 3670 Node* m = find_raw_mem(region->in(j), NULL, memory_nodes, phase); 3671 Node* nnew = m; 3672 if (m != raw_mem) { 3673 if (u->adr_type() == TypePtr::BOTTOM) { 3674 if (mm == NULL || 1) { 3675 mm = allocate_merge_mem(raw_mem, alias, m, phase->ctrl_or_self(m), phase); 3676 } 3677 nnew = mm; 3678 } 3679 DEBUG_ONLY(if (trace) { tty->print("ZZZ setting memory of phi %d", j); u->dump(); }); 3680 phase->igvn().replace_input_of(u, j, nnew); 3681 replaced = true; 3682 } 3683 } 3684 } 3685 if (replaced) { 3686 --i; 3687 } 3688 } 3689 } else if ((u->adr_type() == TypePtr::BOTTOM && u->Opcode() != Op_StrInflatedCopy) || 3690 u->adr_type() == NULL) { 3691 assert(u->adr_type() != NULL || 3692 u->Opcode() == Op_Rethrow || 3693 u->Opcode() == Op_Return || 3694 u->Opcode() == Op_SafePoint || 3695 (u->is_CallStaticJava() && u->as_CallStaticJava()->uncommon_trap_request() != 0) || 3696 (u->is_CallStaticJava() && u->as_CallStaticJava()->_entry_point == OptoRuntime::rethrow_stub()) || 3697 u->Opcode() == Op_CallLeaf, ""); 3698 Node* m = find_raw_mem(phase->ctrl_or_self(u), u, memory_nodes, phase); 3699 if (m != raw_mem) { 3700 if (mm == NULL || 1) { 3701 mm = allocate_merge_mem(raw_mem, alias, m, phase->get_ctrl(m), phase); 3702 } 3703 phase->igvn().replace_input_of(u, u->find_edge(raw_mem), mm); 3704 --i; 3705 } 3706 } else if (phase->C->get_alias_index(u->adr_type()) == alias) { 3707 Node* m = find_raw_mem(phase->ctrl_or_self(u), u, memory_nodes, phase); 3708 if (m != raw_mem) { 3709 DEBUG_ONLY(if (trace) { tty->print("ZZZ setting memory of use"); u->dump(); }); 3710 phase->igvn().replace_input_of(u, u->find_edge(raw_mem), m); 3711 --i; 3712 } 3713 } 3714 } 3715 } 3716 #ifdef ASSERT 3717 assert(raw_mem_phi->outcnt() > 0, ""); 3718 for (int i = 0; i < phis.length(); i++) { 3719 Node* n = phis.at(i); 3720 assert(n->outcnt() > 0, "new phi must have uses now"); 3721 } 3722 #endif 3723 } 3724 3725 void ShenandoahWriteBarrierNode::test_heap_stable(Node* ctrl, Node* raw_mem, Node*& gc_state, Node*& heap_stable, 3726 Node*& heap_not_stable, PhaseIdealLoop* phase) { 3727 IdealLoopTree *loop = phase->get_loop(ctrl); 3728 Node* thread = new ThreadLocalNode(); 3729 phase->register_new_node(thread, ctrl); 3730 Node* offset = phase->igvn().MakeConX(in_bytes(ShenandoahThreadLocalData::gc_state_offset())); 3731 phase->set_ctrl(offset, phase->C->root()); 3732 Node* gc_state_addr = new AddPNode(phase->C->top(), thread, offset); 3733 phase->register_new_node(gc_state_addr, ctrl); 3734 uint gc_state_idx = Compile::AliasIdxRaw; 3735 const TypePtr* gc_state_adr_type = NULL; // debug-mode-only argument 3736 debug_only(gc_state_adr_type = phase->C->get_adr_type(gc_state_idx)); 3737 3738 gc_state = new LoadBNode(ctrl, raw_mem, gc_state_addr, gc_state_adr_type, TypeInt::BYTE, MemNode::unordered); 3739 phase->register_new_node(gc_state, ctrl); 3740 3741 Node* heap_stable_cmp = new CmpINode(gc_state, phase->igvn().zerocon(T_INT)); 3742 phase->register_new_node(heap_stable_cmp, ctrl); 3743 Node* heap_stable_test = new BoolNode(heap_stable_cmp, BoolTest::ne); 3744 phase->register_new_node(heap_stable_test, ctrl); 3745 IfNode* heap_stable_iff = new IfNode(ctrl, heap_stable_test, PROB_UNLIKELY(0.999), COUNT_UNKNOWN); 3746 phase->register_control(heap_stable_iff, loop, ctrl); 3747 3748 heap_stable = new IfFalseNode(heap_stable_iff); 3749 phase->register_control(heap_stable, loop, heap_stable_iff); 3750 heap_not_stable = new IfTrueNode(heap_stable_iff); 3751 phase->register_control(heap_not_stable, loop, heap_stable_iff); 3752 3753 assert(is_heap_stable_test(heap_stable_iff), "Should match the shape"); 3754 } 3755 3756 3757 void ShenandoahWriteBarrierNode::test_evacuation_in_progress(Node* ctrl, int alias, Node*& raw_mem, Node*& wb_mem, 3758 Node*& evac_in_progress, Node*& evac_not_in_progress, Node*& heap_stable, 3759 PhaseIdealLoop* phase) { 3760 IdealLoopTree *loop = phase->get_loop(ctrl); 3761 Node* heap_not_stable = NULL; 3762 Node* unused_gc_state = NULL; 3763 3764 test_heap_stable(ctrl, raw_mem, unused_gc_state, heap_stable, heap_not_stable, phase); 3765 3766 ctrl = heap_not_stable; 3767 3768 Node* thread = new ThreadLocalNode(); 3769 phase->register_new_node(thread, ctrl); 3770 Node* offset = phase->igvn().MakeConX(in_bytes(ShenandoahThreadLocalData::gc_state_offset())); 3771 phase->set_ctrl(offset, phase->C->root()); 3772 Node* gc_state_addr = new AddPNode(phase->C->top(), thread, offset); 3773 phase->register_new_node(gc_state_addr, ctrl); 3774 uint gc_state_idx = Compile::AliasIdxRaw; 3775 const TypePtr* gc_state_adr_type = NULL; // debug-mode-only argument 3776 debug_only(gc_state_adr_type = phase->C->get_adr_type(gc_state_idx)); 3777 3778 Node* gc_state = new LoadBNode(ctrl, raw_mem, gc_state_addr, gc_state_adr_type, TypeInt::BYTE, MemNode::unordered); 3779 phase->register_new_node(gc_state, ctrl); 3780 3781 Node* evacuation_in_progress = new AndINode(gc_state, phase->igvn().intcon(ShenandoahHeap::EVACUATION | ShenandoahHeap::TRAVERSAL)); 3782 phase->register_new_node(evacuation_in_progress, ctrl); 3783 Node* evacuation_in_progress_cmp = new CmpINode(evacuation_in_progress, phase->igvn().zerocon(T_INT)); 3784 phase->register_new_node(evacuation_in_progress_cmp, ctrl); 3785 Node* evacuation_in_progress_test = new BoolNode(evacuation_in_progress_cmp, BoolTest::ne); 3786 phase->register_new_node(evacuation_in_progress_test, ctrl); 3787 IfNode* evacuation_iff = new IfNode(ctrl, evacuation_in_progress_test, PROB_UNLIKELY(0.999), COUNT_UNKNOWN); 3788 phase->register_control(evacuation_iff, loop, ctrl); 3789 3790 assert(is_evacuation_in_progress_test(evacuation_iff), "Should match the shape"); 3791 assert(is_gc_state_load(gc_state), "Should match the shape"); 3792 3793 evac_not_in_progress = new IfFalseNode(evacuation_iff); 3794 phase->register_control(evac_not_in_progress, loop, evacuation_iff); 3795 evac_in_progress = new IfTrueNode(evacuation_iff); 3796 phase->register_control(evac_in_progress, loop, evacuation_iff); 3797 } 3798 3799 Node* ShenandoahWriteBarrierNode::clone_null_check(Node*& c, Node* val, Node* unc_ctrl, 3800 Node* unc_region, uint input, PhaseIdealLoop* phase) { 3801 IdealLoopTree *loop = phase->get_loop(c); 3802 Node* iff = unc_ctrl->in(0); 3803 assert(iff->is_If(), "broken"); 3804 Node* new_iff = iff->clone(); 3805 new_iff->set_req(0, c); 3806 phase->register_control(new_iff, loop, c); 3807 Node* iffalse = new IfFalseNode(new_iff->as_If()); 3808 phase->register_control(iffalse, loop, new_iff); 3809 Node* iftrue = new IfTrueNode(new_iff->as_If()); 3810 phase->register_control(iftrue, loop, new_iff); 3811 c = iftrue; 3812 const Type *t = phase->igvn().type(val); 3813 assert(val->Opcode() == Op_CastPP, "expect cast to non null here"); 3814 Node* uncasted_val = val->in(1); 3815 val = new CastPPNode(uncasted_val, t); 3816 val->init_req(0, c); 3817 phase->register_new_node(val, c); 3818 unc_region->init_req(input, iffalse); 3819 return val; 3820 } 3821 3822 void ShenandoahWriteBarrierNode::fix_null_check(Node* dom, Node* unc, Node* unc_ctrl, Node* unc_region, 3823 Unique_Node_List& uses, PhaseIdealLoop* phase) { 3824 IfNode* iff = unc_ctrl->in(0)->as_If(); 3825 Node* proj = iff->proj_out(0); 3826 assert(proj != unc_ctrl, "bad projection"); 3827 Node* use = proj->unique_ctrl_out(); 3828 3829 assert(use == unc || use->is_Region(), "what else?"); 3830 3831 uses.clear(); 3832 if (use == unc) { 3833 phase->set_idom(use, unc_region, phase->dom_depth(use)); 3834 for (uint i = 1; i < unc->req(); i++) { 3835 Node* n = unc->in(i); 3836 if (phase->has_ctrl(n) && phase->get_ctrl(n) == proj) { 3837 uses.push(n); 3838 } 3839 } 3840 } else { 3841 assert(use->is_Region(), "what else?"); 3842 uint idx = 1; 3843 for (; use->in(idx) != proj; idx++); 3844 for (DUIterator_Fast imax, i = use->fast_outs(imax); i < imax; i++) { 3845 Node* u = use->fast_out(i); 3846 if (u->is_Phi() && phase->get_ctrl(u->in(idx)) == proj) { 3847 uses.push(u->in(idx)); 3848 } 3849 } 3850 } 3851 for(uint next = 0; next < uses.size(); next++ ) { 3852 Node *n = uses.at(next); 3853 assert(phase->get_ctrl(n) == proj, "bad control"); 3854 phase->set_ctrl_and_loop(n, unc_region); 3855 if (n->in(0) == proj) { 3856 phase->igvn().replace_input_of(n, 0, unc_region); 3857 } 3858 for (uint i = 0; i < n->req(); i++) { 3859 Node* m = n->in(i); 3860 if (m != NULL && phase->has_ctrl(m) && phase->get_ctrl(m) == proj) { 3861 uses.push(m); 3862 } 3863 } 3864 } 3865 3866 phase->igvn().rehash_node_delayed(use); 3867 int nb = use->replace_edge(proj, unc_region); 3868 assert(nb == 1, "only use expected"); 3869 phase->register_control(unc_region, phase->ltree_root(), dom); 3870 } 3871 3872 void ShenandoahWriteBarrierNode::evacuation_not_in_progress_null_check(Node*& c, Node*& val, Node* unc_ctrl, Node*& unc_region, PhaseIdealLoop* phase) { 3873 if (unc_ctrl != NULL) { 3874 // Clone the null check in this branch to allow implicit null check 3875 unc_region = new RegionNode(3); 3876 val = clone_null_check(c, val, unc_ctrl, unc_region, 1, phase); 3877 } 3878 } 3879 3880 void ShenandoahWriteBarrierNode::evacuation_not_in_progress(Node* c, Node* val, Node* unc_ctrl, Node* raw_mem, Node* wb_mem, Node* region, 3881 Node* val_phi, Node* mem_phi, Node* raw_mem_phi, Node*& unc_region, PhaseIdealLoop* phase) { 3882 evacuation_not_in_progress_null_check(c, val, unc_ctrl, unc_region, phase); 3883 region->init_req(1, c); 3884 if (ShenandoahWriteBarrierRB) { 3885 Node* rbfalse = new ShenandoahReadBarrierNode(c, wb_mem, val); 3886 phase->register_new_node(rbfalse, c); 3887 val_phi->init_req(1, rbfalse); 3888 } else { 3889 val_phi->init_req(1, val); 3890 } 3891 mem_phi->init_req(1, wb_mem); 3892 raw_mem_phi->init_req(1, raw_mem); 3893 } 3894 3895 void ShenandoahWriteBarrierNode::heap_stable(Node* c, Node* val, Node* unc_ctrl, Node* raw_mem, Node* wb_mem, Node* region, 3896 Node* val_phi, Node* mem_phi, Node* raw_mem_phi, Node* unc_region, PhaseIdealLoop* phase) { 3897 region->init_req(1, c); 3898 if (unc_ctrl != NULL) { 3899 val = val->in(1); 3900 } 3901 val_phi->init_req(1, val); 3902 mem_phi->init_req(1, wb_mem); 3903 raw_mem_phi->init_req(1, raw_mem); 3904 } 3905 3906 void ShenandoahWriteBarrierNode::evacuation_in_progress_null_check(Node*& c, Node*& val, Node* evacuation_iff, Node* unc, Node* unc_ctrl, 3907 Node* unc_region, Unique_Node_List& uses, PhaseIdealLoop* phase) { 3908 if (unc != NULL) { 3909 // Clone the null check in this branch to allow implicit null check 3910 val = clone_null_check(c, val, unc_ctrl, unc_region, 2, phase); 3911 3912 fix_null_check(evacuation_iff, unc, unc_ctrl, unc_region, uses, phase); 3913 3914 IfNode* iff = unc_ctrl->in(0)->as_If(); 3915 phase->igvn().replace_input_of(iff, 1, phase->igvn().intcon(1)); 3916 } 3917 } 3918 3919 void ShenandoahWriteBarrierNode::in_cset_fast_test(Node*& c, Node* rbtrue, Node* raw_mem, Node* wb_mem, Node* region, Node* val_phi, Node* mem_phi, 3920 Node* raw_mem_phi, PhaseIdealLoop* phase) { 3921 if (ShenandoahWriteBarrierCsetTestInIR) { 3922 IdealLoopTree *loop = phase->get_loop(c); 3923 Node* raw_rbtrue = new CastP2XNode(c, rbtrue); 3924 phase->register_new_node(raw_rbtrue, c); 3925 Node* cset_offset = new URShiftXNode(raw_rbtrue, phase->igvn().intcon(ShenandoahHeapRegion::region_size_bytes_shift_jint())); 3926 phase->register_new_node(cset_offset, c); 3927 Node* in_cset_fast_test_base_addr = phase->igvn().makecon(TypeRawPtr::make(ShenandoahHeap::in_cset_fast_test_addr())); 3928 phase->set_ctrl(in_cset_fast_test_base_addr, phase->C->root()); 3929 Node* in_cset_fast_test_adr = new AddPNode(phase->C->top(), in_cset_fast_test_base_addr, cset_offset); 3930 phase->register_new_node(in_cset_fast_test_adr, c); 3931 uint in_cset_fast_test_idx = Compile::AliasIdxRaw; 3932 const TypePtr* in_cset_fast_test_adr_type = NULL; // debug-mode-only argument 3933 debug_only(in_cset_fast_test_adr_type = phase->C->get_adr_type(in_cset_fast_test_idx)); 3934 Node* in_cset_fast_test_load = new LoadUBNode(c, raw_mem, in_cset_fast_test_adr, in_cset_fast_test_adr_type, TypeInt::BOOL, MemNode::unordered); 3935 phase->register_new_node(in_cset_fast_test_load, c); 3936 Node* in_cset_fast_test_cmp = new CmpINode(in_cset_fast_test_load, phase->igvn().zerocon(T_INT)); 3937 phase->register_new_node(in_cset_fast_test_cmp, c); 3938 Node* in_cset_fast_test_test = new BoolNode(in_cset_fast_test_cmp, BoolTest::ne); 3939 phase->register_new_node(in_cset_fast_test_test, c); 3940 IfNode* in_cset_fast_test_iff = new IfNode(c, in_cset_fast_test_test, PROB_UNLIKELY(0.999), COUNT_UNKNOWN); 3941 phase->register_control(in_cset_fast_test_iff, loop, c); 3942 3943 Node* in_cset_fast_test_success = new IfFalseNode(in_cset_fast_test_iff); 3944 phase->register_control(in_cset_fast_test_success, loop, in_cset_fast_test_iff); 3945 3946 region->init_req(3, in_cset_fast_test_success); 3947 val_phi->init_req(3, rbtrue); 3948 mem_phi->init_req(3, wb_mem); 3949 raw_mem_phi->init_req(3, raw_mem); 3950 3951 Node* in_cset_fast_test_failure = new IfTrueNode(in_cset_fast_test_iff); 3952 phase->register_control(in_cset_fast_test_failure, loop, in_cset_fast_test_iff); 3953 3954 c = in_cset_fast_test_failure; 3955 } 3956 } 3957 3958 void ShenandoahWriteBarrierNode::evacuation_in_progress(Node* c, Node* val, Node* evacuation_iff, Node* unc, Node* unc_ctrl, 3959 Node* raw_mem, Node* wb_mem, Node* region, Node* val_phi, Node* mem_phi, 3960 Node* raw_mem_phi, Node* unc_region, int alias, Unique_Node_List& uses, 3961 PhaseIdealLoop* phase) { 3962 evacuation_in_progress_null_check(c, val, evacuation_iff, unc, unc_ctrl, unc_region, uses, phase); 3963 3964 IdealLoopTree *loop = phase->get_loop(c); 3965 Node* rbtrue = new ShenandoahReadBarrierNode(c, wb_mem, val); 3966 phase->register_new_node(rbtrue, c); 3967 3968 Node* in_cset_fast_test_failure = NULL; 3969 in_cset_fast_test(c, rbtrue, raw_mem, wb_mem, region, val_phi, mem_phi, raw_mem_phi, phase); 3970 3971 // The slow path stub consumes and produces raw memory in addition 3972 // to the existing memory edges 3973 Node* base = find_bottom_mem(c, phase); 3974 3975 MergeMemNode* mm = MergeMemNode::make(base); 3976 mm->set_memory_at(alias, wb_mem); 3977 mm->set_memory_at(Compile::AliasIdxRaw, raw_mem); 3978 phase->register_new_node(mm, c); 3979 3980 Node* call = new CallLeafNoFPNode(ShenandoahBarrierSetC2::shenandoah_write_barrier_Type(), ShenandoahBarrierSetAssembler::shenandoah_wb_C(), "shenandoah_write_barrier", TypeRawPtr::BOTTOM); 3981 call->init_req(TypeFunc::Control, c); 3982 call->init_req(TypeFunc::I_O, phase->C->top()); 3983 call->init_req(TypeFunc::Memory, mm); 3984 call->init_req(TypeFunc::FramePtr, phase->C->top()); 3985 call->init_req(TypeFunc::ReturnAdr, phase->C->top()); 3986 call->init_req(TypeFunc::Parms, rbtrue); 3987 phase->register_control(call, loop, c); 3988 Node* ctrl_proj = new ProjNode(call, TypeFunc::Control); 3989 phase->register_control(ctrl_proj, loop, call); 3990 Node* mem_proj = new ProjNode(call, TypeFunc::Memory); 3991 phase->register_new_node(mem_proj, call); 3992 Node* res_proj = new ProjNode(call, TypeFunc::Parms); 3993 phase->register_new_node(res_proj, call); 3994 Node* res = new CheckCastPPNode(ctrl_proj, res_proj, phase->igvn().type(val)->is_oopptr()->cast_to_nonconst()); 3995 phase->register_new_node(res, ctrl_proj); 3996 region->init_req(2, ctrl_proj); 3997 val_phi->init_req(2, res); 3998 mem_phi->init_req(2, mem_proj); 3999 raw_mem_phi->init_req(2, mem_proj); 4000 } 4001 4002 void ShenandoahWriteBarrierNode::pin_and_expand(PhaseIdealLoop* phase) { 4003 const bool trace = false; 4004 4005 // Collect raw memory state at CFG points in the entire graph and 4006 // record it in memory_nodes. Optimize the raw memory graph in the 4007 // process. Optimizing the memory graph also makes the memory graph 4008 // simpler. 4009 Node_List memory_nodes; 4010 collect_memory_nodes(Compile::AliasIdxRaw, memory_nodes, phase); 4011 4012 // Let's try to common write barriers again 4013 for (;;) { 4014 bool progress = false; 4015 for (int i = ShenandoahBarrierSetC2::bsc2()->state()->shenandoah_barriers_count(); i > 0; i--) { 4016 ShenandoahBarrierNode* wb = ShenandoahBarrierSetC2::bsc2()->state()->shenandoah_barrier(i-1); 4017 Node* ctrl = phase->get_ctrl(wb); 4018 if (wb->try_common(ctrl, phase) != NULL) { 4019 progress = true; 4020 } 4021 } 4022 if (!progress) { 4023 break; 4024 } 4025 } 4026 4027 Unique_Node_List uses; 4028 for (int i = 0; i < ShenandoahBarrierSetC2::bsc2()->state()->shenandoah_barriers_count(); i++) { 4029 ShenandoahWriteBarrierNode* wb = ShenandoahBarrierSetC2::bsc2()->state()->shenandoah_barrier(i); 4030 Node* ctrl = phase->get_ctrl(wb); 4031 4032 Node* val = wb->in(ValueIn); 4033 if (ctrl->is_Proj() && ctrl->in(0)->is_CallJava()) { 4034 assert(is_dominator(phase->get_ctrl(val), ctrl->in(0)->in(0), val, ctrl->in(0), phase), "can't move"); 4035 phase->set_ctrl(wb, ctrl->in(0)->in(0)); 4036 } else if (ctrl->is_CallRuntime()) { 4037 assert(is_dominator(phase->get_ctrl(val), ctrl->in(0), val, ctrl, phase), "can't move"); 4038 phase->set_ctrl(wb, ctrl->in(0)); 4039 } 4040 4041 assert(wb->Opcode() == Op_ShenandoahWriteBarrier, "only for write barriers"); 4042 // Look for a null check that dominates this barrier and move the 4043 // barrier right after the null check to enable implicit null 4044 // checks 4045 wb->pin_and_expand_move_barrier(phase, uses); 4046 4047 wb->pin_and_expand_helper(phase); 4048 } 4049 4050 Unique_Node_List uses_to_ignore; 4051 for (int i = ShenandoahBarrierSetC2::bsc2()->state()->shenandoah_barriers_count(); i > 0; i--) { 4052 int cnt = ShenandoahBarrierSetC2::bsc2()->state()->shenandoah_barriers_count(); 4053 ShenandoahWriteBarrierNode* wb = ShenandoahBarrierSetC2::bsc2()->state()->shenandoah_barrier(i-1); 4054 4055 uint last = phase->C->unique(); 4056 Node* ctrl = phase->get_ctrl(wb); 4057 4058 Node* raw_mem = find_raw_mem(ctrl, wb, memory_nodes, phase); 4059 Node* init_raw_mem = raw_mem; 4060 Node* raw_mem_for_ctrl = find_raw_mem(ctrl, NULL, memory_nodes, phase); 4061 int alias = phase->C->get_alias_index(wb->adr_type()); 4062 Node* wb_mem = wb->in(Memory); 4063 Node* init_wb_mem = wb_mem; 4064 4065 Node* val = wb->in(ValueIn); 4066 Node* wbproj = wb->find_out_with(Op_ShenandoahWBMemProj); 4067 IdealLoopTree *loop = phase->get_loop(ctrl); 4068 4069 assert(val->Opcode() != Op_ShenandoahWriteBarrier || phase->C->has_irreducible_loop(), "No chain of write barriers"); 4070 4071 CallStaticJavaNode* unc = wb->pin_and_expand_null_check(phase->igvn()); 4072 Node* unc_ctrl = NULL; 4073 if (unc != NULL) { 4074 if (val->in(0) != ctrl) { 4075 unc = NULL; 4076 } else { 4077 unc_ctrl = val->in(0); 4078 } 4079 } 4080 4081 Node* uncasted_val = val; 4082 if (unc != NULL) { 4083 uncasted_val = val->in(1); 4084 } 4085 4086 Node* evac_in_progress = NULL; 4087 Node* evac_not_in_progress = NULL; 4088 Node* heap_stable_ctrl = NULL; 4089 test_evacuation_in_progress(ctrl, alias, raw_mem, wb_mem, evac_in_progress, evac_not_in_progress, heap_stable_ctrl, phase); 4090 IfNode* evacuation_iff = evac_in_progress->in(0)->as_If(); 4091 IfNode* heap_stable_iff = heap_stable_ctrl->in(0)->as_If(); 4092 4093 Node* evacuation_region = new RegionNode(4); 4094 Node* evacuation_val_phi = new PhiNode(evacuation_region, uncasted_val->bottom_type()->is_oopptr()->cast_to_nonconst()); 4095 Node* evacuation_mem_phi = PhiNode::make(evacuation_region, wb_mem, Type::MEMORY, phase->C->alias_type(wb->adr_type())->adr_type()); 4096 Node* evacuation_raw_mem_phi = PhiNode::make(evacuation_region, raw_mem, Type::MEMORY, TypeRawPtr::BOTTOM); 4097 Node* region = new RegionNode(3); 4098 Node* val_phi = new PhiNode(region, uncasted_val->bottom_type()->is_oopptr()->cast_to_nonconst()); 4099 Node* mem_phi = PhiNode::make(region, wb_mem, Type::MEMORY, phase->C->alias_type(wb->adr_type())->adr_type()); 4100 Node* raw_mem_phi = PhiNode::make(region, raw_mem, Type::MEMORY, TypeRawPtr::BOTTOM); 4101 4102 Node* unc_region = NULL; 4103 evacuation_not_in_progress(evac_not_in_progress, val, unc_ctrl, raw_mem, wb_mem, 4104 evacuation_region, evacuation_val_phi, evacuation_mem_phi, evacuation_raw_mem_phi, unc_region, 4105 phase); 4106 4107 heap_stable(heap_stable_ctrl, val, unc_ctrl, init_raw_mem, init_wb_mem, region, val_phi, mem_phi, raw_mem_phi, 4108 unc_region, phase); 4109 4110 evacuation_in_progress(evac_in_progress, val, evacuation_iff, unc, unc_ctrl, 4111 raw_mem, wb_mem, evacuation_region, evacuation_val_phi, evacuation_mem_phi, evacuation_raw_mem_phi, 4112 unc_region, alias, uses, 4113 phase); 4114 region->init_req(2, evacuation_region); 4115 val_phi->init_req(2, evacuation_val_phi); 4116 mem_phi->init_req(2, evacuation_mem_phi); 4117 raw_mem_phi->init_req(2, evacuation_raw_mem_phi); 4118 phase->register_control(evacuation_region, loop, evacuation_iff); 4119 phase->register_new_node(evacuation_val_phi, evacuation_region); 4120 phase->register_new_node(evacuation_mem_phi, evacuation_region); 4121 phase->register_new_node(evacuation_raw_mem_phi, evacuation_region); 4122 4123 phase->register_control(region, loop, heap_stable_iff); 4124 4125 Node* out_val = val_phi; 4126 phase->register_new_node(val_phi, region); 4127 phase->register_new_node(mem_phi, region); 4128 phase->register_new_node(raw_mem_phi, region); 4129 4130 // Update the control of all nodes that should be after the 4131 // barrier control flow 4132 uses.clear(); 4133 // Every node that is control dependent on the barrier's input 4134 // control will be after the expanded barrier. The raw memory (if 4135 // its memory is control dependent on the barrier's input control) 4136 // must stay above the barrier. 4137 uses_to_ignore.clear(); 4138 if (phase->has_ctrl(init_raw_mem) && phase->get_ctrl(init_raw_mem) == ctrl && !init_raw_mem->is_Phi()) { 4139 uses_to_ignore.push(init_raw_mem); 4140 } 4141 for (uint next = 0; next < uses_to_ignore.size(); next++) { 4142 Node *n = uses_to_ignore.at(next); 4143 for (uint i = 0; i < n->req(); i++) { 4144 Node* in = n->in(i); 4145 if (in != NULL && phase->has_ctrl(in) && phase->get_ctrl(in) == ctrl) { 4146 uses_to_ignore.push(in); 4147 } 4148 } 4149 } 4150 for (DUIterator_Fast imax, i = ctrl->fast_outs(imax); i < imax; i++) { 4151 Node* u = ctrl->fast_out(i); 4152 if (u->_idx < last && 4153 u != wb && 4154 !uses_to_ignore.member(u) && 4155 (u->in(0) != ctrl || (!u->is_Region() && !u->is_Phi())) && 4156 (ctrl->Opcode() != Op_CatchProj || u->Opcode() != Op_CreateEx)) { 4157 Node* old_c = phase->ctrl_or_self(u); 4158 Node* c = old_c; 4159 if (c != ctrl || 4160 is_dominator_same_ctrl(old_c, wb, u, phase) || 4161 u->is_g1_marking_load()) { 4162 phase->igvn().rehash_node_delayed(u); 4163 int nb = u->replace_edge(ctrl, region); 4164 if (u->is_CFG()) { 4165 if (phase->idom(u) == ctrl) { 4166 phase->set_idom(u, region, phase->dom_depth(region)); 4167 } 4168 } else if (phase->get_ctrl(u) == ctrl) { 4169 assert(u != init_raw_mem, "should leave input raw mem above the barrier"); 4170 uses.push(u); 4171 } 4172 assert(nb == 1, "more than 1 ctrl input?"); 4173 --i, imax -= nb; 4174 } 4175 } 4176 } 4177 4178 if (wbproj != NULL) { 4179 phase->igvn().replace_input_of(wbproj, 0, phase->C->top()); 4180 phase->lazy_replace(wbproj, mem_phi); 4181 } 4182 if (unc != NULL) { 4183 for (DUIterator_Fast imax, i = val->fast_outs(imax); i < imax; i++) { 4184 Node* u = val->fast_out(i); 4185 Node* c = phase->ctrl_or_self(u); 4186 if (u != wb && (c != ctrl || is_dominator_same_ctrl(c, wb, u, phase))) { 4187 phase->igvn().rehash_node_delayed(u); 4188 int nb = u->replace_edge(val, out_val); 4189 --i, imax -= nb; 4190 } 4191 } 4192 if (val->outcnt() == 0) { 4193 phase->lazy_update(val, out_val); 4194 phase->igvn()._worklist.push(val); 4195 } 4196 } 4197 phase->lazy_replace(wb, out_val); 4198 4199 follow_barrier_uses(mem_phi, ctrl, uses, phase); 4200 follow_barrier_uses(out_val, ctrl, uses, phase); 4201 4202 for(uint next = 0; next < uses.size(); next++ ) { 4203 Node *n = uses.at(next); 4204 assert(phase->get_ctrl(n) == ctrl, "bad control"); 4205 assert(n != init_raw_mem, "should leave input raw mem above the barrier"); 4206 phase->set_ctrl(n, region); 4207 follow_barrier_uses(n, ctrl, uses, phase); 4208 } 4209 4210 // The slow path call produces memory: hook the raw memory phi 4211 // from the expanded write barrier with the rest of the graph 4212 // which may require adding memory phis at every post dominated 4213 // region and at enclosing loop heads. Use the memory state 4214 // collected in memory_nodes to fix the memory graph. Update that 4215 // memory state as we go. 4216 fix_raw_mem(ctrl,region, init_raw_mem, raw_mem_for_ctrl, raw_mem_phi, memory_nodes, uses, phase); 4217 assert(ShenandoahBarrierSetC2::bsc2()->state()->shenandoah_barriers_count() == cnt - 1, "not replaced"); 4218 } 4219 4220 assert(ShenandoahBarrierSetC2::bsc2()->state()->shenandoah_barriers_count() == 0, "all write barrier nodes should have been replaced"); 4221 } 4222 4223 void ShenandoahWriteBarrierNode::move_evacuation_test_out_of_loop(IfNode* iff, PhaseIdealLoop* phase) { 4224 // move test and its mem barriers out of the loop 4225 assert(is_evacuation_in_progress_test(iff), "inconsistent"); 4226 4227 IdealLoopTree *loop = phase->get_loop(iff); 4228 Node* loop_head = loop->_head; 4229 Node* entry_c = loop_head->in(LoopNode::EntryControl); 4230 4231 Node* load = iff->in(1)->in(1)->in(1)->in(1); 4232 assert(is_gc_state_load(load), "broken"); 4233 if (!phase->is_dominator(load->in(0), entry_c)) { 4234 Node* mem_ctrl = NULL; 4235 Node* mem = dom_mem(load->in(MemNode::Memory), loop_head, Compile::AliasIdxRaw, mem_ctrl, phase); 4236 phase->igvn().replace_input_of(load, MemNode::Memory, mem); 4237 phase->igvn().replace_input_of(load, 0, entry_c); 4238 phase->set_ctrl_and_loop(load, entry_c); 4239 } 4240 } 4241 4242 void ShenandoahWriteBarrierNode::move_heap_stable_test_out_of_loop(IfNode* iff, PhaseIdealLoop* phase) { 4243 IdealLoopTree *loop = phase->get_loop(iff); 4244 Node* loop_head = loop->_head; 4245 Node* entry_c = loop_head->in(LoopNode::EntryControl); 4246 4247 Node* load = iff->in(1)->in(1)->in(1); 4248 assert(is_gc_state_load(load), "broken"); 4249 if (!phase->is_dominator(load->in(0), entry_c)) { 4250 Node* mem_ctrl = NULL; 4251 Node* mem = dom_mem(load->in(MemNode::Memory), loop_head, Compile::AliasIdxRaw, mem_ctrl, phase); 4252 phase->igvn().replace_input_of(load, MemNode::Memory, mem); 4253 phase->igvn().replace_input_of(load, 0, entry_c); 4254 phase->set_ctrl_and_loop(load, entry_c); 4255 } 4256 } 4257 4258 void ShenandoahWriteBarrierNode::merge_back_to_back_tests(Node* n, PhaseIdealLoop* phase) { 4259 assert(is_evacuation_in_progress_test(n) || is_heap_stable_test(n), "no other tests"); 4260 if (phase->identical_backtoback_ifs(n)) { 4261 Node* n_ctrl = is_evacuation_in_progress_test(n) ? ShenandoahWriteBarrierNode::evacuation_in_progress_test_ctrl(n) : n->in(0); 4262 if (phase->can_split_if(n_ctrl)) { 4263 IfNode* dom_if = phase->idom(n_ctrl)->as_If(); 4264 if (is_heap_stable_test(n)) { 4265 Node* gc_state_load = n->in(1)->in(1)->in(1); 4266 assert(is_gc_state_load(gc_state_load), "broken"); 4267 Node* dom_gc_state_load = dom_if->in(1)->in(1)->in(1); 4268 assert(is_gc_state_load(dom_gc_state_load), "broken"); 4269 if (gc_state_load != dom_gc_state_load) { 4270 phase->igvn().replace_node(gc_state_load, dom_gc_state_load); 4271 } 4272 } 4273 PhiNode* bolphi = PhiNode::make_blank(n_ctrl, n->in(1)); 4274 Node* proj_true = dom_if->proj_out(1); 4275 Node* proj_false = dom_if->proj_out(0); 4276 Node* con_true = phase->igvn().makecon(TypeInt::ONE); 4277 Node* con_false = phase->igvn().makecon(TypeInt::ZERO); 4278 4279 for (uint i = 1; i < n_ctrl->req(); i++) { 4280 if (phase->is_dominator(proj_true, n_ctrl->in(i))) { 4281 bolphi->init_req(i, con_true); 4282 } else { 4283 assert(phase->is_dominator(proj_false, n_ctrl->in(i)), "bad if"); 4284 bolphi->init_req(i, con_false); 4285 } 4286 } 4287 phase->register_new_node(bolphi, n_ctrl); 4288 phase->igvn().replace_input_of(n, 1, bolphi); 4289 phase->do_split_if(n); 4290 } 4291 } 4292 } 4293 4294 void ShenandoahWriteBarrierNode::optimize_after_expansion(VectorSet &visited, Node_Stack &stack, Node_List &old_new, PhaseIdealLoop* phase) { 4295 Node_List heap_stable_tests; 4296 Node_List evacuation_tests; 4297 Node_List gc_state_loads; 4298 4299 stack.push(phase->C->start(), 0); 4300 do { 4301 Node* n = stack.node(); 4302 uint i = stack.index(); 4303 4304 if (i < n->outcnt()) { 4305 Node* u = n->raw_out(i); 4306 stack.set_index(i+1); 4307 if (!visited.test_set(u->_idx)) { 4308 stack.push(u, 0); 4309 } 4310 } else { 4311 stack.pop(); 4312 if (n->is_If() && ShenandoahWriteBarrierNode::is_evacuation_in_progress_test(n)) { 4313 evacuation_tests.push(n); 4314 } 4315 if (ShenandoahCommonGCStateLoads && ShenandoahWriteBarrierNode::is_gc_state_load(n)) { 4316 gc_state_loads.push(n); 4317 } 4318 if (n->is_If() && ShenandoahWriteBarrierNode::is_heap_stable_test(n)) { 4319 heap_stable_tests.push(n); 4320 } 4321 } 4322 } while (stack.size() > 0); 4323 4324 bool progress; 4325 do { 4326 progress = false; 4327 for (uint i = 0; i < gc_state_loads.size(); i++) { 4328 Node* n = gc_state_loads.at(i); 4329 if (n->outcnt() != 0) { 4330 progress |= ShenandoahWriteBarrierNode::try_common_gc_state_load(n, phase); 4331 } 4332 } 4333 } while (progress); 4334 4335 for (uint i = 0; i < heap_stable_tests.size(); i++) { 4336 Node* n = heap_stable_tests.at(i); 4337 assert(is_heap_stable_test(n), "only evacuation test"); 4338 merge_back_to_back_tests(n, phase); 4339 } 4340 4341 if (!phase->C->major_progress()) { 4342 for (uint i = 0; i < evacuation_tests.size(); i++) { 4343 Node* n = evacuation_tests.at(i); 4344 assert(is_evacuation_in_progress_test(n), "only evacuation test"); 4345 merge_back_to_back_tests(n, phase); 4346 } 4347 } 4348 4349 if (!phase->C->major_progress()) { 4350 VectorSet seen(Thread::current()->resource_area()); 4351 for (uint i = 0; i < heap_stable_tests.size(); i++) { 4352 Node* n = heap_stable_tests.at(i); 4353 IdealLoopTree* loop = phase->get_loop(n); 4354 if (loop != phase->ltree_root() && 4355 loop->_child == NULL && 4356 !loop->_irreducible) { 4357 LoopNode* head = loop->_head->as_Loop(); 4358 if ((!head->is_CountedLoop() || head->as_CountedLoop()->is_main_loop() || head->as_CountedLoop()->is_normal_loop()) && 4359 !seen.test_set(head->_idx) && 4360 loop->policy_unswitching(phase, true)) { 4361 IfNode* iff = phase->find_unswitching_candidate(loop, true); 4362 if (iff != NULL && (is_evacuation_in_progress_test(iff) || is_heap_stable_test(iff))) { 4363 if (head->is_strip_mined()) { 4364 head->verify_strip_mined(0); 4365 OuterStripMinedLoopNode* outer = head->as_CountedLoop()->outer_loop(); 4366 OuterStripMinedLoopEndNode* le = head->outer_loop_end(); 4367 Node* new_outer = new LoopNode(outer->in(LoopNode::EntryControl), outer->in(LoopNode::LoopBackControl)); 4368 phase->register_control(new_outer, phase->get_loop(outer), outer->in(LoopNode::EntryControl)); 4369 Node* new_le = new IfNode(le->in(0), le->in(1), le->_prob, le->_fcnt); 4370 phase->register_control(new_le, phase->get_loop(le), le->in(0)); 4371 phase->lazy_replace(outer, new_outer); 4372 phase->lazy_replace(le, new_le); 4373 head->clear_strip_mined(); 4374 } 4375 phase->do_unswitching(loop, old_new, true); 4376 } 4377 } 4378 } 4379 } 4380 } 4381 } 4382 4383 #ifdef ASSERT 4384 void ShenandoahBarrierNode::verify_raw_mem(RootNode* root) { 4385 const bool trace = false; 4386 ResourceMark rm; 4387 Unique_Node_List nodes; 4388 Unique_Node_List controls; 4389 Unique_Node_List memories; 4390 4391 nodes.push(root); 4392 for (uint next = 0; next < nodes.size(); next++) { 4393 Node *n = nodes.at(next); 4394 if (n->Opcode() == Op_CallLeafNoFP && n->as_Call()->_entry_point == ShenandoahBarrierSetAssembler::shenandoah_wb_C()) { 4395 controls.push(n); 4396 if (trace) { tty->print("XXXXXX verifying"); n->dump(); } 4397 for (uint next2 = 0; next2 < controls.size(); next2++) { 4398 Node *m = controls.at(next2); 4399 if (!m->is_Loop() || controls.member(m->in(LoopNode::EntryControl)) || 1) { 4400 for (DUIterator_Fast imax, i = m->fast_outs(imax); i < imax; i++) { 4401 Node* u = m->fast_out(i); 4402 if (u->is_CFG() && !u->is_Root() && 4403 !(u->Opcode() == Op_CProj && u->in(0)->Opcode() == Op_NeverBranch && u->as_Proj()->_con == 1) && 4404 !(u->is_Region() && u->unique_ctrl_out()->Opcode() == Op_Halt)) { 4405 if (trace) { tty->print("XXXXXX pushing control"); u->dump(); } 4406 controls.push(u); 4407 } 4408 } 4409 } 4410 } 4411 memories.push(n->as_Call()->proj_out(TypeFunc::Memory)); 4412 for (uint next2 = 0; next2 < memories.size(); next2++) { 4413 Node *m = memories.at(next2); 4414 assert(m->bottom_type() == Type::MEMORY, ""); 4415 if (!m->is_Phi() || !m->in(0)->is_Loop() || controls.member(m->in(0)->in(LoopNode::EntryControl)) || 1) { 4416 for (DUIterator_Fast imax, i = m->fast_outs(imax); i < imax; i++) { 4417 Node* u = m->fast_out(i); 4418 if (u->bottom_type() == Type::MEMORY && (u->is_Mem() || u->is_ClearArray())) { 4419 if (trace) { tty->print("XXXXXX pushing memory"); u->dump(); } 4420 memories.push(u); 4421 } else if (u->is_LoadStore()) { 4422 if (trace) { tty->print("XXXXXX pushing memory"); u->find_out_with(Op_SCMemProj)->dump(); } 4423 memories.push(u->find_out_with(Op_SCMemProj)); 4424 } else if (u->is_MergeMem() && u->as_MergeMem()->memory_at(Compile::AliasIdxRaw) == m) { 4425 if (trace) { tty->print("XXXXXX pushing memory"); u->dump(); } 4426 memories.push(u); 4427 } else if (u->is_Phi()) { 4428 assert(u->bottom_type() == Type::MEMORY, ""); 4429 if (u->adr_type() == TypeRawPtr::BOTTOM || u->adr_type() == TypePtr::BOTTOM) { 4430 assert(controls.member(u->in(0)), ""); 4431 if (trace) { tty->print("XXXXXX pushing memory"); u->dump(); } 4432 memories.push(u); 4433 } 4434 } else if (u->is_SafePoint() || u->is_MemBar()) { 4435 for (DUIterator_Fast jmax, j = u->fast_outs(jmax); j < jmax; j++) { 4436 Node* uu = u->fast_out(j); 4437 if (uu->bottom_type() == Type::MEMORY) { 4438 if (trace) { tty->print("XXXXXX pushing memory"); uu->dump(); } 4439 memories.push(uu); 4440 } 4441 } 4442 } 4443 } 4444 } 4445 } 4446 for (uint next2 = 0; next2 < controls.size(); next2++) { 4447 Node *m = controls.at(next2); 4448 if (m->is_Region()) { 4449 bool all_in = true; 4450 for (uint i = 1; i < m->req(); i++) { 4451 if (!controls.member(m->in(i))) { 4452 all_in = false; 4453 break; 4454 } 4455 } 4456 if (trace) { tty->print("XXX verifying %s", all_in ? "all in" : ""); m->dump(); } 4457 bool found_phi = false; 4458 for (DUIterator_Fast jmax, j = m->fast_outs(jmax); j < jmax && !found_phi; j++) { 4459 Node* u = m->fast_out(j); 4460 if (u->is_Phi() && memories.member(u)) { 4461 found_phi = true; 4462 for (uint i = 1; i < u->req() && found_phi; i++) { 4463 Node* k = u->in(i); 4464 if (memories.member(k) != controls.member(m->in(i))) { 4465 found_phi = false; 4466 } 4467 } 4468 } 4469 } 4470 assert(found_phi || all_in, ""); 4471 } 4472 } 4473 controls.clear(); 4474 memories.clear(); 4475 } 4476 for( uint i = 0; i < n->len(); ++i ) { 4477 Node *m = n->in(i); 4478 if (m != NULL) { 4479 nodes.push(m); 4480 } 4481 } 4482 } 4483 } 4484 #endif 4485 4486 static bool is_on_null_check_path(Block* b, Block* null_check_block) { 4487 if (null_check_block == NULL) { 4488 return false; 4489 } 4490 do { 4491 assert(null_check_block->_num_succs == 1, "only one succ on the path to unc"); 4492 if (b == null_check_block) { 4493 return true; 4494 } 4495 null_check_block = null_check_block->_succs[0]; 4496 } while(!null_check_block->head()->is_Root()); 4497 4498 return false; 4499 } 4500 4501 int PhaseCFG::replace_uses_with_shenandoah_barrier_helper(Node* n, Node* use, Node* val, Block* block, Block* null_check_block) { 4502 int nb = 0; 4503 Block* buse = get_block_for_node(use); 4504 if (is_on_null_check_path(buse, null_check_block)) { 4505 return 0; 4506 } 4507 if (use->is_Phi()) { 4508 for (uint j = 1; j < use->req(); j++) { 4509 if (use->in(j) == val) { 4510 Block* b = get_block_for_node(use->in(0)->in(j)); 4511 if ((block != b && block->dom_lca(b) == block) || 4512 block == b) { 4513 use->set_req(j, n); 4514 nb++; 4515 } 4516 } 4517 } 4518 } else { 4519 if ((block != buse && block->dom_lca(buse) == block) || 4520 (block == buse && !use->is_scheduled())) { 4521 // Let precedence edges alone (can confuse anti-dependence verification code) 4522 for (uint i = 0; i < use->req(); i++) { 4523 if (use->in(i) == val) { 4524 use->set_req(i, n); 4525 nb++; 4526 } 4527 } 4528 assert(nb > 0 || use->find_prec_edge(val) != -1, "no replacement?"); 4529 } 4530 } 4531 4532 return nb; 4533 } 4534 4535 void PhaseCFG::replace_uses_with_shenandoah_barrier(Node* n, Block* block, Node_List& worklist, GrowableArray<int>& ready_cnt, uint max_idx, uint& phi_cnt) { 4536 // Replace all uses of barrier's input that are dominated by the 4537 // barrier with the value returned by the barrier: no need to keep 4538 // both live. 4539 if (n->is_Mach() && n->as_Mach()->ideal_Opcode() == Op_ShenandoahReadBarrier) { 4540 MachNullCheckNode* null_check = NULL; 4541 for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax && null_check == NULL; i++) { 4542 Node* use = n->fast_out(i); 4543 if (use->is_MachNullCheck()) { 4544 null_check = use->as_MachNullCheck(); 4545 } 4546 } 4547 Block* null_check_block = NULL; 4548 if (null_check != NULL) { 4549 Node* proj = null_check->find_out_with(Op_IfTrue); 4550 Node* head = proj->unique_out(); 4551 null_check_block = get_block_for_node(head); 4552 } 4553 4554 Node* val = n->in(ShenandoahBarrierNode::ValueIn); 4555 if (!val->bottom_type()->isa_narrowoop()) { 4556 for (DUIterator_Fast imax, i = val->fast_outs(imax); i < imax; i++) { 4557 Node* use = val->fast_out(i); 4558 if (use != n) { 4559 int nb = replace_uses_with_shenandoah_barrier_helper(n, use, val, block, null_check_block); 4560 if (nb > 0) { 4561 --i; imax -= nb; 4562 } 4563 } 4564 } 4565 } else { 4566 for (DUIterator_Fast imax, i = val->fast_outs(imax); i < imax; i++) { 4567 Node* u = val->fast_out(i); 4568 if (u->is_Mach() && u->as_Mach()->ideal_Opcode() == Op_DecodeN) { 4569 int projs = 0; 4570 for (DUIterator_Fast jmax, j = u->fast_outs(jmax); j < jmax; j++) { 4571 Node* uu = u->fast_out(j); 4572 assert(!uu->is_MachTemp(), ""); 4573 if (uu->is_MachProj() && uu->outcnt() == 0) { 4574 projs++; 4575 } else { 4576 int nb = replace_uses_with_shenandoah_barrier_helper(n, uu, u, block, null_check_block); 4577 if (nb > 0) { 4578 if (!u->is_scheduled()) { 4579 push_ready_nodes(n, uu, block, ready_cnt, worklist, max_idx, nb); 4580 } 4581 --j; jmax -= nb; 4582 } 4583 } 4584 } 4585 // The DecodeN may have gone dead 4586 if (u->outcnt() - projs == 0) { 4587 u->disconnect_inputs(NULL, C); 4588 Block* bu = get_block_for_node(u); 4589 unmap_node_from_block(u); 4590 if (bu == block) { 4591 if (u->is_scheduled()) { 4592 block->find_remove(u); 4593 phi_cnt--; 4594 } else { 4595 worklist.yank(u); 4596 block->remove_node(block->end_idx()-1); 4597 } 4598 } else { 4599 bu->find_remove(u); 4600 } 4601 for (DUIterator_Fast jmax, j = u->fast_outs(jmax); j < jmax; j++) { 4602 Node* uu = u->fast_out(j); 4603 assert(uu->is_MachProj() && uu->outcnt() == 0, ""); 4604 assert(bu == get_block_for_node(uu), ""); 4605 uu->disconnect_inputs(NULL, C); 4606 --j; --jmax; 4607 unmap_node_from_block(uu); 4608 if (bu == block) { 4609 if (u->is_scheduled()) { 4610 block->find_remove(uu); 4611 phi_cnt--; 4612 } else { 4613 worklist.yank(uu); 4614 block->remove_node(block->end_idx()-1); 4615 } 4616 } else { 4617 bu->find_remove(uu); 4618 } 4619 assert(uu->is_scheduled() == u->is_scheduled(), ""); 4620 } 4621 --i; --imax; 4622 } 4623 } 4624 } 4625 } 4626 } 4627 }