hotspot/src/share/vm/opto/macro.cpp
changeset 3268 f034e0c86895
parent 2867 69187054225f
child 4450 6d700b859b3e
equal deleted inserted replaced
3267:519fbe71f995 3268:f034e0c86895
   196   }
   196   }
   197 
   197 
   198 }
   198 }
   199 
   199 
   200 // Eliminate a card mark sequence.  p2x is a ConvP2XNode
   200 // Eliminate a card mark sequence.  p2x is a ConvP2XNode
   201 void PhaseMacroExpand::eliminate_card_mark(Node *p2x) {
   201 void PhaseMacroExpand::eliminate_card_mark(Node* p2x) {
   202   assert(p2x->Opcode() == Op_CastP2X, "ConvP2XNode required");
   202   assert(p2x->Opcode() == Op_CastP2X, "ConvP2XNode required");
   203   Node *shift = p2x->unique_out();
   203   if (!UseG1GC) {
   204   Node *addp = shift->unique_out();
   204     // vanilla/CMS post barrier
   205   for (DUIterator_Last jmin, j = addp->last_outs(jmin); j >= jmin; --j) {
   205     Node *shift = p2x->unique_out();
   206     Node *st = addp->last_out(j);
   206     Node *addp = shift->unique_out();
   207     assert(st->is_Store(), "store required");
   207     for (DUIterator_Last jmin, j = addp->last_outs(jmin); j >= jmin; --j) {
   208     _igvn.replace_node(st, st->in(MemNode::Memory));
   208       Node *st = addp->last_out(j);
       
   209       assert(st->is_Store(), "store required");
       
   210       _igvn.replace_node(st, st->in(MemNode::Memory));
       
   211     }
       
   212   } else {
       
   213     // G1 pre/post barriers
       
   214     assert(p2x->outcnt() == 2, "expects 2 users: Xor and URShift nodes");
       
   215     // It could be only one user, URShift node, in Object.clone() instrinsic
       
   216     // but the new allocation is passed to arraycopy stub and it could not
       
   217     // be scalar replaced. So we don't check the case.
       
   218 
       
   219     // Remove G1 post barrier.
       
   220 
       
   221     // Search for CastP2X->Xor->URShift->Cmp path which
       
   222     // checks if the store done to a different from the value's region.
       
   223     // And replace Cmp with #0 (false) to collapse G1 post barrier.
       
   224     Node* xorx = NULL;
       
   225     for (DUIterator_Fast imax, i = p2x->fast_outs(imax); i < imax; i++) {
       
   226       Node* u = p2x->fast_out(i);
       
   227       if (u->Opcode() == Op_XorX) {
       
   228         xorx = u;
       
   229         break;
       
   230       }
       
   231     }
       
   232     assert(xorx != NULL, "missing G1 post barrier");
       
   233     Node* shift = xorx->unique_out();
       
   234     Node* cmpx = shift->unique_out();
       
   235     assert(cmpx->is_Cmp() && cmpx->unique_out()->is_Bool() &&
       
   236     cmpx->unique_out()->as_Bool()->_test._test == BoolTest::ne,
       
   237     "missing region check in G1 post barrier");
       
   238     _igvn.replace_node(cmpx, makecon(TypeInt::CC_EQ));
       
   239 
       
   240     // Remove G1 pre barrier.
       
   241 
       
   242     // Search "if (marking != 0)" check and set it to "false".
       
   243     Node* this_region = p2x->in(0);
       
   244     assert(this_region != NULL, "");
       
   245     // There is no G1 pre barrier if previous stored value is NULL
       
   246     // (for example, after initialization).
       
   247     if (this_region->is_Region() && this_region->req() == 3) {
       
   248       int ind = 1;
       
   249       if (!this_region->in(ind)->is_IfFalse()) {
       
   250         ind = 2;
       
   251       }
       
   252       if (this_region->in(ind)->is_IfFalse()) {
       
   253         Node* bol = this_region->in(ind)->in(0)->in(1);
       
   254         assert(bol->is_Bool(), "");
       
   255         cmpx = bol->in(1);
       
   256         if (bol->as_Bool()->_test._test == BoolTest::ne &&
       
   257             cmpx->is_Cmp() && cmpx->in(2) == intcon(0) &&
       
   258             cmpx->in(1)->is_Load()) {
       
   259           Node* adr = cmpx->in(1)->as_Load()->in(MemNode::Address);
       
   260           const int marking_offset = in_bytes(JavaThread::satb_mark_queue_offset() +
       
   261                                               PtrQueue::byte_offset_of_active());
       
   262           if (adr->is_AddP() && adr->in(AddPNode::Base) == top() &&
       
   263               adr->in(AddPNode::Address)->Opcode() == Op_ThreadLocal &&
       
   264               adr->in(AddPNode::Offset) == MakeConX(marking_offset)) {
       
   265             _igvn.replace_node(cmpx, makecon(TypeInt::CC_EQ));
       
   266           }
       
   267         }
       
   268       }
       
   269     }
       
   270     // Now CastP2X can be removed since it is used only on dead path
       
   271     // which currently still alive until igvn optimize it.
       
   272     assert(p2x->unique_out()->Opcode() == Op_URShiftX, "");
       
   273     _igvn.replace_node(p2x, top());
   209   }
   274   }
   210 }
   275 }
   211 
   276 
   212 // Search for a memory operation for the specified memory slice.
   277 // Search for a memory operation for the specified memory slice.
   213 static Node *scan_mem_chain(Node *mem, int alias_idx, int offset, Node *start_mem, Node *alloc, PhaseGVN *phase) {
   278 static Node *scan_mem_chain(Node *mem, int alias_idx, int offset, Node *start_mem, Node *alloc, PhaseGVN *phase) {
   758           Node *n = use->last_out(k);
   823           Node *n = use->last_out(k);
   759           uint oc2 = use->outcnt();
   824           uint oc2 = use->outcnt();
   760           if (n->is_Store()) {
   825           if (n->is_Store()) {
   761             _igvn.replace_node(n, n->in(MemNode::Memory));
   826             _igvn.replace_node(n, n->in(MemNode::Memory));
   762           } else {
   827           } else {
   763             assert( n->Opcode() == Op_CastP2X, "CastP2X required");
       
   764             eliminate_card_mark(n);
   828             eliminate_card_mark(n);
   765           }
   829           }
   766           k -= (oc2 - use->outcnt());
   830           k -= (oc2 - use->outcnt());
   767         }
   831         }
   768       } else {
   832       } else {
   769         assert( !use->is_SafePoint(), "safepoint uses must have been already elimiated");
       
   770         assert( use->Opcode() == Op_CastP2X, "CastP2X required");
       
   771         eliminate_card_mark(use);
   833         eliminate_card_mark(use);
   772       }
   834       }
   773       j -= (oc1 - res->outcnt());
   835       j -= (oc1 - res->outcnt());
   774     }
   836     }
   775     assert(res->outcnt() == 0, "all uses of allocated objects must be deleted");
   837     assert(res->outcnt() == 0, "all uses of allocated objects must be deleted");