changeset 3584:a1c7f6472621

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
author kvn
date Mon, 27 Aug 2012 09:46:38 -0700
parents 153776c4cb6f
children a5dd6e3ef9f3
files src/share/vm/opto/chaitin.cpp src/share/vm/opto/chaitin.hpp src/share/vm/opto/reg_split.cpp
diffstat 3 files changed, 23 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/opto/chaitin.cpp	Fri Aug 24 16:23:59 2012 -0700
+++ b/src/share/vm/opto/chaitin.cpp	Mon Aug 27 09:46:38 2012 -0700
@@ -222,6 +222,7 @@
   _alternate = 0;
   _matcher._allocation_started = true;
 
+  ResourceArea split_arena;     // Arena for Split local resources
   ResourceArea live_arena;      // Arena for liveness & IFG info
   ResourceMark rm(&live_arena);
 
@@ -324,7 +325,7 @@
     // Bail out if unique gets too large (ie - unique > MaxNodeLimit)
     C->check_node_count(10*must_spill, "out of nodes before split");
     if (C->failing())  return;
-    _maxlrg = Split( _maxlrg );        // Split spilling LRG everywhere
+    _maxlrg = Split(_maxlrg, &split_arena);  // Split spilling LRG everywhere
     // Bail out if unique gets too large (ie - unique > MaxNodeLimit - 2*NodeLimitFudgeFactor)
     // or we failed to split
     C->check_node_count(2*NodeLimitFudgeFactor, "out of nodes after physical split");
@@ -390,7 +391,7 @@
     }
 
     if( !_maxlrg ) return;
-    _maxlrg = Split( _maxlrg );        // Split spilling LRG everywhere
+    _maxlrg = Split(_maxlrg, &split_arena);  // Split spilling LRG everywhere
     // Bail out if unique gets too large (ie - unique > MaxNodeLimit - 2*NodeLimitFudgeFactor)
     C->check_node_count(2*NodeLimitFudgeFactor, "out of nodes after split");
     if (C->failing())  return;
--- a/src/share/vm/opto/chaitin.hpp	Fri Aug 24 16:23:59 2012 -0700
+++ b/src/share/vm/opto/chaitin.hpp	Mon Aug 27 09:46:38 2012 -0700
@@ -470,7 +470,7 @@
 
   // Split uncolorable live ranges
   // Return new number of live ranges
-  uint Split( uint maxlrg );
+  uint Split(uint maxlrg, ResourceArea* split_arena);
 
   // Copy 'was_spilled'-edness from one Node to another.
   void copy_was_spilled( Node *src, Node *dst );
--- a/src/share/vm/opto/reg_split.cpp	Fri Aug 24 16:23:59 2012 -0700
+++ b/src/share/vm/opto/reg_split.cpp	Mon Aug 27 09:46:38 2012 -0700
@@ -449,9 +449,12 @@
 // USES: If USE is in HRP, split at use to leave main LRG on stack.
 //       Else, hoist LRG back up to register only (ie - split is also DEF)
 // We will compute a new maxlrg as we go
-uint PhaseChaitin::Split( uint maxlrg ) {
+uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) {
   NOT_PRODUCT( Compile::TracePhase t3("regAllocSplit", &_t_regAllocSplit, TimeCompiler); )
 
+  // Free thread local resources used by this method on exit.
+  ResourceMark rm(split_arena);
+
   uint                 bidx, pidx, slidx, insidx, inpidx, twoidx;
   uint                 non_phi = 1, spill_cnt = 0;
   Node               **Reachblock;
@@ -461,14 +464,17 @@
   bool                 u1, u2, u3;
   Block               *b, *pred;
   PhiNode             *phi;
-  GrowableArray<uint>  lidxs;
+  GrowableArray<uint>  lidxs(split_arena, _maxlrg, 0, 0);
 
   // Array of counters to count splits per live range
-  GrowableArray<uint>  splits;
+  GrowableArray<uint>  splits(split_arena, _maxlrg, 0, 0);
+
+#define NEW_SPLIT_ARRAY(type, size)\
+  (type*) split_arena->allocate_bytes((size) * sizeof(type))
 
   //----------Setup Code----------
   // Create a convenient mapping from lrg numbers to reaches/leaves indices
-  uint *lrg2reach = NEW_RESOURCE_ARRAY( uint, _maxlrg );
+  uint *lrg2reach = NEW_SPLIT_ARRAY( uint, _maxlrg );
   // Keep track of DEFS & Phis for later passes
   defs = new Node_List();
   phis = new Node_List();
@@ -500,15 +506,15 @@
   // a Def is UP or DOWN.  UP means that it should get a register (ie -
   // it is always in LRP regions), and DOWN means that it is probably
   // on the stack (ie - it crosses HRP regions).
-  Node ***Reaches     = NEW_RESOURCE_ARRAY( Node**, _cfg._num_blocks+1 );
-  bool  **UP          = NEW_RESOURCE_ARRAY( bool*, _cfg._num_blocks+1 );
-  Node  **debug_defs  = NEW_RESOURCE_ARRAY( Node*, spill_cnt );
-  VectorSet **UP_entry= NEW_RESOURCE_ARRAY( VectorSet*, spill_cnt );
+  Node ***Reaches     = NEW_SPLIT_ARRAY( Node**, _cfg._num_blocks+1 );
+  bool  **UP          = NEW_SPLIT_ARRAY( bool*, _cfg._num_blocks+1 );
+  Node  **debug_defs  = NEW_SPLIT_ARRAY( Node*, spill_cnt );
+  VectorSet **UP_entry= NEW_SPLIT_ARRAY( VectorSet*, spill_cnt );
 
   // Initialize Reaches & UP
   for( bidx = 0; bidx < _cfg._num_blocks+1; bidx++ ) {
-    Reaches[bidx]     = NEW_RESOURCE_ARRAY( Node*, spill_cnt );
-    UP[bidx]          = NEW_RESOURCE_ARRAY( bool, spill_cnt );
+    Reaches[bidx]     = NEW_SPLIT_ARRAY( Node*, spill_cnt );
+    UP[bidx]          = NEW_SPLIT_ARRAY( bool, spill_cnt );
     Node **Reachblock = Reaches[bidx];
     bool *UPblock     = UP[bidx];
     for( slidx = 0; slidx < spill_cnt; slidx++ ) {
@@ -517,9 +523,11 @@
     }
   }
 
+#undef NEW_SPLIT_ARRAY
+
   // Initialize to array of empty vectorsets
   for( slidx = 0; slidx < spill_cnt; slidx++ )
-    UP_entry[slidx] = new VectorSet(Thread::current()->resource_area());
+    UP_entry[slidx] = new VectorSet(split_arena);
 
   //----------PASS 1----------
   //----------Propagation & Node Insertion Code----------