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