src/share/vm/opto/output.cpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File
6961690 Cdiff src/share/vm/opto/output.cpp
src/share/vm/opto/output.cpp
Print this page
rev 1839 : 6961690: load oops from constant table on SPARC
Summary: oops should be loaded from the constant table of an nmethod instead of materializing them with a long code sequence.
Reviewed-by:
*** 43,57 ****
// Convert Nodes to instruction bits and pass off to the VM
void Compile::Output() {
// RootNode goes
assert( _cfg->_broot->_nodes.size() == 0, "" );
- // Initialize the space for the BufferBlob used to find and verify
- // instruction size in MachNode::emit_size()
- init_scratch_buffer_blob();
- if (failing()) return; // Out of memory
-
// The number of new nodes (mostly MachNop) is proportional to
// the number of java calls and inner loops which are aligned.
if ( C->check_node_count((NodeLimitFudgeFactor + C->java_calls()*3 +
C->inner_loops()*(OptoLoopAlignment-1)),
"out of nodes before code generation" ) ) {
--- 43,52 ----
*** 315,325 ****
}
//----------------------Shorten_branches---------------------------------------
// The architecture description provides short branch variants for some long
// branch instructions. Replace eligible long branches with short branches.
! void Compile::Shorten_branches(Label *labels, int& code_size, int& reloc_size, int& stub_size, int& const_size) {
// fill in the nop array for bundling computations
MachNode *_nop_list[Bundle::_nop_count];
Bundle::initialize_nops(_nop_list, this);
--- 310,320 ----
}
//----------------------Shorten_branches---------------------------------------
// The architecture description provides short branch variants for some long
// branch instructions. Replace eligible long branches with short branches.
! void Compile::Shorten_branches(Label *labels, int& code_size, int& reloc_size, int& stub_size) {
// fill in the nop array for bundling computations
MachNode *_nop_list[Bundle::_nop_count];
Bundle::initialize_nops(_nop_list, this);
*** 335,350 ****
code_size = 0; // Size in bytes of generated code
stub_size = 0; // Size in bytes of all stub entries
// Size in bytes of all relocation entries, including those in local stubs.
// Start with 2-bytes of reloc info for the unvalidated entry point
reloc_size = 1; // Number of relocation entries
- const_size = 0; // size of fp constants in words
// Make three passes. The first computes pessimistic blk_starts,
! // relative jmp_end, reloc_size and const_size information.
! // The second performs short branch substitution using the pessimistic
! // sizing. The third inserts nops where needed.
Node *nj; // tmp
// Step one, perform a pessimistic sizing pass.
uint i;
--- 330,344 ----
code_size = 0; // Size in bytes of generated code
stub_size = 0; // Size in bytes of all stub entries
// Size in bytes of all relocation entries, including those in local stubs.
// Start with 2-bytes of reloc info for the unvalidated entry point
reloc_size = 1; // Number of relocation entries
// Make three passes. The first computes pessimistic blk_starts,
! // relative jmp_end and reloc_size information. The second performs
! // short branch substitution using the pessimistic sizing. The
! // third inserts nops where needed.
Node *nj; // tmp
// Step one, perform a pessimistic sizing pass.
uint i;
*** 363,373 ****
// Handle machine instruction nodes
if( nj->is_Mach() ) {
MachNode *mach = nj->as_Mach();
blk_size += (mach->alignment_required() - 1) * relocInfo::addr_unit(); // assume worst case padding
reloc_size += mach->reloc();
- const_size += mach->const_size();
if( mach->is_MachCall() ) {
MachCallNode *mcall = mach->as_MachCall();
// This destination address is NOT PC-relative
mcall->method_set((intptr_t)mcall->entry_point());
--- 357,366 ----
*** 380,393 ****
// If call/safepoint are adjacent, account for possible
// nop to disambiguate the two safepoints.
if (min_offset_from_last_call == 0) {
blk_size += nop_size;
}
- } else if (mach->ideal_Opcode() == Op_Jump) {
- const_size += b->_num_succs; // Address table size
- // The size is valid even for 64 bit since it is
- // multiplied by 2*jintSize on this method exit.
}
}
min_offset_from_last_call += inst_size;
// Remember end of call offset
if (nj->is_MachCall() && nj->as_MachCall()->is_safepoint_node()) {
--- 373,382 ----
*** 544,557 ****
// Adjust reloc_size to number of record of relocation info
// Min is 2 bytes, max is probably 6 or 8, with a tax up to 25% for
// a relocation index.
// The CodeBuffer will expand the locs array if this estimate is too low.
reloc_size *= 10 / sizeof(relocInfo);
-
- // Adjust const_size to number of bytes
- const_size *= 2*jintSize; // both float and double take two words per entry
-
}
//------------------------------FillLocArray-----------------------------------
// Create a bit of debug info and append it to the array. The mapping is from
// Java local or expression stack to constant, register or stack-slot. For
--- 533,542 ----
*** 1084,1097 ****
for( i=0; i <= _cfg->_num_blocks; i++ ) {
blk_labels[i].init();
}
// If this machine supports different size branch offsets, then pre-compute
// the length of the blocks
if( _matcher->is_short_branch_offset(-1, 0) ) {
! Shorten_branches(blk_labels, code_req, locs_req, stub_req, const_req);
labels_not_set = false;
}
// nmethod and CodeBuffer count stubs & constants as part of method's code.
int exception_handler_req = size_exception_handler();
--- 1069,1111 ----
for( i=0; i <= _cfg->_num_blocks; i++ ) {
blk_labels[i].init();
}
+ if (has_mach_constant_base_node()) {
+ // Fill the constant table.
+ // Note: This must happen before Shorten_branches.
+ for (i = 0; i < _cfg->_num_blocks; i++) {
+ Block* b = _cfg->_blocks[i];
+
+ for (uint j = 0; j < b->_nodes.size(); j++) {
+ Node* n = b->_nodes[j];
+
+ // If the node is a MachConstantNode evaluate the constant
+ // value section.
+ if (n->is_MachConstant()) {
+ MachConstantNode* machcon = n->as_MachConstant();
+ machcon->eval_constant(C);
+ }
+ }
+ }
+
+ // Calculate the offsets of the constants and the size of the
+ // constant table (including the padding to the next section).
+ constant_table().calculate_offsets_and_size();
+ const_req = constant_table().size();
+ }
+
+ // Initialize the space for the BufferBlob used to find and verify
+ // instruction size in MachNode::emit_size()
+ init_scratch_buffer_blob(const_req);
+ if (failing()) return; // Out of memory
+
// If this machine supports different size branch offsets, then pre-compute
// the length of the blocks
if( _matcher->is_short_branch_offset(-1, 0) ) {
! Shorten_branches(blk_labels, code_req, locs_req, stub_req);
labels_not_set = false;
}
// nmethod and CodeBuffer count stubs & constants as part of method's code.
int exception_handler_req = size_exception_handler();
*** 1103,1118 ****
if (StressCodeBuffers)
code_req = const_req = stub_req = exception_handler_req = deopt_handler_req = 0x10; // force expansion
int total_req =
code_req +
pad_req +
stub_req +
exception_handler_req +
! deopt_handler_req + // deopt handler
! const_req;
if (has_method_handle_invokes())
total_req += deopt_handler_req; // deopt MH handler
CodeBuffer* cb = code_buffer();
--- 1117,1132 ----
if (StressCodeBuffers)
code_req = const_req = stub_req = exception_handler_req = deopt_handler_req = 0x10; // force expansion
int total_req =
+ const_req +
code_req +
pad_req +
stub_req +
exception_handler_req +
! deopt_handler_req; // deopt handler
if (has_method_handle_invokes())
total_req += deopt_handler_req; // deopt MH handler
CodeBuffer* cb = code_buffer();
*** 1162,1171 ****
--- 1176,1190 ----
node_offsets = NEW_RESOURCE_ARRAY(int, node_offset_limit);
#endif
NonSafepointEmitter non_safepoints(this); // emit non-safepoints lazily
+ // Emit the constant table.
+ if (has_mach_constant_base_node()) {
+ constant_table().emit(*cb);
+ }
+
// ------------------
// Now fill in the code buffer
Node *delay_slot = NULL;
for( i=0; i < _cfg->_num_blocks; i++ ) {
*** 1178,1193 ****
// start of a new bundle.
if( Pipeline::requires_bundling() && starts_bundle(head) )
cb->flush_bundle(true);
// Define the label at the beginning of the basic block
! if( labels_not_set )
! MacroAssembler(cb).bind( blk_labels[b->_pre_order] );
!
! else
! assert( blk_labels[b->_pre_order].loc_pos() == cb->insts_size(),
! "label position does not match code offset" );
uint last_inst = b->_nodes.size();
// Emit block normally, except for last instruction.
// Emit means "dump code bits into code buffer".
--- 1197,1213 ----
// start of a new bundle.
if( Pipeline::requires_bundling() && starts_bundle(head) )
cb->flush_bundle(true);
// Define the label at the beginning of the basic block
! if (labels_not_set) {
! MacroAssembler(cb).bind(blk_labels[b->_pre_order]);
! } else {
! assert(blk_labels[b->_pre_order].loc_pos() == cb->insts_size(),
! err_msg("label position does not match code offset: %d != %d",
! blk_labels[b->_pre_order].loc_pos(), cb->insts_size()));
! }
uint last_inst = b->_nodes.size();
// Emit block normally, except for last instruction.
// Emit means "dump code bits into code buffer".
*** 1700,1712 ****
--- 1720,1740 ----
NOT_PRODUCT( TracePhase t2("isched", &_t_instrSched, TimeCompiler); )
// Create a data structure for all the scheduling information
Scheduling scheduling(Thread::current()->resource_area(), *this);
+ // Initialize the space for the BufferBlob used to find and verify
+ // instruction size in MachNode::emit_size()
+ init_scratch_buffer_blob(MAX_const_size);
+ if (failing()) return; // Out of memory
+
// Walk backwards over each basic block, computing the needed alignment
// Walk over all the basic blocks
scheduling.DoScheduling();
+
+ // Clear the BufferBlob used for scheduling.
+ clear_scratch_buffer_blob();
}
//------------------------------ComputeLocalLatenciesForward-------------------
// Compute the latency of all the instructions. This is fairly simple,
// because we already have a legal ordering. Walk over the instructions
src/share/vm/opto/output.cpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File