1 /* 2 * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #include "code/vmreg.inline.hpp" 26 #include "gc/shared/barrierSet.hpp" 27 #include "gc/shared/tlab_globals.hpp" 28 #include "gc/shared/c2/barrierSetC2.hpp" 29 #include "opto/arraycopynode.hpp" 30 #include "opto/block.hpp" 31 #include "opto/convertnode.hpp" 32 #include "opto/graphKit.hpp" 33 #include "opto/idealKit.hpp" 34 #include "opto/macro.hpp" 35 #include "opto/narrowptrnode.hpp" 36 #include "opto/output.hpp" 37 #include "opto/regalloc.hpp" 38 #include "opto/runtime.hpp" 39 #include "utilities/macros.hpp" 40 #include CPU_HEADER(gc/shared/barrierSetAssembler) 41 42 // By default this is a no-op. 43 void BarrierSetC2::resolve_address(C2Access& access) const { } 44 45 void* C2ParseAccess::barrier_set_state() const { 46 return _kit->barrier_set_state(); 47 } 48 49 PhaseGVN& C2ParseAccess::gvn() const { return _kit->gvn(); } 50 51 Node* C2ParseAccess::control() const { 52 return _ctl == nullptr ? _kit->control() : _ctl; 53 } 54 55 bool C2Access::needs_cpu_membar() const { 56 bool mismatched = (_decorators & C2_MISMATCHED) != 0; 57 bool is_unordered = (_decorators & MO_UNORDERED) != 0; 58 59 bool anonymous = (_decorators & C2_UNSAFE_ACCESS) != 0; 60 bool in_heap = (_decorators & IN_HEAP) != 0; 61 bool in_native = (_decorators & IN_NATIVE) != 0; 62 bool is_mixed = !in_heap && !in_native; 63 64 bool is_write = (_decorators & C2_WRITE_ACCESS) != 0; 65 bool is_read = (_decorators & C2_READ_ACCESS) != 0; 66 bool is_atomic = is_read && is_write; 67 68 if (is_atomic) { 69 // Atomics always need to be wrapped in CPU membars 70 return true; 71 } 72 73 if (anonymous) { 74 // We will need memory barriers unless we can determine a unique 75 // alias category for this reference. (Note: If for some reason 76 // the barriers get omitted and the unsafe reference begins to "pollute" 77 // the alias analysis of the rest of the graph, either Compile::can_alias 78 // or Compile::must_alias will throw a diagnostic assert.) 79 if (is_mixed || !is_unordered || (mismatched && !_addr.type()->isa_aryptr())) { 80 return true; 81 } 82 } else { 83 assert(!is_mixed, "not unsafe"); 84 } 85 86 return false; 87 } 88 89 static BarrierSetC2State* barrier_set_state() { 90 return reinterpret_cast<BarrierSetC2State*>(Compile::current()->barrier_set_state()); 91 } 92 93 RegMask& BarrierStubC2::live() const { 94 return *barrier_set_state()->live(_node); 95 } 96 97 BarrierStubC2::BarrierStubC2(const MachNode* node) 98 : _node(node), 99 _entry(), 100 _continuation(), 101 _preserve(live()) {} 102 103 Label* BarrierStubC2::entry() { 104 // The _entry will never be bound when in_scratch_emit_size() is true. 105 // However, we still need to return a label that is not bound now, but 106 // will eventually be bound. Any eventually bound label will do, as it 107 // will only act as a placeholder, so we return the _continuation label. 108 return Compile::current()->output()->in_scratch_emit_size() ? &_continuation : &_entry; 109 } 110 111 Label* BarrierStubC2::continuation() { 112 return &_continuation; 113 } 114 115 uint8_t BarrierStubC2::barrier_data() const { 116 return _node->barrier_data(); 117 } 118 119 void BarrierStubC2::preserve(Register r) { 120 const VMReg vm_reg = r->as_VMReg(); 121 assert(vm_reg->is_Register(), "r must be a general-purpose register"); 122 _preserve.Insert(OptoReg::as_OptoReg(vm_reg)); 123 } 124 125 void BarrierStubC2::dont_preserve(Register r) { 126 VMReg vm_reg = r->as_VMReg(); 127 assert(vm_reg->is_Register(), "r must be a general-purpose register"); 128 // Subtract the given register and all its sub-registers (e.g. {R11, R11_H} 129 // for r11 in aarch64). 130 do { 131 _preserve.Remove(OptoReg::as_OptoReg(vm_reg)); 132 vm_reg = vm_reg->next(); 133 } while (vm_reg->is_Register() && !vm_reg->is_concrete()); 134 } 135 136 const RegMask& BarrierStubC2::preserve_set() const { 137 return _preserve; 138 } 139 140 Node* BarrierSetC2::store_at_resolved(C2Access& access, C2AccessValue& val) const { 141 DecoratorSet decorators = access.decorators(); 142 143 bool mismatched = (decorators & C2_MISMATCHED) != 0; 144 bool unaligned = (decorators & C2_UNALIGNED) != 0; 145 bool unsafe = (decorators & C2_UNSAFE_ACCESS) != 0; 146 bool requires_atomic_access = (decorators & MO_UNORDERED) == 0; 147 148 MemNode::MemOrd mo = access.mem_node_mo(); 149 150 Node* store; 151 BasicType bt = access.type(); 152 if (access.is_parse_access()) { 153 C2ParseAccess& parse_access = static_cast<C2ParseAccess&>(access); 154 155 GraphKit* kit = parse_access.kit(); 156 if (bt == T_DOUBLE) { 157 Node* new_val = kit->dprecision_rounding(val.node()); 158 val.set_node(new_val); 159 } 160 161 store = kit->store_to_memory(kit->control(), access.addr().node(), val.node(), bt, 162 mo, requires_atomic_access, unaligned, mismatched, 163 unsafe, access.barrier_data()); 164 } else { 165 assert(access.is_opt_access(), "either parse or opt access"); 166 C2OptAccess& opt_access = static_cast<C2OptAccess&>(access); 167 Node* ctl = opt_access.ctl(); 168 MergeMemNode* mm = opt_access.mem(); 169 PhaseGVN& gvn = opt_access.gvn(); 170 const TypePtr* adr_type = access.addr().type(); 171 int alias = gvn.C->get_alias_index(adr_type); 172 Node* mem = mm->memory_at(alias); 173 174 StoreNode* st = StoreNode::make(gvn, ctl, mem, access.addr().node(), adr_type, val.node(), bt, mo, requires_atomic_access); 175 if (unaligned) { 176 st->set_unaligned_access(); 177 } 178 if (mismatched) { 179 st->set_mismatched_access(); 180 } 181 st->set_barrier_data(access.barrier_data()); 182 store = gvn.transform(st); 183 if (store == st) { 184 mm->set_memory_at(alias, st); 185 } 186 } 187 access.set_raw_access(store); 188 189 return store; 190 } 191 192 Node* BarrierSetC2::load_at_resolved(C2Access& access, const Type* val_type) const { 193 DecoratorSet decorators = access.decorators(); 194 195 Node* adr = access.addr().node(); 196 const TypePtr* adr_type = access.addr().type(); 197 198 bool mismatched = (decorators & C2_MISMATCHED) != 0; 199 bool requires_atomic_access = (decorators & MO_UNORDERED) == 0; 200 bool unaligned = (decorators & C2_UNALIGNED) != 0; 201 bool control_dependent = (decorators & C2_CONTROL_DEPENDENT_LOAD) != 0; 202 bool unknown_control = (decorators & C2_UNKNOWN_CONTROL_LOAD) != 0; 203 bool unsafe = (decorators & C2_UNSAFE_ACCESS) != 0; 204 bool immutable = (decorators & C2_IMMUTABLE_MEMORY) != 0; 205 206 MemNode::MemOrd mo = access.mem_node_mo(); 207 LoadNode::ControlDependency dep = unknown_control ? LoadNode::UnknownControl : LoadNode::DependsOnlyOnTest; 208 209 Node* load; 210 if (access.is_parse_access()) { 211 C2ParseAccess& parse_access = static_cast<C2ParseAccess&>(access); 212 GraphKit* kit = parse_access.kit(); 213 Node* control = control_dependent ? parse_access.control() : nullptr; 214 215 if (immutable) { 216 Compile* C = Compile::current(); 217 Node* mem = kit->immutable_memory(); 218 load = LoadNode::make(kit->gvn(), control, mem, adr, 219 adr_type, val_type, access.type(), mo, dep, requires_atomic_access, 220 unaligned, mismatched, unsafe, access.barrier_data()); 221 load = kit->gvn().transform(load); 222 } else { 223 load = kit->make_load(control, adr, val_type, access.type(), mo, 224 dep, requires_atomic_access, unaligned, mismatched, unsafe, 225 access.barrier_data()); 226 } 227 } else { 228 assert(access.is_opt_access(), "either parse or opt access"); 229 C2OptAccess& opt_access = static_cast<C2OptAccess&>(access); 230 Node* control = control_dependent ? opt_access.ctl() : nullptr; 231 MergeMemNode* mm = opt_access.mem(); 232 PhaseGVN& gvn = opt_access.gvn(); 233 Node* mem = mm->memory_at(gvn.C->get_alias_index(adr_type)); 234 load = LoadNode::make(gvn, control, mem, adr, adr_type, val_type, access.type(), mo, dep, 235 requires_atomic_access, unaligned, mismatched, unsafe, access.barrier_data()); 236 load = gvn.transform(load); 237 } 238 access.set_raw_access(load); 239 240 return load; 241 } 242 243 class C2AccessFence: public StackObj { 244 C2Access& _access; 245 Node* _leading_membar; 246 247 public: 248 C2AccessFence(C2Access& access) : 249 _access(access), _leading_membar(nullptr) { 250 GraphKit* kit = nullptr; 251 if (access.is_parse_access()) { 252 C2ParseAccess& parse_access = static_cast<C2ParseAccess&>(access); 253 kit = parse_access.kit(); 254 } 255 DecoratorSet decorators = access.decorators(); 256 257 bool is_write = (decorators & C2_WRITE_ACCESS) != 0; 258 bool is_read = (decorators & C2_READ_ACCESS) != 0; 259 bool is_atomic = is_read && is_write; 260 261 bool is_volatile = (decorators & MO_SEQ_CST) != 0; 262 bool is_release = (decorators & MO_RELEASE) != 0; 263 264 if (is_atomic) { 265 assert(kit != nullptr, "unsupported at optimization time"); 266 // Memory-model-wise, a LoadStore acts like a little synchronized 267 // block, so needs barriers on each side. These don't translate 268 // into actual barriers on most machines, but we still need rest of 269 // compiler to respect ordering. 270 if (is_release) { 271 _leading_membar = kit->insert_mem_bar(Op_MemBarRelease); 272 } else if (is_volatile) { 273 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 274 _leading_membar = kit->insert_mem_bar(Op_MemBarVolatile); 275 } else { 276 _leading_membar = kit->insert_mem_bar(Op_MemBarRelease); 277 } 278 } 279 } else if (is_write) { 280 // If reference is volatile, prevent following memory ops from 281 // floating down past the volatile write. Also prevents commoning 282 // another volatile read. 283 if (is_volatile || is_release) { 284 assert(kit != nullptr, "unsupported at optimization time"); 285 _leading_membar = kit->insert_mem_bar(Op_MemBarRelease); 286 } 287 } else { 288 // Memory barrier to prevent normal and 'unsafe' accesses from 289 // bypassing each other. Happens after null checks, so the 290 // exception paths do not take memory state from the memory barrier, 291 // so there's no problems making a strong assert about mixing users 292 // of safe & unsafe memory. 293 if (is_volatile && support_IRIW_for_not_multiple_copy_atomic_cpu) { 294 assert(kit != nullptr, "unsupported at optimization time"); 295 _leading_membar = kit->insert_mem_bar(Op_MemBarVolatile); 296 } 297 } 298 299 if (access.needs_cpu_membar()) { 300 assert(kit != nullptr, "unsupported at optimization time"); 301 kit->insert_mem_bar(Op_MemBarCPUOrder); 302 } 303 304 if (is_atomic) { 305 // 4984716: MemBars must be inserted before this 306 // memory node in order to avoid a false 307 // dependency which will confuse the scheduler. 308 access.set_memory(); 309 } 310 } 311 312 ~C2AccessFence() { 313 GraphKit* kit = nullptr; 314 if (_access.is_parse_access()) { 315 C2ParseAccess& parse_access = static_cast<C2ParseAccess&>(_access); 316 kit = parse_access.kit(); 317 } 318 DecoratorSet decorators = _access.decorators(); 319 320 bool is_write = (decorators & C2_WRITE_ACCESS) != 0; 321 bool is_read = (decorators & C2_READ_ACCESS) != 0; 322 bool is_atomic = is_read && is_write; 323 324 bool is_volatile = (decorators & MO_SEQ_CST) != 0; 325 bool is_acquire = (decorators & MO_ACQUIRE) != 0; 326 327 // If reference is volatile, prevent following volatiles ops from 328 // floating up before the volatile access. 329 if (_access.needs_cpu_membar()) { 330 kit->insert_mem_bar(Op_MemBarCPUOrder); 331 } 332 333 if (is_atomic) { 334 assert(kit != nullptr, "unsupported at optimization time"); 335 if (is_acquire || is_volatile) { 336 Node* n = _access.raw_access(); 337 Node* mb = kit->insert_mem_bar(Op_MemBarAcquire, n); 338 if (_leading_membar != nullptr) { 339 MemBarNode::set_load_store_pair(_leading_membar->as_MemBar(), mb->as_MemBar()); 340 } 341 } 342 } else if (is_write) { 343 // If not multiple copy atomic, we do the MemBarVolatile before the load. 344 if (is_volatile && !support_IRIW_for_not_multiple_copy_atomic_cpu) { 345 assert(kit != nullptr, "unsupported at optimization time"); 346 Node* n = _access.raw_access(); 347 Node* mb = kit->insert_mem_bar(Op_MemBarVolatile, n); // Use fat membar 348 if (_leading_membar != nullptr) { 349 MemBarNode::set_store_pair(_leading_membar->as_MemBar(), mb->as_MemBar()); 350 } 351 } 352 } else { 353 if (is_volatile || is_acquire) { 354 assert(kit != nullptr, "unsupported at optimization time"); 355 Node* n = _access.raw_access(); 356 assert(_leading_membar == nullptr || support_IRIW_for_not_multiple_copy_atomic_cpu, "no leading membar expected"); 357 Node* mb = kit->insert_mem_bar(Op_MemBarAcquire, n); 358 mb->as_MemBar()->set_trailing_load(); 359 } 360 } 361 } 362 }; 363 364 Node* BarrierSetC2::store_at(C2Access& access, C2AccessValue& val) const { 365 C2AccessFence fence(access); 366 resolve_address(access); 367 return store_at_resolved(access, val); 368 } 369 370 Node* BarrierSetC2::load_at(C2Access& access, const Type* val_type) const { 371 C2AccessFence fence(access); 372 resolve_address(access); 373 return load_at_resolved(access, val_type); 374 } 375 376 MemNode::MemOrd C2Access::mem_node_mo() const { 377 bool is_write = (_decorators & C2_WRITE_ACCESS) != 0; 378 bool is_read = (_decorators & C2_READ_ACCESS) != 0; 379 if ((_decorators & MO_SEQ_CST) != 0) { 380 if (is_write && is_read) { 381 // For atomic operations 382 return MemNode::seqcst; 383 } else if (is_write) { 384 return MemNode::release; 385 } else { 386 assert(is_read, "what else?"); 387 return MemNode::acquire; 388 } 389 } else if ((_decorators & MO_RELEASE) != 0) { 390 return MemNode::release; 391 } else if ((_decorators & MO_ACQUIRE) != 0) { 392 return MemNode::acquire; 393 } else if (is_write) { 394 // Volatile fields need releasing stores. 395 // Non-volatile fields also need releasing stores if they hold an 396 // object reference, because the object reference might point to 397 // a freshly created object. 398 // Conservatively release stores of object references. 399 return StoreNode::release_if_reference(_type); 400 } else { 401 return MemNode::unordered; 402 } 403 } 404 405 void C2Access::fixup_decorators() { 406 bool default_mo = (_decorators & MO_DECORATOR_MASK) == 0; 407 bool is_unordered = (_decorators & MO_UNORDERED) != 0 || default_mo; 408 bool anonymous = (_decorators & C2_UNSAFE_ACCESS) != 0; 409 410 bool is_read = (_decorators & C2_READ_ACCESS) != 0; 411 bool is_write = (_decorators & C2_WRITE_ACCESS) != 0; 412 413 if (AlwaysAtomicAccesses && is_unordered) { 414 _decorators &= ~MO_DECORATOR_MASK; // clear the MO bits 415 _decorators |= MO_RELAXED; // Force the MO_RELAXED decorator with AlwaysAtomicAccess 416 } 417 418 _decorators = AccessInternal::decorator_fixup(_decorators, _type); 419 420 if (is_read && !is_write && anonymous) { 421 // To be valid, unsafe loads may depend on other conditions than 422 // the one that guards them: pin the Load node 423 _decorators |= C2_CONTROL_DEPENDENT_LOAD; 424 _decorators |= C2_UNKNOWN_CONTROL_LOAD; 425 const TypePtr* adr_type = _addr.type(); 426 Node* adr = _addr.node(); 427 if (!needs_cpu_membar() && adr_type->isa_instptr()) { 428 assert(adr_type->meet(TypePtr::NULL_PTR) != adr_type->remove_speculative(), "should be not null"); 429 intptr_t offset = Type::OffsetBot; 430 AddPNode::Ideal_base_and_offset(adr, &gvn(), offset); 431 if (offset >= 0) { 432 int s = Klass::layout_helper_size_in_bytes(adr_type->isa_instptr()->instance_klass()->layout_helper()); 433 if (offset < s) { 434 // Guaranteed to be a valid access, no need to pin it 435 _decorators ^= C2_CONTROL_DEPENDENT_LOAD; 436 _decorators ^= C2_UNKNOWN_CONTROL_LOAD; 437 } 438 } 439 } 440 } 441 } 442 443 //--------------------------- atomic operations--------------------------------- 444 445 void BarrierSetC2::pin_atomic_op(C2AtomicParseAccess& access) const { 446 // SCMemProjNodes represent the memory state of a LoadStore. Their 447 // main role is to prevent LoadStore nodes from being optimized away 448 // when their results aren't used. 449 assert(access.is_parse_access(), "entry not supported at optimization time"); 450 C2ParseAccess& parse_access = static_cast<C2ParseAccess&>(access); 451 GraphKit* kit = parse_access.kit(); 452 Node* load_store = access.raw_access(); 453 assert(load_store != nullptr, "must pin atomic op"); 454 Node* proj = kit->gvn().transform(new SCMemProjNode(load_store)); 455 kit->set_memory(proj, access.alias_idx()); 456 } 457 458 void C2AtomicParseAccess::set_memory() { 459 Node *mem = _kit->memory(_alias_idx); 460 _memory = mem; 461 } 462 463 Node* BarrierSetC2::atomic_cmpxchg_val_at_resolved(C2AtomicParseAccess& access, Node* expected_val, 464 Node* new_val, const Type* value_type) const { 465 GraphKit* kit = access.kit(); 466 MemNode::MemOrd mo = access.mem_node_mo(); 467 Node* mem = access.memory(); 468 469 Node* adr = access.addr().node(); 470 const TypePtr* adr_type = access.addr().type(); 471 472 Node* load_store = nullptr; 473 474 if (access.is_oop()) { 475 #ifdef _LP64 476 if (adr->bottom_type()->is_ptr_to_narrowoop()) { 477 Node *newval_enc = kit->gvn().transform(new EncodePNode(new_val, new_val->bottom_type()->make_narrowoop())); 478 Node *oldval_enc = kit->gvn().transform(new EncodePNode(expected_val, expected_val->bottom_type()->make_narrowoop())); 479 load_store = new CompareAndExchangeNNode(kit->control(), mem, adr, newval_enc, oldval_enc, adr_type, value_type->make_narrowoop(), mo); 480 } else 481 #endif 482 { 483 load_store = new CompareAndExchangePNode(kit->control(), mem, adr, new_val, expected_val, adr_type, value_type->is_oopptr(), mo); 484 } 485 } else { 486 switch (access.type()) { 487 case T_BYTE: { 488 load_store = new CompareAndExchangeBNode(kit->control(), mem, adr, new_val, expected_val, adr_type, mo); 489 break; 490 } 491 case T_SHORT: { 492 load_store = new CompareAndExchangeSNode(kit->control(), mem, adr, new_val, expected_val, adr_type, mo); 493 break; 494 } 495 case T_INT: { 496 load_store = new CompareAndExchangeINode(kit->control(), mem, adr, new_val, expected_val, adr_type, mo); 497 break; 498 } 499 case T_LONG: { 500 load_store = new CompareAndExchangeLNode(kit->control(), mem, adr, new_val, expected_val, adr_type, mo); 501 break; 502 } 503 default: 504 ShouldNotReachHere(); 505 } 506 } 507 508 load_store->as_LoadStore()->set_barrier_data(access.barrier_data()); 509 load_store = kit->gvn().transform(load_store); 510 511 access.set_raw_access(load_store); 512 pin_atomic_op(access); 513 514 #ifdef _LP64 515 if (access.is_oop() && adr->bottom_type()->is_ptr_to_narrowoop()) { 516 return kit->gvn().transform(new DecodeNNode(load_store, load_store->get_ptr_type())); 517 } 518 #endif 519 520 return load_store; 521 } 522 523 Node* BarrierSetC2::atomic_cmpxchg_bool_at_resolved(C2AtomicParseAccess& access, Node* expected_val, 524 Node* new_val, const Type* value_type) const { 525 GraphKit* kit = access.kit(); 526 DecoratorSet decorators = access.decorators(); 527 MemNode::MemOrd mo = access.mem_node_mo(); 528 Node* mem = access.memory(); 529 bool is_weak_cas = (decorators & C2_WEAK_CMPXCHG) != 0; 530 Node* load_store = nullptr; 531 Node* adr = access.addr().node(); 532 533 if (access.is_oop()) { 534 #ifdef _LP64 535 if (adr->bottom_type()->is_ptr_to_narrowoop()) { 536 Node *newval_enc = kit->gvn().transform(new EncodePNode(new_val, new_val->bottom_type()->make_narrowoop())); 537 Node *oldval_enc = kit->gvn().transform(new EncodePNode(expected_val, expected_val->bottom_type()->make_narrowoop())); 538 if (is_weak_cas) { 539 load_store = new WeakCompareAndSwapNNode(kit->control(), mem, adr, newval_enc, oldval_enc, mo); 540 } else { 541 load_store = new CompareAndSwapNNode(kit->control(), mem, adr, newval_enc, oldval_enc, mo); 542 } 543 } else 544 #endif 545 { 546 if (is_weak_cas) { 547 load_store = new WeakCompareAndSwapPNode(kit->control(), mem, adr, new_val, expected_val, mo); 548 } else { 549 load_store = new CompareAndSwapPNode(kit->control(), mem, adr, new_val, expected_val, mo); 550 } 551 } 552 } else { 553 switch(access.type()) { 554 case T_BYTE: { 555 if (is_weak_cas) { 556 load_store = new WeakCompareAndSwapBNode(kit->control(), mem, adr, new_val, expected_val, mo); 557 } else { 558 load_store = new CompareAndSwapBNode(kit->control(), mem, adr, new_val, expected_val, mo); 559 } 560 break; 561 } 562 case T_SHORT: { 563 if (is_weak_cas) { 564 load_store = new WeakCompareAndSwapSNode(kit->control(), mem, adr, new_val, expected_val, mo); 565 } else { 566 load_store = new CompareAndSwapSNode(kit->control(), mem, adr, new_val, expected_val, mo); 567 } 568 break; 569 } 570 case T_INT: { 571 if (is_weak_cas) { 572 load_store = new WeakCompareAndSwapINode(kit->control(), mem, adr, new_val, expected_val, mo); 573 } else { 574 load_store = new CompareAndSwapINode(kit->control(), mem, adr, new_val, expected_val, mo); 575 } 576 break; 577 } 578 case T_LONG: { 579 if (is_weak_cas) { 580 load_store = new WeakCompareAndSwapLNode(kit->control(), mem, adr, new_val, expected_val, mo); 581 } else { 582 load_store = new CompareAndSwapLNode(kit->control(), mem, adr, new_val, expected_val, mo); 583 } 584 break; 585 } 586 default: 587 ShouldNotReachHere(); 588 } 589 } 590 591 load_store->as_LoadStore()->set_barrier_data(access.barrier_data()); 592 load_store = kit->gvn().transform(load_store); 593 594 access.set_raw_access(load_store); 595 pin_atomic_op(access); 596 597 return load_store; 598 } 599 600 Node* BarrierSetC2::atomic_xchg_at_resolved(C2AtomicParseAccess& access, Node* new_val, const Type* value_type) const { 601 GraphKit* kit = access.kit(); 602 Node* mem = access.memory(); 603 Node* adr = access.addr().node(); 604 const TypePtr* adr_type = access.addr().type(); 605 Node* load_store = nullptr; 606 607 if (access.is_oop()) { 608 #ifdef _LP64 609 if (adr->bottom_type()->is_ptr_to_narrowoop()) { 610 Node *newval_enc = kit->gvn().transform(new EncodePNode(new_val, new_val->bottom_type()->make_narrowoop())); 611 load_store = kit->gvn().transform(new GetAndSetNNode(kit->control(), mem, adr, newval_enc, adr_type, value_type->make_narrowoop())); 612 } else 613 #endif 614 { 615 load_store = new GetAndSetPNode(kit->control(), mem, adr, new_val, adr_type, value_type->is_oopptr()); 616 } 617 } else { 618 switch (access.type()) { 619 case T_BYTE: 620 load_store = new GetAndSetBNode(kit->control(), mem, adr, new_val, adr_type); 621 break; 622 case T_SHORT: 623 load_store = new GetAndSetSNode(kit->control(), mem, adr, new_val, adr_type); 624 break; 625 case T_INT: 626 load_store = new GetAndSetINode(kit->control(), mem, adr, new_val, adr_type); 627 break; 628 case T_LONG: 629 load_store = new GetAndSetLNode(kit->control(), mem, adr, new_val, adr_type); 630 break; 631 default: 632 ShouldNotReachHere(); 633 } 634 } 635 636 load_store->as_LoadStore()->set_barrier_data(access.barrier_data()); 637 load_store = kit->gvn().transform(load_store); 638 639 access.set_raw_access(load_store); 640 pin_atomic_op(access); 641 642 #ifdef _LP64 643 if (access.is_oop() && adr->bottom_type()->is_ptr_to_narrowoop()) { 644 return kit->gvn().transform(new DecodeNNode(load_store, load_store->get_ptr_type())); 645 } 646 #endif 647 648 return load_store; 649 } 650 651 Node* BarrierSetC2::atomic_add_at_resolved(C2AtomicParseAccess& access, Node* new_val, const Type* value_type) const { 652 Node* load_store = nullptr; 653 GraphKit* kit = access.kit(); 654 Node* adr = access.addr().node(); 655 const TypePtr* adr_type = access.addr().type(); 656 Node* mem = access.memory(); 657 658 switch(access.type()) { 659 case T_BYTE: 660 load_store = new GetAndAddBNode(kit->control(), mem, adr, new_val, adr_type); 661 break; 662 case T_SHORT: 663 load_store = new GetAndAddSNode(kit->control(), mem, adr, new_val, adr_type); 664 break; 665 case T_INT: 666 load_store = new GetAndAddINode(kit->control(), mem, adr, new_val, adr_type); 667 break; 668 case T_LONG: 669 load_store = new GetAndAddLNode(kit->control(), mem, adr, new_val, adr_type); 670 break; 671 default: 672 ShouldNotReachHere(); 673 } 674 675 load_store->as_LoadStore()->set_barrier_data(access.barrier_data()); 676 load_store = kit->gvn().transform(load_store); 677 678 access.set_raw_access(load_store); 679 pin_atomic_op(access); 680 681 return load_store; 682 } 683 684 Node* BarrierSetC2::atomic_cmpxchg_val_at(C2AtomicParseAccess& access, Node* expected_val, 685 Node* new_val, const Type* value_type) const { 686 C2AccessFence fence(access); 687 resolve_address(access); 688 return atomic_cmpxchg_val_at_resolved(access, expected_val, new_val, value_type); 689 } 690 691 Node* BarrierSetC2::atomic_cmpxchg_bool_at(C2AtomicParseAccess& access, Node* expected_val, 692 Node* new_val, const Type* value_type) const { 693 C2AccessFence fence(access); 694 resolve_address(access); 695 return atomic_cmpxchg_bool_at_resolved(access, expected_val, new_val, value_type); 696 } 697 698 Node* BarrierSetC2::atomic_xchg_at(C2AtomicParseAccess& access, Node* new_val, const Type* value_type) const { 699 C2AccessFence fence(access); 700 resolve_address(access); 701 return atomic_xchg_at_resolved(access, new_val, value_type); 702 } 703 704 Node* BarrierSetC2::atomic_add_at(C2AtomicParseAccess& access, Node* new_val, const Type* value_type) const { 705 C2AccessFence fence(access); 706 resolve_address(access); 707 return atomic_add_at_resolved(access, new_val, value_type); 708 } 709 710 int BarrierSetC2::arraycopy_payload_base_offset(bool is_array) { 711 // Exclude the header but include array length to copy by 8 bytes words. 712 // Can't use base_offset_in_bytes(bt) since basic type is unknown. 713 int base_off = is_array ? arrayOopDesc::length_offset_in_bytes() : 714 instanceOopDesc::base_offset_in_bytes(); 715 // base_off: 716 // 8 - 32-bit VM or 64-bit VM, compact headers 717 // 12 - 64-bit VM, compressed klass 718 // 16 - 64-bit VM, normal klass 719 if (base_off % BytesPerLong != 0) { 720 assert(UseCompressedClassPointers, ""); 721 assert(!UseCompactObjectHeaders, ""); 722 if (is_array) { 723 // Exclude length to copy by 8 bytes words. 724 base_off += sizeof(int); 725 } else { 726 // Include klass to copy by 8 bytes words. 727 base_off = instanceOopDesc::klass_offset_in_bytes(); 728 } 729 assert(base_off % BytesPerLong == 0, "expect 8 bytes alignment"); 730 } 731 return base_off; 732 } 733 734 void BarrierSetC2::clone(GraphKit* kit, Node* src_base, Node* dst_base, Node* size, bool is_array) const { 735 int base_off = arraycopy_payload_base_offset(is_array); 736 Node* payload_size = size; 737 Node* offset = kit->MakeConX(base_off); 738 payload_size = kit->gvn().transform(new SubXNode(payload_size, offset)); 739 if (is_array) { 740 // Ensure the array payload size is rounded up to the next BytesPerLong 741 // multiple when converting to double-words. This is necessary because array 742 // size does not include object alignment padding, so it might not be a 743 // multiple of BytesPerLong for sub-long element types. 744 payload_size = kit->gvn().transform(new AddXNode(payload_size, kit->MakeConX(BytesPerLong - 1))); 745 } 746 payload_size = kit->gvn().transform(new URShiftXNode(payload_size, kit->intcon(LogBytesPerLong))); 747 ArrayCopyNode* ac = ArrayCopyNode::make(kit, false, src_base, offset, dst_base, offset, payload_size, true, false); 748 if (is_array) { 749 ac->set_clone_array(); 750 } else { 751 ac->set_clone_inst(); 752 } 753 Node* n = kit->gvn().transform(ac); 754 if (n == ac) { 755 const TypePtr* raw_adr_type = TypeRawPtr::BOTTOM; 756 ac->set_adr_type(TypeRawPtr::BOTTOM); 757 kit->set_predefined_output_for_runtime_call(ac, ac->in(TypeFunc::Memory), raw_adr_type); 758 } else { 759 kit->set_all_memory(n); 760 } 761 } 762 763 Node* BarrierSetC2::obj_allocate(PhaseMacroExpand* macro, Node* mem, Node* toobig_false, Node* size_in_bytes, 764 Node*& i_o, Node*& needgc_ctrl, 765 Node*& fast_oop_ctrl, Node*& fast_oop_rawmem, 766 intx prefetch_lines) const { 767 assert(UseTLAB, "Only for TLAB enabled allocations"); 768 769 Node* thread = macro->transform_later(new ThreadLocalNode()); 770 Node* tlab_top_adr = macro->basic_plus_adr(macro->top()/*not oop*/, thread, in_bytes(JavaThread::tlab_top_offset())); 771 Node* tlab_end_adr = macro->basic_plus_adr(macro->top()/*not oop*/, thread, in_bytes(JavaThread::tlab_end_offset())); 772 773 // Load TLAB end. 774 // 775 // Note: We set the control input on "tlab_end" and "old_tlab_top" to work around 776 // a bug where these values were being moved across 777 // a safepoint. These are not oops, so they cannot be include in the oop 778 // map, but they can be changed by a GC. The proper way to fix this would 779 // be to set the raw memory state when generating a SafepointNode. However 780 // this will require extensive changes to the loop optimization in order to 781 // prevent a degradation of the optimization. 782 // See comment in memnode.hpp, around line 227 in class LoadPNode. 783 Node* tlab_end = macro->make_load(toobig_false, mem, tlab_end_adr, 0, TypeRawPtr::BOTTOM, T_ADDRESS); 784 785 // Load the TLAB top. 786 Node* old_tlab_top = new LoadPNode(toobig_false, mem, tlab_top_adr, TypeRawPtr::BOTTOM, TypeRawPtr::BOTTOM, MemNode::unordered); 787 macro->transform_later(old_tlab_top); 788 789 // Add to heap top to get a new TLAB top 790 Node* new_tlab_top = new AddPNode(macro->top(), old_tlab_top, size_in_bytes); 791 macro->transform_later(new_tlab_top); 792 793 // Check against TLAB end 794 Node* tlab_full = new CmpPNode(new_tlab_top, tlab_end); 795 macro->transform_later(tlab_full); 796 797 Node* needgc_bol = new BoolNode(tlab_full, BoolTest::ge); 798 macro->transform_later(needgc_bol); 799 IfNode* needgc_iff = new IfNode(toobig_false, needgc_bol, PROB_UNLIKELY_MAG(4), COUNT_UNKNOWN); 800 macro->transform_later(needgc_iff); 801 802 // Plug the failing-heap-space-need-gc test into the slow-path region 803 Node* needgc_true = new IfTrueNode(needgc_iff); 804 macro->transform_later(needgc_true); 805 needgc_ctrl = needgc_true; 806 807 // No need for a GC. 808 Node* needgc_false = new IfFalseNode(needgc_iff); 809 macro->transform_later(needgc_false); 810 811 // Fast path: 812 i_o = macro->prefetch_allocation(i_o, needgc_false, mem, 813 old_tlab_top, new_tlab_top, prefetch_lines); 814 815 // Store the modified TLAB top back down. 816 Node* store_tlab_top = new StorePNode(needgc_false, mem, tlab_top_adr, 817 TypeRawPtr::BOTTOM, new_tlab_top, MemNode::unordered); 818 macro->transform_later(store_tlab_top); 819 820 fast_oop_ctrl = needgc_false; 821 fast_oop_rawmem = store_tlab_top; 822 return old_tlab_top; 823 } 824 825 static const TypeFunc* clone_type() { 826 // Create input type (domain) 827 int argcnt = NOT_LP64(3) LP64_ONLY(4); 828 const Type** const domain_fields = TypeTuple::fields(argcnt); 829 int argp = TypeFunc::Parms; 830 domain_fields[argp++] = TypeInstPtr::NOTNULL; // src 831 domain_fields[argp++] = TypeInstPtr::NOTNULL; // dst 832 domain_fields[argp++] = TypeX_X; // size lower 833 LP64_ONLY(domain_fields[argp++] = Type::HALF); // size upper 834 assert(argp == TypeFunc::Parms+argcnt, "correct decoding"); 835 const TypeTuple* const domain = TypeTuple::make(TypeFunc::Parms + argcnt, domain_fields); 836 837 // Create result type (range) 838 const Type** const range_fields = TypeTuple::fields(0); 839 const TypeTuple* const range = TypeTuple::make(TypeFunc::Parms + 0, range_fields); 840 841 return TypeFunc::make(domain, range); 842 } 843 844 #define XTOP LP64_ONLY(COMMA phase->top()) 845 846 void BarrierSetC2::clone_in_runtime(PhaseMacroExpand* phase, ArrayCopyNode* ac, 847 address clone_addr, const char* clone_name) const { 848 Node* const ctrl = ac->in(TypeFunc::Control); 849 Node* const mem = ac->in(TypeFunc::Memory); 850 Node* const src = ac->in(ArrayCopyNode::Src); 851 Node* const dst = ac->in(ArrayCopyNode::Dest); 852 Node* const size = ac->in(ArrayCopyNode::Length); 853 854 assert(size->bottom_type()->base() == Type_X, 855 "Should be of object size type (int for 32 bits, long for 64 bits)"); 856 857 // The native clone we are calling here expects the object size in words. 858 // Add header/offset size to payload size to get object size. 859 Node* const base_offset = phase->MakeConX(arraycopy_payload_base_offset(ac->is_clone_array()) >> LogBytesPerLong); 860 Node* const full_size = phase->transform_later(new AddXNode(size, base_offset)); 861 // HeapAccess<>::clone expects size in heap words. 862 // For 64-bits platforms, this is a no-operation. 863 // For 32-bits platforms, we need to multiply full_size by HeapWordsPerLong (2). 864 Node* const full_size_in_heap_words = phase->transform_later(new LShiftXNode(full_size, phase->intcon(LogHeapWordsPerLong))); 865 866 Node* const call = phase->make_leaf_call(ctrl, 867 mem, 868 clone_type(), 869 clone_addr, 870 clone_name, 871 TypeRawPtr::BOTTOM, 872 src, dst, full_size_in_heap_words XTOP); 873 phase->transform_later(call); 874 phase->replace_node(ac, call); 875 } 876 877 void BarrierSetC2::clone_at_expansion(PhaseMacroExpand* phase, ArrayCopyNode* ac) const { 878 Node* ctrl = ac->in(TypeFunc::Control); 879 Node* mem = ac->in(TypeFunc::Memory); 880 Node* src = ac->in(ArrayCopyNode::Src); 881 Node* src_offset = ac->in(ArrayCopyNode::SrcPos); 882 Node* dest = ac->in(ArrayCopyNode::Dest); 883 Node* dest_offset = ac->in(ArrayCopyNode::DestPos); 884 Node* length = ac->in(ArrayCopyNode::Length); 885 886 Node* payload_src = phase->basic_plus_adr(src, src_offset); 887 Node* payload_dst = phase->basic_plus_adr(dest, dest_offset); 888 889 const char* copyfunc_name = "arraycopy"; 890 address copyfunc_addr = phase->basictype2arraycopy(T_LONG, nullptr, nullptr, true, copyfunc_name, true); 891 892 const TypePtr* raw_adr_type = TypeRawPtr::BOTTOM; 893 const TypeFunc* call_type = OptoRuntime::fast_arraycopy_Type(); 894 895 Node* call = phase->make_leaf_call(ctrl, mem, call_type, copyfunc_addr, copyfunc_name, raw_adr_type, payload_src, payload_dst, length XTOP); 896 phase->transform_later(call); 897 898 phase->replace_node(ac, call); 899 } 900 901 #undef XTOP 902 903 static bool block_has_safepoint(const Block* block, uint from, uint to) { 904 for (uint i = from; i < to; i++) { 905 if (block->get_node(i)->is_MachSafePoint()) { 906 // Safepoint found 907 return true; 908 } 909 } 910 911 // Safepoint not found 912 return false; 913 } 914 915 static bool block_has_safepoint(const Block* block) { 916 return block_has_safepoint(block, 0, block->number_of_nodes()); 917 } 918 919 static uint block_index(const Block* block, const Node* node) { 920 for (uint j = 0; j < block->number_of_nodes(); ++j) { 921 if (block->get_node(j) == node) { 922 return j; 923 } 924 } 925 ShouldNotReachHere(); 926 return 0; 927 } 928 929 // Look through various node aliases 930 static const Node* look_through_node(const Node* node) { 931 while (node != nullptr) { 932 const Node* new_node = node; 933 if (node->is_Mach()) { 934 const MachNode* const node_mach = node->as_Mach(); 935 if (node_mach->ideal_Opcode() == Op_CheckCastPP) { 936 new_node = node->in(1); 937 } 938 if (node_mach->is_SpillCopy()) { 939 new_node = node->in(1); 940 } 941 } 942 if (new_node == node || new_node == nullptr) { 943 break; 944 } else { 945 node = new_node; 946 } 947 } 948 949 return node; 950 } 951 952 // Whether the given offset is undefined. 953 static bool is_undefined(intptr_t offset) { 954 return offset == Type::OffsetTop; 955 } 956 957 // Whether the given offset is unknown. 958 static bool is_unknown(intptr_t offset) { 959 return offset == Type::OffsetBot; 960 } 961 962 // Whether the given offset is concrete (defined and compile-time known). 963 static bool is_concrete(intptr_t offset) { 964 return !is_undefined(offset) && !is_unknown(offset); 965 } 966 967 // Compute base + offset components of the memory address accessed by mach. 968 // Return a node representing the base address, or null if the base cannot be 969 // found or the offset is undefined or a concrete negative value. If a non-null 970 // base is returned, the offset is a concrete, nonnegative value or unknown. 971 static const Node* get_base_and_offset(const MachNode* mach, intptr_t& offset) { 972 const TypePtr* adr_type = nullptr; 973 offset = 0; 974 const Node* base = mach->get_base_and_disp(offset, adr_type); 975 976 if (base == nullptr || base == NodeSentinel) { 977 return nullptr; 978 } 979 980 if (offset == 0 && base->is_Mach() && base->as_Mach()->ideal_Opcode() == Op_AddP) { 981 // The memory address is computed by 'base' and fed to 'mach' via an 982 // indirect memory operand (indicated by offset == 0). The ultimate base and 983 // offset can be fetched directly from the inputs and Ideal type of 'base'. 984 const TypeOopPtr* oopptr = base->bottom_type()->isa_oopptr(); 985 if (oopptr == nullptr) return nullptr; 986 offset = oopptr->offset(); 987 // Even if 'base' is not an Ideal AddP node anymore, Matcher::ReduceInst() 988 // guarantees that the base address is still available at the same slot. 989 base = base->in(AddPNode::Base); 990 assert(base != nullptr, ""); 991 } 992 993 if (is_undefined(offset) || (is_concrete(offset) && offset < 0)) { 994 return nullptr; 995 } 996 997 return look_through_node(base); 998 } 999 1000 // Whether a phi node corresponds to an array allocation. 1001 // This test is incomplete: in some edge cases, it might return false even 1002 // though the node does correspond to an array allocation. 1003 static bool is_array_allocation(const Node* phi) { 1004 precond(phi->is_Phi()); 1005 // Check whether phi has a successor cast (CheckCastPP) to Java array pointer, 1006 // possibly below spill copies and other cast nodes. Limit the exploration to 1007 // a single path from the phi node consisting of these node types. 1008 const Node* current = phi; 1009 while (true) { 1010 const Node* next = nullptr; 1011 for (DUIterator_Fast imax, i = current->fast_outs(imax); i < imax; i++) { 1012 if (!current->fast_out(i)->isa_Mach()) { 1013 continue; 1014 } 1015 const MachNode* succ = current->fast_out(i)->as_Mach(); 1016 if (succ->ideal_Opcode() == Op_CheckCastPP) { 1017 if (succ->get_ptr_type()->isa_aryptr()) { 1018 // Cast to Java array pointer: phi corresponds to an array allocation. 1019 return true; 1020 } 1021 // Other cast: record as candidate for further exploration. 1022 next = succ; 1023 } else if (succ->is_SpillCopy() && next == nullptr) { 1024 // Spill copy, and no better candidate found: record as candidate. 1025 next = succ; 1026 } 1027 } 1028 if (next == nullptr) { 1029 // No evidence found that phi corresponds to an array allocation, and no 1030 // candidates available to continue exploring. 1031 return false; 1032 } 1033 // Continue exploring from the best candidate found. 1034 current = next; 1035 } 1036 ShouldNotReachHere(); 1037 } 1038 1039 bool BarrierSetC2::is_allocation(const Node* node) { 1040 assert(node->is_Phi(), "expected phi node"); 1041 if (node->req() != 3) { 1042 return false; 1043 } 1044 const Node* const fast_node = node->in(2); 1045 if (!fast_node->is_Mach()) { 1046 return false; 1047 } 1048 const MachNode* const fast_mach = fast_node->as_Mach(); 1049 if (fast_mach->ideal_Opcode() != Op_LoadP) { 1050 return false; 1051 } 1052 intptr_t offset; 1053 const Node* const base = get_base_and_offset(fast_mach, offset); 1054 if (base == nullptr || !base->is_Mach() || !is_concrete(offset)) { 1055 return false; 1056 } 1057 const MachNode* const base_mach = base->as_Mach(); 1058 if (base_mach->ideal_Opcode() != Op_ThreadLocal) { 1059 return false; 1060 } 1061 return offset == in_bytes(Thread::tlab_top_offset()); 1062 } 1063 1064 void BarrierSetC2::elide_dominated_barriers(Node_List& accesses, Node_List& access_dominators) const { 1065 Compile* const C = Compile::current(); 1066 PhaseCFG* const cfg = C->cfg(); 1067 1068 for (uint i = 0; i < accesses.size(); i++) { 1069 MachNode* const access = accesses.at(i)->as_Mach(); 1070 intptr_t access_offset; 1071 const Node* const access_obj = get_base_and_offset(access, access_offset); 1072 Block* const access_block = cfg->get_block_for_node(access); 1073 const uint access_index = block_index(access_block, access); 1074 1075 if (access_obj == nullptr) { 1076 // No information available 1077 continue; 1078 } 1079 1080 for (uint j = 0; j < access_dominators.size(); j++) { 1081 const Node* const mem = access_dominators.at(j); 1082 if (mem->is_Phi()) { 1083 assert(is_allocation(mem), "expected allocation phi node"); 1084 if (mem != access_obj) { 1085 continue; 1086 } 1087 if (is_unknown(access_offset) && !is_array_allocation(mem)) { 1088 // The accessed address has an unknown offset, but the allocated 1089 // object cannot be determined to be an array. Avoid eliding in this 1090 // case, to be on the safe side. 1091 continue; 1092 } 1093 assert((is_concrete(access_offset) && access_offset >= 0) || (is_unknown(access_offset) && is_array_allocation(mem)), 1094 "candidate allocation-dominated access offsets must be either concrete and nonnegative, or unknown (for array allocations only)"); 1095 } else { 1096 // Access node 1097 const MachNode* const mem_mach = mem->as_Mach(); 1098 intptr_t mem_offset; 1099 const Node* const mem_obj = get_base_and_offset(mem_mach, mem_offset); 1100 1101 if (mem_obj == nullptr || 1102 !is_concrete(access_offset) || 1103 !is_concrete(mem_offset)) { 1104 // No information available 1105 continue; 1106 } 1107 1108 if (mem_obj != access_obj || mem_offset != access_offset) { 1109 // Not the same addresses, not a candidate 1110 continue; 1111 } 1112 assert(is_concrete(access_offset) && access_offset >= 0, 1113 "candidate non-allocation-dominated access offsets must be concrete and nonnegative"); 1114 } 1115 1116 Block* mem_block = cfg->get_block_for_node(mem); 1117 const uint mem_index = block_index(mem_block, mem); 1118 1119 if (access_block == mem_block) { 1120 // Earlier accesses in the same block 1121 if (mem_index < access_index && !block_has_safepoint(mem_block, mem_index + 1, access_index)) { 1122 elide_dominated_barrier(access); 1123 } 1124 } else if (mem_block->dominates(access_block)) { 1125 // Dominating block? Look around for safepoints 1126 ResourceMark rm; 1127 Block_List stack; 1128 VectorSet visited; 1129 stack.push(access_block); 1130 bool safepoint_found = block_has_safepoint(access_block); 1131 while (!safepoint_found && stack.size() > 0) { 1132 const Block* const block = stack.pop(); 1133 if (visited.test_set(block->_pre_order)) { 1134 continue; 1135 } 1136 if (block_has_safepoint(block)) { 1137 safepoint_found = true; 1138 break; 1139 } 1140 if (block == mem_block) { 1141 continue; 1142 } 1143 1144 // Push predecessor blocks 1145 for (uint p = 1; p < block->num_preds(); ++p) { 1146 Block* const pred = cfg->get_block_for_node(block->pred(p)); 1147 stack.push(pred); 1148 } 1149 } 1150 1151 if (!safepoint_found) { 1152 elide_dominated_barrier(access); 1153 } 1154 } 1155 } 1156 } 1157 } 1158 1159 void BarrierSetC2::compute_liveness_at_stubs() const { 1160 ResourceMark rm; 1161 Compile* const C = Compile::current(); 1162 Arena* const A = Thread::current()->resource_area(); 1163 PhaseCFG* const cfg = C->cfg(); 1164 PhaseRegAlloc* const regalloc = C->regalloc(); 1165 RegMask* const live = NEW_ARENA_ARRAY(A, RegMask, cfg->number_of_blocks() * sizeof(RegMask)); 1166 BarrierSetAssembler* const bs = BarrierSet::barrier_set()->barrier_set_assembler(); 1167 BarrierSetC2State* bs_state = barrier_set_state(); 1168 Block_List worklist; 1169 1170 for (uint i = 0; i < cfg->number_of_blocks(); ++i) { 1171 new ((void*)(live + i)) RegMask(); 1172 worklist.push(cfg->get_block(i)); 1173 } 1174 1175 while (worklist.size() > 0) { 1176 const Block* const block = worklist.pop(); 1177 RegMask& old_live = live[block->_pre_order]; 1178 RegMask new_live; 1179 1180 // Initialize to union of successors 1181 for (uint i = 0; i < block->_num_succs; i++) { 1182 const uint succ_id = block->_succs[i]->_pre_order; 1183 new_live.OR(live[succ_id]); 1184 } 1185 1186 // Walk block backwards, computing liveness 1187 for (int i = block->number_of_nodes() - 1; i >= 0; --i) { 1188 const Node* const node = block->get_node(i); 1189 1190 // If this node tracks out-liveness, update it 1191 if (!bs_state->needs_livein_data()) { 1192 RegMask* const regs = bs_state->live(node); 1193 if (regs != nullptr) { 1194 regs->OR(new_live); 1195 } 1196 } 1197 1198 // Remove def bits 1199 const OptoReg::Name first = bs->refine_register(node, regalloc->get_reg_first(node)); 1200 const OptoReg::Name second = bs->refine_register(node, regalloc->get_reg_second(node)); 1201 if (first != OptoReg::Bad) { 1202 new_live.Remove(first); 1203 } 1204 if (second != OptoReg::Bad) { 1205 new_live.Remove(second); 1206 } 1207 1208 // Add use bits 1209 for (uint j = 1; j < node->req(); ++j) { 1210 const Node* const use = node->in(j); 1211 const OptoReg::Name first = bs->refine_register(use, regalloc->get_reg_first(use)); 1212 const OptoReg::Name second = bs->refine_register(use, regalloc->get_reg_second(use)); 1213 if (first != OptoReg::Bad) { 1214 new_live.Insert(first); 1215 } 1216 if (second != OptoReg::Bad) { 1217 new_live.Insert(second); 1218 } 1219 } 1220 1221 // If this node tracks in-liveness, update it 1222 if (bs_state->needs_livein_data()) { 1223 RegMask* const regs = bs_state->live(node); 1224 if (regs != nullptr) { 1225 regs->OR(new_live); 1226 } 1227 } 1228 } 1229 1230 // Now at block top, see if we have any changes 1231 new_live.SUBTRACT(old_live); 1232 if (new_live.is_NotEmpty()) { 1233 // Liveness has refined, update and propagate to prior blocks 1234 old_live.OR(new_live); 1235 for (uint i = 1; i < block->num_preds(); ++i) { 1236 Block* const pred = cfg->get_block_for_node(block->pred(i)); 1237 worklist.push(pred); 1238 } 1239 } 1240 } 1241 } --- EOF ---