changeset 5093:8ada83878f30

8021898: Broken JIT compiler optimization for loop unswitching Summary: fix method clone_projs() to clone all related MachProj nodes. Reviewed-by: roland, adlertz
author kvn
date Fri, 16 Aug 2013 14:11:40 -0700
parents ee9355903a26
children 68ae51f39b18
files src/share/vm/opto/coalesce.cpp src/share/vm/opto/reg_split.cpp src/share/vm/runtime/frame.cpp src/share/vm/utilities/vmError.cpp
diffstat 4 files changed, 44 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/opto/coalesce.cpp	Thu Aug 29 11:05:55 2013 +0200
+++ b/src/share/vm/opto/coalesce.cpp	Fri Aug 16 14:11:40 2013 -0700
@@ -135,20 +135,26 @@
 // After cloning some rematerialized instruction, clone any MachProj's that
 // follow it.  Example: Intel zero is XOR, kills flags.  Sparc FP constants
 // use G3 as an address temp.
-int PhaseChaitin::clone_projs( Block *b, uint idx, Node *con, Node *copy, uint &maxlrg ) {
-  Block *bcon = _cfg._bbs[con->_idx];
-  uint cindex = bcon->find_node(con);
-  Node *con_next = bcon->_nodes[cindex+1];
-  if( con_next->in(0) != con || !con_next->is_MachProj() )
-    return false;               // No MachProj's follow
-
-  // Copy kills after the cloned constant
-  Node *kills = con_next->clone();
-  kills->set_req( 0, copy );
-  b->_nodes.insert( idx, kills );
-  _cfg._bbs.map( kills->_idx, b );
-  new_lrg( kills, maxlrg++ );
-  return true;
+int PhaseChaitin::clone_projs(Block* b, uint idx, Node* orig, Node* copy, uint& max_lrg_id) {
+  assert(b->find_node(copy) == (idx - 1), "incorrect insert index for copy kill projections");
+  DEBUG_ONLY( Block* borig = _cfg._bbs[orig->_idx]; )
+  int found_projs = 0;
+  uint cnt = orig->outcnt();
+  for (uint i = 0; i < cnt; i++) {
+    Node* proj = orig->raw_out(i);
+    if (proj->is_MachProj()) {
+      assert(proj->outcnt() == 0, "only kill projections are expected here");
+      assert(_cfg._bbs[proj->_idx] == borig, "incorrect block for kill projections");
+      found_projs++;
+      // Copy kill projections after the cloned node
+      Node* kills = proj->clone();
+      kills->set_req(0, copy);
+      b->_nodes.insert(idx++, kills);
+      _cfg._bbs.map(kills->_idx, b);
+      new_lrg(kills, max_lrg_id++);
+    }
+  }
+  return found_projs;
 }
 
 //------------------------------compact----------------------------------------
@@ -464,8 +470,7 @@
               copy = m->clone();
               // Insert the copy in the basic block, just before us
               b->_nodes.insert( l++, copy );
-              if( _phc.clone_projs( b, l, m, copy, _phc._maxlrg ) )
-                l++;
+              l += _phc.clone_projs(b, l, m, copy, _phc._maxlrg);
             } else {
               const RegMask *rm = C->matcher()->idealreg2spillmask[m->ideal_reg()];
               copy = new (C) MachSpillCopyNode( m, *rm, *rm );
--- a/src/share/vm/opto/reg_split.cpp	Thu Aug 29 11:05:55 2013 +0200
+++ b/src/share/vm/opto/reg_split.cpp	Fri Aug 16 14:11:40 2013 -0700
@@ -391,10 +391,15 @@
 #endif
   // See if the cloned def kills any flags, and copy those kills as well
   uint i = insidx+1;
-  if( clone_projs( b, i, def, spill, maxlrg ) ) {
+  int found_projs = clone_projs(b, i, def, spill, maxlrg);
+  if (found_projs > 0) {
     // Adjust the point where we go hi-pressure
-    if( i <= b->_ihrp_index ) b->_ihrp_index++;
-    if( i <= b->_fhrp_index ) b->_fhrp_index++;
+    if (i <= b->_ihrp_index) {
+      b->_ihrp_index += found_projs;
+    }
+    if (i <= b->_fhrp_index) {
+      b->_fhrp_index += found_projs;
+    }
   }
 
   return spill;
--- a/src/share/vm/runtime/frame.cpp	Thu Aug 29 11:05:55 2013 +0200
+++ b/src/share/vm/runtime/frame.cpp	Fri Aug 16 14:11:40 2013 -0700
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "compiler/abstractCompiler.hpp"
 #include "gc_interface/collectedHeap.inline.hpp"
 #include "interpreter/interpreter.hpp"
 #include "interpreter/oopMapCache.hpp"
@@ -559,7 +560,7 @@
 
   st->print("%s frame (sp=" INTPTR_FORMAT " unextended sp=" INTPTR_FORMAT, print_name(), sp(), unextended_sp());
   if (sp() != NULL)
-    st->print(", fp=" INTPTR_FORMAT ", pc=" INTPTR_FORMAT, fp(), pc());
+    st->print(", fp=" INTPTR_FORMAT ", real_fp=" INTPTR_FORMAT ", pc=" INTPTR_FORMAT, fp(), real_fp(), pc());
 
   if (StubRoutines::contains(pc())) {
     st->print_cr(")");
@@ -720,10 +721,14 @@
     } else if (_cb->is_buffer_blob()) {
       st->print("v  ~BufferBlob::%s", ((BufferBlob *)_cb)->name());
     } else if (_cb->is_nmethod()) {
-      methodOop m = ((nmethod *)_cb)->method();
+      nmethod* nm = (nmethod*)_cb;
+      methodOop m = nm->method();
       if (m != NULL) {
         m->name_and_sig_as_C_string(buf, buflen);
-        st->print("J  %s", buf);
+        st->print("J %d%s %s %s (%d bytes) @ " PTR_FORMAT " [" PTR_FORMAT "+0x%x]",
+                  nm->compile_id(), (nm->is_osr_method() ? "%" : ""),
+                  ((nm->compiler() != NULL) ? nm->compiler()->name() : ""),
+                  buf, m->code_size(), _pc, _cb->code_begin(), _pc - _cb->code_begin());
       } else {
         st->print("J  " PTR_FORMAT, pc());
       }
--- a/src/share/vm/utilities/vmError.cpp	Thu Aug 29 11:05:55 2013 +0200
+++ b/src/share/vm/utilities/vmError.cpp	Fri Aug 16 14:11:40 2013 -0700
@@ -583,6 +583,13 @@
           while (count++ < StackPrintLimit) {
              fr.print_on_error(st, buf, sizeof(buf));
              st->cr();
+             // Compiled code may use EBP register on x86 so it looks like
+             // non-walkable C frame. Use frame.sender() for java frames.
+             if (_thread && _thread->is_Java_thread() && fr.is_java_frame()) {
+               RegisterMap map((JavaThread*)_thread, false); // No update
+               fr = fr.sender(&map);
+               continue;
+             }
              if (os::is_first_C_frame(&fr)) break;
              fr = os::get_sender_for_C_frame(&fr);
           }