@@ -53,6 +53,7 @@ class BlockListBuilder {
5353
5454 BlockList _blocks; // internal list of all blocks
5555 BlockList* _bci2block; // mapping from bci to blocks for GraphBuilder
56+ GrowableArray<BlockList> _bci2block_successors; // Mapping bcis to their blocks successors while we dont have a blockend
5657
5758 // fields used by mark_loops
5859 ResourceBitMap _active; // for iteration of control flow graph
@@ -89,6 +90,11 @@ class BlockListBuilder {
8990 void print ();
9091#endif
9192
93+ int number_of_successors (BlockBegin* block);
94+ BlockBegin* successor_at (BlockBegin* block, int i);
95+ void add_successor (BlockBegin* block, BlockBegin* sux);
96+ bool is_successor (BlockBegin* block, BlockBegin* sux);
97+
9298 public:
9399 // creation
94100 BlockListBuilder (Compilation* compilation, IRScope* scope, int osr_bci);
@@ -105,6 +111,7 @@ BlockListBuilder::BlockListBuilder(Compilation* compilation, IRScope* scope, int
105111 , _scope(scope)
106112 , _blocks(16 )
107113 , _bci2block(new BlockList(scope->method ()->code_size(), NULL))
114+ , _bci2block_successors(scope->method ()->code_size())
108115 , _active() // size not known yet
109116 , _visited() // size not known yet
110117 , _loop_map() // size not known yet
@@ -118,6 +125,8 @@ BlockListBuilder::BlockListBuilder(Compilation* compilation, IRScope* scope, int
118125 mark_loops ();
119126 NOT_PRODUCT (if (PrintInitialBlockList) print ());
120127
128+ // _bci2block still contains blocks with _end == null and > 0 sux in _bci2block_successors.
129+
121130#ifndef PRODUCT
122131 if (PrintCFGToFile) {
123132 stringStream title;
@@ -160,6 +169,7 @@ BlockBegin* BlockListBuilder::make_block_at(int cur_bci, BlockBegin* predecessor
160169 block = new BlockBegin (cur_bci);
161170 block->init_stores_to_locals (method ()->max_locals ());
162171 _bci2block->at_put (cur_bci, block);
172+ _bci2block_successors.at_put_grow (cur_bci, BlockList ());
163173 _blocks.append (block);
164174
165175 assert (predecessor == NULL || predecessor->bci () < cur_bci, " targets for backward branches must already exist" );
@@ -170,7 +180,7 @@ BlockBegin* BlockListBuilder::make_block_at(int cur_bci, BlockBegin* predecessor
170180 BAILOUT_ (" Exception handler can be reached by both normal and exceptional control flow" , block);
171181 }
172182
173- predecessor-> add_successor (block);
183+ add_successor (predecessor, block);
174184 block->increment_total_preds ();
175185 }
176186
@@ -201,8 +211,8 @@ void BlockListBuilder::handle_exceptions(BlockBegin* current, int cur_bci) {
201211 assert (entry->is_set (BlockBegin::exception_entry_flag), " flag must be set" );
202212
203213 // add each exception handler only once
204- if (!current-> is_successor (entry)) {
205- current-> add_successor (entry);
214+ if (! is_successor (current, entry)) {
215+ add_successor (current, entry);
206216 entry->increment_total_preds ();
207217 }
208218
@@ -418,9 +428,9 @@ int BlockListBuilder::mark_loops(BlockBegin* block, bool in_subroutine) {
418428 _active.set_bit (block_id);
419429
420430 intptr_t loop_state = 0 ;
421- for (int i = block-> number_of_sux ( ) - 1 ; i >= 0 ; i--) {
431+ for (int i = number_of_successors (block ) - 1 ; i >= 0 ; i--) {
422432 // recursively process all successors
423- loop_state |= mark_loops (block-> sux_at ( i), in_subroutine);
433+ loop_state |= mark_loops (successor_at (block, i), in_subroutine);
424434 }
425435
426436 // clear active-bit after all successors are processed
@@ -452,6 +462,28 @@ int BlockListBuilder::mark_loops(BlockBegin* block, bool in_subroutine) {
452462 return loop_state;
453463}
454464
465+ inline int BlockListBuilder::number_of_successors (BlockBegin* block)
466+ {
467+ assert (_bci2block_successors.length () > block->bci (), " sux must exist" );
468+ return _bci2block_successors.at (block->bci ()).length ();
469+ }
470+
471+ inline BlockBegin* BlockListBuilder::successor_at (BlockBegin* block, int i)
472+ {
473+ assert (_bci2block_successors.length () > block->bci (), " sux must exist" );
474+ return _bci2block_successors.at (block->bci ()).at (i);
475+ }
476+
477+ inline void BlockListBuilder::add_successor (BlockBegin* block, BlockBegin* sux)
478+ {
479+ assert (_bci2block_successors.length () > block->bci (), " sux must exist" );
480+ _bci2block_successors.at (block->bci ()).append (sux);
481+ }
482+
483+ inline bool BlockListBuilder::is_successor (BlockBegin* block, BlockBegin* sux) {
484+ assert (_bci2block_successors.length () > block->bci (), " sux must exist" );
485+ return _bci2block_successors.at (block->bci ()).contains (sux);
486+ }
455487
456488#ifndef PRODUCT
457489
@@ -477,10 +509,10 @@ void BlockListBuilder::print() {
477509 tty->print (cur->is_set (BlockBegin::subroutine_entry_flag) ? " sr" : " " );
478510 tty->print (cur->is_set (BlockBegin::parser_loop_header_flag) ? " lh" : " " );
479511
480- if (cur-> number_of_sux ( ) > 0 ) {
512+ if (number_of_successors (cur ) > 0 ) {
481513 tty->print (" sux: " );
482- for (int j = 0 ; j < cur-> number_of_sux ( ); j++) {
483- BlockBegin* sux = cur-> sux_at ( j);
514+ for (int j = 0 ; j < number_of_successors (cur ); j++) {
515+ BlockBegin* sux = successor_at (cur, j);
484516 tty->print (" B%d " , sux->block_id ());
485517 }
486518 }
@@ -3230,6 +3262,8 @@ GraphBuilder::GraphBuilder(Compilation* compilation, IRScope* scope)
32303262 _initial_state = state_at_entry ();
32313263 start_block->merge (_initial_state);
32323264
3265+ // End nulls still exist here
3266+
32333267 // complete graph
32343268 _vmap = new ValueMap ();
32353269 switch (scope->method ()->intrinsic_id ()) {
@@ -3333,6 +3367,27 @@ GraphBuilder::GraphBuilder(Compilation* compilation, IRScope* scope)
33333367 }
33343368 CHECK_BAILOUT ();
33353369
3370+ # ifdef ASSERT
3371+ // All blocks reachable from start_block have _end != NULL
3372+ {
3373+ BlockList processed;
3374+ BlockList to_go;
3375+ to_go.append (start_block);
3376+ while (to_go.length () > 0 ) {
3377+ BlockBegin* current = to_go.pop ();
3378+ assert (current != NULL , " Should not happen." );
3379+ assert (current->end () != NULL , " All blocks reachable from start_block should have end() != NULL." );
3380+ processed.append (current);
3381+ for (int i = 0 ; i < current->number_of_sux (); i++) {
3382+ BlockBegin* s = current->sux_at (i);
3383+ if (!processed.contains (s)) {
3384+ to_go.append (s);
3385+ }
3386+ }
3387+ }
3388+ }
3389+ #endif // ASSERT
3390+
33363391 _start = setup_start_block (osr_bci, start_block, _osr_entry, _initial_state);
33373392
33383393 eliminate_redundant_phis (_start);
0 commit comments