Mercurial > hg > truffle
comparison src/share/vm/opto/output.cpp @ 8874:0a8c2ea3902d
8010437: guarantee(this->is8bit(imm8)) failed: Short forward jump exceeds 8-bit offset
Summary: Fix shorten_branches() to accurately count an initial nop that may be inserted in a block that starts with a safepoint.
Reviewed-by: kvn
author | rasbold |
---|---|
date | Wed, 03 Apr 2013 15:00:55 -0700 |
parents | f15df3af32c5 |
children | b9a918201d47 a7fb14888912 a6e09d6dd8e5 |
comparison
equal
deleted
inserted
replaced
8873:e961c11b85fe | 8874:0a8c2ea3902d |
---|---|
447 if (i< nblocks-1) { | 447 if (i< nblocks-1) { |
448 Block *nb = _cfg->_blocks[i+1]; | 448 Block *nb = _cfg->_blocks[i+1]; |
449 int max_loop_pad = nb->code_alignment()-relocInfo::addr_unit(); | 449 int max_loop_pad = nb->code_alignment()-relocInfo::addr_unit(); |
450 if (max_loop_pad > 0) { | 450 if (max_loop_pad > 0) { |
451 assert(is_power_of_2(max_loop_pad+relocInfo::addr_unit()), ""); | 451 assert(is_power_of_2(max_loop_pad+relocInfo::addr_unit()), ""); |
452 // Adjust last_call_adr and/or last_avoid_back_to_back_adr. | |
453 // If either is the last instruction in this block, bump by | |
454 // max_loop_pad in lock-step with blk_size, so sizing | |
455 // calculations in subsequent blocks still can conservatively | |
456 // detect that it may the last instruction in this block. | |
457 if (last_call_adr == blk_starts[i]+blk_size) { | |
458 last_call_adr += max_loop_pad; | |
459 } | |
460 if (last_avoid_back_to_back_adr == blk_starts[i]+blk_size) { | |
461 last_avoid_back_to_back_adr += max_loop_pad; | |
462 } | |
452 blk_size += max_loop_pad; | 463 blk_size += max_loop_pad; |
453 } | 464 } |
454 } | 465 } |
455 | 466 |
456 // Save block size; update total method size | 467 // Save block size; update total method size |
1191 int previous_offset = 0; | 1202 int previous_offset = 0; |
1192 int current_offset = 0; | 1203 int current_offset = 0; |
1193 int last_call_offset = -1; | 1204 int last_call_offset = -1; |
1194 int last_avoid_back_to_back_offset = -1; | 1205 int last_avoid_back_to_back_offset = -1; |
1195 #ifdef ASSERT | 1206 #ifdef ASSERT |
1196 int block_alignment_padding = 0; | |
1197 | |
1198 uint* jmp_target = NEW_RESOURCE_ARRAY(uint,nblocks); | 1207 uint* jmp_target = NEW_RESOURCE_ARRAY(uint,nblocks); |
1199 uint* jmp_offset = NEW_RESOURCE_ARRAY(uint,nblocks); | 1208 uint* jmp_offset = NEW_RESOURCE_ARRAY(uint,nblocks); |
1200 uint* jmp_size = NEW_RESOURCE_ARRAY(uint,nblocks); | 1209 uint* jmp_size = NEW_RESOURCE_ARRAY(uint,nblocks); |
1201 uint* jmp_rule = NEW_RESOURCE_ARRAY(uint,nblocks); | 1210 uint* jmp_rule = NEW_RESOURCE_ARRAY(uint,nblocks); |
1202 #endif | 1211 #endif |
1226 // ------------------ | 1235 // ------------------ |
1227 // Now fill in the code buffer | 1236 // Now fill in the code buffer |
1228 Node *delay_slot = NULL; | 1237 Node *delay_slot = NULL; |
1229 | 1238 |
1230 for (uint i=0; i < nblocks; i++) { | 1239 for (uint i=0; i < nblocks; i++) { |
1231 guarantee(blk_starts[i] >= (uint)cb->insts_size(),"should not increase size"); | |
1232 | |
1233 Block *b = _cfg->_blocks[i]; | 1240 Block *b = _cfg->_blocks[i]; |
1234 | 1241 |
1235 Node *head = b->head(); | 1242 Node *head = b->head(); |
1236 | 1243 |
1237 // If this block needs to start aligned (i.e, can be reached other | 1244 // If this block needs to start aligned (i.e, can be reached other |
1248 } | 1255 } |
1249 jmp_target[i] = 0; | 1256 jmp_target[i] = 0; |
1250 jmp_offset[i] = 0; | 1257 jmp_offset[i] = 0; |
1251 jmp_size[i] = 0; | 1258 jmp_size[i] = 0; |
1252 jmp_rule[i] = 0; | 1259 jmp_rule[i] = 0; |
1253 | |
1254 // Maximum alignment padding for loop block was used | |
1255 // during first round of branches shortening, as result | |
1256 // padding for nodes (sfpt after call) was not added. | |
1257 // Take this into account for block's size change check | |
1258 // and allow increase block's size by the difference | |
1259 // of maximum and actual alignment paddings. | |
1260 int orig_blk_size = blk_starts[i+1] - blk_starts[i] + block_alignment_padding; | |
1261 #endif | 1260 #endif |
1262 int blk_offset = current_offset; | 1261 int blk_offset = current_offset; |
1263 | 1262 |
1264 // Define the label at the beginning of the basic block | 1263 // Define the label at the beginning of the basic block |
1265 MacroAssembler(cb).bind(blk_labels[b->_pre_order]); | 1264 MacroAssembler(cb).bind(blk_labels[b->_pre_order]); |
1555 // Don't reuse it | 1554 // Don't reuse it |
1556 delay_slot = NULL; | 1555 delay_slot = NULL; |
1557 } | 1556 } |
1558 | 1557 |
1559 } // End for all instructions in block | 1558 } // End for all instructions in block |
1560 assert((uint)blk_offset <= blk_starts[i], "shouldn't increase distance"); | |
1561 blk_starts[i] = blk_offset; | |
1562 | 1559 |
1563 // If the next block is the top of a loop, pad this block out to align | 1560 // If the next block is the top of a loop, pad this block out to align |
1564 // the loop top a little. Helps prevent pipe stalls at loop back branches. | 1561 // the loop top a little. Helps prevent pipe stalls at loop back branches. |
1565 if (i < nblocks-1) { | 1562 if (i < nblocks-1) { |
1566 Block *nb = _cfg->_blocks[i+1]; | 1563 Block *nb = _cfg->_blocks[i+1]; |
1570 b->_nodes.insert( b->_nodes.size(), nop ); | 1567 b->_nodes.insert( b->_nodes.size(), nop ); |
1571 _cfg->_bbs.map( nop->_idx, b ); | 1568 _cfg->_bbs.map( nop->_idx, b ); |
1572 nop->emit(*cb, _regalloc); | 1569 nop->emit(*cb, _regalloc); |
1573 current_offset = cb->insts_size(); | 1570 current_offset = cb->insts_size(); |
1574 } | 1571 } |
1575 #ifdef ASSERT | |
1576 int max_loop_pad = nb->code_alignment()-relocInfo::addr_unit(); | |
1577 block_alignment_padding = (max_loop_pad - padding); | |
1578 assert(block_alignment_padding >= 0, "sanity"); | |
1579 #endif | |
1580 } | 1572 } |
1581 // Verify that the distance for generated before forward | 1573 // Verify that the distance for generated before forward |
1582 // short branches is still valid. | 1574 // short branches is still valid. |
1583 assert(orig_blk_size >= (current_offset - blk_offset), "shouldn't increase block size"); | 1575 guarantee((int)(blk_starts[i+1] - blk_starts[i]) >= (current_offset - blk_offset), "shouldn't increase block size"); |
1584 | 1576 |
1577 // Save new block start offset | |
1578 blk_starts[i] = blk_offset; | |
1585 } // End of for all blocks | 1579 } // End of for all blocks |
1586 blk_starts[nblocks] = current_offset; | 1580 blk_starts[nblocks] = current_offset; |
1587 | 1581 |
1588 non_safepoints.flush_at_end(); | 1582 non_safepoints.flush_at_end(); |
1589 | 1583 |