comparison src/share/vm/opto/reg_split.cpp @ 6632: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 8c92982cbbc4
children da91efe96a93
comparison
equal deleted inserted replaced
6625:153776c4cb6f 6632:a1c7f6472621
447 // one of its uses, and then split at the HRP block. 447 // one of its uses, and then split at the HRP block.
448 // 448 //
449 // USES: If USE is in HRP, split at use to leave main LRG on stack. 449 // USES: If USE is in HRP, split at use to leave main LRG on stack.
450 // Else, hoist LRG back up to register only (ie - split is also DEF) 450 // Else, hoist LRG back up to register only (ie - split is also DEF)
451 // We will compute a new maxlrg as we go 451 // We will compute a new maxlrg as we go
452 uint PhaseChaitin::Split( uint maxlrg ) { 452 uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) {
453 NOT_PRODUCT( Compile::TracePhase t3("regAllocSplit", &_t_regAllocSplit, TimeCompiler); ) 453 NOT_PRODUCT( Compile::TracePhase t3("regAllocSplit", &_t_regAllocSplit, TimeCompiler); )
454
455 // Free thread local resources used by this method on exit.
456 ResourceMark rm(split_arena);
454 457
455 uint bidx, pidx, slidx, insidx, inpidx, twoidx; 458 uint bidx, pidx, slidx, insidx, inpidx, twoidx;
456 uint non_phi = 1, spill_cnt = 0; 459 uint non_phi = 1, spill_cnt = 0;
457 Node **Reachblock; 460 Node **Reachblock;
458 Node *n1, *n2, *n3; 461 Node *n1, *n2, *n3;
459 Node_List *defs,*phis; 462 Node_List *defs,*phis;
460 bool *UPblock; 463 bool *UPblock;
461 bool u1, u2, u3; 464 bool u1, u2, u3;
462 Block *b, *pred; 465 Block *b, *pred;
463 PhiNode *phi; 466 PhiNode *phi;
464 GrowableArray<uint> lidxs; 467 GrowableArray<uint> lidxs(split_arena, _maxlrg, 0, 0);
465 468
466 // Array of counters to count splits per live range 469 // Array of counters to count splits per live range
467 GrowableArray<uint> splits; 470 GrowableArray<uint> splits(split_arena, _maxlrg, 0, 0);
471
472 #define NEW_SPLIT_ARRAY(type, size)\
473 (type*) split_arena->allocate_bytes((size) * sizeof(type))
468 474
469 //----------Setup Code---------- 475 //----------Setup Code----------
470 // Create a convenient mapping from lrg numbers to reaches/leaves indices 476 // Create a convenient mapping from lrg numbers to reaches/leaves indices
471 uint *lrg2reach = NEW_RESOURCE_ARRAY( uint, _maxlrg ); 477 uint *lrg2reach = NEW_SPLIT_ARRAY( uint, _maxlrg );
472 // Keep track of DEFS & Phis for later passes 478 // Keep track of DEFS & Phis for later passes
473 defs = new Node_List(); 479 defs = new Node_List();
474 phis = new Node_List(); 480 phis = new Node_List();
475 // Gather info on which LRG's are spilling, and build maps 481 // Gather info on which LRG's are spilling, and build maps
476 for( bidx = 1; bidx < _maxlrg; bidx++ ) { 482 for( bidx = 1; bidx < _maxlrg; bidx++ ) {
498 // Def in the block, and then becomes the output for the block when 504 // Def in the block, and then becomes the output for the block when
499 // processing of the block is complete. We also need to track whether 505 // processing of the block is complete. We also need to track whether
500 // a Def is UP or DOWN. UP means that it should get a register (ie - 506 // a Def is UP or DOWN. UP means that it should get a register (ie -
501 // it is always in LRP regions), and DOWN means that it is probably 507 // it is always in LRP regions), and DOWN means that it is probably
502 // on the stack (ie - it crosses HRP regions). 508 // on the stack (ie - it crosses HRP regions).
503 Node ***Reaches = NEW_RESOURCE_ARRAY( Node**, _cfg._num_blocks+1 ); 509 Node ***Reaches = NEW_SPLIT_ARRAY( Node**, _cfg._num_blocks+1 );
504 bool **UP = NEW_RESOURCE_ARRAY( bool*, _cfg._num_blocks+1 ); 510 bool **UP = NEW_SPLIT_ARRAY( bool*, _cfg._num_blocks+1 );
505 Node **debug_defs = NEW_RESOURCE_ARRAY( Node*, spill_cnt ); 511 Node **debug_defs = NEW_SPLIT_ARRAY( Node*, spill_cnt );
506 VectorSet **UP_entry= NEW_RESOURCE_ARRAY( VectorSet*, spill_cnt ); 512 VectorSet **UP_entry= NEW_SPLIT_ARRAY( VectorSet*, spill_cnt );
507 513
508 // Initialize Reaches & UP 514 // Initialize Reaches & UP
509 for( bidx = 0; bidx < _cfg._num_blocks+1; bidx++ ) { 515 for( bidx = 0; bidx < _cfg._num_blocks+1; bidx++ ) {
510 Reaches[bidx] = NEW_RESOURCE_ARRAY( Node*, spill_cnt ); 516 Reaches[bidx] = NEW_SPLIT_ARRAY( Node*, spill_cnt );
511 UP[bidx] = NEW_RESOURCE_ARRAY( bool, spill_cnt ); 517 UP[bidx] = NEW_SPLIT_ARRAY( bool, spill_cnt );
512 Node **Reachblock = Reaches[bidx]; 518 Node **Reachblock = Reaches[bidx];
513 bool *UPblock = UP[bidx]; 519 bool *UPblock = UP[bidx];
514 for( slidx = 0; slidx < spill_cnt; slidx++ ) { 520 for( slidx = 0; slidx < spill_cnt; slidx++ ) {
515 UPblock[slidx] = true; // Assume they start in registers 521 UPblock[slidx] = true; // Assume they start in registers
516 Reachblock[slidx] = NULL; // Assume that no def is present 522 Reachblock[slidx] = NULL; // Assume that no def is present
517 } 523 }
518 } 524 }
519 525
526 #undef NEW_SPLIT_ARRAY
527
520 // Initialize to array of empty vectorsets 528 // Initialize to array of empty vectorsets
521 for( slidx = 0; slidx < spill_cnt; slidx++ ) 529 for( slidx = 0; slidx < spill_cnt; slidx++ )
522 UP_entry[slidx] = new VectorSet(Thread::current()->resource_area()); 530 UP_entry[slidx] = new VectorSet(split_arena);
523 531
524 //----------PASS 1---------- 532 //----------PASS 1----------
525 //----------Propagation & Node Insertion Code---------- 533 //----------Propagation & Node Insertion Code----------
526 // Walk the Blocks in RPO for DEF & USE info 534 // Walk the Blocks in RPO for DEF & USE info
527 for( bidx = 0; bidx < _cfg._num_blocks; bidx++ ) { 535 for( bidx = 0; bidx < _cfg._num_blocks; bidx++ ) {