172 Node* val, 173 Node* adr, 174 bool weak, 175 bool writeback, 176 bool oop_reload_allowed) : 177 MultiNode(Number_of_Inputs), 178 _weak(weak), 179 _writeback(writeback), 180 _oop_reload_allowed(oop_reload_allowed) { 181 init_req(Control, c); 182 init_req(Memory, mem); 183 init_req(Oop, val); 184 init_req(Address, adr); 185 init_req(Similar, C->top()); 186 187 init_class_id(Class_LoadBarrier); 188 BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2(); 189 bs->register_potential_barrier_node(this); 190 } 191 192 const Type *LoadBarrierNode::bottom_type() const { 193 const Type** floadbarrier = (const Type **)(Compile::current()->type_arena()->Amalloc_4((Number_of_Outputs)*sizeof(Type*))); 194 Node* in_oop = in(Oop); 195 floadbarrier[Control] = Type::CONTROL; 196 floadbarrier[Memory] = Type::MEMORY; 197 floadbarrier[Oop] = in_oop == NULL ? Type::TOP : in_oop->bottom_type(); 198 return TypeTuple::make(Number_of_Outputs, floadbarrier); 199 } 200 201 const Type *LoadBarrierNode::Value(PhaseGVN *phase) const { 202 const Type** floadbarrier = (const Type **)(phase->C->type_arena()->Amalloc_4((Number_of_Outputs)*sizeof(Type*))); 203 const Type* val_t = phase->type(in(Oop)); 204 floadbarrier[Control] = Type::CONTROL; 205 floadbarrier[Memory] = Type::MEMORY; 206 floadbarrier[Oop] = val_t; 207 return TypeTuple::make(Number_of_Outputs, floadbarrier); 208 } 209 210 bool LoadBarrierNode::is_dominator(PhaseIdealLoop* phase, bool linear_only, Node *d, Node *n) { 211 if (phase != NULL) { 212 return phase->is_dominator(d, n); 213 } 214 215 for (int i = 0; i < 10 && n != NULL; i++) { 216 n = IfNode::up_one_dom(n, linear_only); 217 if (n == d) { 218 return true; 219 } 220 } 422 // dominated barrier and both barriers have the same Oop field, 423 // the dominated barrier can go away, so push it for reprocessing. 424 // We also want to avoid a barrier to depend on another dominating 425 // barrier through its Similar edge that itself depend on another 426 // barrier through its Similar edge and rather have the first 427 // depend on the third. 428 PhaseIterGVN* igvn = phase->is_IterGVN(); 429 Node* out_res = proj_out(Oop); 430 for (DUIterator_Fast imax, i = out_res->fast_outs(imax); i < imax; i++) { 431 Node* u = out_res->fast_out(i); 432 if (u->is_LoadBarrier() && u->in(Similar) == out_res && 433 (u->in(Oop) == val || !u->in(Similar)->is_top())) { 434 igvn->_worklist.push(u); 435 } 436 } 437 438 push_dominated_barriers(igvn); 439 } 440 441 return NULL; 442 } 443 444 void LoadBarrierNode::fix_similar_in_uses(PhaseIterGVN* igvn) { 445 Node* out_res = proj_out_or_null(Oop); 446 if (out_res == NULL) { 447 return; 448 } 449 450 for (DUIterator_Fast imax, i = out_res->fast_outs(imax); i < imax; i++) { 451 Node* u = out_res->fast_out(i); 452 if (u->is_LoadBarrier() && u->in(Similar) == out_res) { 453 igvn->replace_input_of(u, Similar, igvn->C->top()); 454 --i; 455 --imax; 456 } 457 } 458 } 459 460 bool LoadBarrierNode::has_true_uses() const { 461 Node* out_res = proj_out_or_null(Oop); | 172 Node* val, 173 Node* adr, 174 bool weak, 175 bool writeback, 176 bool oop_reload_allowed) : 177 MultiNode(Number_of_Inputs), 178 _weak(weak), 179 _writeback(writeback), 180 _oop_reload_allowed(oop_reload_allowed) { 181 init_req(Control, c); 182 init_req(Memory, mem); 183 init_req(Oop, val); 184 init_req(Address, adr); 185 init_req(Similar, C->top()); 186 187 init_class_id(Class_LoadBarrier); 188 BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2(); 189 bs->register_potential_barrier_node(this); 190 } 191 192 uint LoadBarrierNode::size_of() const { 193 return sizeof(*this); 194 } 195 196 uint LoadBarrierNode::cmp(const Node& n) const { 197 ShouldNotReachHere(); 198 return 0; 199 } 200 201 const Type *LoadBarrierNode::bottom_type() const { 202 const Type** floadbarrier = (const Type **)(Compile::current()->type_arena()->Amalloc_4((Number_of_Outputs)*sizeof(Type*))); 203 Node* in_oop = in(Oop); 204 floadbarrier[Control] = Type::CONTROL; 205 floadbarrier[Memory] = Type::MEMORY; 206 floadbarrier[Oop] = in_oop == NULL ? Type::TOP : in_oop->bottom_type(); 207 return TypeTuple::make(Number_of_Outputs, floadbarrier); 208 } 209 210 const TypePtr* LoadBarrierNode::adr_type() const { 211 ShouldNotReachHere(); 212 return NULL; 213 } 214 215 const Type *LoadBarrierNode::Value(PhaseGVN *phase) const { 216 const Type** floadbarrier = (const Type **)(phase->C->type_arena()->Amalloc_4((Number_of_Outputs)*sizeof(Type*))); 217 const Type* val_t = phase->type(in(Oop)); 218 floadbarrier[Control] = Type::CONTROL; 219 floadbarrier[Memory] = Type::MEMORY; 220 floadbarrier[Oop] = val_t; 221 return TypeTuple::make(Number_of_Outputs, floadbarrier); 222 } 223 224 bool LoadBarrierNode::is_dominator(PhaseIdealLoop* phase, bool linear_only, Node *d, Node *n) { 225 if (phase != NULL) { 226 return phase->is_dominator(d, n); 227 } 228 229 for (int i = 0; i < 10 && n != NULL; i++) { 230 n = IfNode::up_one_dom(n, linear_only); 231 if (n == d) { 232 return true; 233 } 234 } 436 // dominated barrier and both barriers have the same Oop field, 437 // the dominated barrier can go away, so push it for reprocessing. 438 // We also want to avoid a barrier to depend on another dominating 439 // barrier through its Similar edge that itself depend on another 440 // barrier through its Similar edge and rather have the first 441 // depend on the third. 442 PhaseIterGVN* igvn = phase->is_IterGVN(); 443 Node* out_res = proj_out(Oop); 444 for (DUIterator_Fast imax, i = out_res->fast_outs(imax); i < imax; i++) { 445 Node* u = out_res->fast_out(i); 446 if (u->is_LoadBarrier() && u->in(Similar) == out_res && 447 (u->in(Oop) == val || !u->in(Similar)->is_top())) { 448 igvn->_worklist.push(u); 449 } 450 } 451 452 push_dominated_barriers(igvn); 453 } 454 455 return NULL; 456 } 457 458 uint LoadBarrierNode::match_edge(uint idx) const { 459 ShouldNotReachHere(); 460 return 0; 461 } 462 463 void LoadBarrierNode::fix_similar_in_uses(PhaseIterGVN* igvn) { 464 Node* out_res = proj_out_or_null(Oop); 465 if (out_res == NULL) { 466 return; 467 } 468 469 for (DUIterator_Fast imax, i = out_res->fast_outs(imax); i < imax; i++) { 470 Node* u = out_res->fast_out(i); 471 if (u->is_LoadBarrier() && u->in(Similar) == out_res) { 472 igvn->replace_input_of(u, Similar, igvn->C->top()); 473 --i; 474 --imax; 475 } 476 } 477 } 478 479 bool LoadBarrierNode::has_true_uses() const { 480 Node* out_res = proj_out_or_null(Oop); |