src/share/vm/opto/escape.cpp

changeset 2556
3763ca6579b7
parent 2409
a21ff35351ec
child 2741
55973726c600
     1.1 --- a/src/share/vm/opto/escape.cpp	Mon Feb 07 09:46:01 2011 -0800
     1.2 +++ b/src/share/vm/opto/escape.cpp	Mon Feb 07 10:25:39 2011 -0800
     1.3 @@ -1,5 +1,5 @@
     1.4  /*
     1.5 - * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
     1.6 + * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
     1.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.8   *
     1.9   * This code is free software; you can redistribute it and/or modify it
    1.10 @@ -93,6 +93,9 @@
    1.11  ConnectionGraph::ConnectionGraph(Compile * C, PhaseIterGVN *igvn) :
    1.12    _nodes(C->comp_arena(), C->unique(), C->unique(), PointsToNode()),
    1.13    _processed(C->comp_arena()),
    1.14 +  pt_ptset(C->comp_arena()),
    1.15 +  pt_visited(C->comp_arena()),
    1.16 +  pt_worklist(C->comp_arena(), 4, 0, 0),
    1.17    _collecting(true),
    1.18    _progress(false),
    1.19    _compile(C),
    1.20 @@ -220,9 +223,7 @@
    1.21    PointsToNode::EscapeState orig_es = es;
    1.22  
    1.23    // compute max escape state of anything this node could point to
    1.24 -  VectorSet ptset(Thread::current()->resource_area());
    1.25 -  PointsTo(ptset, n);
    1.26 -  for(VectorSetI i(&ptset); i.test() && es != PointsToNode::GlobalEscape; ++i) {
    1.27 +  for(VectorSetI i(PointsTo(n)); i.test() && es != PointsToNode::GlobalEscape; ++i) {
    1.28      uint pt = i.elem;
    1.29      PointsToNode::EscapeState pes = ptnode_adr(pt)->escape_state();
    1.30      if (pes > es)
    1.31 @@ -236,9 +237,10 @@
    1.32    return es;
    1.33  }
    1.34  
    1.35 -void ConnectionGraph::PointsTo(VectorSet &ptset, Node * n) {
    1.36 -  VectorSet visited(Thread::current()->resource_area());
    1.37 -  GrowableArray<uint>  worklist;
    1.38 +VectorSet* ConnectionGraph::PointsTo(Node * n) {
    1.39 +  pt_ptset.Reset();
    1.40 +  pt_visited.Reset();
    1.41 +  pt_worklist.clear();
    1.42  
    1.43  #ifdef ASSERT
    1.44    Node *orig_n = n;
    1.45 @@ -249,8 +251,8 @@
    1.46  
    1.47    // If we have a JavaObject, return just that object
    1.48    if (npt->node_type() == PointsToNode::JavaObject) {
    1.49 -    ptset.set(n->_idx);
    1.50 -    return;
    1.51 +    pt_ptset.set(n->_idx);
    1.52 +    return &pt_ptset;
    1.53    }
    1.54  #ifdef ASSERT
    1.55    if (npt->_node == NULL) {
    1.56 @@ -260,10 +262,10 @@
    1.57      assert(npt->_node != NULL, "unregistered node");
    1.58    }
    1.59  #endif
    1.60 -  worklist.push(n->_idx);
    1.61 -  while(worklist.length() > 0) {
    1.62 -    int ni = worklist.pop();
    1.63 -    if (visited.test_set(ni))
    1.64 +  pt_worklist.push(n->_idx);
    1.65 +  while(pt_worklist.length() > 0) {
    1.66 +    int ni = pt_worklist.pop();
    1.67 +    if (pt_visited.test_set(ni))
    1.68        continue;
    1.69  
    1.70      PointsToNode* pn = ptnode_adr(ni);
    1.71 @@ -276,10 +278,10 @@
    1.72        uint etgt = pn->edge_target(e);
    1.73        PointsToNode::EdgeType et = pn->edge_type(e);
    1.74        if (et == PointsToNode::PointsToEdge) {
    1.75 -        ptset.set(etgt);
    1.76 +        pt_ptset.set(etgt);
    1.77          edges_processed++;
    1.78        } else if (et == PointsToNode::DeferredEdge) {
    1.79 -        worklist.push(etgt);
    1.80 +        pt_worklist.push(etgt);
    1.81          edges_processed++;
    1.82        } else {
    1.83          assert(false,"neither PointsToEdge or DeferredEdge");
    1.84 @@ -288,16 +290,17 @@
    1.85      if (edges_processed == 0) {
    1.86        // no deferred or pointsto edges found.  Assume the value was set
    1.87        // outside this method.  Add the phantom object to the pointsto set.
    1.88 -      ptset.set(_phantom_object);
    1.89 +      pt_ptset.set(_phantom_object);
    1.90      }
    1.91    }
    1.92 +  return &pt_ptset;
    1.93  }
    1.94  
    1.95  void ConnectionGraph::remove_deferred(uint ni, GrowableArray<uint>* deferred_edges, VectorSet* visited) {
    1.96    // This method is most expensive during ConnectionGraph construction.
    1.97    // Reuse vectorSet and an additional growable array for deferred edges.
    1.98    deferred_edges->clear();
    1.99 -  visited->Clear();
   1.100 +  visited->Reset();
   1.101  
   1.102    visited->set(ni);
   1.103    PointsToNode *ptn = ptnode_adr(ni);
   1.104 @@ -1009,7 +1012,6 @@
   1.105    uint new_index_start = (uint) _compile->num_alias_types();
   1.106    Arena* arena = Thread::current()->resource_area();
   1.107    VectorSet visited(arena);
   1.108 -  VectorSet ptset(arena);
   1.109  
   1.110  
   1.111    //  Phase 1:  Process possible allocations from alloc_worklist.
   1.112 @@ -1137,10 +1139,9 @@
   1.113          }
   1.114        }
   1.115      } else if (n->is_AddP()) {
   1.116 -      ptset.Clear();
   1.117 -      PointsTo(ptset, get_addp_base(n));
   1.118 -      assert(ptset.Size() == 1, "AddP address is unique");
   1.119 -      uint elem = ptset.getelem(); // Allocation node's index
   1.120 +      VectorSet* ptset = PointsTo(get_addp_base(n));
   1.121 +      assert(ptset->Size() == 1, "AddP address is unique");
   1.122 +      uint elem = ptset->getelem(); // Allocation node's index
   1.123        if (elem == _phantom_object) {
   1.124          assert(false, "escaped allocation");
   1.125          continue; // Assume the value was set outside this method.
   1.126 @@ -1157,10 +1158,9 @@
   1.127          assert(n->is_Phi(), "loops only through Phi's");
   1.128          continue;  // already processed
   1.129        }
   1.130 -      ptset.Clear();
   1.131 -      PointsTo(ptset, n);
   1.132 -      if (ptset.Size() == 1) {
   1.133 -        uint elem = ptset.getelem(); // Allocation node's index
   1.134 +      VectorSet* ptset = PointsTo(n);
   1.135 +      if (ptset->Size() == 1) {
   1.136 +        uint elem = ptset->getelem(); // Allocation node's index
   1.137          if (elem == _phantom_object) {
   1.138            assert(false, "escaped allocation");
   1.139            continue; // Assume the value was set outside this method.
   1.140 @@ -1434,7 +1434,7 @@
   1.141    // Update the memory inputs of MemNodes with the value we computed
   1.142    // in Phase 2 and move stores memory users to corresponding memory slices.
   1.143  #ifdef ASSERT
   1.144 -  visited.Clear();
   1.145 +  visited.Reset();
   1.146    Node_Stack old_mems(arena, _compile->unique() >> 2);
   1.147  #endif
   1.148    for (uint i = 0; i < nodes_size(); i++) {
   1.149 @@ -1640,7 +1640,6 @@
   1.150  #undef CG_BUILD_ITER_LIMIT
   1.151  
   1.152    Arena* arena = Thread::current()->resource_area();
   1.153 -  VectorSet ptset(arena);
   1.154    VectorSet visited(arena);
   1.155    worklist.clear();
   1.156  
   1.157 @@ -1657,7 +1656,7 @@
   1.158        if (n->is_AddP()) {
   1.159          // Search for objects which are not scalar replaceable
   1.160          // and adjust their escape state.
   1.161 -        verify_escape_state(ni, ptset, igvn);
   1.162 +        adjust_escape_state(ni, igvn);
   1.163        }
   1.164      }
   1.165    }
   1.166 @@ -1776,8 +1775,8 @@
   1.167    return has_non_escaping_obj;
   1.168  }
   1.169  
   1.170 -// Search for objects which are not scalar replaceable.
   1.171 -void ConnectionGraph::verify_escape_state(int nidx, VectorSet& ptset, PhaseTransform* phase) {
   1.172 +// Adjust escape state after Connection Graph is built.
   1.173 +void ConnectionGraph::adjust_escape_state(int nidx, PhaseTransform* phase) {
   1.174    PointsToNode* ptn = ptnode_adr(nidx);
   1.175    Node* n = ptn->_node;
   1.176    assert(n->is_AddP(), "Should be called for AddP nodes only");
   1.177 @@ -1792,9 +1791,8 @@
   1.178  
   1.179    int offset = ptn->offset();
   1.180    Node* base = get_addp_base(n);
   1.181 -  ptset.Clear();
   1.182 -  PointsTo(ptset, base);
   1.183 -  int ptset_size = ptset.Size();
   1.184 +  VectorSet* ptset = PointsTo(base);
   1.185 +  int ptset_size = ptset->Size();
   1.186  
   1.187    // Check if a oop field's initializing value is recorded and add
   1.188    // a corresponding NULL field's value if it is not recorded.
   1.189 @@ -1814,7 +1812,7 @@
   1.190    // Do a simple control flow analysis to distinguish above cases.
   1.191    //
   1.192    if (offset != Type::OffsetBot && ptset_size == 1) {
   1.193 -    uint elem = ptset.getelem(); // Allocation node's index
   1.194 +    uint elem = ptset->getelem(); // Allocation node's index
   1.195      // It does not matter if it is not Allocation node since
   1.196      // only non-escaping allocations are scalar replaced.
   1.197      if (ptnode_adr(elem)->_node->is_Allocate() &&
   1.198 @@ -1913,7 +1911,7 @@
   1.199    //
   1.200    if (ptset_size > 1 || ptset_size != 0 &&
   1.201        (has_LoadStore || offset == Type::OffsetBot)) {
   1.202 -    for( VectorSetI j(&ptset); j.test(); ++j ) {
   1.203 +    for( VectorSetI j(ptset); j.test(); ++j ) {
   1.204        set_escape_state(j.elem, PointsToNode::ArgEscape);
   1.205        ptnode_adr(j.elem)->_scalar_replaceable = false;
   1.206      }
   1.207 @@ -1937,7 +1935,6 @@
   1.208        // Stub calls, objects do not escape but they are not scale replaceable.
   1.209        // Adjust escape state for outgoing arguments.
   1.210        const TypeTuple * d = call->tf()->domain();
   1.211 -      VectorSet ptset(Thread::current()->resource_area());
   1.212        for (uint i = TypeFunc::Parms; i < d->cnt(); i++) {
   1.213          const Type* at = d->field_at(i);
   1.214          Node *arg = call->in(i)->uncast();
   1.215 @@ -1970,9 +1967,7 @@
   1.216              //
   1.217              arg = get_addp_base(arg);
   1.218            }
   1.219 -          ptset.Clear();
   1.220 -          PointsTo(ptset, arg);
   1.221 -          for( VectorSetI j(&ptset); j.test(); ++j ) {
   1.222 +          for( VectorSetI j(PointsTo(arg)); j.test(); ++j ) {
   1.223              uint pt = j.elem;
   1.224              set_escape_state(pt, PointsToNode::ArgEscape);
   1.225            }
   1.226 @@ -1990,7 +1985,6 @@
   1.227        // fall-through if not a Java method or no analyzer information
   1.228        if (call_analyzer != NULL) {
   1.229          const TypeTuple * d = call->tf()->domain();
   1.230 -        VectorSet ptset(Thread::current()->resource_area());
   1.231          bool copy_dependencies = false;
   1.232          for (uint i = TypeFunc::Parms; i < d->cnt(); i++) {
   1.233            const Type* at = d->field_at(i);
   1.234 @@ -2015,9 +2009,7 @@
   1.235                copy_dependencies = true;
   1.236              }
   1.237  
   1.238 -            ptset.Clear();
   1.239 -            PointsTo(ptset, arg);
   1.240 -            for( VectorSetI j(&ptset); j.test(); ++j ) {
   1.241 +            for( VectorSetI j(PointsTo(arg)); j.test(); ++j ) {
   1.242                uint pt = j.elem;
   1.243                if (global_escapes) {
   1.244                  //The argument global escapes, mark everything it could point to
   1.245 @@ -2045,15 +2037,12 @@
   1.246      {
   1.247        // adjust escape state for  outgoing arguments
   1.248        const TypeTuple * d = call->tf()->domain();
   1.249 -      VectorSet ptset(Thread::current()->resource_area());
   1.250        for (uint i = TypeFunc::Parms; i < d->cnt(); i++) {
   1.251          const Type* at = d->field_at(i);
   1.252          if (at->isa_oopptr() != NULL) {
   1.253            Node *arg = call->in(i)->uncast();
   1.254            set_escape_state(arg->_idx, PointsToNode::GlobalEscape);
   1.255 -          ptset.Clear();
   1.256 -          PointsTo(ptset, arg);
   1.257 -          for( VectorSetI j(&ptset); j.test(); ++j ) {
   1.258 +          for( VectorSetI j(PointsTo(arg)); j.test(); ++j ) {
   1.259              uint pt = j.elem;
   1.260              set_escape_state(pt, PointsToNode::GlobalEscape);
   1.261            }
   1.262 @@ -2515,9 +2504,7 @@
   1.263      {
   1.264        Node *base = get_addp_base(n);
   1.265        // Create a field edge to this node from everything base could point to.
   1.266 -      VectorSet ptset(Thread::current()->resource_area());
   1.267 -      PointsTo(ptset, base);
   1.268 -      for( VectorSetI i(&ptset); i.test(); ++i ) {
   1.269 +      for( VectorSetI i(PointsTo(base)); i.test(); ++i ) {
   1.270          uint pt = i.elem;
   1.271          add_field_edge(pt, n_idx, address_offset(n, phase));
   1.272        }
   1.273 @@ -2583,10 +2570,8 @@
   1.274  
   1.275        // For everything "adr_base" could point to, create a deferred edge from
   1.276        // this node to each field with the same offset.
   1.277 -      VectorSet ptset(Thread::current()->resource_area());
   1.278 -      PointsTo(ptset, adr_base);
   1.279        int offset = address_offset(adr, phase);
   1.280 -      for( VectorSetI i(&ptset); i.test(); ++i ) {
   1.281 +      for( VectorSetI i(PointsTo(adr_base)); i.test(); ++i ) {
   1.282          uint pt = i.elem;
   1.283          add_deferred_edge_to_fields(n_idx, pt, offset);
   1.284        }
   1.285 @@ -2676,9 +2661,7 @@
   1.286        Node *val = n->in(MemNode::ValueIn)->uncast();
   1.287        // For everything "adr_base" could point to, create a deferred edge
   1.288        // to "val" from each field with the same offset.
   1.289 -      VectorSet ptset(Thread::current()->resource_area());
   1.290 -      PointsTo(ptset, adr_base);
   1.291 -      for( VectorSetI i(&ptset); i.test(); ++i ) {
   1.292 +      for( VectorSetI i(PointsTo(adr_base)); i.test(); ++i ) {
   1.293          uint pt = i.elem;
   1.294          add_edge_from_fields(pt, val->_idx, address_offset(adr, phase));
   1.295        }

mercurial