提交 37c5fea2 编写于 作者: K kvn

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
上级 9e00ee75
...@@ -222,6 +222,7 @@ void PhaseChaitin::Register_Allocate() { ...@@ -222,6 +222,7 @@ void PhaseChaitin::Register_Allocate() {
_alternate = 0; _alternate = 0;
_matcher._allocation_started = true; _matcher._allocation_started = true;
ResourceArea split_arena; // Arena for Split local resources
ResourceArea live_arena; // Arena for liveness & IFG info ResourceArea live_arena; // Arena for liveness & IFG info
ResourceMark rm(&live_arena); ResourceMark rm(&live_arena);
...@@ -324,7 +325,7 @@ void PhaseChaitin::Register_Allocate() { ...@@ -324,7 +325,7 @@ void PhaseChaitin::Register_Allocate() {
// Bail out if unique gets too large (ie - unique > MaxNodeLimit) // Bail out if unique gets too large (ie - unique > MaxNodeLimit)
C->check_node_count(10*must_spill, "out of nodes before split"); C->check_node_count(10*must_spill, "out of nodes before split");
if (C->failing()) return; 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) // Bail out if unique gets too large (ie - unique > MaxNodeLimit - 2*NodeLimitFudgeFactor)
// or we failed to split // or we failed to split
C->check_node_count(2*NodeLimitFudgeFactor, "out of nodes after physical split"); C->check_node_count(2*NodeLimitFudgeFactor, "out of nodes after physical split");
...@@ -390,7 +391,7 @@ void PhaseChaitin::Register_Allocate() { ...@@ -390,7 +391,7 @@ void PhaseChaitin::Register_Allocate() {
} }
if( !_maxlrg ) return; 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) // Bail out if unique gets too large (ie - unique > MaxNodeLimit - 2*NodeLimitFudgeFactor)
C->check_node_count(2*NodeLimitFudgeFactor, "out of nodes after split"); C->check_node_count(2*NodeLimitFudgeFactor, "out of nodes after split");
if (C->failing()) return; if (C->failing()) return;
......
...@@ -470,7 +470,7 @@ private: ...@@ -470,7 +470,7 @@ private:
// Split uncolorable live ranges // Split uncolorable live ranges
// Return new number of 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. // Copy 'was_spilled'-edness from one Node to another.
void copy_was_spilled( Node *src, Node *dst ); void copy_was_spilled( Node *src, Node *dst );
......
...@@ -449,9 +449,12 @@ bool PhaseChaitin::prompt_use( Block *b, uint lidx ) { ...@@ -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. // 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) // Else, hoist LRG back up to register only (ie - split is also DEF)
// We will compute a new maxlrg as we go // 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); ) 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 bidx, pidx, slidx, insidx, inpidx, twoidx;
uint non_phi = 1, spill_cnt = 0; uint non_phi = 1, spill_cnt = 0;
Node **Reachblock; Node **Reachblock;
...@@ -461,14 +464,17 @@ uint PhaseChaitin::Split( uint maxlrg ) { ...@@ -461,14 +464,17 @@ uint PhaseChaitin::Split( uint maxlrg ) {
bool u1, u2, u3; bool u1, u2, u3;
Block *b, *pred; Block *b, *pred;
PhiNode *phi; PhiNode *phi;
GrowableArray<uint> lidxs; GrowableArray<uint> lidxs(split_arena, _maxlrg, 0, 0);
// Array of counters to count splits per live range // 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---------- //----------Setup Code----------
// Create a convenient mapping from lrg numbers to reaches/leaves indices // 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 // Keep track of DEFS & Phis for later passes
defs = new Node_List(); defs = new Node_List();
phis = new Node_List(); phis = new Node_List();
...@@ -500,15 +506,15 @@ uint PhaseChaitin::Split( uint maxlrg ) { ...@@ -500,15 +506,15 @@ uint PhaseChaitin::Split( uint maxlrg ) {
// a Def is UP or DOWN. UP means that it should get a register (ie - // 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 // it is always in LRP regions), and DOWN means that it is probably
// on the stack (ie - it crosses HRP regions). // on the stack (ie - it crosses HRP regions).
Node ***Reaches = NEW_RESOURCE_ARRAY( Node**, _cfg._num_blocks+1 ); Node ***Reaches = NEW_SPLIT_ARRAY( Node**, _cfg._num_blocks+1 );
bool **UP = NEW_RESOURCE_ARRAY( bool*, _cfg._num_blocks+1 ); bool **UP = NEW_SPLIT_ARRAY( bool*, _cfg._num_blocks+1 );
Node **debug_defs = NEW_RESOURCE_ARRAY( Node*, spill_cnt ); Node **debug_defs = NEW_SPLIT_ARRAY( Node*, spill_cnt );
VectorSet **UP_entry= NEW_RESOURCE_ARRAY( VectorSet*, spill_cnt ); VectorSet **UP_entry= NEW_SPLIT_ARRAY( VectorSet*, spill_cnt );
// Initialize Reaches & UP // Initialize Reaches & UP
for( bidx = 0; bidx < _cfg._num_blocks+1; bidx++ ) { for( bidx = 0; bidx < _cfg._num_blocks+1; bidx++ ) {
Reaches[bidx] = NEW_RESOURCE_ARRAY( Node*, spill_cnt ); Reaches[bidx] = NEW_SPLIT_ARRAY( Node*, spill_cnt );
UP[bidx] = NEW_RESOURCE_ARRAY( bool, spill_cnt ); UP[bidx] = NEW_SPLIT_ARRAY( bool, spill_cnt );
Node **Reachblock = Reaches[bidx]; Node **Reachblock = Reaches[bidx];
bool *UPblock = UP[bidx]; bool *UPblock = UP[bidx];
for( slidx = 0; slidx < spill_cnt; slidx++ ) { for( slidx = 0; slidx < spill_cnt; slidx++ ) {
...@@ -517,9 +523,11 @@ uint PhaseChaitin::Split( uint maxlrg ) { ...@@ -517,9 +523,11 @@ uint PhaseChaitin::Split( uint maxlrg ) {
} }
} }
#undef NEW_SPLIT_ARRAY
// Initialize to array of empty vectorsets // Initialize to array of empty vectorsets
for( slidx = 0; slidx < spill_cnt; slidx++ ) 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---------- //----------PASS 1----------
//----------Propagation & Node Insertion Code---------- //----------Propagation & Node Insertion Code----------
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册