From 37c5fea2f61a443ddac1c521a2ded7edd34813b7 Mon Sep 17 00:00:00 2001 From: kvn Date: Mon, 27 Aug 2012 09:46:38 -0700 Subject: [PATCH] 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 | 5 +++-- src/share/vm/opto/chaitin.hpp | 2 +- src/share/vm/opto/reg_split.cpp | 30 +++++++++++++++++++----------- 3 files changed, 23 insertions(+), 14 deletions(-) diff --git a/src/share/vm/opto/chaitin.cpp b/src/share/vm/opto/chaitin.cpp index ae057c069..9e5234de6 100644 --- a/src/share/vm/opto/chaitin.cpp +++ b/src/share/vm/opto/chaitin.cpp @@ -222,6 +222,7 @@ void PhaseChaitin::Register_Allocate() { _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 @@ void PhaseChaitin::Register_Allocate() { // 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 @@ void PhaseChaitin::Register_Allocate() { } 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; diff --git a/src/share/vm/opto/chaitin.hpp b/src/share/vm/opto/chaitin.hpp index c10f18d74..340e46d49 100644 --- a/src/share/vm/opto/chaitin.hpp +++ b/src/share/vm/opto/chaitin.hpp @@ -470,7 +470,7 @@ private: // 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 ); diff --git a/src/share/vm/opto/reg_split.cpp b/src/share/vm/opto/reg_split.cpp index cae363bea..2c488894a 100644 --- a/src/share/vm/opto/reg_split.cpp +++ b/src/share/vm/opto/reg_split.cpp @@ -449,9 +449,12 @@ bool PhaseChaitin::prompt_use( Block *b, uint lidx ) { // 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 @@ uint PhaseChaitin::Split( uint maxlrg ) { bool u1, u2, u3; Block *b, *pred; PhiNode *phi; - GrowableArray lidxs; + GrowableArray lidxs(split_arena, _maxlrg, 0, 0); // Array of counters to count splits per live range - GrowableArray splits; + GrowableArray 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 @@ uint PhaseChaitin::Split( uint maxlrg ) { // 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 @@ uint PhaseChaitin::Split( uint maxlrg ) { } } +#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---------- -- GitLab