7148109: C2 compiler consumes too much heap resources

Mon, 27 Aug 2012 09:46:38 -0700

author
kvn
date
Mon, 27 Aug 2012 09:46:38 -0700
changeset 4019
a1c7f6472621
parent 4012
153776c4cb6f
child 4020
a5dd6e3ef9f3

7148109: C2 compiler consumes too much heap resources
Summary: Add split_arena to allocate temporary arrays in PhaseChaitin::Split() and free them on method's exit.
Reviewed-by: twisti

src/share/vm/opto/chaitin.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/chaitin.hpp file | annotate | diff | comparison | revisions
src/share/vm/opto/reg_split.cpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/vm/opto/chaitin.cpp	Fri Aug 24 16:23:59 2012 -0700
     1.2 +++ b/src/share/vm/opto/chaitin.cpp	Mon Aug 27 09:46:38 2012 -0700
     1.3 @@ -222,6 +222,7 @@
     1.4    _alternate = 0;
     1.5    _matcher._allocation_started = true;
     1.6  
     1.7 +  ResourceArea split_arena;     // Arena for Split local resources
     1.8    ResourceArea live_arena;      // Arena for liveness & IFG info
     1.9    ResourceMark rm(&live_arena);
    1.10  
    1.11 @@ -324,7 +325,7 @@
    1.12      // Bail out if unique gets too large (ie - unique > MaxNodeLimit)
    1.13      C->check_node_count(10*must_spill, "out of nodes before split");
    1.14      if (C->failing())  return;
    1.15 -    _maxlrg = Split( _maxlrg );        // Split spilling LRG everywhere
    1.16 +    _maxlrg = Split(_maxlrg, &split_arena);  // Split spilling LRG everywhere
    1.17      // Bail out if unique gets too large (ie - unique > MaxNodeLimit - 2*NodeLimitFudgeFactor)
    1.18      // or we failed to split
    1.19      C->check_node_count(2*NodeLimitFudgeFactor, "out of nodes after physical split");
    1.20 @@ -390,7 +391,7 @@
    1.21      }
    1.22  
    1.23      if( !_maxlrg ) return;
    1.24 -    _maxlrg = Split( _maxlrg );        // Split spilling LRG everywhere
    1.25 +    _maxlrg = Split(_maxlrg, &split_arena);  // Split spilling LRG everywhere
    1.26      // Bail out if unique gets too large (ie - unique > MaxNodeLimit - 2*NodeLimitFudgeFactor)
    1.27      C->check_node_count(2*NodeLimitFudgeFactor, "out of nodes after split");
    1.28      if (C->failing())  return;
     2.1 --- a/src/share/vm/opto/chaitin.hpp	Fri Aug 24 16:23:59 2012 -0700
     2.2 +++ b/src/share/vm/opto/chaitin.hpp	Mon Aug 27 09:46:38 2012 -0700
     2.3 @@ -470,7 +470,7 @@
     2.4  
     2.5    // Split uncolorable live ranges
     2.6    // Return new number of live ranges
     2.7 -  uint Split( uint maxlrg );
     2.8 +  uint Split(uint maxlrg, ResourceArea* split_arena);
     2.9  
    2.10    // Copy 'was_spilled'-edness from one Node to another.
    2.11    void copy_was_spilled( Node *src, Node *dst );
     3.1 --- a/src/share/vm/opto/reg_split.cpp	Fri Aug 24 16:23:59 2012 -0700
     3.2 +++ b/src/share/vm/opto/reg_split.cpp	Mon Aug 27 09:46:38 2012 -0700
     3.3 @@ -449,9 +449,12 @@
     3.4  // USES: If USE is in HRP, split at use to leave main LRG on stack.
     3.5  //       Else, hoist LRG back up to register only (ie - split is also DEF)
     3.6  // We will compute a new maxlrg as we go
     3.7 -uint PhaseChaitin::Split( uint maxlrg ) {
     3.8 +uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) {
     3.9    NOT_PRODUCT( Compile::TracePhase t3("regAllocSplit", &_t_regAllocSplit, TimeCompiler); )
    3.10  
    3.11 +  // Free thread local resources used by this method on exit.
    3.12 +  ResourceMark rm(split_arena);
    3.13 +
    3.14    uint                 bidx, pidx, slidx, insidx, inpidx, twoidx;
    3.15    uint                 non_phi = 1, spill_cnt = 0;
    3.16    Node               **Reachblock;
    3.17 @@ -461,14 +464,17 @@
    3.18    bool                 u1, u2, u3;
    3.19    Block               *b, *pred;
    3.20    PhiNode             *phi;
    3.21 -  GrowableArray<uint>  lidxs;
    3.22 +  GrowableArray<uint>  lidxs(split_arena, _maxlrg, 0, 0);
    3.23  
    3.24    // Array of counters to count splits per live range
    3.25 -  GrowableArray<uint>  splits;
    3.26 +  GrowableArray<uint>  splits(split_arena, _maxlrg, 0, 0);
    3.27 +
    3.28 +#define NEW_SPLIT_ARRAY(type, size)\
    3.29 +  (type*) split_arena->allocate_bytes((size) * sizeof(type))
    3.30  
    3.31    //----------Setup Code----------
    3.32    // Create a convenient mapping from lrg numbers to reaches/leaves indices
    3.33 -  uint *lrg2reach = NEW_RESOURCE_ARRAY( uint, _maxlrg );
    3.34 +  uint *lrg2reach = NEW_SPLIT_ARRAY( uint, _maxlrg );
    3.35    // Keep track of DEFS & Phis for later passes
    3.36    defs = new Node_List();
    3.37    phis = new Node_List();
    3.38 @@ -500,15 +506,15 @@
    3.39    // a Def is UP or DOWN.  UP means that it should get a register (ie -
    3.40    // it is always in LRP regions), and DOWN means that it is probably
    3.41    // on the stack (ie - it crosses HRP regions).
    3.42 -  Node ***Reaches     = NEW_RESOURCE_ARRAY( Node**, _cfg._num_blocks+1 );
    3.43 -  bool  **UP          = NEW_RESOURCE_ARRAY( bool*, _cfg._num_blocks+1 );
    3.44 -  Node  **debug_defs  = NEW_RESOURCE_ARRAY( Node*, spill_cnt );
    3.45 -  VectorSet **UP_entry= NEW_RESOURCE_ARRAY( VectorSet*, spill_cnt );
    3.46 +  Node ***Reaches     = NEW_SPLIT_ARRAY( Node**, _cfg._num_blocks+1 );
    3.47 +  bool  **UP          = NEW_SPLIT_ARRAY( bool*, _cfg._num_blocks+1 );
    3.48 +  Node  **debug_defs  = NEW_SPLIT_ARRAY( Node*, spill_cnt );
    3.49 +  VectorSet **UP_entry= NEW_SPLIT_ARRAY( VectorSet*, spill_cnt );
    3.50  
    3.51    // Initialize Reaches & UP
    3.52    for( bidx = 0; bidx < _cfg._num_blocks+1; bidx++ ) {
    3.53 -    Reaches[bidx]     = NEW_RESOURCE_ARRAY( Node*, spill_cnt );
    3.54 -    UP[bidx]          = NEW_RESOURCE_ARRAY( bool, spill_cnt );
    3.55 +    Reaches[bidx]     = NEW_SPLIT_ARRAY( Node*, spill_cnt );
    3.56 +    UP[bidx]          = NEW_SPLIT_ARRAY( bool, spill_cnt );
    3.57      Node **Reachblock = Reaches[bidx];
    3.58      bool *UPblock     = UP[bidx];
    3.59      for( slidx = 0; slidx < spill_cnt; slidx++ ) {
    3.60 @@ -517,9 +523,11 @@
    3.61      }
    3.62    }
    3.63  
    3.64 +#undef NEW_SPLIT_ARRAY
    3.65 +
    3.66    // Initialize to array of empty vectorsets
    3.67    for( slidx = 0; slidx < spill_cnt; slidx++ )
    3.68 -    UP_entry[slidx] = new VectorSet(Thread::current()->resource_area());
    3.69 +    UP_entry[slidx] = new VectorSet(split_arena);
    3.70  
    3.71    //----------PASS 1----------
    3.72    //----------Propagation & Node Insertion Code----------

mercurial