8031755: Type speculation should be used to optimize explicit null checks
authorroland
Mon, 31 Mar 2014 09:08:53 +0200
changeset 23525 e3eb08ead679
parent 23524 2a2aa2a6b3c3
child 23526 6851d341ad52
8031755: Type speculation should be used to optimize explicit null checks Summary: feed profiling data about reference nullness to type speculation. Reviewed-by: kvn, iveresov
hotspot/src/share/vm/ci/ciMethod.cpp
hotspot/src/share/vm/ci/ciMethod.hpp
hotspot/src/share/vm/oops/methodData.cpp
hotspot/src/share/vm/oops/methodData.hpp
hotspot/src/share/vm/opto/connode.cpp
hotspot/src/share/vm/opto/doCall.cpp
hotspot/src/share/vm/opto/graphKit.cpp
hotspot/src/share/vm/opto/graphKit.hpp
hotspot/src/share/vm/opto/library_call.cpp
hotspot/src/share/vm/opto/parse2.cpp
hotspot/src/share/vm/opto/phaseX.cpp
hotspot/src/share/vm/opto/type.cpp
hotspot/src/share/vm/opto/type.hpp
hotspot/src/share/vm/runtime/arguments.cpp
hotspot/src/share/vm/runtime/deoptimization.cpp
hotspot/src/share/vm/runtime/deoptimization.hpp
--- a/hotspot/src/share/vm/ci/ciMethod.cpp	Sat Mar 29 14:54:48 2014 +0400
+++ b/hotspot/src/share/vm/ci/ciMethod.cpp	Mon Mar 31 09:08:53 2014 +0200
@@ -581,14 +581,14 @@
  * Check whether profiling provides a type for the argument i to the
  * call at bci bci
  *
- * @param bci  bci of the call
- * @param i    argument number
- * @return     profiled type
+ * @param [in]bci         bci of the call
+ * @param [in]i           argument number
+ * @param [out]type       profiled type of argument, NULL if none
+ * @param [out]maybe_null true if null was seen for argument
+ * @return                true if profiling exists
  *
- * If the profile reports that the argument may be null, return false
- * at least for now.
  */
-ciKlass* ciMethod::argument_profiled_type(int bci, int i) {
+bool ciMethod::argument_profiled_type(int bci, int i, ciKlass*& type, bool& maybe_null) {
   if (MethodData::profile_parameters() && method_data() != NULL && method_data()->is_mature()) {
     ciProfileData* data = method_data()->bci_to_data(bci);
     if (data != NULL) {
@@ -596,82 +596,77 @@
         assert_virtual_call_type_ok(bci);
         ciVirtualCallTypeData* call = (ciVirtualCallTypeData*)data->as_VirtualCallTypeData();
         if (i >= call->number_of_arguments()) {
-          return NULL;
+          return false;
         }
-        ciKlass* type = call->valid_argument_type(i);
-        if (type != NULL && !call->argument_maybe_null(i)) {
-          return type;
-        }
+        type = call->valid_argument_type(i);
+        maybe_null = call->argument_maybe_null(i);
+        return true;
       } else if (data->is_CallTypeData()) {
         assert_call_type_ok(bci);
         ciCallTypeData* call = (ciCallTypeData*)data->as_CallTypeData();
         if (i >= call->number_of_arguments()) {
-          return NULL;
+          return false;
         }
-        ciKlass* type = call->valid_argument_type(i);
-        if (type != NULL && !call->argument_maybe_null(i)) {
-          return type;
-        }
+        type = call->valid_argument_type(i);
+        maybe_null = call->argument_maybe_null(i);
+        return true;
       }
     }
   }
-  return NULL;
+  return false;
 }
 
 /**
  * Check whether profiling provides a type for the return value from
  * the call at bci bci
  *
- * @param bci  bci of the call
- * @return     profiled type
+ * @param [in]bci         bci of the call
+ * @param [out]type       profiled type of argument, NULL if none
+ * @param [out]maybe_null true if null was seen for argument
+ * @return                true if profiling exists
  *
- * If the profile reports that the argument may be null, return false
- * at least for now.
  */
-ciKlass* ciMethod::return_profiled_type(int bci) {
+bool ciMethod::return_profiled_type(int bci, ciKlass*& type, bool& maybe_null) {
   if (MethodData::profile_return() && method_data() != NULL && method_data()->is_mature()) {
     ciProfileData* data = method_data()->bci_to_data(bci);
     if (data != NULL) {
       if (data->is_VirtualCallTypeData()) {
         assert_virtual_call_type_ok(bci);
         ciVirtualCallTypeData* call = (ciVirtualCallTypeData*)data->as_VirtualCallTypeData();
-        ciKlass* type = call->valid_return_type();
-        if (type != NULL && !call->return_maybe_null()) {
-          return type;
-        }
+        type = call->valid_return_type();
+        maybe_null = call->return_maybe_null();
+        return true;
       } else if (data->is_CallTypeData()) {
         assert_call_type_ok(bci);
         ciCallTypeData* call = (ciCallTypeData*)data->as_CallTypeData();
-        ciKlass* type = call->valid_return_type();
-        if (type != NULL && !call->return_maybe_null()) {
-          return type;
-        }
+        type = call->valid_return_type();
+        maybe_null = call->return_maybe_null();
+        return true;
       }
     }
   }
-  return NULL;
+  return false;
 }
 
 /**
  * Check whether profiling provides a type for the parameter i
  *
- * @param i    parameter number
- * @return     profiled type
+ * @param [in]i           parameter number
+ * @param [out]type       profiled type of parameter, NULL if none
+ * @param [out]maybe_null true if null was seen for parameter
+ * @return                true if profiling exists
  *
- * If the profile reports that the argument may be null, return false
- * at least for now.
  */
-ciKlass* ciMethod::parameter_profiled_type(int i) {
+bool ciMethod::parameter_profiled_type(int i, ciKlass*& type, bool& maybe_null) {
   if (MethodData::profile_parameters() && method_data() != NULL && method_data()->is_mature()) {
     ciParametersTypeData* parameters = method_data()->parameters_type_data();
     if (parameters != NULL && i < parameters->number_of_parameters()) {
-      ciKlass* type = parameters->valid_parameter_type(i);
-      if (type != NULL && !parameters->parameter_maybe_null(i)) {
-        return type;
-      }
+      type = parameters->valid_parameter_type(i);
+      maybe_null = parameters->parameter_maybe_null(i);
+      return true;
     }
   }
-  return NULL;
+  return false;
 }
 
 
--- a/hotspot/src/share/vm/ci/ciMethod.hpp	Sat Mar 29 14:54:48 2014 +0400
+++ b/hotspot/src/share/vm/ci/ciMethod.hpp	Mon Mar 31 09:08:53 2014 +0200
@@ -234,10 +234,10 @@
   ciCallProfile call_profile_at_bci(int bci);
   int           interpreter_call_site_count(int bci);
 
-  // Does type profiling provide a useful type at this point?
-  ciKlass*      argument_profiled_type(int bci, int i);
-  ciKlass*      parameter_profiled_type(int i);
-  ciKlass*      return_profiled_type(int bci);
+  // Does type profiling provide any useful information at this point?
+  bool          argument_profiled_type(int bci, int i, ciKlass*& type, bool& maybe_null);
+  bool          parameter_profiled_type(int i, ciKlass*& type, bool& maybe_null);
+  bool          return_profiled_type(int bci, ciKlass*& type, bool& maybe_null);
 
   ciField*      get_field_at_bci( int bci, bool &will_link);
   ciMethod*     get_method_at_bci(int bci, bool &will_link, ciSignature* *declared_signature);
--- a/hotspot/src/share/vm/oops/methodData.cpp	Sat Mar 29 14:54:48 2014 +0400
+++ b/hotspot/src/share/vm/oops/methodData.cpp	Mon Mar 31 09:08:53 2014 +0200
@@ -801,6 +801,8 @@
   case Bytecodes::_invokeinterface:
   case Bytecodes::_if_acmpeq:
   case Bytecodes::_if_acmpne:
+  case Bytecodes::_ifnull:
+  case Bytecodes::_ifnonnull:
   case Bytecodes::_invokestatic:
 #ifdef COMPILER2
     return UseTypeSpeculation;
--- a/hotspot/src/share/vm/oops/methodData.hpp	Sat Mar 29 14:54:48 2014 +0400
+++ b/hotspot/src/share/vm/oops/methodData.hpp	Mon Mar 31 09:08:53 2014 +0200
@@ -2052,7 +2052,7 @@
 
   // Whole-method sticky bits and flags
   enum {
-    _trap_hist_limit    = 19,   // decoupled from Deoptimization::Reason_LIMIT
+    _trap_hist_limit    = 20,   // decoupled from Deoptimization::Reason_LIMIT
     _trap_hist_mask     = max_jubyte,
     _extra_data_count   = 4     // extra DataLayout headers, for trap history
   }; // Public flag values
--- a/hotspot/src/share/vm/opto/connode.cpp	Sat Mar 29 14:54:48 2014 +0400
+++ b/hotspot/src/share/vm/opto/connode.cpp	Mon Mar 31 09:08:53 2014 +0200
@@ -399,7 +399,7 @@
 // Take 'join' of input and cast-up type
 const Type *ConstraintCastNode::Value( PhaseTransform *phase ) const {
   if( in(0) && phase->type(in(0)) == Type::TOP ) return Type::TOP;
-const Type* ft = phase->type(in(1))->filter_speculative(_type);
+  const Type* ft = phase->type(in(1))->filter_speculative(_type);
 
 #ifdef ASSERT
   // Previous versions of this function had some special case logic,
@@ -493,7 +493,17 @@
       result =  my_type->cast_to_ptr_type( my_type->join_ptr(in_ptr) );
     }
   }
-  return result;
+
+  // This is the code from TypePtr::xmeet() that prevents us from
+  // having 2 ways to represent the same type. We have to replicate it
+  // here because we don't go through meet/join.
+  if (result->remove_speculative() == result->speculative()) {
+    result = result->remove_speculative();
+  }
+
+  // Same as above: because we don't go through meet/join, remove the
+  // speculative type if we know we won't use it.
+  return result->cleanup_speculative();
 
   // JOIN NOT DONE HERE BECAUSE OF INTERFACE ISSUES.
   // FIX THIS (DO THE JOIN) WHEN UNION TYPES APPEAR!
--- a/hotspot/src/share/vm/opto/doCall.cpp	Sat Mar 29 14:54:48 2014 +0400
+++ b/hotspot/src/share/vm/opto/doCall.cpp	Mon Mar 31 09:08:53 2014 +0200
@@ -249,8 +249,7 @@
           }
           CallGenerator* miss_cg;
           Deoptimization::DeoptReason reason = morphism == 2 ?
-                                    Deoptimization::Reason_bimorphic :
-                                    (speculative_receiver_type == NULL ? Deoptimization::Reason_class_check : Deoptimization::Reason_speculate_class_check);
+            Deoptimization::Reason_bimorphic : Deoptimization::reason_class_check(speculative_receiver_type != NULL);
           if ((morphism == 1 || (morphism == 2 && next_hit_cg != NULL)) &&
               !too_many_traps(jvms->method(), jvms->bci(), reason)
              ) {
@@ -631,13 +630,7 @@
     }
     BasicType ct = ctype->basic_type();
     if (ct == T_OBJECT || ct == T_ARRAY) {
-      ciKlass* better_type = method()->return_profiled_type(bci());
-      if (UseTypeSpeculation && better_type != NULL) {
-        // If profiling reports a single type for the return value,
-        // feed it to the type system so it can propagate it as a
-        // speculative type
-        record_profile_for_speculation(stack(sp()-1), better_type);
-      }
+      record_profiled_return_for_speculation();
     }
   }
 
