src/share/vm/runtime/deoptimization.hpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Sdiff src/share/vm/runtime

src/share/vm/runtime/deoptimization.hpp

Print this page
rev 5771 : 8031752: Failed speculative optimizations should be reattempted when root of compilation is different
Summary: support for speculative traps that keep track of the root of the compilation in which a trap occurs.
Reviewed-by:


  42     Reason_many = -1,             // indicates presence of several reasons
  43     Reason_none = 0,              // indicates absence of a relevant deopt.
  44     // Next 7 reasons are recorded per bytecode in DataLayout::trap_bits
  45     Reason_null_check,            // saw unexpected null or zero divisor (@bci)
  46     Reason_null_assert,           // saw unexpected non-null or non-zero (@bci)
  47     Reason_range_check,           // saw unexpected array index (@bci)
  48     Reason_class_check,           // saw unexpected object class (@bci)
  49     Reason_array_check,           // saw unexpected array class (aastore @bci)
  50     Reason_intrinsic,             // saw unexpected operand to intrinsic (@bci)
  51     Reason_bimorphic,             // saw unexpected object class in bimorphic inlining (@bci)
  52 
  53     Reason_unloaded,              // unloaded class or constant pool entry
  54     Reason_uninitialized,         // bad class state (uninitialized)
  55     Reason_unreached,             // code is not reached, compiler
  56     Reason_unhandled,             // arbitrary compiler limitation
  57     Reason_constraint,            // arbitrary runtime constraint violated
  58     Reason_div0_check,            // a null_check due to division by zero
  59     Reason_age,                   // nmethod too old; tier threshold reached
  60     Reason_predicate,             // compiler generated predicate failed
  61     Reason_loop_limit_check,      // compiler generated loop limits check failed

  62     Reason_LIMIT,
  63     // Note:  Keep this enum in sync. with _trap_reason_name.
  64     Reason_RECORDED_LIMIT = Reason_bimorphic  // some are not recorded per bc
  65     // Note:  Reason_RECORDED_LIMIT should be < 8 to fit into 3 bits of
  66     // DataLayout::trap_bits.  This dependency is enforced indirectly
  67     // via asserts, to avoid excessive direct header-to-header dependencies.
  68     // See Deoptimization::trap_state_reason and class DataLayout.
  69   };
  70 
  71   // What action must be taken by the runtime?
  72   enum DeoptAction {
  73     Action_none,                  // just interpret, do not invalidate nmethod
  74     Action_maybe_recompile,       // recompile the nmethod; need not invalidate
  75     Action_reinterpret,           // invalidate the nmethod, reset IC, maybe recompile
  76     Action_make_not_entrant,      // invalidate the nmethod, recompile (probably)
  77     Action_make_not_compilable,   // invalidate the nmethod and do not compile
  78     Action_LIMIT
  79     // Note:  Keep this enum in sync. with _trap_action_name.
  80   };
  81 


 294   //           or if there were multiple deopts with differing reasons.
 295   //  recompiled: If a deoptimization here triggered a recompilation.
 296   // Note that not all reasons are recorded per-bci.
 297   static DeoptReason trap_state_reason(int trap_state);
 298   static int  trap_state_has_reason(int trap_state, int reason);
 299   static int  trap_state_add_reason(int trap_state, int reason);
 300   static bool trap_state_is_recompiled(int trap_state);
 301   static int  trap_state_set_recompiled(int trap_state, bool z);
 302   static const char* format_trap_state(char* buf, size_t buflen,
 303                                        int trap_state);
 304 
 305   static bool reason_is_recorded_per_bytecode(DeoptReason reason) {
 306     return reason > Reason_none && reason <= Reason_RECORDED_LIMIT;
 307   }
 308 
 309   static DeoptReason reason_recorded_per_bytecode_if_any(DeoptReason reason) {
 310     if (reason_is_recorded_per_bytecode(reason))
 311       return reason;
 312     else if (reason == Reason_div0_check) // null check due to divide-by-zero?
 313       return Reason_null_check;           // recorded per BCI as a null check


 314     else
 315       return Reason_none;
 316   }
 317 











 318   static const char* trap_reason_name(int reason);
 319   static const char* trap_action_name(int action);
 320   // Format like reason='foo' action='bar' index='123'.
 321   // This is suitable both for XML and for tty output.
 322   static const char* format_trap_request(char* buf, size_t buflen,
 323                                          int trap_request);
 324 
 325   static jint total_deoptimization_count();
 326   static jint deoptimization_count(DeoptReason reason);
 327 
 328   // JVMTI PopFrame support
 329 
 330   // Preserves incoming arguments to the popped frame when it is
 331   // returning to a deoptimized caller
 332   static void popframe_preserve_args(JavaThread* thread, int bytes_to_save, void* start_address);
 333 
 334  private:
 335   static MethodData* get_method_data(JavaThread* thread, methodHandle m, bool create_if_missing);
 336   // Update the mdo's count and per-BCI reason bits, returning previous state:
 337   static ProfileData* query_update_method_data(MethodData* trap_mdo,
 338                                                int trap_bci,
 339                                                DeoptReason reason,

 340                                                //outputs:
 341                                                uint& ret_this_trap_count,
 342                                                bool& ret_maybe_prior_trap,
 343                                                bool& ret_maybe_prior_recompile);
 344   // class loading support for uncommon trap
 345   static void load_class_by_index(constantPoolHandle constant_pool, int index, TRAPS);
 346   static void load_class_by_index(constantPoolHandle constant_pool, int index);
 347 
 348   static UnrollBlock* fetch_unroll_info_helper(JavaThread* thread);
 349 
 350   static DeoptAction _unloaded_action; // == Action_reinterpret;
 351   static const char* _trap_reason_name[Reason_LIMIT];
 352   static const char* _trap_action_name[Action_LIMIT];
 353 
 354   static juint _deoptimization_hist[Reason_LIMIT][1+Action_LIMIT][BC_CASE_LIMIT];
 355   // Note:  Histogram array size is 1-2 Kb.
 356 
 357  public:
 358   static void update_method_data_from_interpreter(MethodData* trap_mdo, int trap_bci, int reason);
 359 };


  42     Reason_many = -1,             // indicates presence of several reasons
  43     Reason_none = 0,              // indicates absence of a relevant deopt.
  44     // Next 7 reasons are recorded per bytecode in DataLayout::trap_bits
  45     Reason_null_check,            // saw unexpected null or zero divisor (@bci)
  46     Reason_null_assert,           // saw unexpected non-null or non-zero (@bci)
  47     Reason_range_check,           // saw unexpected array index (@bci)
  48     Reason_class_check,           // saw unexpected object class (@bci)
  49     Reason_array_check,           // saw unexpected array class (aastore @bci)
  50     Reason_intrinsic,             // saw unexpected operand to intrinsic (@bci)
  51     Reason_bimorphic,             // saw unexpected object class in bimorphic inlining (@bci)
  52 
  53     Reason_unloaded,              // unloaded class or constant pool entry
  54     Reason_uninitialized,         // bad class state (uninitialized)
  55     Reason_unreached,             // code is not reached, compiler
  56     Reason_unhandled,             // arbitrary compiler limitation
  57     Reason_constraint,            // arbitrary runtime constraint violated
  58     Reason_div0_check,            // a null_check due to division by zero
  59     Reason_age,                   // nmethod too old; tier threshold reached
  60     Reason_predicate,             // compiler generated predicate failed
  61     Reason_loop_limit_check,      // compiler generated loop limits check failed
  62     Reason_speculate_class_check, // saw unexpected object class from type speculation
  63     Reason_LIMIT,
  64     // Note:  Keep this enum in sync. with _trap_reason_name.
  65     Reason_RECORDED_LIMIT = Reason_bimorphic  // some are not recorded per bc
  66     // Note:  Reason_RECORDED_LIMIT should be < 8 to fit into 3 bits of
  67     // DataLayout::trap_bits.  This dependency is enforced indirectly
  68     // via asserts, to avoid excessive direct header-to-header dependencies.
  69     // See Deoptimization::trap_state_reason and class DataLayout.
  70   };
  71 
  72   // What action must be taken by the runtime?
  73   enum DeoptAction {
  74     Action_none,                  // just interpret, do not invalidate nmethod
  75     Action_maybe_recompile,       // recompile the nmethod; need not invalidate
  76     Action_reinterpret,           // invalidate the nmethod, reset IC, maybe recompile
  77     Action_make_not_entrant,      // invalidate the nmethod, recompile (probably)
  78     Action_make_not_compilable,   // invalidate the nmethod and do not compile
  79     Action_LIMIT
  80     // Note:  Keep this enum in sync. with _trap_action_name.
  81   };
  82 


 295   //           or if there were multiple deopts with differing reasons.
 296   //  recompiled: If a deoptimization here triggered a recompilation.
 297   // Note that not all reasons are recorded per-bci.
 298   static DeoptReason trap_state_reason(int trap_state);
 299   static int  trap_state_has_reason(int trap_state, int reason);
 300   static int  trap_state_add_reason(int trap_state, int reason);
 301   static bool trap_state_is_recompiled(int trap_state);
 302   static int  trap_state_set_recompiled(int trap_state, bool z);
 303   static const char* format_trap_state(char* buf, size_t buflen,
 304                                        int trap_state);
 305 
 306   static bool reason_is_recorded_per_bytecode(DeoptReason reason) {
 307     return reason > Reason_none && reason <= Reason_RECORDED_LIMIT;
 308   }
 309 
 310   static DeoptReason reason_recorded_per_bytecode_if_any(DeoptReason reason) {
 311     if (reason_is_recorded_per_bytecode(reason))
 312       return reason;
 313     else if (reason == Reason_div0_check) // null check due to divide-by-zero?
 314       return Reason_null_check;           // recorded per BCI as a null check
 315     else if (reason == Reason_speculate_class_check)
 316       return Reason_class_check;
 317     else
 318       return Reason_none;
 319   }
 320 
 321   static bool reason_is_speculate(int reason) {
 322     if (reason == Reason_speculate_class_check) {
 323       return true;
 324     }
 325     return false;
 326   }
 327 
 328   static uint per_method_trap_limit(int reason) {
 329     return reason_is_speculate(reason) ? (uint)PerMethodSpecTrapLimit : (uint)PerMethodTrapLimit;
 330   }
 331 
 332   static const char* trap_reason_name(int reason);
 333   static const char* trap_action_name(int action);
 334   // Format like reason='foo' action='bar' index='123'.
 335   // This is suitable both for XML and for tty output.
 336   static const char* format_trap_request(char* buf, size_t buflen,
 337                                          int trap_request);
 338 
 339   static jint total_deoptimization_count();
 340   static jint deoptimization_count(DeoptReason reason);
 341 
 342   // JVMTI PopFrame support
 343 
 344   // Preserves incoming arguments to the popped frame when it is
 345   // returning to a deoptimized caller
 346   static void popframe_preserve_args(JavaThread* thread, int bytes_to_save, void* start_address);
 347 
 348  private:
 349   static MethodData* get_method_data(JavaThread* thread, methodHandle m, bool create_if_missing);
 350   // Update the mdo's count and per-BCI reason bits, returning previous state:
 351   static ProfileData* query_update_method_data(MethodData* trap_mdo,
 352                                                int trap_bci,
 353                                                DeoptReason reason,
 354                                                Method* compiled_method,
 355                                                //outputs:
 356                                                uint& ret_this_trap_count,
 357                                                bool& ret_maybe_prior_trap,
 358                                                bool& ret_maybe_prior_recompile);
 359   // class loading support for uncommon trap
 360   static void load_class_by_index(constantPoolHandle constant_pool, int index, TRAPS);
 361   static void load_class_by_index(constantPoolHandle constant_pool, int index);
 362 
 363   static UnrollBlock* fetch_unroll_info_helper(JavaThread* thread);
 364 
 365   static DeoptAction _unloaded_action; // == Action_reinterpret;
 366   static const char* _trap_reason_name[Reason_LIMIT];
 367   static const char* _trap_action_name[Action_LIMIT];
 368 
 369   static juint _deoptimization_hist[Reason_LIMIT][1+Action_LIMIT][BC_CASE_LIMIT];
 370   // Note:  Histogram array size is 1-2 Kb.
 371 
 372  public:
 373   static void update_method_data_from_interpreter(MethodData* trap_mdo, int trap_bci, int reason);
 374 };
src/share/vm/runtime/deoptimization.hpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File