1.1 --- a/src/share/vm/opto/lcm.cpp Tue Jan 24 17:00:51 2012 -0800 1.2 +++ b/src/share/vm/opto/lcm.cpp Wed Jan 25 09:31:47 2012 +0100 1.3 @@ -404,7 +404,7 @@ 1.4 // remaining cases (most), choose the instruction with the greatest latency 1.5 // (that is, the most number of pseudo-cycles required to the end of the 1.6 // routine). If there is a tie, choose the instruction with the most inputs. 1.7 -Node *Block::select(PhaseCFG *cfg, Node_List &worklist, int *ready_cnt, VectorSet &next_call, uint sched_slot) { 1.8 +Node *Block::select(PhaseCFG *cfg, Node_List &worklist, GrowableArray<int> &ready_cnt, VectorSet &next_call, uint sched_slot) { 1.9 1.10 // If only a single entry on the stack, use it 1.11 uint cnt = worklist.size(); 1.12 @@ -465,7 +465,7 @@ 1.13 1.14 // More than this instruction pending for successor to be ready, 1.15 // don't choose this if other opportunities are ready 1.16 - if (ready_cnt[use->_idx] > 1) 1.17 + if (ready_cnt.at(use->_idx) > 1) 1.18 n_choice = 1; 1.19 } 1.20 1.21 @@ -565,7 +565,7 @@ 1.22 1.23 1.24 //------------------------------sched_call------------------------------------- 1.25 -uint Block::sched_call( Matcher &matcher, Block_Array &bbs, uint node_cnt, Node_List &worklist, int *ready_cnt, MachCallNode *mcall, VectorSet &next_call ) { 1.26 +uint Block::sched_call( Matcher &matcher, Block_Array &bbs, uint node_cnt, Node_List &worklist, GrowableArray<int> &ready_cnt, MachCallNode *mcall, VectorSet &next_call ) { 1.27 RegMask regs; 1.28 1.29 // Schedule all the users of the call right now. All the users are 1.30 @@ -574,8 +574,9 @@ 1.31 for (DUIterator_Fast imax, i = mcall->fast_outs(imax); i < imax; i++) { 1.32 Node* n = mcall->fast_out(i); 1.33 assert( n->is_MachProj(), "" ); 1.34 - --ready_cnt[n->_idx]; 1.35 - assert( !ready_cnt[n->_idx], "" ); 1.36 + int n_cnt = ready_cnt.at(n->_idx)-1; 1.37 + ready_cnt.at_put(n->_idx, n_cnt); 1.38 + assert( n_cnt == 0, "" ); 1.39 // Schedule next to call 1.40 _nodes.map(node_cnt++, n); 1.41 // Collect defined registers 1.42 @@ -590,7 +591,9 @@ 1.43 Node* m = n->fast_out(j); // Get user 1.44 if( bbs[m->_idx] != this ) continue; 1.45 if( m->is_Phi() ) continue; 1.46 - if( !--ready_cnt[m->_idx] ) 1.47 + int m_cnt = ready_cnt.at(m->_idx)-1; 1.48 + ready_cnt.at_put(m->_idx, m_cnt); 1.49 + if( m_cnt == 0 ) 1.50 worklist.push(m); 1.51 } 1.52 1.53 @@ -655,7 +658,7 @@ 1.54 1.55 //------------------------------schedule_local--------------------------------- 1.56 // Topological sort within a block. Someday become a real scheduler. 1.57 -bool Block::schedule_local(PhaseCFG *cfg, Matcher &matcher, int *ready_cnt, VectorSet &next_call) { 1.58 +bool Block::schedule_local(PhaseCFG *cfg, Matcher &matcher, GrowableArray<int> &ready_cnt, VectorSet &next_call) { 1.59 // Already "sorted" are the block start Node (as the first entry), and 1.60 // the block-ending Node and any trailing control projections. We leave 1.61 // these alone. PhiNodes and ParmNodes are made to follow the block start 1.62 @@ -695,7 +698,7 @@ 1.63 if( m && cfg->_bbs[m->_idx] == this && !m->is_top() ) 1.64 local++; // One more block-local input 1.65 } 1.66 - ready_cnt[n->_idx] = local; // Count em up 1.67 + ready_cnt.at_put(n->_idx, local); // Count em up 1.68 1.69 #ifdef ASSERT 1.70 if( UseConcMarkSweepGC || UseG1GC ) { 1.71 @@ -729,7 +732,7 @@ 1.72 } 1.73 } 1.74 for(uint i2=i; i2<_nodes.size(); i2++ ) // Trailing guys get zapped count 1.75 - ready_cnt[_nodes[i2]->_idx] = 0; 1.76 + ready_cnt.at_put(_nodes[i2]->_idx, 0); 1.77 1.78 // All the prescheduled guys do not hold back internal nodes 1.79 uint i3; 1.80 @@ -737,8 +740,10 @@ 1.81 Node *n = _nodes[i3]; // Get pre-scheduled 1.82 for (DUIterator_Fast jmax, j = n->fast_outs(jmax); j < jmax; j++) { 1.83 Node* m = n->fast_out(j); 1.84 - if( cfg->_bbs[m->_idx] ==this ) // Local-block user 1.85 - ready_cnt[m->_idx]--; // Fix ready count 1.86 + if( cfg->_bbs[m->_idx] ==this ) { // Local-block user 1.87 + int m_cnt = ready_cnt.at(m->_idx)-1; 1.88 + ready_cnt.at_put(m->_idx, m_cnt); // Fix ready count 1.89 + } 1.90 } 1.91 } 1.92 1.93 @@ -747,7 +752,7 @@ 1.94 Node_List worklist; 1.95 for(uint i4=i3; i4<node_cnt; i4++ ) { // Put ready guys on worklist 1.96 Node *m = _nodes[i4]; 1.97 - if( !ready_cnt[m->_idx] ) { // Zero ready count? 1.98 + if( !ready_cnt.at(m->_idx) ) { // Zero ready count? 1.99 if (m->is_iteratively_computed()) { 1.100 // Push induction variable increments last to allow other uses 1.101 // of the phi to be scheduled first. The select() method breaks 1.102 @@ -775,14 +780,14 @@ 1.103 for (uint j=0; j<_nodes.size(); j++) { 1.104 Node *n = _nodes[j]; 1.105 int idx = n->_idx; 1.106 - tty->print("# ready cnt:%3d ", ready_cnt[idx]); 1.107 + tty->print("# ready cnt:%3d ", ready_cnt.at(idx)); 1.108 tty->print("latency:%3d ", cfg->_node_latency->at_grow(idx)); 1.109 tty->print("%4d: %s\n", idx, n->Name()); 1.110 } 1.111 } 1.112 #endif 1.113 1.114 - uint max_idx = matcher.C->unique(); 1.115 + uint max_idx = (uint)ready_cnt.length(); 1.116 // Pull from worklist and schedule 1.117 while( worklist.size() ) { // Worklist is not ready 1.118 1.119 @@ -840,11 +845,13 @@ 1.120 Node* m = n->fast_out(i5); // Get user 1.121 if( cfg->_bbs[m->_idx] != this ) continue; 1.122 if( m->is_Phi() ) continue; 1.123 - if (m->_idx > max_idx) { // new node, skip it 1.124 + if (m->_idx >= max_idx) { // new node, skip it 1.125 assert(m->is_MachProj() && n->is_Mach() && n->as_Mach()->has_call(), "unexpected node types"); 1.126 continue; 1.127 } 1.128 - if( !--ready_cnt[m->_idx] ) 1.129 + int m_cnt = ready_cnt.at(m->_idx)-1; 1.130 + ready_cnt.at_put(m->_idx, m_cnt); 1.131 + if( m_cnt == 0 ) 1.132 worklist.push(m); 1.133 } 1.134 }