diff src/share/vm/opto/output.cpp @ 2008:2f644f85485d

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: never, kvn
author twisti
date Fri, 03 Dec 2010 01:34:31 -0800
parents f95d63e2154a
children 51bd2d261853
line wrap: on
line diff
--- a/src/share/vm/opto/output.cpp	Thu Dec 02 17:21:12 2010 -0800
+++ b/src/share/vm/opto/output.cpp	Fri Dec 03 01:34:31 2010 -0800
@@ -61,11 +61,6 @@
   // 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 +
@@ -333,7 +328,7 @@
 //----------------------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) {
+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];
@@ -353,12 +348,11 @@
   // 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.
+  // 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
 
@@ -381,7 +375,6 @@
         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
@@ -398,10 +391,6 @@
           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;
@@ -562,10 +551,6 @@
   // 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-----------------------------------
@@ -1102,10 +1087,39 @@
     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, const_req);
+    Shorten_branches(blk_labels, code_req, locs_req, stub_req);
     labels_not_set = false;
   }
 
@@ -1121,12 +1135,12 @@
     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
-    const_req;
+    deopt_handler_req;               // deopt handler
 
   if (has_method_handle_invokes())
     total_req += deopt_handler_req;  // deopt MH handler
@@ -1180,6 +1194,11 @@
 
   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;
@@ -1196,12 +1215,13 @@
       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" );
+    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();
 
@@ -1718,9 +1738,17 @@
   // 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-------------------