Merge
authorvlivanov
Fri, 20 Mar 2015 20:32:07 +0000
changeset 30191 7fad0b2b89b0
parent 30185 4b08d63ac105 (current diff)
parent 30190 a57955ac2bc1 (diff)
child 30192 87a5d3461a1e
Merge
hotspot/src/share/vm/opto/library_call.cpp
--- a/hotspot/src/share/vm/classfile/vmSymbols.hpp	Mon Mar 16 12:24:06 2015 +0100
+++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp	Fri Mar 20 20:32:07 2015 +0000
@@ -868,9 +868,12 @@
                                                                                                                         \
   /* Custom branch frequencies profiling support for JSR292 */                                                          \
   do_class(java_lang_invoke_MethodHandleImpl,               "java/lang/invoke/MethodHandleImpl")                        \
-  do_intrinsic(_profileBoolean, java_lang_invoke_MethodHandleImpl, profileBoolean_name, profileBoolean_signature,    F_S)  \
-   do_name(     profileBoolean_name,                               "profileBoolean")                                     \
-   do_signature(profileBoolean_signature,                           "(Z[I)Z")                                            \
+  do_intrinsic(_profileBoolean, java_lang_invoke_MethodHandleImpl, profileBoolean_name, profileBoolean_signature, F_S)  \
+   do_name(     profileBoolean_name,                             "profileBoolean")                                      \
+   do_signature(profileBoolean_signature,                        "(Z[I)Z")                                              \
+  do_intrinsic(_isCompileConstant, java_lang_invoke_MethodHandleImpl, isCompileConstant_name, isCompileConstant_signature, F_S) \
+   do_name(     isCompileConstant_name,                          "isCompileConstant")                                   \
+   do_alias(    isCompileConstant_signature,                      object_boolean_signature)                             \
                                                                                                                         \
   /* unsafe memory references (there are a lot of them...) */                                                           \
   do_signature(getObject_signature,       "(Ljava/lang/Object;J)Ljava/lang/Object;")                                    \
--- a/hotspot/src/share/vm/code/nmethod.cpp	Mon Mar 16 12:24:06 2015 +0100
+++ b/hotspot/src/share/vm/code/nmethod.cpp	Fri Mar 20 20:32:07 2015 +0000
@@ -504,7 +504,7 @@
                                             basic_lock_owner_sp_offset,
                                             basic_lock_sp_offset, oop_maps);
     NOT_PRODUCT(if (nm != NULL)  nmethod_stats.note_native_nmethod(nm));
-    if (PrintAssembly && nm != NULL) {
+    if ((PrintAssembly || CompilerOracle::should_print(method)) && nm != NULL) {
       Disassembler::decode(nm);
     }
   }
@@ -2837,11 +2837,21 @@
           st.print(")");
           return st.as_string();
         }
+        case relocInfo::runtime_call_type: {
+          stringStream st;
+          st.print("runtime_call");
+          runtime_call_Relocation* r = iter.runtime_call_reloc();
+          address dest = r->destination();
+          CodeBlob* cb = CodeCache::find_blob(dest);
+          if (cb != NULL) {
+            st.print(" %s", cb->name());
+          }
+          return st.as_string();
+        }
         case relocInfo::virtual_call_type:     return "virtual_call";
         case relocInfo::opt_virtual_call_type: return "optimized virtual_call";
         case relocInfo::static_call_type:      return "static_call";
         case relocInfo::static_stub_type:      return "static_stub";
-        case relocInfo::runtime_call_type:     return "runtime_call";
         case relocInfo::external_word_type:    return "external_word";
         case relocInfo::internal_word_type:    return "internal_word";
         case relocInfo::section_word_type:     return "section_word";
--- a/hotspot/src/share/vm/code/pcDesc.cpp	Mon Mar 16 12:24:06 2015 +0100
+++ b/hotspot/src/share/vm/code/pcDesc.cpp	Fri Mar 20 20:32:07 2015 +0000
@@ -54,12 +54,7 @@
   for (ScopeDesc* sd = code->scope_desc_at(real_pc(code));
        sd != NULL;
        sd = sd->sender()) {
-    tty->print("  ");
-    sd->method()->print_short_name(tty);
-    tty->print("  @%d", sd->bci());
-    if (sd->should_reexecute())
-      tty->print("  reexecute=true");
-    tty->cr();
+    sd->print_on(tty);
   }
 #endif
 }
