< prev index next >
src/share/vm/runtime/deoptimization.hpp
Print this page
*** 39,57 ****
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
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)
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
--- 39,70 ----
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.
! // 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,76 ****
--- 75,97 ----
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,100 ****
--- 110,123 ----
};
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,147 ****
// 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);
private:
// Does the actual work for deoptimizing a single frame
! static void deoptimize_single_frame(JavaThread* thread, frame fr);
// 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
// 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 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
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> {
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
--- 130,174 ----
// 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, 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);
! #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, 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 || 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,254 ****
//** 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);
! // If thread is not the current thread then execute
// VM_DeoptimizeFrame otherwise deoptimize directly.
static void deoptimize_frame(JavaThread* thread, intptr_t* id);
// Statistics
static void gather_statistics(DeoptReason reason, DeoptAction action,
Bytecodes::Code bc = Bytecodes::_illegal);
--- 268,282 ----
//** 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, DeoptReason reason);
! // 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,283 ****
--- 302,319 ----
((~(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,381 ****
--- 408,421 ----
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 >