< prev index next >

src/share/vm/runtime/deoptimization.hpp

Print this page

        

@@ -39,19 +39,32 @@
  public:
   // What condition caused the deoptimization?
   enum DeoptReason {
     Reason_many = -1,             // indicates presence of several reasons
     Reason_none = 0,              // indicates absence of a relevant deopt.
-    // Next 7 reasons are recorded per bytecode in DataLayout::trap_bits
+    // Next 7 reasons are recorded per bytecode in DataLayout::trap_bits.
+    // This is more complicated for JVMCI as JVMCI may deoptimize to *some* bytecode before the
+    // bytecode that actually caused the deopt (with inlining, JVMCI may even deoptimize to a
+    // bytecode in another method):
+    //  - bytecode y in method b() causes deopt
+    //  - JVMCI deoptimizes to bytecode x in method a()
+    // -> the deopt reason will be recorded for method a() at bytecode x
     Reason_null_check,            // saw unexpected null or zero divisor (@bci)
     Reason_null_assert,           // saw unexpected non-null or non-zero (@bci)
     Reason_range_check,           // saw unexpected array index (@bci)
     Reason_class_check,           // saw unexpected object class (@bci)
     Reason_array_check,           // saw unexpected array class (aastore @bci)
     Reason_intrinsic,             // saw unexpected operand to intrinsic (@bci)
     Reason_bimorphic,             // saw unexpected object class in bimorphic inlining (@bci)
 
+#if INCLUDE_JVMCI
+    Reason_unreached0             = Reason_null_assert,
+    Reason_type_checked_inlining  = Reason_intrinsic,
+    Reason_optimized_type_check   = Reason_bimorphic,
+#endif
+
+    // recorded per method
     Reason_unloaded,              // unloaded class or constant pool entry
     Reason_uninitialized,         // bad class state (uninitialized)
     Reason_unreached,             // code is not reached, compiler
     Reason_unhandled,             // arbitrary compiler limitation
     Reason_constraint,            // arbitrary runtime constraint violated

@@ -62,15 +75,23 @@
     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_unstable_if,           // a branch predicted always false was taken
     Reason_unstable_fused_if,     // fused two ifs that had each one untaken branch. One is now taken.
+#if INCLUDE_JVMCI
+    Reason_aliasing,              // optimistic assumption about aliasing failed
+    Reason_transfer_to_interpreter, // explicit transferToInterpreter()
+    Reason_not_compiled_exception_handler,
+    Reason_unresolved,
+    Reason_jsr_mismatch,
+#endif
 
     // Reason_tenured is counted separately, add normal counted Reasons above.
     // Related to MethodData::_trap_hist_limit where Reason_tenured isn't included
     Reason_tenured,               // age of the code has reached the limit
     Reason_LIMIT,
+
     // Note:  Keep this enum in sync. with _trap_reason_name.
     Reason_RECORDED_LIMIT = Reason_bimorphic  // some are not recorded per bc
     // Note:  Reason_RECORDED_LIMIT should be < 8 to fit into 3 bits of
     // DataLayout::trap_bits.  This dependency is enforced indirectly
     // via asserts, to avoid excessive direct header-to-header dependencies.

@@ -89,12 +110,14 @@
   };
 
   enum {
     _action_bits = 3,
     _reason_bits = 5,
+    _debug_id_bits = 23,
     _action_shift = 0,
     _reason_shift = _action_shift+_action_bits,
+    _debug_id_shift = _reason_shift+_reason_bits,
     BC_CASE_LIMIT = PRODUCT_ONLY(1) NOT_PRODUCT(4) // for _deoptimization_hist
   };
 
   enum UnpackType {
     Unpack_deopt                = 0, // normal deoptimization, use pc computed in unpack_vframe_on_stack

@@ -107,41 +130,45 @@
   // corresponding activations are deoptimized.
   static int deoptimize_dependents();
 
   // Deoptimizes a frame lazily. nmethod gets patched deopt happens on return to the frame
   static void deoptimize(JavaThread* thread, frame fr, RegisterMap *reg_map);
+  static void deoptimize(JavaThread* thread, frame fr, RegisterMap *reg_map, DeoptReason reason);
 
   private:
   // Does the actual work for deoptimizing a single frame
-  static void deoptimize_single_frame(JavaThread* thread, frame fr);
+  static void deoptimize_single_frame(JavaThread* thread, frame fr, DeoptReason reason);
 
   // Helper function to revoke biases of all monitors in frame if UseBiasedLocking
   // is enabled
   static void revoke_biases_of_monitors(JavaThread* thread, frame fr, RegisterMap* map);
   // Helper function to revoke biases of all monitors in frames
   // executing in a particular CodeBlob if UseBiasedLocking is enabled
   static void revoke_biases_of_monitors(CodeBlob* cb);
 
-#ifdef COMPILER2
+#if defined(COMPILER2) || INCLUDE_JVMCI
+JVMCI_ONLY(public:)
+
   // Support for restoring non-escaping objects
   static bool realloc_objects(JavaThread* thread, frame* fr, GrowableArray<ScopeValue*>* objects, TRAPS);
   static void reassign_type_array_elements(frame* fr, RegisterMap* reg_map, ObjectValue* sv, typeArrayOop obj, BasicType type);
   static void reassign_object_array_elements(frame* fr, RegisterMap* reg_map, ObjectValue* sv, objArrayOop obj);
-  static void reassign_fields(frame* fr, RegisterMap* reg_map, GrowableArray<ScopeValue*>* objects, bool realloc_failures);
+  static void reassign_fields(frame* fr, RegisterMap* reg_map, GrowableArray<ScopeValue*>* objects, bool realloc_failures, bool skip_internal);
   static void relock_objects(GrowableArray<MonitorInfo*>* monitors, JavaThread* thread, bool realloc_failures);
   static void pop_frames_failed_reallocs(JavaThread* thread, vframeArray* array);
   NOT_PRODUCT(static void print_objects(GrowableArray<ScopeValue*>* objects, bool realloc_failures);)
-#endif // COMPILER2
+#endif // COMPILER2 || INCLUDE_JVMCI
 
   public:
   static vframeArray* create_vframeArray(JavaThread* thread, frame fr, RegisterMap *reg_map, GrowableArray<compiledVFrame*>* chunk, bool realloc_failures);
 
   // Interface used for unpacking deoptimized frames
 
   // UnrollBlock is returned by fetch_unroll_info() to the deoptimization handler (blob).
   // This is only a CheapObj to ease debugging after a deopt failure
   class UnrollBlock : public CHeapObj<mtCompiler> {
+    friend class VMStructs;
    private:
     int       _size_of_deoptimized_frame; // Size, in bytes, of current deoptimized frame
     int       _caller_adjustment;         // Adjustment, in bytes, to caller's SP by initial interpreted frame
     int       _number_of_frames;          // Number frames to unroll
     int       _total_frame_sizes;         // Total of number*sizes frames

@@ -241,14 +268,15 @@
 
   //** Deoptimizes the frame identified by id.
   // Only called from VMDeoptimizeFrame
   // @argument thread.     Thread where stub_frame resides.
   // @argument id.         id of frame that should be deoptimized.
-  static void deoptimize_frame_internal(JavaThread* thread, intptr_t* id);
+  static void deoptimize_frame_internal(JavaThread* thread, intptr_t* id, DeoptReason reason);
 
-  // If thread is not the current thread then execute
+  // if thread is not the current thread then execute
   // VM_DeoptimizeFrame otherwise deoptimize directly.
+  static void deoptimize_frame(JavaThread* thread, intptr_t* id, DeoptReason reason);
   static void deoptimize_frame(JavaThread* thread, intptr_t* id);
 
   // Statistics
   static void gather_statistics(DeoptReason reason, DeoptAction action,
                                 Bytecodes::Code bc = Bytecodes::_illegal);

@@ -274,10 +302,18 @@
         ((~(trap_request) >> _action_shift) & right_n_bits(_action_bits));
     else
       // standard action for unloaded CP entry
       return _unloaded_action;
   }
+  static int trap_request_debug_id(int trap_request) {
+    if (trap_request < 0) {
+      return ((~(trap_request) >> _debug_id_shift) & right_n_bits(_debug_id_bits));
+    } else {
+      // standard action for unloaded CP entry
+      return 0;
+    }
+  }
   static int trap_request_index(int trap_request) {
     if (trap_request < 0)
       return -1;
     else
       return trap_request;

@@ -372,10 +408,14 @@
  private:
   // Update the mdo's count and per-BCI reason bits, returning previous state:
   static ProfileData* query_update_method_data(MethodData* trap_mdo,
                                                int trap_bci,
                                                DeoptReason reason,
+                                               bool update_total_trap_count,
+#if INCLUDE_JVMCI
+                                               bool is_osr,
+#endif
                                                Method* compiled_method,
                                                //outputs:
                                                uint& ret_this_trap_count,
                                                bool& ret_maybe_prior_trap,
                                                bool& ret_maybe_prior_recompile);
< prev index next >