--- a/hotspot/src/share/vm/code/scopeDesc.cpp	Mon Mar 16 12:24:06 2015 +0100
+++ b/hotspot/src/share/vm/code/scopeDesc.cpp	Fri Mar 20 20:32:07 2015 +0000
@@ -157,14 +157,18 @@
 #ifndef PRODUCT
 
 void ScopeDesc::print_value_on(outputStream* st) const {
-  tty->print("   ");
+  st->print("  ");
   method()->print_short_name(st);
   int lineno = method()->line_number_from_bci(bci());
   if (lineno != -1) {
-    st->print_cr("@%d (line %d)", bci(), lineno);
+    st->print("@%d (line %d)", bci(), lineno);
   } else {
-    st->print_cr("@%d", bci());
+    st->print("@%d", bci());
   }
+  if (should_reexecute()) {
+    st->print("  reexecute=true");
+  }
+  st->cr();
 }
 
 void ScopeDesc::print_on(outputStream* st) const {
@@ -174,7 +178,7 @@
 void ScopeDesc::print_on(outputStream* st, PcDesc* pd) const {
   // header
   if (pd != NULL) {
-    tty->print_cr("ScopeDesc(pc=" PTR_FORMAT " offset=%x):", pd->real_pc(_code), pd->pc_offset());
+    st->print_cr("ScopeDesc(pc=" PTR_FORMAT " offset=%x):", pd->real_pc(_code), pd->pc_offset());
   }
 
   print_value_on(st);
@@ -192,7 +196,7 @@
   // locals
   { GrowableArray<ScopeValue*>* l = ((ScopeDesc*) this)->locals();
     if (l != NULL) {
-      tty->print_cr("   Locals");
+      st->print_cr("   Locals");
       for (int index = 0; index < l->length(); index++) {
         st->print("    - l%d: ", index);
         l->at(index)->print_on(st);
@@ -205,7 +209,7 @@
     if (l != NULL) {
       st->print_cr("   Expression stack");
       for (int index = 0; index < l->length(); index++) {
-        st->print("   - @%d: ", index);
+        st->print("    - @%d: ", index);
         l->at(index)->print_on(st);
         st->cr();
       }
@@ -225,12 +229,12 @@
 
 #ifdef COMPILER2
   if (DoEscapeAnalysis && is_top() && _objects != NULL) {
-    tty->print_cr("Objects");
+    st->print_cr("   Objects");
     for (int i = 0; i < _objects->length(); i++) {
       ObjectValue* sv = (ObjectValue*) _objects->at(i);
-      tty->print(" - %d: ", sv->id());
-      sv->print_fields_on(tty);
-      tty->cr();
+      st->print("    - %d: ", sv->id());
+      sv->print_fields_on(st);
+      st->cr();
     }
   }
 #endif // COMPILER2
--- a/hotspot/src/share/vm/opto/library_call.cpp	Mon Mar 16 12:24:06 2015 +0100
+++ b/hotspot/src/share/vm/opto/library_call.cpp	Fri Mar 20 20:32:07 2015 +0000
@@ -293,6 +293,7 @@
   bool inline_multiplyToLen();
 
   bool inline_profileBoolean();
+  bool inline_isCompileConstant();
 };
 
 
@@ -903,6 +904,8 @@
 
   case vmIntrinsics::_profileBoolean:
     return inline_profileBoolean();
+  case vmIntrinsics::_isCompileConstant:
+    return inline_isCompileConstant();
 
   default:
     // If you get here, it may be that someone has added a new intrinsic
@@ -5995,12 +5998,46 @@
                           Deoptimization::Action_reinterpret);
       return true;
     }
+
+    // result is a boolean (0 or 1) and its profile (false_cnt & true_cnt)
+    // is a number of each value occurrences.
+    Node* result = argument(0);
+    if (false_cnt == 0 || true_cnt == 0) {
+      // According to profile, one value has been never seen.
+      int expected_val = (false_cnt == 0) ? 1 : 0;
+
+      Node* cmp  = _gvn.transform(new CmpINode(result, intcon(expected_val)));
+      Node* test = _gvn.transform(new BoolNode(cmp, BoolTest::eq));
+
+      IfNode* check = create_and_map_if(control(), test, PROB_ALWAYS, COUNT_UNKNOWN);
+      Node* fast_path = _gvn.transform(new IfTrueNode(check));
+      Node* slow_path = _gvn.transform(new IfFalseNode(check));
+
+      { // Slow path: uncommon trap for never seen value and then reexecute
+        // MethodHandleImpl::profileBoolean() to bump the count, so JIT knows
+        // the value has been seen at least once.
+        PreserveJVMState pjvms(this);
+        PreserveReexecuteState preexecs(this);
+        jvms()->set_should_reexecute(true);
+
+        set_control(slow_path);
+        set_i_o(i_o());
+
+        uncommon_trap_exact(Deoptimization::Reason_intrinsic,
+                            Deoptimization::Action_reinterpret);
+      }
+      // The guard for never seen value enables sharpening of the result and
+      // returning a constant. It allows to eliminate branches on the same value
+      // later on.
+      set_control(fast_path);
+      result = intcon(expected_val);
+    }
     // Stop profiling.
-    // MethodHandleImpl::profileBoolean() has profiling logic in it's bytecode.
-    // By replacing method's body with profile data (represented as ProfileBooleanNode
+    // MethodHandleImpl::profileBoolean() has profiling logic in its bytecode.
+    // By replacing method body with profile data (represented as ProfileBooleanNode
     // on IR level) we effectively disable profiling.
     // It enables full speed execution once optimized code is generated.
-    Node* profile = _gvn.transform(new ProfileBooleanNode(argument(0), false_cnt, true_cnt));
+    Node* profile = _gvn.transform(new ProfileBooleanNode(result, false_cnt, true_cnt));
     C->record_for_igvn(profile);
     set_result(profile);
     return true;
@@ -6013,3 +6050,9 @@
     return false;
   }
 }
+
+bool LibraryCallKit::inline_isCompileConstant() {
+  Node* n = argument(0);
+  set_result(n->is_Con() ? intcon(1) : intcon(0));
+  return true;
+}