hotspot/src/share/vm/opto/macro.cpp
changeset 30629 b6e5ad2f18d5
parent 30248 5c6dacbd17ae
child 32370 38b7b5772b4f
equal deleted inserted replaced
30628:3c15b4a3bf4d 30629:b6e5ad2f18d5
    24 
    24 
    25 #include "precompiled.hpp"
    25 #include "precompiled.hpp"
    26 #include "compiler/compileLog.hpp"
    26 #include "compiler/compileLog.hpp"
    27 #include "libadt/vectset.hpp"
    27 #include "libadt/vectset.hpp"
    28 #include "opto/addnode.hpp"
    28 #include "opto/addnode.hpp"
       
    29 #include "opto/arraycopynode.hpp"
    29 #include "opto/callnode.hpp"
    30 #include "opto/callnode.hpp"
    30 #include "opto/castnode.hpp"
    31 #include "opto/castnode.hpp"
    31 #include "opto/cfgnode.hpp"
    32 #include "opto/cfgnode.hpp"
    32 #include "opto/compile.hpp"
    33 #include "opto/compile.hpp"
    33 #include "opto/convertnode.hpp"
    34 #include "opto/convertnode.hpp"
   611           break;
   612           break;
   612         }
   613         }
   613         for (DUIterator_Fast kmax, k = use->fast_outs(kmax);
   614         for (DUIterator_Fast kmax, k = use->fast_outs(kmax);
   614                                    k < kmax && can_eliminate; k++) {
   615                                    k < kmax && can_eliminate; k++) {
   615           Node* n = use->fast_out(k);
   616           Node* n = use->fast_out(k);
   616           if (!n->is_Store() && n->Opcode() != Op_CastP2X) {
   617           if (!n->is_Store() && n->Opcode() != Op_CastP2X &&
       
   618               !(n->is_ArrayCopy() &&
       
   619                 n->as_ArrayCopy()->is_clonebasic() &&
       
   620                 n->in(ArrayCopyNode::Dest) == use)) {
   617             DEBUG_ONLY(disq_node = n;)
   621             DEBUG_ONLY(disq_node = n;)
   618             if (n->is_Load() || n->is_LoadStore()) {
   622             if (n->is_Load() || n->is_LoadStore()) {
   619               NOT_PRODUCT(fail_eliminate = "Field load";)
   623               NOT_PRODUCT(fail_eliminate = "Field load";)
   620             } else {
   624             } else {
   621               NOT_PRODUCT(fail_eliminate = "Not store field referrence";)
   625               NOT_PRODUCT(fail_eliminate = "Not store field referrence";)
   622             }
   626             }
   623             can_eliminate = false;
   627             can_eliminate = false;
   624           }
   628           }
   625         }
   629         }
       
   630       } else if (use->is_ArrayCopy() &&
       
   631                  (use->as_ArrayCopy()->is_arraycopy_validated() ||
       
   632                   use->as_ArrayCopy()->is_copyof_validated() ||
       
   633                   use->as_ArrayCopy()->is_copyofrange_validated()) &&
       
   634                  use->in(ArrayCopyNode::Dest) == res) {
       
   635         // ok to eliminate
   626       } else if (use->is_SafePoint()) {
   636       } else if (use->is_SafePoint()) {
   627         SafePointNode* sfpt = use->as_SafePoint();
   637         SafePointNode* sfpt = use->as_SafePoint();
   628         if (sfpt->is_Call() && sfpt->as_Call()->has_non_debug_use(res)) {
   638         if (sfpt->is_Call() && sfpt->as_Call()->has_non_debug_use(res)) {
   629           // Object is passed as argument.
   639           // Object is passed as argument.
   630           DEBUG_ONLY(disq_node = use;)
   640           DEBUG_ONLY(disq_node = use;)
   885                      mb->in(MemBarNode::Precedent) != n,
   895                      mb->in(MemBarNode::Precedent) != n,
   886                      "MemBarVolatile should be eliminated for non-escaping object");
   896                      "MemBarVolatile should be eliminated for non-escaping object");
   887             }
   897             }
   888 #endif
   898 #endif
   889             _igvn.replace_node(n, n->in(MemNode::Memory));
   899             _igvn.replace_node(n, n->in(MemNode::Memory));
       
   900           } else if (n->is_ArrayCopy()) {
       
   901             // Disconnect ArrayCopy node
       
   902             ArrayCopyNode* ac = n->as_ArrayCopy();
       
   903             assert(ac->is_clonebasic(), "unexpected array copy kind");
       
   904             Node* ctl_proj = ac->proj_out(TypeFunc::Control);
       
   905             Node* mem_proj = ac->proj_out(TypeFunc::Memory);
       
   906             if (ctl_proj != NULL) {
       
   907               _igvn.replace_node(ctl_proj, n->in(0));
       
   908             }
       
   909             if (mem_proj != NULL) {
       
   910               _igvn.replace_node(mem_proj, n->in(TypeFunc::Memory));
       
   911             }
   890           } else {
   912           } else {
   891             eliminate_card_mark(n);
   913             eliminate_card_mark(n);
   892           }
   914           }
   893           k -= (oc2 - use->outcnt());
   915           k -= (oc2 - use->outcnt());
   894         }
   916         }
       
   917       } else if (use->is_ArrayCopy()) {
       
   918         // Disconnect ArrayCopy node
       
   919         ArrayCopyNode* ac = use->as_ArrayCopy();
       
   920         assert(ac->is_arraycopy_validated() ||
       
   921                ac->is_copyof_validated() ||
       
   922                ac->is_copyofrange_validated(), "unsupported");
       
   923         CallProjections callprojs;
       
   924         ac->extract_projections(&callprojs, true);
       
   925 
       
   926         _igvn.replace_node(callprojs.fallthrough_ioproj, ac->in(TypeFunc::I_O));
       
   927         _igvn.replace_node(callprojs.fallthrough_memproj, ac->in(TypeFunc::Memory));
       
   928         _igvn.replace_node(callprojs.fallthrough_catchproj, ac->in(TypeFunc::Control));
       
   929 
       
   930         // Set control to top. IGVN will remove the remaining projections
       
   931         ac->set_req(0, top());
       
   932         ac->replace_edge(res, top());
       
   933 
       
   934         // Disconnect src right away: it can help find new
       
   935         // opportunities for allocation elimination
       
   936         Node* src = ac->in(ArrayCopyNode::Src);
       
   937         ac->replace_edge(src, top());
       
   938         if (src->outcnt() == 0) {
       
   939           _igvn.remove_dead_node(src);
       
   940         }
       
   941 
       
   942         _igvn._worklist.push(ac);
   895       } else {
   943       } else {
   896         eliminate_card_mark(use);
   944         eliminate_card_mark(use);
   897       }
   945       }
   898       j -= (oc1 - res->outcnt());
   946       j -= (oc1 - res->outcnt());
   899     }
   947     }