--- a/hotspot/src/share/vm/opto/graphKit.cpp	Sat Mar 29 14:54:48 2014 +0400
+++ b/hotspot/src/share/vm/opto/graphKit.cpp	Mon Mar 31 09:08:53 2014 +0200
@@ -612,10 +612,10 @@
   // Usual case:  Bail to interpreter.
   // Reserve the right to recompile if we haven't seen anything yet.
 
-  assert(!Deoptimization::reason_is_speculate(reason), "unsupported");
+  ciMethod* m = Deoptimization::reason_is_speculate(reason) ? C->method() : NULL;
   Deoptimization::DeoptAction action = Deoptimization::Action_maybe_recompile;
   if (treat_throw_as_hot
-      && (method()->method_data()->trap_recompiled_at(bci(), NULL)
+      && (method()->method_data()->trap_recompiled_at(bci(), m)
           || C->too_many_traps(reason))) {
     // We cannot afford to take more traps here.  Suffer in the interpreter.
     if (C->log() != NULL)
@@ -1181,7 +1181,8 @@
 Node* GraphKit::null_check_common(Node* value, BasicType type,
                                   // optional arguments for variations:
                                   bool assert_null,
-                                  Node* *null_control) {
+                                  Node* *null_control,
+                                  bool speculative) {
   assert(!assert_null || null_control == NULL, "not both at once");
   if (stopped())  return top();
   if (!GenerateCompilerNullChecks && !assert_null && null_control == NULL) {
@@ -1291,13 +1292,13 @@
   // Branch to failure if null
   float ok_prob = PROB_MAX;  // a priori estimate:  nulls never happen
   Deoptimization::DeoptReason reason;
-  if (assert_null)
+  if (assert_null) {
     reason = Deoptimization::Reason_null_assert;
-  else if (type == T_OBJECT)
-    reason = Deoptimization::Reason_null_check;
-  else
+  } else if (type == T_OBJECT) {
+    reason = Deoptimization::reason_null_check(speculative);
+  } else {
     reason = Deoptimization::Reason_div0_check;
-
+  }
   // %%% Since Reason_unhandled is not recorded on a per-bytecode basis,
   // ciMethodData::has_trap_at will return a conservative -1 if any
   // must-be-null assertion has failed.  This could cause performance
@@ -2120,21 +2121,36 @@
  *
  * @param n          node that the type applies to
  * @param exact_kls  type from profiling
+ * @param maybe_null did profiling see null?
  *
  * @return           node with improved type
  */
-Node* GraphKit::record_profile_for_speculation(Node* n, ciKlass* exact_kls) {
+Node* GraphKit::record_profile_for_speculation(Node* n, ciKlass* exact_kls, bool maybe_null) {
   const Type* current_type = _gvn.type(n);
   assert(UseTypeSpeculation, "type speculation must be on");
 
-  const TypeOopPtr* speculative = current_type->speculative();
-
+  const TypePtr* speculative = current_type->speculative();
+
+  // Should the klass from the profile be recorded in the speculative type?
   if (current_type->would_improve_type(exact_kls, jvms()->depth())) {
     const TypeKlassPtr* tklass = TypeKlassPtr::make(exact_kls);
     const TypeOopPtr* xtype = tklass->as_instance_type();
     assert(xtype->klass_is_exact(), "Should be exact");
+    // Any reason to believe n is not null (from this profiling or a previous one)?
+    const TypePtr* ptr = (maybe_null && current_type->speculative_maybe_null()) ? TypePtr::BOTTOM : TypePtr::NOTNULL;
     // record the new speculative type's depth
-    speculative = xtype->with_inline_depth(jvms()->depth());
+    speculative = xtype->cast_to_ptr_type(ptr->ptr())->is_ptr();
+    speculative = speculative->with_inline_depth(jvms()->depth());
+  } else if (current_type->would_improve_ptr(maybe_null)) {
+    // Profiling report that null was never seen so we can change the
+    // speculative type to non null ptr.
+    assert(!maybe_null, "nothing to improve");
+    if (speculative == NULL) {
+      speculative = TypePtr::NOTNULL;
+    } else {
+      const TypePtr* ptr = TypePtr::NOTNULL;
+      speculative = speculative->cast_to_ptr_type(ptr->ptr())->is_ptr();
+    }
   }
 
   if (speculative != current_type->speculative()) {
@@ -2167,7 +2183,15 @@
     return n;
   }
   ciKlass* exact_kls = profile_has_unique_klass();
-  return record_profile_for_speculation(n, exact_kls);
+  bool maybe_null = true;
+  if (java_bc() == Bytecodes::_checkcast ||
+      java_bc() == Bytecodes::_instanceof ||
+      java_bc() == Bytecodes::_aastore) {
+    ciProfileData* data = method()->method_data()->bci_to_data(bci());
+    bool maybe_null = data == NULL ? true : data->as_BitData()->null_seen();
+  }
+  return record_profile_for_speculation(n, exact_kls, maybe_null);
+  return n;
 }
 
 /**
@@ -2187,9 +2211,10 @@
   for (int j = skip, i = 0; j < nargs && i < TypeProfileArgsLimit; j++) {
     const Type *targ = tf->_domain->field_at(j + TypeFunc::Parms);
     if (targ->basic_type() == T_OBJECT || targ->basic_type() == T_ARRAY) {
-      ciKlass* better_type = method()->argument_profiled_type(bci(), i);
-      if (better_type != NULL) {
-        record_profile_for_speculation(argument(j), better_type);
+      bool maybe_null = true;
+      ciKlass* better_type = NULL;
+      if (method()->argument_profiled_type(bci(), i, better_type, maybe_null)) {
+        record_profile_for_speculation(argument(j), better_type, maybe_null);
       }
       i++;
     }
@@ -2206,15 +2231,34 @@
   }
   for (int i = 0, j = 0; i < method()->arg_size() ; i++) {
     if (_gvn.type(local(i))->isa_oopptr()) {
-      ciKlass* better_type = method()->parameter_profiled_type(j);
-      if (better_type != NULL) {
-        record_profile_for_speculation(local(i), better_type);
+      bool maybe_null = true;
+      ciKlass* better_type = NULL;
+      if (method()->parameter_profiled_type(j, better_type, maybe_null)) {
+        record_profile_for_speculation(local(i), better_type, maybe_null);
       }
       j++;
     }
   }
 }
 
+/**
+ * Record profiling data from return value profiling at an invoke with
+ * the type system so that it can propagate it (speculation)
+ */
+void GraphKit::record_profiled_return_for_speculation() {
+  if (!UseTypeSpeculation) {
+    return;
+  }
+  bool maybe_null = true;
+  ciKlass* better_type = NULL;
+  if (method()->return_profiled_type(bci(), better_type, maybe_null)) {
+    // If profiling reports a single type for the return value,
+    // feed it to the type system so it can propagate it as a
+    // speculative type
+    record_profile_for_speculation(stack(sp()-1), better_type, maybe_null);
+  }
+}
+
 void GraphKit::round_double_result(ciMethod* dest_method) {
   // A non-strict method may return a double value which has an extended
   // exponent, but this must not be visible in a caller which is 'strict'
@@ -2294,10 +2338,12 @@
 // Null check oop.  Set null-path control into Region in slot 3.
 // Make a cast-not-nullness use the other not-null control.  Return cast.
 Node* GraphKit::null_check_oop(Node* value, Node* *null_control,
-                               bool never_see_null, bool safe_for_replace) {
+                               bool never_see_null,
+                               bool safe_for_replace,
+                               bool speculative) {
   // Initial NULL check taken path
   (*null_control) = top();
-  Node* cast = null_check_common(value, T_OBJECT, false, null_control);
+  Node* cast = null_check_common(value, T_OBJECT, false, null_control, speculative);
 
   // Generate uncommon_trap:
   if (never_see_null && (*null_control) != top()) {
@@ -2308,7 +2354,8 @@
     PreserveJVMState pjvms(this);
     set_control(*null_control);
     replace_in_map(value, null());
-    uncommon_trap(Deoptimization::Reason_null_check,
+    Deoptimization::DeoptReason reason = Deoptimization::reason_null_check(speculative);
+    uncommon_trap(reason,
                   Deoptimization::Action_make_not_entrant);
     (*null_control) = top();    // NULL path is dead
   }
@@ -2732,11 +2779,16 @@
 // recompile; the offending check will be recompiled to handle NULLs.
 // If we see several offending BCIs, then all checks in the
 // method will be recompiled.
-bool GraphKit::seems_never_null(Node* obj, ciProfileData* data) {
+bool GraphKit::seems_never_null(Node* obj, ciProfileData* data, bool& speculating) {
+  speculating = !_gvn.type(obj)->speculative_maybe_null();
+  Deoptimization::DeoptReason reason = Deoptimization::reason_null_check(speculating);
   if (UncommonNullCast               // Cutout for this technique
       && obj != null()               // And not the -Xcomp stupid case?
-      && !too_many_traps(Deoptimization::Reason_null_check)
+      && !too_many_traps(reason)
       ) {
+    if (speculating) {
+      return true;
+    }
     if (data == NULL)
       // Edge case:  no mature data.  Be optimistic here.
       return true;
@@ -2746,6 +2798,7 @@
            java_bc() == Bytecodes::_aastore, "MDO must collect null_seen bit here");
     return !data->as_BitData()->null_seen();
   }
+  speculating = false;
   return false;
 }
 
@@ -2758,7 +2811,7 @@
                                              bool safe_for_replace) {
   if (!UseTypeProfile || !TypeProfileCasts) return NULL;
 
-  Deoptimization::DeoptReason reason = spec_klass == NULL ? Deoptimization::Reason_class_check : Deoptimization::Reason_speculate_class_check;
+  Deoptimization::DeoptReason reason = Deoptimization::reason_class_check(spec_klass != NULL);
 
   // Make sure we haven't already deoptimized from this tactic.
   if (too_many_traps(reason))
@@ -2811,7 +2864,7 @@
   // type == NULL if profiling tells us this object is always null
   if (type != NULL) {
     Deoptimization::DeoptReason class_reason = Deoptimization::Reason_speculate_class_check;
-    Deoptimization::DeoptReason null_reason = Deoptimization::Reason_null_check;
+    Deoptimization::DeoptReason null_reason = Deoptimization::Reason_speculate_null_check;
     if (!too_many_traps(null_reason) &&
         !too_many_traps(class_reason)) {
       Node* not_null_obj = NULL;
@@ -2819,7 +2872,7 @@
       // there's no need for a null check
       if (!not_null) {
         Node* null_ctl = top();
-        not_null_obj = null_check_oop(obj, &null_ctl, true, true);
+        not_null_obj = null_check_oop(obj, &null_ctl, true, true, true);
         assert(null_ctl->is_top(), "no null control here");
       } else {
         not_null_obj = obj;
@@ -2867,12 +2920,13 @@
   if (java_bc() == Bytecodes::_instanceof) {  // Only for the bytecode
     data = method()->method_data()->bci_to_data(bci());
   }
+  bool speculative_not_null = false;
   bool never_see_null = (ProfileDynamicTypes  // aggressive use of profile
-                         && seems_never_null(obj, data));
+                         && seems_never_null(obj, data, speculative_not_null));
 
   // Null check; get casted pointer; set region slot 3
   Node* null_ctl = top();
-  Node* not_null_obj = null_check_oop(obj, &null_ctl, never_see_null, safe_for_replace);
+  Node* not_null_obj = null_check_oop(obj, &null_ctl, never_see_null, safe_for_replace, speculative_not_null);
 
   // If not_null_obj is dead, only null-path is taken
   if (stopped()) {              // Doing instance-of on a NULL?
@@ -2995,12 +3049,13 @@
   C->set_has_split_ifs(true); // Has chance for split-if optimization
 
   // Use null-cast information if it is available
+  bool speculative_not_null = false;
   bool never_see_null = ((failure_control == NULL)  // regular case only
-                         && seems_never_null(obj, data));
+                         && seems_never_null(obj, data, speculative_not_null));
 
   // Null check; get casted pointer; set region slot 3
   Node* null_ctl = top();
-  Node* not_null_obj = null_check_oop(obj, &null_ctl, never_see_null, safe_for_replace);
+  Node* not_null_obj = null_check_oop(obj, &null_ctl, never_see_null, safe_for_replace, speculative_not_null);
 
   // If not_null_obj is dead, only null-path is taken
   if (stopped()) {              // Doing instance-of on a NULL?
--- a/hotspot/src/share/vm/opto/graphKit.hpp	Sat Mar 29 14:54:48 2014 +0400
+++ b/hotspot/src/share/vm/opto/graphKit.hpp	Mon Mar 31 09:08:53 2014 +0200
@@ -351,9 +351,11 @@
   // Return the value cast to not-null.
   // Be clever about equivalent dominating null checks.
   Node* null_check_common(Node* value, BasicType type,
-                          bool assert_null = false, Node* *null_control = NULL);
+                          bool assert_null = false,
+                          Node* *null_control = NULL,
+                          bool speculative = false);
   Node* null_check(Node* value, BasicType type = T_OBJECT) {
-    return null_check_common(value, type);
+    return null_check_common(value, type, false, NULL, !_gvn.type(value)->speculative_maybe_null());
   }
   Node* null_check_receiver() {
     assert(argument(0)->bottom_type()->isa_ptr(), "must be");
@@ -382,10 +384,12 @@
   // If safe_for_replace, then we can replace the value with the cast
   // in the parsing map (the cast is guaranteed to dominate the map)
   Node* null_check_oop(Node* value, Node* *null_control,
-                       bool never_see_null = false, bool safe_for_replace = false);
+                       bool never_see_null = false,
+                       bool safe_for_replace = false,
+                       bool speculative = false);
 
   // Check the null_seen bit.
-  bool seems_never_null(Node* obj, ciProfileData* data);
+  bool seems_never_null(Node* obj, ciProfileData* data, bool& speculating);
 
   // Check for unique class for receiver at call
   ciKlass* profile_has_unique_klass() {
@@ -399,10 +403,11 @@
   }
 
   // record type from profiling with the type system
-  Node* record_profile_for_speculation(Node* n, ciKlass* exact_kls);
-  Node* record_profiled_receiver_for_speculation(Node* n);
+  Node* record_profile_for_speculation(Node* n, ciKlass* exact_kls, bool maybe_null);
   void record_profiled_arguments_for_speculation(ciMethod* dest_method, Bytecodes::Code bc);
   void record_profiled_parameters_for_speculation();
+  void record_profiled_return_for_speculation();
+  Node* record_profiled_receiver_for_speculation(Node* n);
 
   // Use the type profile to narrow an object type.
   Node* maybe_cast_profiled_receiver(Node* not_null_obj,
--- a/hotspot/src/share/vm/opto/library_call.cpp	Sat Mar 29 14:54:48 2014 +0400
+++ b/hotspot/src/share/vm/opto/library_call.cpp	Mon Mar 31 09:08:53 2014 +0200
@@ -4658,7 +4658,7 @@
 
     ciKlass* src_k = NULL;
     if (!has_src) {
-      src_k = src_type->speculative_type();
+      src_k = src_type->speculative_type_not_null();
       if (src_k != NULL && src_k->is_array_klass()) {
         could_have_src = true;
       }
@@ -4666,7 +4666,7 @@
 
     ciKlass* dest_k = NULL;
     if (!has_dest) {
-      dest_k = dest_type->speculative_type();
+      dest_k = dest_type->speculative_type_not_null();
       if (dest_k != NULL && dest_k->is_array_klass()) {
         could_have_dest = true;
       }
@@ -4738,13 +4738,13 @@
     ciKlass* src_k = top_src->klass();
     ciKlass* dest_k = top_dest->klass();
     if (!src_spec) {
-      src_k = src_type->speculative_type();
+      src_k = src_type->speculative_type_not_null();
       if (src_k != NULL && src_k->is_array_klass()) {
           could_have_src = true;
       }
     }
     if (!dest_spec) {
-      dest_k = dest_type->speculative_type();
+      dest_k = dest_type->speculative_type_not_null();
       if (dest_k != NULL && dest_k->is_array_klass()) {
         could_have_dest = true;
       }
--- a/hotspot/src/share/vm/opto/parse2.cpp	Sat Mar 29 14:54:48 2014 +0400
+++ b/hotspot/src/share/vm/opto/parse2.cpp	Mon Mar 31 09:08:53 2014 +0200
@@ -1288,7 +1288,7 @@
               (jvms->is_loc(obj_in_map) || jvms->is_stk(obj_in_map))) {
             TypeNode* ccast = new (C) CheckCastPPNode(control(), obj, tboth);
             const Type* tcc = ccast->as_Type()->type();
-            assert(tcc != obj_type && tcc->higher_equal_speculative(obj_type), "must improve");
+            assert(tcc != obj_type && tcc->higher_equal(obj_type), "must improve");
             // Delay transform() call to allow recovery of pre-cast value
             // at the control merge.
             _gvn.set_type_bottom(ccast);
@@ -1352,7 +1352,7 @@
 
   if (ccast != NULL) {
     const Type* tcc = ccast->as_Type()->type();
-    assert(tcc != tval && tcc->higher_equal_speculative(tval), "must improve");
+    assert(tcc != tval && tcc->higher_equal(tval), "must improve");
     // Delay transform() call to allow recovery of pre-cast value
     // at the control merge.
     ccast->set_req(0, control());
@@ -1393,7 +1393,7 @@
       Node* addp = load_klass->in(2);
       Node* obj = addp->in(AddPNode::Address);
       const TypeOopPtr* obj_type = _gvn.type(obj)->is_oopptr();
-      if (obj_type->speculative_type() != NULL) {
+      if (obj_type->speculative_type_not_null() != NULL) {
         ciKlass* k = obj_type->speculative_type();
         inc_sp(2);
         obj = maybe_cast_profiled_obj(obj, k);
@@ -2277,6 +2277,14 @@
     maybe_add_safepoint(iter().get_dest());
     a = null();
     b = pop();
+    if (!_gvn.type(b)->speculative_maybe_null() &&
+        !too_many_traps(Deoptimization::Reason_speculate_null_check)) {
+      inc_sp(1);
+      Node* null_ctl = top();
+      b = null_check_oop(b, &null_ctl, true, true, true);
+      assert(null_ctl->is_top(), "no null control here");
+      dec_sp(1);
+    }
     c = _gvn.transform( new (C) CmpPNode(b, a) );
     do_ifnull(btest, c);
     break;
--- a/hotspot/src/share/vm/opto/phaseX.cpp	Sat Mar 29 14:54:48 2014 +0400
+++ b/hotspot/src/share/vm/opto/phaseX.cpp	Mon Mar 31 09:08:53 2014 +0200
@@ -330,7 +330,7 @@
   Node *sentinel_node = sentinel();
   for (uint i = 0; i < max; ++i) {
     Node *n = at(i);
-    if(n != NULL && n != sentinel_node && n->is_Type()) {
+    if(n != NULL && n != sentinel_node && n->is_Type() && n->outcnt() > 0) {
       TypeNode* tn = n->as_Type();
       const Type* t = tn->type();
       const Type* t_no_spec = t->remove_speculative();
--- a/hotspot/src/share/vm/opto/type.cpp	Sat Mar 29 14:54:48 2014 +0400
+++ b/hotspot/src/share/vm/opto/type.cpp	Mon Mar 31 09:08:53 2014 +0200
@@ -350,9 +350,9 @@
   floop[1] = TypeInt::INT;
   TypeTuple::LOOPBODY = TypeTuple::make( 2, floop );
 
-  TypePtr::NULL_PTR= TypePtr::make( AnyPtr, TypePtr::Null, 0 );
-  TypePtr::NOTNULL = TypePtr::make( AnyPtr, TypePtr::NotNull, OffsetBot );
-  TypePtr::BOTTOM  = TypePtr::make( AnyPtr, TypePtr::BotPTR, OffsetBot );
+  TypePtr::NULL_PTR= TypePtr::make(AnyPtr, TypePtr::Null, 0);
+  TypePtr::NOTNULL = TypePtr::make(AnyPtr, TypePtr::NotNull, OffsetBot);
+  TypePtr::BOTTOM  = TypePtr::make(AnyPtr, TypePtr::BotPTR, OffsetBot);
 
   TypeRawPtr::BOTTOM = TypeRawPtr::make( TypePtr::BotPTR );
   TypeRawPtr::NOTNULL= TypeRawPtr::make( TypePtr::NotNull );
@@ -372,7 +372,7 @@
                                            false, 0, oopDesc::mark_offset_in_bytes());
   TypeInstPtr::KLASS   = TypeInstPtr::make(TypePtr::BotPTR,  current->env()->Object_klass(),
                                            false, 0, oopDesc::klass_offset_in_bytes());
-  TypeOopPtr::BOTTOM  = TypeOopPtr::make(TypePtr::BotPTR, OffsetBot, TypeOopPtr::InstanceBot, NULL);
+  TypeOopPtr::BOTTOM  = TypeOopPtr::make(TypePtr::BotPTR, OffsetBot, TypeOopPtr::InstanceBot);
 
   TypeMetadataPtr::BOTTOM = TypeMetadataPtr::make(TypePtr::BotPTR, NULL, OffsetBot);
 
@@ -620,8 +620,8 @@
     return true;
   }
   // Now check the speculative parts as well
-  const TypeOopPtr* this_spec = isa_oopptr() != NULL ? isa_oopptr()->speculative() : NULL;
-  const TypeOopPtr* t_spec = t->isa_oopptr() != NULL ? t->isa_oopptr()->speculative() : NULL;
+  const TypePtr* this_spec = isa_ptr() != NULL ? is_ptr()->speculative() : NULL;
+  const TypePtr* t_spec = t->isa_ptr() != NULL ? t->is_ptr()->speculative() : NULL;
   if (this_spec != NULL && t_spec != NULL) {
     if (this_spec->interface_vs_oop_helper(t_spec)) {
       return true;
@@ -1975,6 +1975,25 @@
   return make(_elem->remove_speculative(), _size, _stable);
 }
 
+/**
+ * Return same type with cleaned up speculative part of element
+ */
+const Type* TypeAry::cleanup_speculative() const {
+  return make(_elem->cleanup_speculative(), _size, _stable);
+}
+
+/**
+ * Return same type but with a different inline depth (used for speculation)
+ *
+ * @param depth  depth to meet with
+ */
+const TypePtr* TypePtr::with_inline_depth(int depth) const {
+  if (!UseInlineDepthForSpeculativeTypes) {
+    return this;
+  }
+  return make(AnyPtr, _ptr, _offset, _speculative, depth);
+}
+
 //----------------------interface_vs_oop---------------------------------------
 #ifdef ASSERT
 bool TypeAry::interface_vs_oop(const Type *t) const {
@@ -2179,15 +2198,15 @@
 };
 
 //------------------------------make-------------------------------------------
-const TypePtr *TypePtr::make( TYPES t, enum PTR ptr, int offset ) {
-  return (TypePtr*)(new TypePtr(t,ptr,offset))->hashcons();
+const TypePtr *TypePtr::make(TYPES t, enum PTR ptr, int offset, const TypePtr* speculative, int inline_depth) {
+  return (TypePtr*)(new TypePtr(t,ptr,offset, speculative, inline_depth))->hashcons();
 }
 
 //------------------------------cast_to_ptr_type-------------------------------
 const Type *TypePtr::cast_to_ptr_type(PTR ptr) const {
   assert(_base == AnyPtr, "subclass must override cast_to_ptr_type");
   if( ptr == _ptr ) return this;
-  return make(_base, ptr, _offset);
+  return make(_base, ptr, _offset, _speculative, _inline_depth);
 }
 
 //------------------------------get_con----------------------------------------
@@ -2198,7 +2217,29 @@
 
 //------------------------------meet-------------------------------------------
 // Compute the MEET of two types.  It returns a new Type object.
-const Type *TypePtr::xmeet( const Type *t ) const {
+const Type *TypePtr::xmeet(const Type *t) const {
+  const Type* res = xmeet_helper(t);
+  if (res->isa_ptr() == NULL) {
+    return res;
+  }
+
+  const TypePtr* res_ptr = res->is_ptr();
+  if (res_ptr->speculative() != NULL) {
+    // type->speculative() == NULL means that speculation is no better
+    // than type, i.e. type->speculative() == type. So there are 2
+    // ways to represent the fact that we have no useful speculative
+    // data and we should use a single one to be able to test for
+    // equality between types. Check whether type->speculative() ==
+    // type and set speculative to NULL if it is the case.
+    if (res_ptr->remove_speculative() == res_ptr->speculative()) {
+      return res_ptr->remove_speculative();
+    }
+  }
+
+  return res;
+}
+
+const Type *TypePtr::xmeet_helper(const Type *t) const {
   // Perform a fast test for common case; meeting the same types together.
   if( this == t ) return this;  // Meeting same type-rep?
 
@@ -2221,7 +2262,9 @@
 
   case AnyPtr: {                // Meeting to AnyPtrs
     const TypePtr *tp = t->is_ptr();
-    return make( AnyPtr, meet_ptr(tp->ptr()), meet_offset(tp->offset()) );
+    const TypePtr* speculative = xmeet_speculative(tp);
+    int depth = meet_inline_depth(tp->inline_depth());
+    return make(AnyPtr, meet_ptr(tp->ptr()), meet_offset(tp->offset()), speculative, depth);
   }
   case RawPtr:                  // For these, flip the call around to cut down
   case OopPtr:
@@ -2260,7 +2303,7 @@
   BotPTR, NotNull, Constant, Null, AnyNull, TopPTR
 };
 const Type *TypePtr::xdual() const {
-  return new TypePtr( AnyPtr, dual_ptr(), dual_offset() );
+  return new TypePtr(AnyPtr, dual_ptr(), dual_offset(), dual_speculative(), dual_inline_depth());
 }
 
 //------------------------------xadd_offset------------------------------------
@@ -2281,20 +2324,245 @@
 
 //------------------------------add_offset-------------------------------------
 const TypePtr *TypePtr::add_offset( intptr_t offset ) const {
-  return make( AnyPtr, _ptr, xadd_offset(offset) );
+  return make(AnyPtr, _ptr, xadd_offset(offset), _speculative, _inline_depth);
 }
 
 //------------------------------eq---------------------------------------------
 // Structural equality check for Type representations
 bool TypePtr::eq( const Type *t ) const {
   const TypePtr *a = (const TypePtr*)t;
-  return _ptr == a->ptr() && _offset == a->offset();
+  return _ptr == a->ptr() && _offset == a->offset() && eq_speculative(a) && _inline_depth == a->_inline_depth;
 }
 
 //------------------------------hash-------------------------------------------
 // Type-specific hashing function.
 int TypePtr::hash(void) const {
-  return _ptr + _offset;
+  return _ptr + _offset + hash_speculative() + _inline_depth;
+;
+}
+
+/**
+ * Return same type without a speculative part
+ */
+const Type* TypePtr::remove_speculative() const {
+  if (_speculative == NULL) {
+    return this;
+  }
+  assert(_inline_depth == InlineDepthTop || _inline_depth == InlineDepthBottom, "non speculative type shouldn't have inline depth");
+  return make(AnyPtr, _ptr, _offset, NULL, _inline_depth);
+}
+
+/**
+ * Return same type but drop speculative part if we know we won't use
+ * it
+ */
+const Type* TypePtr::cleanup_speculative() const {
+  if (speculative() == NULL) {
+    return this;
+  }
+  const Type* no_spec = remove_speculative();
+  // If this is NULL_PTR then we don't need the speculative type
+  // (with_inline_depth in case the current type inline depth is
+  // InlineDepthTop)
+  if (no_spec == NULL_PTR->with_inline_depth(inline_depth())) {
+    return no_spec;
+  }
+  if (above_centerline(speculative()->ptr())) {
+    return no_spec;
+  }
+  const TypeOopPtr* spec_oopptr = speculative()->isa_oopptr();
+  // If the speculative may be null and is an inexact klass then it
+  // doesn't help
+  if (speculative()->maybe_null() && (spec_oopptr == NULL || !spec_oopptr->klass_is_exact())) {
+    return no_spec;
+  }
+  return this;
+}
+
+/**
+ * dual of the speculative part of the type
+ */
+const TypePtr* TypePtr::dual_speculative() const {
+  if (_speculative == NULL) {
+    return NULL;
+  }
+  return _speculative->dual()->is_ptr();
+}
+
+/**
+ * meet of the speculative parts of 2 types
+ *
+ * @param other  type to meet with
+ */
+const TypePtr* TypePtr::xmeet_speculative(const TypePtr* other) const {
+  bool this_has_spec = (_speculative != NULL);
+  bool other_has_spec = (other->speculative() != NULL);
+
+  if (!this_has_spec && !other_has_spec) {
+    return NULL;
+  }
+
+  // If we are at a point where control flow meets and one branch has
+  // a speculative type and the other has not, we meet the speculative
+  // type of one branch with the actual type of the other. If the
+  // actual type is exact and the speculative is as well, then the
+  // result is a speculative type which is exact and we can continue
+  // speculation further.
+  const TypePtr* this_spec = _speculative;
+  const TypePtr* other_spec = other->speculative();
+
+  if (!this_has_spec) {
+    this_spec = this;
+  }
+
+  if (!other_has_spec) {
+    other_spec = other;
+  }
+
+  return this_spec->meet(other_spec)->is_ptr();
+}
+
+/**
+ * dual of the inline depth for this type (used for speculation)
+ */
+int TypePtr::dual_inline_depth() const {
+  return -inline_depth();
+}
+
+/**
+ * meet of 2 inline depths (used for speculation)
+ *
+ * @param depth  depth to meet with
+ */
+int TypePtr::meet_inline_depth(int depth) const {
+  return MAX2(inline_depth(), depth);
+}
+
+/**
+ * Are the speculative parts of 2 types equal?
+ *
+ * @param other  type to compare this one to
+ */
+bool TypePtr::eq_speculative(const TypePtr* other) const {
+  if (_speculative == NULL || other->speculative() == NULL) {
+    return _speculative == other->speculative();
+  }
+
+  if (_speculative->base() != other->speculative()->base()) {
+    return false;
+  }
+
+  return _speculative->eq(other->speculative());
+}
+
+/**
+ * Hash of the speculative part of the type
+ */
+int TypePtr::hash_speculative() const {
+  if (_speculative == NULL) {
+    return 0;
+  }
+
+  return _speculative->hash();
+}
+
+/**
+ * add offset to the speculative part of the type
+ *
+ * @param offset  offset to add
+ */
+const TypePtr* TypePtr::add_offset_speculative(intptr_t offset) const {
+  if (_speculative == NULL) {
+    return NULL;
+  }
+  return _speculative->add_offset(offset)->is_ptr();
+}
+
+/**
+ * return exact klass from the speculative type if there's one
+ */
+ciKlass* TypePtr::speculative_type() const {
+  if (_speculative != NULL && _speculative->isa_oopptr()) {
+    const TypeOopPtr* speculative = _speculative->join(this)->is_oopptr();
+    if (speculative->klass_is_exact()) {
+      return speculative->klass();
+    }
+  }
+  return NULL;
+}
+
+/**
+ * return true if speculative type may be null
+ */
+bool TypePtr::speculative_maybe_null() const {
+  if (_speculative != NULL) {
+    const TypePtr* speculative = _speculative->join(this)->is_ptr();
+    return speculative->maybe_null();
+  }
+  return true;
+}
+
+/**
+ * Same as TypePtr::speculative_type() but return the klass only if
+ * the speculative tells us is not null
+ */
+ciKlass* TypePtr::speculative_type_not_null() const {
+  if (speculative_maybe_null()) {
+    return NULL;
+  }
+  return speculative_type();
+}
+
+/**
+ * Check whether new profiling would improve speculative type
+ *
+ * @param   exact_kls    class from profiling
+ * @param   inline_depth inlining depth of profile point
+ *
+ * @return  true if type profile is valuable
+ */
+bool TypePtr::would_improve_type(ciKlass* exact_kls, int inline_depth) const {
+  // no profiling?
+  if (exact_kls == NULL) {
+    return false;
+  }
+  // no speculative type or non exact speculative type?
+  if (speculative_type() == NULL) {
+    return true;
+  }
+  // If the node already has an exact speculative type keep it,
+  // unless it was provided by profiling that is at a deeper
+  // inlining level. Profiling at a higher inlining depth is
+  // expected to be less accurate.
+  if (_speculative->inline_depth() == InlineDepthBottom) {
+    return false;
+  }
+  assert(_speculative->inline_depth() != InlineDepthTop, "can't do the comparison");
+  return inline_depth < _speculative->inline_depth();
+}
+
+/**
+ * Check whether new profiling would improve ptr (= tells us it is non
+ * null)
+ *
+ * @param   maybe_null true if profiling tells the ptr may be null
+ *
+ * @return  true if ptr profile is valuable
+ */
+bool TypePtr::would_improve_ptr(bool maybe_null) const {
+  // profiling doesn't tell us anything useful
+  if (maybe_null) {
+    return false;
+  }
+  // We already know this is not be null
+  if (!this->maybe_null()) {
+    return false;
+  }
+  // We already know the speculative type cannot be null
+  if (!speculative_maybe_null()) {
+    return false;
+  }
+  return true;
 }
 
 //------------------------------dump2------------------------------------------
@@ -2309,6 +2577,32 @@
   if( _offset == OffsetTop ) st->print("+top");
   else if( _offset == OffsetBot ) st->print("+bot");
   else if( _offset ) st->print("+%d", _offset);
+  dump_inline_depth(st);
+  dump_speculative(st);
+}
+
+/**
+ *dump the speculative part of the type
+ */
+void TypePtr::dump_speculative(outputStream *st) const {
+  if (_speculative != NULL) {
+    st->print(" (speculative=");
+    _speculative->dump_on(st);
+    st->print(")");
+  }
+}
+
+/**
+ *dump the inline depth of the type
+ */
+void TypePtr::dump_inline_depth(outputStream *st) const {
+  if (_inline_depth != InlineDepthBottom) {
+    if (_inline_depth == InlineDepthTop) {
+      st->print(" (inline_depth=InlineDepthTop)");
+    } else {
+      st->print(" (inline_depth=%d)", _inline_depth);
+    }
+  }
 }
 #endif
 
@@ -2399,7 +2693,7 @@
   case TypePtr::Null:
     if( _ptr == TypePtr::TopPTR ) return t;
     return TypeRawPtr::BOTTOM;
-  case TypePtr::NotNull: return TypePtr::make( AnyPtr, meet_ptr(TypePtr::NotNull), tp->meet_offset(0) );
+  case TypePtr::NotNull: return TypePtr::make(AnyPtr, meet_ptr(TypePtr::NotNull), tp->meet_offset(0), tp->speculative(), tp->inline_depth());
   case TypePtr::AnyNull:
     if( _ptr == TypePtr::Constant) return this;
     return make( meet_ptr(TypePtr::AnyNull) );
@@ -2463,16 +2757,15 @@
 const TypeOopPtr *TypeOopPtr::BOTTOM;
 
 //------------------------------TypeOopPtr-------------------------------------
-TypeOopPtr::TypeOopPtr(TYPES t, PTR ptr, ciKlass* k, bool xk, ciObject* o, int offset, int instance_id, const TypeOopPtr* speculative, int inline_depth)
-  : TypePtr(t, ptr, offset),
+TypeOopPtr::TypeOopPtr(TYPES t, PTR ptr, ciKlass* k, bool xk, ciObject* o, int offset,
+                       int instance_id, const TypePtr* speculative, int inline_depth)
+  : TypePtr(t, ptr, offset, speculative, inline_depth),
     _const_oop(o), _klass(k),
     _klass_is_exact(xk),
     _is_ptr_to_narrowoop(false),
     _is_ptr_to_narrowklass(false),
     _is_ptr_to_boxed_value(false),
-    _instance_id(instance_id),
-    _speculative(speculative),
-    _inline_depth(inline_depth){
+    _instance_id(instance_id) {
   if (Compile::current()->eliminate_boxing() && (t == InstPtr) &&
       (offset > 0) && xk && (k != 0) && k->is_instance_klass()) {
     _is_ptr_to_boxed_value = k->as_instance_klass()->is_boxed_value_offset(offset);
@@ -2538,8 +2831,8 @@
 }
 
 //------------------------------make-------------------------------------------
-const TypeOopPtr *TypeOopPtr::make(PTR ptr,
-                                   int offset, int instance_id, const TypeOopPtr* speculative, int inline_depth) {
+const TypeOopPtr *TypeOopPtr::make(PTR ptr, int offset, int instance_id,
+                                     const TypePtr* speculative, int inline_depth) {
   assert(ptr != Constant, "no constant generic pointers");
   ciKlass*  k = Compile::current()->env()->Object_klass();
   bool      xk = false;
@@ -2582,28 +2875,6 @@
     return TypeKlassPtr::make(xk? Constant: NotNull, k, 0);
 }
 
-const Type *TypeOopPtr::xmeet(const Type *t) const {
-  const Type* res = xmeet_helper(t);
-  if (res->isa_oopptr() == NULL) {
-    return res;
-  }
-
-  const TypeOopPtr* res_oopptr = res->is_oopptr();
-  if (res_oopptr->speculative() != NULL) {
-    // type->speculative() == NULL means that speculation is no better
-    // than type, i.e. type->speculative() == type. So there are 2
-    // ways to represent the fact that we have no useful speculative
-    // data and we should use a single one to be able to test for
-    // equality between types. Check whether type->speculative() ==
-    // type and set speculative to NULL if it is the case.
-    if (res_oopptr->remove_speculative() == res_oopptr->speculative()) {
-      return res_oopptr->remove_speculative();
-    }
-  }
-
-  return res;
-}
-
 //------------------------------meet-------------------------------------------
 // Compute the MEET of two types.  It returns a new Type object.
 const Type *TypeOopPtr::xmeet_helper(const Type *t) const {
@@ -2641,19 +2912,20 @@
     const TypePtr *tp = t->is_ptr();
     int offset = meet_offset(tp->offset());
     PTR ptr = meet_ptr(tp->ptr());
+    const TypePtr* speculative = xmeet_speculative(tp);
+    int depth = meet_inline_depth(tp->inline_depth());
     switch (tp->ptr()) {
     case Null:
-      if (ptr == Null)  return TypePtr::make(AnyPtr, ptr, offset);
+      if (ptr == Null)  return TypePtr::make(AnyPtr, ptr, offset, speculative, depth);
       // else fall through:
     case TopPTR:
     case AnyNull: {
       int instance_id = meet_instance_id(InstanceTop);
-      const TypeOopPtr* speculative = _speculative;
-      return make(ptr, offset, instance_id, speculative, _inline_depth);
+      return make(ptr, offset, instance_id, speculative, depth);
     }
     case BotPTR:
     case NotNull:
-      return TypePtr::make(AnyPtr, ptr, offset);
+      return TypePtr::make(AnyPtr, ptr, offset, speculative, depth);
     default: typerr(t);
     }
   }
@@ -2661,7 +2933,7 @@
   case OopPtr: {                 // Meeting to other OopPtrs
     const TypeOopPtr *tp = t->is_oopptr();
     int instance_id = meet_instance_id(tp->instance_id());
-    const TypeOopPtr* speculative = xmeet_speculative(tp);
+    const TypePtr* speculative = xmeet_speculative(tp);
     int depth = meet_inline_depth(tp->inline_depth());
     return make(meet_ptr(tp->ptr()), meet_offset(tp->offset()), instance_id, speculative, depth);
   }
@@ -2859,9 +3131,7 @@
 bool TypeOopPtr::eq( const Type *t ) const {
   const TypeOopPtr *a = (const TypeOopPtr*)t;
   if (_klass_is_exact != a->_klass_is_exact ||
-      _instance_id != a->_instance_id ||
-      !eq_speculative(a) ||
-      _inline_depth != a->_inline_depth)  return false;
+      _instance_id != a->_instance_id)  return false;
   ciObject* one = const_oop();
   ciObject* two = a->const_oop();
   if (one == NULL || two == NULL) {
@@ -2878,8 +3148,6 @@
     (const_oop() ? const_oop()->hash() : 0) +
     _klass_is_exact +
     _instance_id +
-    hash_speculative() +
-    _inline_depth +
     TypePtr::hash();
 }
 
@@ -2903,27 +3171,6 @@
   dump_inline_depth(st);
   dump_speculative(st);
 }
-
-/**
- *dump the speculative part of the type
- */
-void TypeOopPtr::dump_speculative(outputStream *st) const {
-  if (_speculative != NULL) {
-    st->print(" (speculative=");
-    _speculative->dump_on(st);
-    st->print(")");
-  }
-}
-
-void TypeOopPtr::dump_inline_depth(outputStream *st) const {
-  if (_inline_depth != InlineDepthBottom) {
-    if (_inline_depth == InlineDepthTop) {
-      st->print(" (inline_depth=InlineDepthTop)");
-    } else {
-      st->print(" (inline_depth=%d)", _inline_depth);
-    }
-  }
-}
 #endif
 
 //------------------------------singleton--------------------------------------
@@ -2952,49 +3199,30 @@
 }
 
 /**
+ * Return same type but drop speculative part if we know we won't use
+ * it
+ */
+const Type* TypeOopPtr::cleanup_speculative() const {
+  // If the klass is exact and the ptr is not null then there's
+  // nothing that the speculative type can help us with
+  if (klass_is_exact() && !maybe_null()) {
+    return remove_speculative();
+  }
+  return TypePtr::cleanup_speculative();
+}
+
+/**
  * Return same type but with a different inline depth (used for speculation)
  *
  * @param depth  depth to meet with
  */
-const TypeOopPtr* TypeOopPtr::with_inline_depth(int depth) const {
+const TypePtr* TypeOopPtr::with_inline_depth(int depth) const {
   if (!UseInlineDepthForSpeculativeTypes) {
     return this;
   }
   return make(_ptr, _offset, _instance_id, _speculative, depth);
 }
 
-/**
- * Check whether new profiling would improve speculative type
- *
- * @param   exact_kls    class from profiling
- * @param   inline_depth inlining depth of profile point
- *
- * @return  true if type profile is valuable
- */
-bool TypeOopPtr::would_improve_type(ciKlass* exact_kls, int inline_depth) const {
-  // no way to improve an already exact type
-  if (klass_is_exact()) {
-    return false;
-  }
-  // no profiling?
-  if (exact_kls == NULL) {
-    return false;
-  }
-  // no speculative type or non exact speculative type?
-  if (speculative_type() == NULL) {
-    return true;
-  }
-  // If the node already has an exact speculative type keep it,
-  // unless it was provided by profiling that is at a deeper
-  // inlining level. Profiling at a higher inlining depth is
-  // expected to be less accurate.
-  if (_speculative->inline_depth() == InlineDepthBottom) {
-    return false;
-  }
-  assert(_speculative->inline_depth() != InlineDepthTop, "can't do the comparison");
-  return inline_depth < _speculative->inline_depth();
-}
-
 //------------------------------meet_instance_id--------------------------------
 int TypeOopPtr::meet_instance_id( int instance_id ) const {
   // Either is 'TOP' instance?  Return the other instance!
@@ -3013,102 +3241,19 @@
 }
 
 /**
- * meet of the speculative parts of 2 types
+ * Check whether new profiling would improve speculative type
  *
- * @param other  type to meet with
+ * @param   exact_kls    class from profiling
+ * @param   inline_depth inlining depth of profile point
+ *
+ * @return  true if type profile is valuable
  */
-const TypeOopPtr* TypeOopPtr::xmeet_speculative(const TypeOopPtr* other) const {
-  bool this_has_spec = (_speculative != NULL);
-  bool other_has_spec = (other->speculative() != NULL);
-
-  if (!this_has_spec && !other_has_spec) {
-    return NULL;
-  }
-
-  // If we are at a point where control flow meets and one branch has
-  // a speculative type and the other has not, we meet the speculative
-  // type of one branch with the actual type of the other. If the
-  // actual type is exact and the speculative is as well, then the
-  // result is a speculative type which is exact and we can continue
-  // speculation further.
-  const TypeOopPtr* this_spec = _speculative;
-  const TypeOopPtr* other_spec = other->speculative();
-
-  if (!this_has_spec) {
-    this_spec = this;
-  }
-
-  if (!other_has_spec) {
-    other_spec = other;
-  }
-
-  return this_spec->meet_speculative(other_spec)->is_oopptr();
-}
-
-/**
- * dual of the speculative part of the type
- */
-const TypeOopPtr* TypeOopPtr::dual_speculative() const {
-  if (_speculative == NULL) {
-    return NULL;
-  }
-  return _speculative->dual()->is_oopptr();
-}
-
-/**
- * add offset to the speculative part of the type
- *
- * @param offset  offset to add
- */
-const TypeOopPtr* TypeOopPtr::add_offset_speculative(intptr_t offset) const {
-  if (_speculative == NULL) {
-    return NULL;
-  }
-  return _speculative->add_offset(offset)->is_oopptr();
-}
-
-/**
- * Are the speculative parts of 2 types equal?
- *
- * @param other  type to compare this one to
- */
-bool TypeOopPtr::eq_speculative(const TypeOopPtr* other) const {
-  if (_speculative == NULL || other->speculative() == NULL) {
-    return _speculative == other->speculative();
-  }
-
-  if (_speculative->base() != other->speculative()->base()) {
+bool TypeOopPtr::would_improve_type(ciKlass* exact_kls, int inline_depth) const {
+  // no way to improve an already exact type
+  if (klass_is_exact()) {
     return false;
   }
-
-  return _speculative->eq(other->speculative());
-}
-
-/**
- * Hash of the speculative part of the type
- */
-int TypeOopPtr::hash_speculative() const {
-  if (_speculative == NULL) {
-    return 0;
-  }
-
-  return _speculative->hash();
-}
-
-/**
- * dual of the inline depth for this type (used for speculation)
- */
-int TypeOopPtr::dual_inline_depth() const {
-  return -inline_depth();
-}
-
-/**
- * meet of 2 inline depth (used for speculation)
- *
- * @param depth  depth to meet with
- */
-int TypeOopPtr::meet_inline_depth(int depth) const {
-  return MAX2(inline_depth(), depth);
+  return TypePtr::would_improve_type(exact_kls, inline_depth);
 }
 
 //=============================================================================
@@ -3120,8 +3265,10 @@
 const TypeInstPtr *TypeInstPtr::KLASS;
 
 //------------------------------TypeInstPtr-------------------------------------
-TypeInstPtr::TypeInstPtr(PTR ptr, ciKlass* k, bool xk, ciObject* o, int off, int instance_id, const TypeOopPtr* speculative, int inline_depth)
-  : TypeOopPtr(InstPtr, ptr, k, xk, o, off, instance_id, speculative, inline_depth), _name(k->name()) {
+TypeInstPtr::TypeInstPtr(PTR ptr, ciKlass* k, bool xk, ciObject* o, int off,
+                         int instance_id, const TypePtr* speculative, int inline_depth)
+  : TypeOopPtr(InstPtr, ptr, k, xk, o, off, instance_id, speculative, inline_depth),
+    _name(k->name()) {
    assert(k != NULL &&
           (k->is_loaded() || o == NULL),
           "cannot have constants with non-loaded klass");
@@ -3134,7 +3281,7 @@
                                      ciObject* o,
                                      int offset,
                                      int instance_id,
-                                     const TypeOopPtr* speculative,
+                                     const TypePtr* speculative,
                                      int inline_depth) {
   assert( !k->is_loaded() || k->is_instance_klass(), "Must be for instance");
   // Either const_oop() is NULL or else ptr is Constant
@@ -3217,7 +3364,7 @@
     int off = meet_offset(tinst->offset());
     PTR ptr = meet_ptr(tinst->ptr());
     int instance_id = meet_instance_id(tinst->instance_id());
-    const TypeOopPtr* speculative = xmeet_speculative(tinst);
+    const TypePtr* speculative = xmeet_speculative(tinst);
     int depth = meet_inline_depth(tinst->inline_depth());
 
     const TypeInstPtr *loaded    = is_loaded() ? this  : tinst;
@@ -3295,7 +3442,7 @@
     int offset = meet_offset(tp->offset());
     PTR ptr = meet_ptr(tp->ptr());
     int instance_id = meet_instance_id(tp->instance_id());
-    const TypeOopPtr* speculative = xmeet_speculative(tp);
+    const TypePtr* speculative = xmeet_speculative(tp);
     int depth = meet_inline_depth(tp->inline_depth());
     switch (ptr) {
     case TopPTR:
@@ -3346,7 +3493,7 @@
     case TopPTR:
     case AnyNull: {
       int instance_id = meet_instance_id(InstanceTop);
-      const TypeOopPtr* speculative = xmeet_speculative(tp);
+      const TypePtr* speculative = xmeet_speculative(tp);
       int depth = meet_inline_depth(tp->inline_depth());
       return make(ptr, klass(), klass_is_exact(),
                   (ptr == Constant ? const_oop() : NULL), offset, instance_id, speculative, depth);
@@ -3354,7 +3501,7 @@
     case NotNull:
     case BotPTR: {
       int instance_id = meet_instance_id(tp->instance_id());
-      const TypeOopPtr* speculative = xmeet_speculative(tp);
+      const TypePtr* speculative = xmeet_speculative(tp);
       int depth = meet_inline_depth(tp->inline_depth());
       return TypeOopPtr::make(ptr, offset, instance_id, speculative, depth);
     }
@@ -3367,20 +3514,21 @@
     const TypePtr *tp = t->is_ptr();
     int offset = meet_offset(tp->offset());
     PTR ptr = meet_ptr(tp->ptr());
+    int instance_id = meet_instance_id(InstanceTop);
+    const TypePtr* speculative = xmeet_speculative(tp);
+    int depth = meet_inline_depth(tp->inline_depth());
     switch (tp->ptr()) {
     case Null:
-      if( ptr == Null ) return TypePtr::make(AnyPtr, ptr, offset);
+      if( ptr == Null ) return TypePtr::make(AnyPtr, ptr, offset, speculative, depth);
       // else fall through to AnyNull
     case TopPTR:
     case AnyNull: {
-      int instance_id = meet_instance_id(InstanceTop);
-      const TypeOopPtr* speculative = _speculative;
       return make(ptr, klass(), klass_is_exact(),
-                  (ptr == Constant ? const_oop() : NULL), offset, instance_id, speculative, _inline_depth);
+                  (ptr == Constant ? const_oop() : NULL), offset, instance_id, speculative, depth);
     }
     case NotNull:
     case BotPTR:
-      return TypePtr::make(AnyPtr, ptr, offset);
+      return TypePtr::make(AnyPtr, ptr, offset, speculative,depth);
     default: typerr(t);
     }
   }
@@ -3407,7 +3555,7 @@
     int off = meet_offset( tinst->offset() );
     PTR ptr = meet_ptr( tinst->ptr() );
     int instance_id = meet_instance_id(tinst->instance_id());
-    const TypeOopPtr* speculative = xmeet_speculative(tinst);
+    const TypePtr* speculative = xmeet_speculative(tinst);
     int depth = meet_inline_depth(tinst->inline_depth());
 
     // Check for easy case; klasses are equal (and perhaps not loaded!)
@@ -3563,6 +3711,7 @@
     // class hierarchy - which means we have to fall to at least NotNull.
     if( ptr == TopPTR || ptr == AnyNull || ptr == Constant )
       ptr = NotNull;
+
     instance_id = InstanceBot;
 
     // Now we find the LCA of Java classes
@@ -3655,7 +3804,8 @@
 
 //------------------------------add_offset-------------------------------------
 const TypePtr *TypeInstPtr::add_offset(intptr_t offset) const {
-  return make(_ptr, klass(), klass_is_exact(), const_oop(), xadd_offset(offset), _instance_id, add_offset_speculative(offset));
+  return make(_ptr, klass(), klass_is_exact(), const_oop(), xadd_offset(offset),
+              _instance_id, add_offset_speculative(offset), _inline_depth);
 }
 
 const Type *TypeInstPtr::remove_speculative() const {
@@ -3663,10 +3813,11 @@
     return this;
   }
   assert(_inline_depth == InlineDepthTop || _inline_depth == InlineDepthBottom, "non speculative type shouldn't have inline depth");
-  return make(_ptr, klass(), klass_is_exact(), const_oop(), _offset, _instance_id, NULL, _inline_depth);
-}
-
-const TypeOopPtr *TypeInstPtr::with_inline_depth(int depth) const {
+  return make(_ptr, klass(), klass_is_exact(), const_oop(), _offset,
+              _instance_id, NULL, _inline_depth);
+}
+
+const TypePtr *TypeInstPtr::with_inline_depth(int depth) const {
   if (!UseInlineDepthForSpeculativeTypes) {
     return this;
   }
@@ -3687,7 +3838,8 @@
 const TypeAryPtr *TypeAryPtr::DOUBLES;
 
 //------------------------------make-------------------------------------------
-const TypeAryPtr *TypeAryPtr::make(PTR ptr, const TypeAry *ary, ciKlass* k, bool xk, int offset, int instance_id, const TypeOopPtr* speculative, int inline_depth) {
+const TypeAryPtr *TypeAryPtr::make(PTR ptr, const TypeAry *ary, ciKlass* k, bool xk, int offset,
+                                   int instance_id, const TypePtr* speculative, int inline_depth) {
   assert(!(k == NULL && ary->_elem->isa_int()),
          "integral arrays must be pre-equipped with a class");
   if (!xk)  xk = ary->ary_must_be_exact();
@@ -3697,7 +3849,9 @@
 }
 
 //------------------------------make-------------------------------------------
-const TypeAryPtr *TypeAryPtr::make(PTR ptr, ciObject* o, const TypeAry *ary, ciKlass* k, bool xk, int offset, int instance_id, const TypeOopPtr* speculative, int inline_depth, bool is_autobox_cache) {
+const TypeAryPtr *TypeAryPtr::make(PTR ptr, ciObject* o, const TypeAry *ary, ciKlass* k, bool xk, int offset,
+                                   int instance_id, const TypePtr* speculative, int inline_depth,
+                                   bool is_autobox_cache) {
   assert(!(k == NULL && ary->_elem->isa_int()),
          "integral arrays must be pre-equipped with a class");
   assert( (ptr==Constant && o) || (ptr!=Constant && !o), "" );
@@ -3807,7 +3961,7 @@
 
   const TypeAry* new_ary = TypeAry::make(elem, size(), stable);
 
-  return make(ptr(), const_oop(), new_ary, klass(), klass_is_exact(), _offset, _instance_id);
+  return make(ptr(), const_oop(), new_ary, klass(), klass_is_exact(), _offset, _instance_id, _speculative, _inline_depth);
 }
 
 //-----------------------------stable_dimension--------------------------------
@@ -3868,18 +4022,17 @@
     int offset = meet_offset(tp->offset());
     PTR ptr = meet_ptr(tp->ptr());
     int depth = meet_inline_depth(tp->inline_depth());
+    const TypePtr* speculative = xmeet_speculative(tp);
     switch (tp->ptr()) {
     case TopPTR:
     case AnyNull: {
       int instance_id = meet_instance_id(InstanceTop);
-      const TypeOopPtr* speculative = xmeet_speculative(tp);
       return make(ptr, (ptr == Constant ? const_oop() : NULL),
                   _ary, _klass, _klass_is_exact, offset, instance_id, speculative, depth);
     }
     case BotPTR:
     case NotNull: {
       int instance_id = meet_instance_id(tp->instance_id());
-      const TypeOopPtr* speculative = xmeet_speculative(tp);
       return TypeOopPtr::make(ptr, offset, instance_id, speculative, depth);
     }
     default: ShouldNotReachHere();
@@ -3891,20 +4044,21 @@
     const TypePtr *tp = t->is_ptr();
     int offset = meet_offset(tp->offset());
     PTR ptr = meet_ptr(tp->ptr());
+    const TypePtr* speculative = xmeet_speculative(tp);
+    int depth = meet_inline_depth(tp->inline_depth());
     switch (tp->ptr()) {
     case TopPTR:
       return this;
     case BotPTR:
     case NotNull:
-      return TypePtr::make(AnyPtr, ptr, offset);
+      return TypePtr::make(AnyPtr, ptr, offset, speculative, depth);
     case Null:
-      if( ptr == Null ) return TypePtr::make(AnyPtr, ptr, offset);
+      if( ptr == Null ) return TypePtr::make(AnyPtr, ptr, offset, speculative, depth);
       // else fall through to AnyNull
     case AnyNull: {
       int instance_id = meet_instance_id(InstanceTop);
-      const TypeOopPtr* speculative = _speculative;
       return make(ptr, (ptr == Constant ? const_oop() : NULL),
-                  _ary, _klass, _klass_is_exact, offset, instance_id, speculative, _inline_depth);
+                  _ary, _klass, _klass_is_exact, offset, instance_id, speculative, depth);
     }
     default: ShouldNotReachHere();
     }
@@ -3920,7 +4074,7 @@
     const TypeAry *tary = _ary->meet_speculative(tap->_ary)->is_ary();
     PTR ptr = meet_ptr(tap->ptr());
     int instance_id = meet_instance_id(tap->instance_id());
-    const TypeOopPtr* speculative = xmeet_speculative(tap);
+    const TypePtr* speculative = xmeet_speculative(tap);
     int depth = meet_inline_depth(tap->inline_depth());
     ciKlass* lazy_klass = NULL;
     if (tary->_elem->isa_int()) {
@@ -3949,7 +4103,7 @@
            // 'this' is exact and super or unrelated:
            (this->_klass_is_exact && !klass()->is_subtype_of(tap->klass())))) {
       tary = TypeAry::make(Type::BOTTOM, tary->_size, tary->_stable);
-      return make(NotNull, NULL, tary, lazy_klass, false, off, InstanceBot);
+      return make(NotNull, NULL, tary, lazy_klass, false, off, InstanceBot, speculative, depth);
     }
 
     bool xk = false;
@@ -4001,7 +4155,7 @@
     int offset = meet_offset(tp->offset());
     PTR ptr = meet_ptr(tp->ptr());
     int instance_id = meet_instance_id(tp->instance_id());
-    const TypeOopPtr* speculative = xmeet_speculative(tp);
+    const TypePtr* speculative = xmeet_speculative(tp);
     int depth = meet_inline_depth(tp->inline_depth());
     switch (ptr) {
     case TopPTR:
@@ -4125,7 +4279,7 @@
   return make(_ptr, _const_oop, _ary->remove_speculative()->is_ary(), _klass, _klass_is_exact, _offset, _instance_id, NULL, _inline_depth);
 }
 
-const TypeOopPtr *TypeAryPtr::with_inline_depth(int depth) const {
+const TypePtr *TypeAryPtr::with_inline_depth(int depth) const {
   if (!UseInlineDepthForSpeculativeTypes) {
     return this;
   }
@@ -4250,6 +4404,13 @@
   return (const TypeNarrowOop*)(new TypeNarrowOop(type))->hashcons();
 }
 
+const Type* TypeNarrowOop::remove_speculative() const {
+  return make(_ptrtype->remove_speculative()->is_ptr());
+}
+
+const Type* TypeNarrowOop::cleanup_speculative() const {
+  return make(_ptrtype->cleanup_speculative()->is_ptr());
+}
 
 #ifndef PRODUCT
 void TypeNarrowOop::dump2( Dict & d, uint depth, outputStream *st ) const {
@@ -4376,7 +4537,7 @@
     PTR ptr = meet_ptr(tp->ptr());
     switch (tp->ptr()) {
     case Null:
-      if (ptr == Null)  return TypePtr::make(AnyPtr, ptr, offset);
+      if (ptr == Null)  return TypePtr::make(AnyPtr, ptr, offset, tp->speculative(), tp->inline_depth());
       // else fall through:
     case TopPTR:
     case AnyNull: {
@@ -4384,7 +4545,7 @@
     }
     case BotPTR:
     case NotNull:
-      return TypePtr::make(AnyPtr, ptr, offset);
+      return TypePtr::make(AnyPtr, ptr, offset, tp->speculative(), tp->inline_depth());
     default: typerr(t);
     }
   }
@@ -4698,12 +4859,12 @@
     case TopPTR:
       return this;
     case Null:
-      if( ptr == Null ) return TypePtr::make( AnyPtr, ptr, offset );
+      if( ptr == Null ) return TypePtr::make(AnyPtr, ptr, offset, tp->speculative(), tp->inline_depth());
     case AnyNull:
       return make( ptr, klass(), offset );
     case BotPTR:
     case NotNull:
-      return TypePtr::make(AnyPtr, ptr, offset);
+      return TypePtr::make(AnyPtr, ptr, offset, tp->speculative(), tp->inline_depth());
     default: typerr(t);
     }
   }
--- a/hotspot/src/share/vm/opto/type.hpp	Sat Mar 29 14:54:48 2014 +0400
+++ b/hotspot/src/share/vm/opto/type.hpp	Mon Mar 31 09:08:53 2014 +0200
@@ -224,7 +224,7 @@
   }
   // Variant that keeps the speculative part of the types
   const Type *meet_speculative(const Type *t) const {
-    return meet_helper(t, true);
+    return meet_helper(t, true)->cleanup_speculative();
   }
   // WIDEN: 'widens' for Ints and other range types
   virtual const Type *widen( const Type *old, const Type* limit ) const { return this; }
@@ -247,7 +247,7 @@
   }
   // Variant that keeps the speculative part of the types
   const Type *join_speculative(const Type *t) const {
-    return join_helper(t, true);
+    return join_helper(t, true)->cleanup_speculative();
   }
 
   // Modified version of JOIN adapted to the needs Node::Value.
@@ -259,7 +259,7 @@
   }
   // Variant that keeps the speculative part of the types
   const Type *filter_speculative(const Type *kills) const {
-    return filter_helper(kills, true);
+    return filter_helper(kills, true)->cleanup_speculative();
   }
 
 #ifdef ASSERT
@@ -414,15 +414,18 @@
                                         bool require_constant = false,
                                         bool is_autobox_cache = false);
 
-  // Speculative type. See TypeInstPtr
-  virtual const TypeOopPtr* speculative() const { return NULL; }
-  virtual ciKlass* speculative_type() const { return NULL; }
+  // Speculative type helper methods. See TypePtr.
+  virtual const TypePtr* speculative() const                                  { return NULL; }
+  virtual ciKlass* speculative_type() const                                   { return NULL; }
+  virtual ciKlass* speculative_type_not_null() const                          { return NULL; }
+  virtual bool speculative_maybe_null() const                                 { return true; }
+  virtual const Type* remove_speculative() const                              { return this; }
+  virtual const Type* cleanup_speculative() const                             { return this; }
+  virtual bool would_improve_type(ciKlass* exact_kls, int inline_depth) const { return exact_kls != NULL; }
+  virtual bool would_improve_ptr(bool maybe_null) const                       { return !maybe_null; }
   const Type* maybe_remove_speculative(bool include_speculative) const;
-  virtual const Type* remove_speculative() const { return this; }
 
-  virtual bool would_improve_type(ciKlass* exact_kls, int inline_depth) const {
-    return exact_kls != NULL;
-  }
+  virtual bool maybe_null() const { return true; }
 
 private:
   // support arrays
@@ -679,6 +682,7 @@
   virtual const Type *xdual() const;    // Compute dual right now.
   bool ary_must_be_exact() const;  // true if arrays of such are never generic
   virtual const Type* remove_speculative() const;
+  virtual const Type* cleanup_speculative() const;
 #ifdef ASSERT
   // One type is interface, the other is oop
   virtual bool interface_vs_oop(const Type *t) const;
@@ -761,13 +765,48 @@
 public:
   enum PTR { TopPTR, AnyNull, Constant, Null, NotNull, BotPTR, lastPTR };
 protected:
-  TypePtr( TYPES t, PTR ptr, int offset ) : Type(t), _ptr(ptr), _offset(offset) {}
-  virtual bool eq( const Type *t ) const;
-  virtual int  hash() const;             // Type specific hashing
+  TypePtr(TYPES t, PTR ptr, int offset,
+          const TypePtr* speculative = NULL,
+          int inline_depth = InlineDepthBottom) :
+    Type(t), _ptr(ptr), _offset(offset), _speculative(speculative),
+    _inline_depth(inline_depth) {}
   static const PTR ptr_meet[lastPTR][lastPTR];
   static const PTR ptr_dual[lastPTR];
   static const char * const ptr_msg[lastPTR];
 
+  enum {
+    InlineDepthBottom = INT_MAX,
+    InlineDepthTop = -InlineDepthBottom
+  };
+
+  // Extra type information profiling gave us. We propagate it the
+  // same way the rest of the type info is propagated. If we want to
+  // use it, then we have to emit a guard: this part of the type is
+  // not something we know but something we speculate about the type.
+  const TypePtr*   _speculative;
+  // For speculative types, we record at what inlining depth the
+  // profiling point that provided the data is. We want to favor
+  // profile data coming from outer scopes which are likely better for
+  // the current compilation.
+  int _inline_depth;
+
+  // utility methods to work on the speculative part of the type
+  const TypePtr* dual_speculative() const;
+  const TypePtr* xmeet_speculative(const TypePtr* other) const;
+  bool eq_speculative(const TypePtr* other) const;
+  int hash_speculative() const;
+  const TypePtr* add_offset_speculative(intptr_t offset) const;
+#ifndef PRODUCT
+  void dump_speculative(outputStream *st) const;
+#endif
+
+  // utility methods to work on the inline depth of the type
+  int dual_inline_depth() const;
+  int meet_inline_depth(int depth) const;
+#ifndef PRODUCT
+  void dump_inline_depth(outputStream *st) const;
+#endif
+
 public:
   const int _offset;            // Offset into oop, with TOP & BOT
   const PTR _ptr;               // Pointer equivalence class
@@ -775,7 +814,9 @@
   const int offset() const { return _offset; }
   const PTR ptr()    const { return _ptr; }
 
-  static const TypePtr *make( TYPES t, PTR ptr, int offset );
+  static const TypePtr *make(TYPES t, PTR ptr, int offset,
+                             const TypePtr* speculative = NULL,
+                             int inline_depth = InlineDepthBottom);
 
   // Return a 'ptr' version of this type
   virtual const Type *cast_to_ptr_type(PTR ptr) const;
@@ -784,10 +825,13 @@
 
   int xadd_offset( intptr_t offset ) const;
   virtual const TypePtr *add_offset( intptr_t offset ) const;
+  virtual bool eq(const Type *t) const;
+  virtual int  hash() const;             // Type specific hashing
 
   virtual bool singleton(void) const;    // TRUE if type is a singleton
   virtual bool empty(void) const;        // TRUE if type is vacuous
   virtual const Type *xmeet( const Type *t ) const;
+  virtual const Type *xmeet_helper( const Type *t ) const;
   int meet_offset( int offset ) const;
   int dual_offset( ) const;
   virtual const Type *xdual() const;    // Compute dual right now.
@@ -802,6 +846,20 @@
     return ptr_dual[ ptr_meet[ ptr_dual[in_ptr] ] [ dual_ptr() ] ];
   }
 
+  // Speculative type helper methods.
+  virtual const TypePtr* speculative() const { return _speculative; }
+  int inline_depth() const                   { return _inline_depth; }
+  virtual ciKlass* speculative_type() const;
+  virtual ciKlass* speculative_type_not_null() const;
+  virtual bool speculative_maybe_null() const;
+  virtual const Type* remove_speculative() const;
+  virtual const Type* cleanup_speculative() const;
+  virtual bool would_improve_type(ciKlass* exact_kls, int inline_depth) const;
+  virtual bool would_improve_ptr(bool maybe_null) const;
+  virtual const TypePtr* with_inline_depth(int depth) const;
+
+  virtual bool maybe_null() const { return meet_ptr(Null) == ptr(); }
+
   // Tests for relation to centerline of type lattice:
   static bool above_centerline(PTR ptr) { return (ptr <= AnyNull); }
   static bool below_centerline(PTR ptr) { return (ptr >= NotNull); }
@@ -850,7 +908,8 @@
 // Some kind of oop (Java pointer), either klass or instance or array.
 class TypeOopPtr : public TypePtr {
 protected:
-  TypeOopPtr(TYPES t, PTR ptr, ciKlass* k, bool xk, ciObject* o, int offset, int instance_id, const TypeOopPtr* speculative, int inline_depth);
+  TypeOopPtr(TYPES t, PTR ptr, ciKlass* k, bool xk, ciObject* o, int offset, int instance_id,
+             const TypePtr* speculative, int inline_depth);
 public:
   virtual bool eq( const Type *t ) const;
   virtual int  hash() const;             // Type specific hashing
@@ -861,10 +920,6 @@
   };
 protected:
 
-  enum {
-    InlineDepthBottom = INT_MAX,
-    InlineDepthTop = -InlineDepthBottom
-  };
   // Oop is NULL, unless this is a constant oop.
   ciObject*     _const_oop;   // Constant oop
   // If _klass is NULL, then so is _sig.  This is an unloaded klass.
@@ -880,38 +935,11 @@
   // This is the the node index of the allocation node creating this instance.
   int           _instance_id;
 
-  // Extra type information profiling gave us. We propagate it the
-  // same way the rest of the type info is propagated. If we want to
-  // use it, then we have to emit a guard: this part of the type is
-  // not something we know but something we speculate about the type.
-  const TypeOopPtr*   _speculative;
-  // For speculative types, we record at what inlining depth the
-  // profiling point that provided the data is. We want to favor
-  // profile data coming from outer scopes which are likely better for
-  // the current compilation.
-  int _inline_depth;
-
   static const TypeOopPtr* make_from_klass_common(ciKlass* klass, bool klass_change, bool try_for_exact);
 
   int dual_instance_id() const;
   int meet_instance_id(int uid) const;
 
-  // utility methods to work on the speculative part of the type
-  const TypeOopPtr* dual_speculative() const;
-  const TypeOopPtr* xmeet_speculative(const TypeOopPtr* other) const;
-  bool eq_speculative(const TypeOopPtr* other) const;
-  int hash_speculative() const;
-  const TypeOopPtr* add_offset_speculative(intptr_t offset) const;
-#ifndef PRODUCT
-  void dump_speculative(outputStream *st) const;
-#endif
-  // utility methods to work on the inline depth of the type
-  int dual_inline_depth() const;
-  int meet_inline_depth(int depth) const;
-#ifndef PRODUCT
-  void dump_inline_depth(outputStream *st) const;
-#endif
-
   // Do not allow interface-vs.-noninterface joins to collapse to top.
   virtual const Type *filter_helper(const Type *kills, bool include_speculative) const;
 
@@ -941,7 +969,9 @@
                                               bool not_null_elements = false);
 
   // Make a generic (unclassed) pointer to an oop.
-  static const TypeOopPtr* make(PTR ptr, int offset, int instance_id, const TypeOopPtr* speculative = NULL, int inline_depth = InlineDepthBottom);
+  static const TypeOopPtr* make(PTR ptr, int offset, int instance_id,
+                                const TypePtr* speculative = NULL,
+                                int inline_depth = InlineDepthBottom);
 
   ciObject* const_oop()    const { return _const_oop; }
   virtual ciKlass* klass() const { return _klass;     }
@@ -955,7 +985,6 @@
   bool is_known_instance()       const { return _instance_id > 0; }
   int  instance_id()             const { return _instance_id; }
   bool is_known_instance_field() const { return is_known_instance() && _offset >= 0; }
-  virtual const TypeOopPtr* speculative() const { return _speculative; }
 
   virtual intptr_t get_con() const;
 
@@ -969,10 +998,13 @@
   const TypeKlassPtr* as_klass_type() const;
 
   virtual const TypePtr *add_offset( intptr_t offset ) const;
-  // Return same type without a speculative part
+
+  // Speculative type helper methods.
   virtual const Type* remove_speculative() const;
+  virtual const Type* cleanup_speculative() const;
+  virtual bool would_improve_type(ciKlass* exact_kls, int inline_depth) const;
+  virtual const TypePtr* with_inline_depth(int depth) const;
 
-  virtual const Type *xmeet(const Type *t) const;
   virtual const Type *xdual() const;    // Compute dual right now.
   // the core of the computation of the meet for TypeOopPtr and for its subclasses
   virtual const Type *xmeet_helper(const Type *t) const;
@@ -982,29 +1014,14 @@
 #ifndef PRODUCT
   virtual void dump2( Dict &d, uint depth, outputStream *st ) const;
 #endif
-
-  // Return the speculative type if any
-  ciKlass* speculative_type() const {
-    if (_speculative != NULL) {
-      const TypeOopPtr* speculative = _speculative->join(this)->is_oopptr();
-      if (speculative->klass_is_exact()) {
-        return speculative->klass();
-      }
-    }
-    return NULL;
-  }
-  int inline_depth() const {
-    return _inline_depth;
-  }
-  virtual const TypeOopPtr* with_inline_depth(int depth) const;
-  virtual bool would_improve_type(ciKlass* exact_kls, int inline_depth) const;
 };
 
 //------------------------------TypeInstPtr------------------------------------
 // Class of Java object pointers, pointing either to non-array Java instances
 // or to a Klass* (including array klasses).
 class TypeInstPtr : public TypeOopPtr {
-  TypeInstPtr(PTR ptr, ciKlass* k, bool xk, ciObject* o, int offset, int instance_id, const TypeOopPtr* speculative, int inline_depth);
+  TypeInstPtr(PTR ptr, ciKlass* k, bool xk, ciObject* o, int offset, int instance_id,
+              const TypePtr* speculative, int inline_depth);
   virtual bool eq( const Type *t ) const;
   virtual int  hash() const;             // Type specific hashing
 
@@ -1040,7 +1057,10 @@
   }
 
   // Make a pointer to an oop.
-  static const TypeInstPtr *make(PTR ptr, ciKlass* k, bool xk, ciObject* o, int offset, int instance_id = InstanceBot, const TypeOopPtr* speculative = NULL, int inline_depth = InlineDepthBottom);
+  static const TypeInstPtr *make(PTR ptr, ciKlass* k, bool xk, ciObject* o, int offset,
+                                 int instance_id = InstanceBot,
+                                 const TypePtr* speculative = NULL,
+                                 int inline_depth = InlineDepthBottom);
 
   /** Create constant type for a constant boxed value */
   const Type* get_const_boxed_value() const;
@@ -1057,9 +1077,10 @@
   virtual const TypeOopPtr *cast_to_instance_id(int instance_id) const;
 
   virtual const TypePtr *add_offset( intptr_t offset ) const;
-  // Return same type without a speculative part
+
+  // Speculative type helper methods.
   virtual const Type* remove_speculative() const;
-  virtual const TypeOopPtr* with_inline_depth(int depth) const;
+  virtual const TypePtr* with_inline_depth(int depth) const;
 
   // the core of the computation of the meet of 2 types
   virtual const Type *xmeet_helper(const Type *t) const;
@@ -1081,7 +1102,8 @@
 // Class of Java array pointers
 class TypeAryPtr : public TypeOopPtr {
   TypeAryPtr( PTR ptr, ciObject* o, const TypeAry *ary, ciKlass* k, bool xk,
-              int offset, int instance_id, bool is_autobox_cache, const TypeOopPtr* speculative, int inline_depth)
+              int offset, int instance_id, bool is_autobox_cache,
+              const TypePtr* speculative, int inline_depth)
     : TypeOopPtr(AryPtr,ptr,k,xk,o,offset, instance_id, speculative, inline_depth),
     _ary(ary),
     _is_autobox_cache(is_autobox_cache)
@@ -1120,9 +1142,15 @@
 
   bool is_autobox_cache() const { return _is_autobox_cache; }
 
-  static const TypeAryPtr *make( PTR ptr, const TypeAry *ary, ciKlass* k, bool xk, int offset, int instance_id = InstanceBot, const TypeOopPtr* speculative = NULL, int inline_depth = InlineDepthBottom);
+  static const TypeAryPtr *make(PTR ptr, const TypeAry *ary, ciKlass* k, bool xk, int offset,
+                                int instance_id = InstanceBot,
+                                const TypePtr* speculative = NULL,
+                                int inline_depth = InlineDepthBottom);
   // Constant pointer to array
-  static const TypeAryPtr *make( PTR ptr, ciObject* o, const TypeAry *ary, ciKlass* k, bool xk, int offset, int instance_id = InstanceBot, const TypeOopPtr* speculative = NULL, int inline_depth = InlineDepthBottom, bool is_autobox_cache= false);
+  static const TypeAryPtr *make(PTR ptr, ciObject* o, const TypeAry *ary, ciKlass* k, bool xk, int offset,
+                                int instance_id = InstanceBot,
+                                const TypePtr* speculative = NULL,
+                                int inline_depth = InlineDepthBottom, bool is_autobox_cache = false);
 
   // Return a 'ptr' version of this type
   virtual const Type *cast_to_ptr_type(PTR ptr) const;
@@ -1136,9 +1164,10 @@
 
   virtual bool empty(void) const;        // TRUE if type is vacuous
   virtual const TypePtr *add_offset( intptr_t offset ) const;
-  // Return same type without a speculative part
+
+  // Speculative type helper methods.
   virtual const Type* remove_speculative() const;
-  virtual const TypeOopPtr* with_inline_depth(int depth) const;
+  virtual const TypePtr* with_inline_depth(int depth) const;
 
   // the core of the computation of the meet of 2 types
   virtual const Type *xmeet_helper(const Type *t) const;
@@ -1367,9 +1396,8 @@
   static const TypeNarrowOop *BOTTOM;
   static const TypeNarrowOop *NULL_PTR;
 
-  virtual const Type* remove_speculative() const {
-    return make(_ptrtype->remove_speculative()->is_ptr());
-  }
+  virtual const Type* remove_speculative() const;
+  virtual const Type* cleanup_speculative() const;
 
 #ifndef PRODUCT
   virtual void dump2( Dict &d, uint depth, outputStream *st ) const;
--- a/hotspot/src/share/vm/runtime/arguments.cpp	Sat Mar 29 14:54:48 2014 +0400
+++ b/hotspot/src/share/vm/runtime/arguments.cpp	Mon Mar 31 09:08:53 2014 +0200
@@ -3801,10 +3801,6 @@
     AlwaysIncrementalInline = false;
   }
 #endif
-  if (IncrementalInline && FLAG_IS_DEFAULT(MaxNodeLimit)) {
-    // incremental inlining: bump MaxNodeLimit
-    FLAG_SET_DEFAULT(MaxNodeLimit, (intx)75000);
-  }
   if (!UseTypeSpeculation && FLAG_IS_DEFAULT(TypeProfileLevel)) {
     // nothing to use the profiling, turn if off
     FLAG_SET_DEFAULT(TypeProfileLevel, 0);
--- a/hotspot/src/share/vm/runtime/deoptimization.cpp	Sat Mar 29 14:54:48 2014 +0400
+++ b/hotspot/src/share/vm/runtime/deoptimization.cpp	Mon Mar 31 09:08:53 2014 +0200
@@ -1839,6 +1839,7 @@
   "predicate",
   "loop_limit_check",
   "speculate_class_check",
+  "speculate_null_check",
   "rtm_state_change"
 };
 const char* Deoptimization::_trap_action_name[Action_LIMIT] = {
--- a/hotspot/src/share/vm/runtime/deoptimization.hpp	Sat Mar 29 14:54:48 2014 +0400
+++ b/hotspot/src/share/vm/runtime/deoptimization.hpp	Mon Mar 31 09:08:53 2014 +0200
@@ -60,6 +60,7 @@
     Reason_predicate,             // compiler generated predicate failed
     Reason_loop_limit_check,      // compiler generated loop limits check failed
     Reason_speculate_class_check, // saw unexpected object class from type speculation
+    Reason_speculate_null_check,  // saw unexpected null from type speculation
     Reason_rtm_state_change,      // rtm state change detected
     Reason_LIMIT,
     // Note:  Keep this enum in sync. with _trap_reason_name.
@@ -315,17 +316,27 @@
       return Reason_null_check;           // recorded per BCI as a null check
     else if (reason == Reason_speculate_class_check)
       return Reason_class_check;
+    else if (reason == Reason_speculate_null_check)
+      return Reason_null_check;
     else
       return Reason_none;
   }
 
   static bool reason_is_speculate(int reason) {
-    if (reason == Reason_speculate_class_check) {
+    if (reason == Reason_speculate_class_check || reason == Reason_speculate_null_check) {
       return true;
     }
     return false;
   }
 
+  static DeoptReason reason_null_check(bool speculative) {
+    return speculative ? Deoptimization::Reason_speculate_null_check : Deoptimization::Reason_null_check;
+  }
+
+  static DeoptReason reason_class_check(bool speculative) {
+    return speculative ? Deoptimization::Reason_speculate_class_check : Deoptimization::Reason_class_check;
+  }
+
   static uint per_method_trap_limit(int reason) {
     return reason_is_speculate(reason) ? (uint)PerMethodSpecTrapLimit : (uint)PerMethodTrapLimit;
   }