121 } else if (proj_in->is_MemBar()) { |
121 } else if (proj_in->is_MemBar()) { |
122 result = proj_in->in(TypeFunc::Memory); |
122 result = proj_in->in(TypeFunc::Memory); |
123 } else { |
123 } else { |
124 assert(false, "unexpected projection"); |
124 assert(false, "unexpected projection"); |
125 } |
125 } |
|
126 } else if (result->is_ClearArray()) { |
|
127 if (!ClearArrayNode::step_through(&result, instance_id, phase)) { |
|
128 // Can not bypass initialization of the instance |
|
129 // we are looking for. |
|
130 break; |
|
131 } |
|
132 // Otherwise skip it (the call updated 'result' value). |
126 } else if (result->is_MergeMem()) { |
133 } else if (result->is_MergeMem()) { |
127 result = step_through_mergemem(phase, result->as_MergeMem(), t_adr, NULL, tty); |
134 result = step_through_mergemem(phase, result->as_MergeMem(), t_adr, NULL, tty); |
128 } |
135 } |
129 } |
136 } |
130 return result; |
137 return result; |
535 continue; // (a) advance through independent call memory |
542 continue; // (a) advance through independent call memory |
536 } |
543 } |
537 } else if (mem->is_Proj() && mem->in(0)->is_MemBar()) { |
544 } else if (mem->is_Proj() && mem->in(0)->is_MemBar()) { |
538 mem = mem->in(0)->in(TypeFunc::Memory); |
545 mem = mem->in(0)->in(TypeFunc::Memory); |
539 continue; // (a) advance through independent MemBar memory |
546 continue; // (a) advance through independent MemBar memory |
|
547 } else if (mem->is_ClearArray()) { |
|
548 if (ClearArrayNode::step_through(&mem, (uint)addr_t->instance_id(), phase)) { |
|
549 // (the call updated 'mem' value) |
|
550 continue; // (a) advance through independent allocation memory |
|
551 } else { |
|
552 // Can not bypass initialization of the instance |
|
553 // we are looking for. |
|
554 return mem; |
|
555 } |
540 } else if (mem->is_MergeMem()) { |
556 } else if (mem->is_MergeMem()) { |
541 int alias_idx = phase->C->get_alias_index(adr_type()); |
557 int alias_idx = phase->C->get_alias_index(adr_type()); |
542 mem = mem->as_MergeMem()->memory_at(alias_idx); |
558 mem = mem->as_MergeMem()->memory_at(alias_idx); |
543 continue; // (a) advance through independent MergeMem memory |
559 continue; // (a) advance through independent MergeMem memory |
544 } |
560 } |
2452 mem = new (phase->C, 4) StoreLNode(in(0),mem,adr,atp,zero); |
2468 mem = new (phase->C, 4) StoreLNode(in(0),mem,adr,atp,zero); |
2453 } |
2469 } |
2454 return mem; |
2470 return mem; |
2455 } |
2471 } |
2456 |
2472 |
|
2473 //----------------------------step_through---------------------------------- |
|
2474 // Return allocation input memory edge if it is different instance |
|
2475 // or itself if it is the one we are looking for. |
|
2476 bool ClearArrayNode::step_through(Node** np, uint instance_id, PhaseTransform* phase) { |
|
2477 Node* n = *np; |
|
2478 assert(n->is_ClearArray(), "sanity"); |
|
2479 intptr_t offset; |
|
2480 AllocateNode* alloc = AllocateNode::Ideal_allocation(n->in(3), phase, offset); |
|
2481 // This method is called only before Allocate nodes are expanded during |
|
2482 // macro nodes expansion. Before that ClearArray nodes are only generated |
|
2483 // in LibraryCallKit::generate_arraycopy() which follows allocations. |
|
2484 assert(alloc != NULL, "should have allocation"); |
|
2485 if (alloc->_idx == instance_id) { |
|
2486 // Can not bypass initialization of the instance we are looking for. |
|
2487 return false; |
|
2488 } |
|
2489 // Otherwise skip it. |
|
2490 InitializeNode* init = alloc->initialization(); |
|
2491 if (init != NULL) |
|
2492 *np = init->in(TypeFunc::Memory); |
|
2493 else |
|
2494 *np = alloc->in(TypeFunc::Memory); |
|
2495 return true; |
|
2496 } |
|
2497 |
2457 //----------------------------clear_memory------------------------------------- |
2498 //----------------------------clear_memory------------------------------------- |
2458 // Generate code to initialize object storage to zero. |
2499 // Generate code to initialize object storage to zero. |
2459 Node* ClearArrayNode::clear_memory(Node* ctl, Node* mem, Node* dest, |
2500 Node* ClearArrayNode::clear_memory(Node* ctl, Node* mem, Node* dest, |
2460 intptr_t start_offset, |
2501 intptr_t start_offset, |
2461 Node* end_offset, |
2502 Node* end_offset, |
2625 |
2666 |
2626 //------------------------------Ideal------------------------------------------ |
2667 //------------------------------Ideal------------------------------------------ |
2627 // Return a node which is more "ideal" than the current node. Strip out |
2668 // Return a node which is more "ideal" than the current node. Strip out |
2628 // control copies |
2669 // control copies |
2629 Node *MemBarNode::Ideal(PhaseGVN *phase, bool can_reshape) { |
2670 Node *MemBarNode::Ideal(PhaseGVN *phase, bool can_reshape) { |
2630 return remove_dead_region(phase, can_reshape) ? this : NULL; |
2671 if (remove_dead_region(phase, can_reshape)) return this; |
|
2672 |
|
2673 // Eliminate volatile MemBars for scalar replaced objects. |
|
2674 if (can_reshape && req() == (Precedent+1) && |
|
2675 (Opcode() == Op_MemBarAcquire || Opcode() == Op_MemBarVolatile)) { |
|
2676 // Volatile field loads and stores. |
|
2677 Node* my_mem = in(MemBarNode::Precedent); |
|
2678 if (my_mem != NULL && my_mem->is_Mem()) { |
|
2679 const TypeOopPtr* t_oop = my_mem->in(MemNode::Address)->bottom_type()->isa_oopptr(); |
|
2680 // Check for scalar replaced object reference. |
|
2681 if( t_oop != NULL && t_oop->is_known_instance_field() && |
|
2682 t_oop->offset() != Type::OffsetBot && |
|
2683 t_oop->offset() != Type::OffsetTop) { |
|
2684 // Replace MemBar projections by its inputs. |
|
2685 PhaseIterGVN* igvn = phase->is_IterGVN(); |
|
2686 igvn->replace_node(proj_out(TypeFunc::Memory), in(TypeFunc::Memory)); |
|
2687 igvn->replace_node(proj_out(TypeFunc::Control), in(TypeFunc::Control)); |
|
2688 // Must return either the original node (now dead) or a new node |
|
2689 // (Do not return a top here, since that would break the uniqueness of top.) |
|
2690 return new (phase->C, 1) ConINode(TypeInt::ZERO); |
|
2691 } |
|
2692 } |
|
2693 } |
|
2694 return NULL; |
2631 } |
2695 } |
2632 |
2696 |
2633 //------------------------------Value------------------------------------------ |
2697 //------------------------------Value------------------------------------------ |
2634 const Type *MemBarNode::Value( PhaseTransform *phase ) const { |
2698 const Type *MemBarNode::Value( PhaseTransform *phase ) const { |
2635 if( !in(0) ) return Type::TOP; |
2699 if( !in(0) ) return Type::TOP; |