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