hotspot/src/share/vm/opto/macro.cpp
changeset 39254 fb4492288b01
parent 38220 8d86b82e0ac7
child 40031 6cc034201dba
equal deleted inserted replaced
39253:bd5fe208734e 39254:fb4492288b01
     1 /*
     1 /*
     2  * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     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
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     7  * published by the Free Software Foundation.
    30 #include "opto/callnode.hpp"
    30 #include "opto/callnode.hpp"
    31 #include "opto/castnode.hpp"
    31 #include "opto/castnode.hpp"
    32 #include "opto/cfgnode.hpp"
    32 #include "opto/cfgnode.hpp"
    33 #include "opto/compile.hpp"
    33 #include "opto/compile.hpp"
    34 #include "opto/convertnode.hpp"
    34 #include "opto/convertnode.hpp"
       
    35 #include "opto/graphKit.hpp"
    35 #include "opto/locknode.hpp"
    36 #include "opto/locknode.hpp"
    36 #include "opto/loopnode.hpp"
    37 #include "opto/loopnode.hpp"
    37 #include "opto/macro.hpp"
    38 #include "opto/macro.hpp"
    38 #include "opto/memnode.hpp"
    39 #include "opto/memnode.hpp"
    39 #include "opto/narrowptrnode.hpp"
    40 #include "opto/narrowptrnode.hpp"
   261 
   262 
   262     // Search for CastP2X->Xor->URShift->Cmp path which
   263     // Search for CastP2X->Xor->URShift->Cmp path which
   263     // checks if the store done to a different from the value's region.
   264     // checks if the store done to a different from the value's region.
   264     // And replace Cmp with #0 (false) to collapse G1 post barrier.
   265     // And replace Cmp with #0 (false) to collapse G1 post barrier.
   265     Node* xorx = p2x->find_out_with(Op_XorX);
   266     Node* xorx = p2x->find_out_with(Op_XorX);
   266     assert(xorx != NULL, "missing G1 post barrier");
   267     if (xorx != NULL) {
   267     Node* shift = xorx->unique_out();
   268       Node* shift = xorx->unique_out();
   268     Node* cmpx = shift->unique_out();
   269       Node* cmpx = shift->unique_out();
   269     assert(cmpx->is_Cmp() && cmpx->unique_out()->is_Bool() &&
   270       assert(cmpx->is_Cmp() && cmpx->unique_out()->is_Bool() &&
   270     cmpx->unique_out()->as_Bool()->_test._test == BoolTest::ne,
   271       cmpx->unique_out()->as_Bool()->_test._test == BoolTest::ne,
   271     "missing region check in G1 post barrier");
   272       "missing region check in G1 post barrier");
   272     _igvn.replace_node(cmpx, makecon(TypeInt::CC_EQ));
   273       _igvn.replace_node(cmpx, makecon(TypeInt::CC_EQ));
   273 
   274 
   274     // Remove G1 pre barrier.
   275       // Remove G1 pre barrier.
   275 
   276 
   276     // Search "if (marking != 0)" check and set it to "false".
   277       // Search "if (marking != 0)" check and set it to "false".
   277     // There is no G1 pre barrier if previous stored value is NULL
   278       // There is no G1 pre barrier if previous stored value is NULL
   278     // (for example, after initialization).
   279       // (for example, after initialization).
   279     if (this_region->is_Region() && this_region->req() == 3) {
   280       if (this_region->is_Region() && this_region->req() == 3) {
   280       int ind = 1;
   281         int ind = 1;
   281       if (!this_region->in(ind)->is_IfFalse()) {
   282         if (!this_region->in(ind)->is_IfFalse()) {
   282         ind = 2;
   283           ind = 2;
   283       }
   284         }
   284       if (this_region->in(ind)->is_IfFalse()) {
   285         if (this_region->in(ind)->is_IfFalse()) {
   285         Node* bol = this_region->in(ind)->in(0)->in(1);
   286           Node* bol = this_region->in(ind)->in(0)->in(1);
   286         assert(bol->is_Bool(), "");
   287           assert(bol->is_Bool(), "");
   287         cmpx = bol->in(1);
   288           cmpx = bol->in(1);
   288         if (bol->as_Bool()->_test._test == BoolTest::ne &&
   289           if (bol->as_Bool()->_test._test == BoolTest::ne &&
   289             cmpx->is_Cmp() && cmpx->in(2) == intcon(0) &&
   290               cmpx->is_Cmp() && cmpx->in(2) == intcon(0) &&
   290             cmpx->in(1)->is_Load()) {
   291               cmpx->in(1)->is_Load()) {
   291           Node* adr = cmpx->in(1)->as_Load()->in(MemNode::Address);
   292             Node* adr = cmpx->in(1)->as_Load()->in(MemNode::Address);
   292           const int marking_offset = in_bytes(JavaThread::satb_mark_queue_offset() +
   293             const int marking_offset = in_bytes(JavaThread::satb_mark_queue_offset() +
   293                                               SATBMarkQueue::byte_offset_of_active());
   294                                                 SATBMarkQueue::byte_offset_of_active());
   294           if (adr->is_AddP() && adr->in(AddPNode::Base) == top() &&
   295             if (adr->is_AddP() && adr->in(AddPNode::Base) == top() &&
   295               adr->in(AddPNode::Address)->Opcode() == Op_ThreadLocal &&
   296                 adr->in(AddPNode::Address)->Opcode() == Op_ThreadLocal &&
   296               adr->in(AddPNode::Offset) == MakeConX(marking_offset)) {
   297                 adr->in(AddPNode::Offset) == MakeConX(marking_offset)) {
   297             _igvn.replace_node(cmpx, makecon(TypeInt::CC_EQ));
   298               _igvn.replace_node(cmpx, makecon(TypeInt::CC_EQ));
       
   299             }
   298           }
   300           }
   299         }
   301         }
   300       }
   302       }
       
   303     } else {
       
   304       assert(!GraphKit::use_ReduceInitialCardMarks(), "can only happen with card marking");
       
   305       // This is a G1 post barrier emitted by the Object.clone() intrinsic.
       
   306       // Search for the CastP2X->URShiftX->AddP->LoadB->Cmp path which checks if the card
       
   307       // is marked as young_gen and replace the Cmp with 0 (false) to collapse the barrier.
       
   308       Node* shift = p2x->find_out_with(Op_URShiftX);
       
   309       assert(shift != NULL, "missing G1 post barrier");
       
   310       Node* addp = shift->unique_out();
       
   311       Node* load = addp->find_out_with(Op_LoadB);
       
   312       assert(load != NULL, "missing G1 post barrier");
       
   313       Node* cmpx = load->unique_out();
       
   314       assert(cmpx->is_Cmp() && cmpx->unique_out()->is_Bool() &&
       
   315              cmpx->unique_out()->as_Bool()->_test._test == BoolTest::ne,
       
   316              "missing card value check in G1 post barrier");
       
   317       _igvn.replace_node(cmpx, makecon(TypeInt::CC_EQ));
       
   318       // There is no G1 pre barrier in this case
   301     }
   319     }
   302     // Now CastP2X can be removed since it is used only on dead path
   320     // Now CastP2X can be removed since it is used only on dead path
   303     // which currently still alive until igvn optimize it.
   321     // which currently still alive until igvn optimize it.
   304     assert(p2x->outcnt() == 0 || p2x->unique_out()->Opcode() == Op_URShiftX, "");
   322     assert(p2x->outcnt() == 0 || p2x->unique_out()->Opcode() == Op_URShiftX, "");
   305     _igvn.replace_node(p2x, top());
   323     _igvn.replace_node(p2x, top());
   324         return in;
   342         return in;
   325       } else if (in->is_Call()) {
   343       } else if (in->is_Call()) {
   326         CallNode *call = in->as_Call();
   344         CallNode *call = in->as_Call();
   327         if (call->may_modify(tinst, phase)) {
   345         if (call->may_modify(tinst, phase)) {
   328           assert(call->is_ArrayCopy(), "ArrayCopy is the only call node that doesn't make allocation escape");
   346           assert(call->is_ArrayCopy(), "ArrayCopy is the only call node that doesn't make allocation escape");
   329 
       
   330           if (call->as_ArrayCopy()->modifies(offset, offset, phase, false)) {
   347           if (call->as_ArrayCopy()->modifies(offset, offset, phase, false)) {
   331             return in;
   348             return in;
   332           }
   349           }
   333         }
   350         }
   334         mem = in->in(TypeFunc::Memory);
   351         mem = in->in(TypeFunc::Memory);
   335       } else if (in->is_MemBar()) {
   352       } else if (in->is_MemBar()) {
   336         if (ArrayCopyNode::may_modify(tinst, in->as_MemBar(), phase)) {
   353         ArrayCopyNode* ac = NULL;
   337           assert(in->in(0)->is_Proj() && in->in(0)->in(0)->is_ArrayCopy(), "should be arraycopy");
   354         if (ArrayCopyNode::may_modify(tinst, in->as_MemBar(), phase, ac)) {
   338           ArrayCopyNode* ac = in->in(0)->in(0)->as_ArrayCopy();
   355           assert(ac != NULL && ac->is_clonebasic(), "Only basic clone is a non escaping clone");
   339           assert(ac->is_clonebasic(), "Only basic clone is a non escaping clone");
       
   340           return ac;
   356           return ac;
   341         }
   357         }
   342         mem = in->in(TypeFunc::Memory);
   358         mem = in->in(TypeFunc::Memory);
   343       } else {
   359       } else {
   344         assert(false, "unexpected projection");
   360         assert(false, "unexpected projection");