| 1 | /* | 
|---|
| 2 | * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. | 
|---|
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 
|---|
| 4 | * | 
|---|
| 5 | * This code is free software; you can redistribute it and/or modify it | 
|---|
| 6 | * under the terms of the GNU General Public License version 2 only, as | 
|---|
| 7 | * published by the Free Software Foundation. | 
|---|
| 8 | * | 
|---|
| 9 | * This code is distributed in the hope that it will be useful, but WITHOUT | 
|---|
| 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | 
|---|
| 11 | * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License | 
|---|
| 12 | * version 2 for more details (a copy is included in the LICENSE file that | 
|---|
| 13 | * accompanied this code). | 
|---|
| 14 | * | 
|---|
| 15 | * You should have received a copy of the GNU General Public License version | 
|---|
| 16 | * 2 along with this work; if not, write to the Free Software Foundation, | 
|---|
| 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | 
|---|
| 18 | * | 
|---|
| 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | 
|---|
| 20 | * or visit www.oracle.com if you need additional information or have any | 
|---|
| 21 | * questions. | 
|---|
| 22 | * | 
|---|
| 23 | */ | 
|---|
| 24 |  | 
|---|
| 25 | #ifndef SHARE_RUNTIME_DEOPTIMIZATION_HPP | 
|---|
| 26 | #define SHARE_RUNTIME_DEOPTIMIZATION_HPP | 
|---|
| 27 |  | 
|---|
| 28 | #include "memory/allocation.hpp" | 
|---|
| 29 | #include "runtime/frame.hpp" | 
|---|
| 30 |  | 
|---|
| 31 | class ProfileData; | 
|---|
| 32 | class vframeArray; | 
|---|
| 33 | class MonitorInfo; | 
|---|
| 34 | class MonitorValue; | 
|---|
| 35 | class ObjectValue; | 
|---|
| 36 | class AutoBoxObjectValue; | 
|---|
| 37 | class ScopeValue; | 
|---|
| 38 | class compiledVFrame; | 
|---|
| 39 |  | 
|---|
| 40 | template<class E> class GrowableArray; | 
|---|
| 41 |  | 
|---|
| 42 | class Deoptimization : AllStatic { | 
|---|
| 43 | friend class VMStructs; | 
|---|
| 44 |  | 
|---|
| 45 | public: | 
|---|
| 46 | // What condition caused the deoptimization? | 
|---|
| 47 | enum DeoptReason { | 
|---|
| 48 | Reason_many = -1,             // indicates presence of several reasons | 
|---|
| 49 | Reason_none = 0,              // indicates absence of a relevant deopt. | 
|---|
| 50 | // Next 8 reasons are recorded per bytecode in DataLayout::trap_bits. | 
|---|
| 51 | // This is more complicated for JVMCI as JVMCI may deoptimize to *some* bytecode before the | 
|---|
| 52 | // bytecode that actually caused the deopt (with inlining, JVMCI may even deoptimize to a | 
|---|
| 53 | // bytecode in another method): | 
|---|
| 54 | //  - bytecode y in method b() causes deopt | 
|---|
| 55 | //  - JVMCI deoptimizes to bytecode x in method a() | 
|---|
| 56 | // -> the deopt reason will be recorded for method a() at bytecode x | 
|---|
| 57 | Reason_null_check,            // saw unexpected null or zero divisor (@bci) | 
|---|
| 58 | Reason_null_assert,           // saw unexpected non-null or non-zero (@bci) | 
|---|
| 59 | Reason_range_check,           // saw unexpected array index (@bci) | 
|---|
| 60 | Reason_class_check,           // saw unexpected object class (@bci) | 
|---|
| 61 | Reason_array_check,           // saw unexpected array class (aastore @bci) | 
|---|
| 62 | Reason_intrinsic,             // saw unexpected operand to intrinsic (@bci) | 
|---|
| 63 | Reason_bimorphic,             // saw unexpected object class in bimorphic inlining (@bci) | 
|---|
| 64 |  | 
|---|
| 65 | #if INCLUDE_JVMCI | 
|---|
| 66 | Reason_unreached0             = Reason_null_assert, | 
|---|
| 67 | Reason_type_checked_inlining  = Reason_intrinsic, | 
|---|
| 68 | Reason_optimized_type_check   = Reason_bimorphic, | 
|---|
| 69 | #endif | 
|---|
| 70 |  | 
|---|
| 71 | Reason_profile_predicate,     // compiler generated predicate moved from frequent branch in a loop failed | 
|---|
| 72 |  | 
|---|
| 73 | // recorded per method | 
|---|
| 74 | Reason_unloaded,              // unloaded class or constant pool entry | 
|---|
| 75 | Reason_uninitialized,         // bad class state (uninitialized) | 
|---|
| 76 | Reason_initialized,           // class has been fully initialized | 
|---|
| 77 | Reason_unreached,             // code is not reached, compiler | 
|---|
| 78 | Reason_unhandled,             // arbitrary compiler limitation | 
|---|
| 79 | Reason_constraint,            // arbitrary runtime constraint violated | 
|---|
| 80 | Reason_div0_check,            // a null_check due to division by zero | 
|---|
| 81 | Reason_age,                   // nmethod too old; tier threshold reached | 
|---|
| 82 | Reason_predicate,             // compiler generated predicate failed | 
|---|
| 83 | Reason_loop_limit_check,      // compiler generated loop limits check failed | 
|---|
| 84 | Reason_speculate_class_check, // saw unexpected object class from type speculation | 
|---|
| 85 | Reason_speculate_null_check,  // saw unexpected null from type speculation | 
|---|
| 86 | Reason_speculate_null_assert, // saw unexpected null from type speculation | 
|---|
| 87 | Reason_rtm_state_change,      // rtm state change detected | 
|---|
| 88 | Reason_unstable_if,           // a branch predicted always false was taken | 
|---|
| 89 | Reason_unstable_fused_if,     // fused two ifs that had each one untaken branch. One is now taken. | 
|---|
| 90 | #if INCLUDE_JVMCI | 
|---|
| 91 | Reason_aliasing,              // optimistic assumption about aliasing failed | 
|---|
| 92 | Reason_transfer_to_interpreter, // explicit transferToInterpreter() | 
|---|
| 93 | Reason_not_compiled_exception_handler, | 
|---|
| 94 | Reason_unresolved, | 
|---|
| 95 | Reason_jsr_mismatch, | 
|---|
| 96 | #endif | 
|---|
| 97 |  | 
|---|
| 98 | // Reason_tenured is counted separately, add normal counted Reasons above. | 
|---|
| 99 | // Related to MethodData::_trap_hist_limit where Reason_tenured isn't included | 
|---|
| 100 | Reason_tenured,               // age of the code has reached the limit | 
|---|
| 101 | Reason_LIMIT, | 
|---|
| 102 |  | 
|---|
| 103 | // Note:  Keep this enum in sync. with _trap_reason_name. | 
|---|
| 104 | Reason_RECORDED_LIMIT = Reason_profile_predicate  // some are not recorded per bc | 
|---|
| 105 | // Note:  Reason_RECORDED_LIMIT should fit into 31 bits of | 
|---|
| 106 | // DataLayout::trap_bits.  This dependency is enforced indirectly | 
|---|
| 107 | // via asserts, to avoid excessive direct header-to-header dependencies. | 
|---|
| 108 | // See Deoptimization::trap_state_reason and class DataLayout. | 
|---|
| 109 | }; | 
|---|
| 110 |  | 
|---|
| 111 | // What action must be taken by the runtime? | 
|---|
| 112 | enum DeoptAction { | 
|---|
| 113 | Action_none,                  // just interpret, do not invalidate nmethod | 
|---|
| 114 | Action_maybe_recompile,       // recompile the nmethod; need not invalidate | 
|---|
| 115 | Action_reinterpret,           // invalidate the nmethod, reset IC, maybe recompile | 
|---|
| 116 | Action_make_not_entrant,      // invalidate the nmethod, recompile (probably) | 
|---|
| 117 | Action_make_not_compilable,   // invalidate the nmethod and do not compile | 
|---|
| 118 | Action_LIMIT | 
|---|
| 119 | // Note:  Keep this enum in sync. with _trap_action_name. | 
|---|
| 120 | }; | 
|---|
| 121 |  | 
|---|
| 122 | enum { | 
|---|
| 123 | _action_bits = 3, | 
|---|
| 124 | _reason_bits = 5, | 
|---|
| 125 | _debug_id_bits = 23, | 
|---|
| 126 | _action_shift = 0, | 
|---|
| 127 | _reason_shift = _action_shift+_action_bits, | 
|---|
| 128 | _debug_id_shift = _reason_shift+_reason_bits, | 
|---|
| 129 | BC_CASE_LIMIT = PRODUCT_ONLY(1) NOT_PRODUCT(4) // for _deoptimization_hist | 
|---|
| 130 | }; | 
|---|
| 131 |  | 
|---|
| 132 | enum UnpackType { | 
|---|
| 133 | Unpack_deopt                = 0, // normal deoptimization, use pc computed in unpack_vframe_on_stack | 
|---|
| 134 | Unpack_exception            = 1, // exception is pending | 
|---|
| 135 | Unpack_uncommon_trap        = 2, // redo last byte code (C2 only) | 
|---|
| 136 | Unpack_reexecute            = 3, // reexecute bytecode (C1 only) | 
|---|
| 137 | Unpack_LIMIT                = 4 | 
|---|
| 138 | }; | 
|---|
| 139 |  | 
|---|
| 140 | // Checks all compiled methods. Invalid methods are deleted and | 
|---|
| 141 | // corresponding activations are deoptimized. | 
|---|
| 142 | static int deoptimize_dependents(); | 
|---|
| 143 |  | 
|---|
| 144 | // Deoptimizes a frame lazily. nmethod gets patched deopt happens on return to the frame | 
|---|
| 145 | static void deoptimize(JavaThread* thread, frame fr, RegisterMap *reg_map); | 
|---|
| 146 | static void deoptimize(JavaThread* thread, frame fr, RegisterMap *reg_map, DeoptReason reason); | 
|---|
| 147 |  | 
|---|
| 148 | #if INCLUDE_JVMCI | 
|---|
| 149 | static address deoptimize_for_missing_exception_handler(CompiledMethod* cm); | 
|---|
| 150 | static oop get_cached_box(AutoBoxObjectValue* bv, frame* fr, RegisterMap* reg_map, TRAPS); | 
|---|
| 151 | #endif | 
|---|
| 152 |  | 
|---|
| 153 | private: | 
|---|
| 154 | // Does the actual work for deoptimizing a single frame | 
|---|
| 155 | static void deoptimize_single_frame(JavaThread* thread, frame fr, DeoptReason reason); | 
|---|
| 156 |  | 
|---|
| 157 | // Helper function to revoke biases of all monitors in frame if UseBiasedLocking | 
|---|
| 158 | // is enabled | 
|---|
| 159 | static void revoke_biases_of_monitors(JavaThread* thread, frame fr, RegisterMap* map); | 
|---|
| 160 |  | 
|---|
| 161 | #if COMPILER2_OR_JVMCI | 
|---|
| 162 | JVMCI_ONLY(public:) | 
|---|
| 163 |  | 
|---|
| 164 | // Support for restoring non-escaping objects | 
|---|
| 165 | static bool realloc_objects(JavaThread* thread, frame* fr, RegisterMap* reg_map, GrowableArray<ScopeValue*>* objects, TRAPS); | 
|---|
| 166 | static void reassign_type_array_elements(frame* fr, RegisterMap* reg_map, ObjectValue* sv, typeArrayOop obj, BasicType type); | 
|---|
| 167 | static void reassign_object_array_elements(frame* fr, RegisterMap* reg_map, ObjectValue* sv, objArrayOop obj); | 
|---|
| 168 | static void reassign_fields(frame* fr, RegisterMap* reg_map, GrowableArray<ScopeValue*>* objects, bool realloc_failures, bool skip_internal); | 
|---|
| 169 | static void relock_objects(GrowableArray<MonitorInfo*>* monitors, JavaThread* thread, bool realloc_failures); | 
|---|
| 170 | static void pop_frames_failed_reallocs(JavaThread* thread, vframeArray* array); | 
|---|
| 171 | NOT_PRODUCT(static void print_objects(GrowableArray<ScopeValue*>* objects, bool realloc_failures);) | 
|---|
| 172 | #endif // COMPILER2_OR_JVMCI | 
|---|
| 173 |  | 
|---|
| 174 | public: | 
|---|
| 175 | static vframeArray* create_vframeArray(JavaThread* thread, frame fr, RegisterMap *reg_map, GrowableArray<compiledVFrame*>* chunk, bool realloc_failures); | 
|---|
| 176 |  | 
|---|
| 177 | // Interface used for unpacking deoptimized frames | 
|---|
| 178 |  | 
|---|
| 179 | // UnrollBlock is returned by fetch_unroll_info() to the deoptimization handler (blob). | 
|---|
| 180 | // This is only a CheapObj to ease debugging after a deopt failure | 
|---|
| 181 | class UnrollBlock : public CHeapObj<mtCompiler> { | 
|---|
| 182 | friend class VMStructs; | 
|---|
| 183 | friend class JVMCIVMStructs; | 
|---|
| 184 | private: | 
|---|
| 185 | int       _size_of_deoptimized_frame; // Size, in bytes, of current deoptimized frame | 
|---|
| 186 | int       _caller_adjustment;         // Adjustment, in bytes, to caller's SP by initial interpreted frame | 
|---|
| 187 | int       _number_of_frames;          // Number frames to unroll | 
|---|
| 188 | int       _total_frame_sizes;         // Total of number*sizes frames | 
|---|
| 189 | intptr_t* _frame_sizes;               // Array of frame sizes, in bytes, for unrolling the stack | 
|---|
| 190 | address*  _frame_pcs;                 // Array of frame pc's, in bytes, for unrolling the stack | 
|---|
| 191 | intptr_t* _register_block;            // Block for storing callee-saved registers. | 
|---|
| 192 | BasicType _return_type;               // Tells if we have to restore double or long return value | 
|---|
| 193 | intptr_t  _initial_info;              // Platform dependent data for the sender frame (was FP on x86) | 
|---|
| 194 | int       _caller_actual_parameters;  // The number of actual arguments at the | 
|---|
| 195 | // interpreted caller of the deoptimized frame | 
|---|
| 196 | int       _unpack_kind;               // exec_mode that can be changed during fetch_unroll_info | 
|---|
| 197 |  | 
|---|
| 198 | // The following fields are used as temps during the unpacking phase | 
|---|
| 199 | // (which is tight on registers, especially on x86). They really ought | 
|---|
| 200 | // to be PD variables but that involves moving this class into its own | 
|---|
| 201 | // file to use the pd include mechanism. Maybe in a later cleanup ... | 
|---|
| 202 | intptr_t  _counter_temp;              // SHOULD BE PD VARIABLE (x86 frame count temp) | 
|---|
| 203 | intptr_t  _sender_sp_temp;            // SHOULD BE PD VARIABLE (x86 sender_sp) | 
|---|
| 204 | public: | 
|---|
| 205 | // Constructor | 
|---|
| 206 | UnrollBlock(int  size_of_deoptimized_frame, | 
|---|
| 207 | int  caller_adjustment, | 
|---|
| 208 | int  caller_actual_parameters, | 
|---|
| 209 | int  number_of_frames, | 
|---|
| 210 | intptr_t* frame_sizes, | 
|---|
| 211 | address* frames_pcs, | 
|---|
| 212 | BasicType return_type, | 
|---|
| 213 | int unpack_kind); | 
|---|
| 214 | ~UnrollBlock(); | 
|---|
| 215 |  | 
|---|
| 216 | // Returns where a register is located. | 
|---|
| 217 | intptr_t* value_addr_at(int register_number) const; | 
|---|
| 218 |  | 
|---|
| 219 | // Accessors | 
|---|
| 220 | intptr_t* frame_sizes()  const { return _frame_sizes; } | 
|---|
| 221 | int number_of_frames()  const { return _number_of_frames; } | 
|---|
| 222 | address*  frame_pcs()   const { return _frame_pcs ; } | 
|---|
| 223 | int  unpack_kind()   const { return _unpack_kind; } | 
|---|
| 224 |  | 
|---|
| 225 | // Returns the total size of frames | 
|---|
| 226 | int size_of_frames() const; | 
|---|
| 227 |  | 
|---|
| 228 | void set_initial_info(intptr_t info) { _initial_info = info; } | 
|---|
| 229 |  | 
|---|
| 230 | int caller_actual_parameters() const { return _caller_actual_parameters; } | 
|---|
| 231 |  | 
|---|
| 232 | // Accessors used by the code generator for the unpack stub. | 
|---|
| 233 | static int size_of_deoptimized_frame_offset_in_bytes() { return offset_of(UnrollBlock, _size_of_deoptimized_frame); } | 
|---|
| 234 | static int caller_adjustment_offset_in_bytes()         { return offset_of(UnrollBlock, _caller_adjustment);         } | 
|---|
| 235 | static int number_of_frames_offset_in_bytes()          { return offset_of(UnrollBlock, _number_of_frames);          } | 
|---|
| 236 | static int frame_sizes_offset_in_bytes()               { return offset_of(UnrollBlock, _frame_sizes);               } | 
|---|
| 237 | static int total_frame_sizes_offset_in_bytes()         { return offset_of(UnrollBlock, _total_frame_sizes);         } | 
|---|
| 238 | static int frame_pcs_offset_in_bytes()                 { return offset_of(UnrollBlock, _frame_pcs);                 } | 
|---|
| 239 | static int register_block_offset_in_bytes()            { return offset_of(UnrollBlock, _register_block);            } | 
|---|
| 240 | static int return_type_offset_in_bytes()               { return offset_of(UnrollBlock, _return_type);               } | 
|---|
| 241 | static int counter_temp_offset_in_bytes()              { return offset_of(UnrollBlock, _counter_temp);              } | 
|---|
| 242 | static int initial_info_offset_in_bytes()              { return offset_of(UnrollBlock, _initial_info);              } | 
|---|
| 243 | static int unpack_kind_offset_in_bytes()               { return offset_of(UnrollBlock, _unpack_kind);               } | 
|---|
| 244 | static int sender_sp_temp_offset_in_bytes()            { return offset_of(UnrollBlock, _sender_sp_temp);            } | 
|---|
| 245 |  | 
|---|
| 246 | BasicType return_type() const { return _return_type; } | 
|---|
| 247 | void print(); | 
|---|
| 248 | }; | 
|---|
| 249 |  | 
|---|
| 250 | //** Returns an UnrollBlock continuing information | 
|---|
| 251 | // how to make room for the resulting interpreter frames. | 
|---|
| 252 | // Called by assembly stub after execution has returned to | 
|---|
| 253 | // deoptimized frame. | 
|---|
| 254 | // @argument thread.     Thread where stub_frame resides. | 
|---|
| 255 | // @see OptoRuntime::deoptimization_fetch_unroll_info_C | 
|---|
| 256 | static UnrollBlock* fetch_unroll_info(JavaThread* thread, int exec_mode); | 
|---|
| 257 |  | 
|---|
| 258 | //** Unpacks vframeArray onto execution stack | 
|---|
| 259 | // Called by assembly stub after execution has returned to | 
|---|
| 260 | // deoptimized frame and after the stack unrolling. | 
|---|
| 261 | // @argument thread.     Thread where stub_frame resides. | 
|---|
| 262 | // @argument exec_mode.  Determines how execution should be continued in top frame. | 
|---|
| 263 | //                       0 means continue after current byte code | 
|---|
| 264 | //                       1 means exception has happened, handle exception | 
|---|
| 265 | //                       2 means reexecute current bytecode (for uncommon traps). | 
|---|
| 266 | // @see OptoRuntime::deoptimization_unpack_frames_C | 
|---|
| 267 | // Return BasicType of call return type, if any | 
|---|
| 268 | static BasicType unpack_frames(JavaThread* thread, int exec_mode); | 
|---|
| 269 |  | 
|---|
| 270 | // Cleans up deoptimization bits on thread after unpacking or in the | 
|---|
| 271 | // case of an exception. | 
|---|
| 272 | static void cleanup_deopt_info(JavaThread  *thread, | 
|---|
| 273 | vframeArray * array); | 
|---|
| 274 |  | 
|---|
| 275 | // Restores callee saved values from deoptimized frame into oldest interpreter frame | 
|---|
| 276 | // so caller of the deoptimized frame will get back the values it expects. | 
|---|
| 277 | static void unwind_callee_save_values(frame* f, vframeArray* vframe_array); | 
|---|
| 278 |  | 
|---|
| 279 | //** Performs an uncommon trap for compiled code. | 
|---|
| 280 | // The top most compiler frame is converted into interpreter frames | 
|---|
| 281 | static UnrollBlock* uncommon_trap(JavaThread* thread, jint unloaded_class_index, jint exec_mode); | 
|---|
| 282 | // Helper routine that enters the VM and may block | 
|---|
| 283 | static void uncommon_trap_inner(JavaThread* thread, jint unloaded_class_index); | 
|---|
| 284 |  | 
|---|
| 285 | //** Deoptimizes the frame identified by id. | 
|---|
| 286 | // Only called from VMDeoptimizeFrame | 
|---|
| 287 | // @argument thread.     Thread where stub_frame resides. | 
|---|
| 288 | // @argument id.         id of frame that should be deoptimized. | 
|---|
| 289 | static void deoptimize_frame_internal(JavaThread* thread, intptr_t* id, DeoptReason reason); | 
|---|
| 290 |  | 
|---|
| 291 | // if thread is not the current thread then execute | 
|---|
| 292 | // VM_DeoptimizeFrame otherwise deoptimize directly. | 
|---|
| 293 | static void deoptimize_frame(JavaThread* thread, intptr_t* id, DeoptReason reason); | 
|---|
| 294 | static void deoptimize_frame(JavaThread* thread, intptr_t* id); | 
|---|
| 295 |  | 
|---|
| 296 | // Statistics | 
|---|
| 297 | static void gather_statistics(DeoptReason reason, DeoptAction action, | 
|---|
| 298 | Bytecodes::Code bc = Bytecodes::_illegal); | 
|---|
| 299 | static void print_statistics(); | 
|---|
| 300 |  | 
|---|
| 301 | // How much room to adjust the last frame's SP by, to make space for | 
|---|
| 302 | // the callee's interpreter frame (which expects locals to be next to | 
|---|
| 303 | // incoming arguments) | 
|---|
| 304 | static int last_frame_adjust(int callee_parameters, int callee_locals); | 
|---|
| 305 |  | 
|---|
| 306 | // trap_request codes | 
|---|
| 307 | static DeoptReason trap_request_reason(int trap_request) { | 
|---|
| 308 | if (trap_request < 0) | 
|---|
| 309 | return (DeoptReason) | 
|---|
| 310 | ((~(trap_request) >> _reason_shift) & right_n_bits(_reason_bits)); | 
|---|
| 311 | else | 
|---|
| 312 | // standard reason for unloaded CP entry | 
|---|
| 313 | return Reason_unloaded; | 
|---|
| 314 | } | 
|---|
| 315 | static DeoptAction trap_request_action(int trap_request) { | 
|---|
| 316 | if (trap_request < 0) | 
|---|
| 317 | return (DeoptAction) | 
|---|
| 318 | ((~(trap_request) >> _action_shift) & right_n_bits(_action_bits)); | 
|---|
| 319 | else | 
|---|
| 320 | // standard action for unloaded CP entry | 
|---|
| 321 | return _unloaded_action; | 
|---|
| 322 | } | 
|---|
| 323 | static int trap_request_debug_id(int trap_request) { | 
|---|
| 324 | if (trap_request < 0) { | 
|---|
| 325 | return ((~(trap_request) >> _debug_id_shift) & right_n_bits(_debug_id_bits)); | 
|---|
| 326 | } else { | 
|---|
| 327 | // standard action for unloaded CP entry | 
|---|
| 328 | return 0; | 
|---|
| 329 | } | 
|---|
| 330 | } | 
|---|
| 331 | static int trap_request_index(int trap_request) { | 
|---|
| 332 | if (trap_request < 0) | 
|---|
| 333 | return -1; | 
|---|
| 334 | else | 
|---|
| 335 | return trap_request; | 
|---|
| 336 | } | 
|---|
| 337 | static int make_trap_request(DeoptReason reason, DeoptAction action, | 
|---|
| 338 | int index = -1) { | 
|---|
| 339 | assert((1 << _reason_bits) >= Reason_LIMIT, "enough bits"); | 
|---|
| 340 | assert((1 << _action_bits) >= Action_LIMIT, "enough bits"); | 
|---|
| 341 | int trap_request; | 
|---|
| 342 | if (index != -1) | 
|---|
| 343 | trap_request = index; | 
|---|
| 344 | else | 
|---|
| 345 | trap_request = (~(((reason) << _reason_shift) | 
|---|
| 346 | + ((action) << _action_shift))); | 
|---|
| 347 | assert(reason == trap_request_reason(trap_request), "valid reason"); | 
|---|
| 348 | assert(action == trap_request_action(trap_request), "valid action"); | 
|---|
| 349 | assert(index  == trap_request_index(trap_request), "valid index"); | 
|---|
| 350 | return trap_request; | 
|---|
| 351 | } | 
|---|
| 352 |  | 
|---|
| 353 | // The trap_state stored in a MDO is decoded here. | 
|---|
| 354 | // It records two items of information. | 
|---|
| 355 | //  reason:  If a deoptimization happened here, what its reason was, | 
|---|
| 356 | //           or if there were multiple deopts with differing reasons. | 
|---|
| 357 | //  recompiled: If a deoptimization here triggered a recompilation. | 
|---|
| 358 | // Note that not all reasons are recorded per-bci. | 
|---|
| 359 | static DeoptReason trap_state_reason(int trap_state); | 
|---|
| 360 | static int  trap_state_has_reason(int trap_state, int reason); | 
|---|
| 361 | static int  trap_state_add_reason(int trap_state, int reason); | 
|---|
| 362 | static bool trap_state_is_recompiled(int trap_state); | 
|---|
| 363 | static int  trap_state_set_recompiled(int trap_state, bool z); | 
|---|
| 364 | static const char* format_trap_state(char* buf, size_t buflen, | 
|---|
| 365 | int trap_state); | 
|---|
| 366 |  | 
|---|
| 367 | static bool reason_is_recorded_per_bytecode(DeoptReason reason) { | 
|---|
| 368 | return reason > Reason_none && reason <= Reason_RECORDED_LIMIT; | 
|---|
| 369 | } | 
|---|
| 370 |  | 
|---|
| 371 | static DeoptReason reason_recorded_per_bytecode_if_any(DeoptReason reason) { | 
|---|
| 372 | if (reason_is_recorded_per_bytecode(reason)) | 
|---|
| 373 | return reason; | 
|---|
| 374 | else if (reason == Reason_div0_check) // null check due to divide-by-zero? | 
|---|
| 375 | return Reason_null_check;           // recorded per BCI as a null check | 
|---|
| 376 | else if (reason == Reason_speculate_class_check) | 
|---|
| 377 | return Reason_class_check; | 
|---|
| 378 | else if (reason == Reason_speculate_null_check) | 
|---|
| 379 | return Reason_null_check; | 
|---|
| 380 | else if (reason == Reason_speculate_null_assert) | 
|---|
| 381 | return Reason_null_assert; | 
|---|
| 382 | else if (reason == Reason_unstable_if) | 
|---|
| 383 | return Reason_intrinsic; | 
|---|
| 384 | else if (reason == Reason_unstable_fused_if) | 
|---|
| 385 | return Reason_range_check; | 
|---|
| 386 | else | 
|---|
| 387 | return Reason_none; | 
|---|
| 388 | } | 
|---|
| 389 |  | 
|---|
| 390 | static bool reason_is_speculate(int reason) { | 
|---|
| 391 | if (reason == Reason_speculate_class_check || | 
|---|
| 392 | reason == Reason_speculate_null_check || | 
|---|
| 393 | reason == Reason_speculate_null_assert) { | 
|---|
| 394 | return true; | 
|---|
| 395 | } | 
|---|
| 396 | return false; | 
|---|
| 397 | } | 
|---|
| 398 |  | 
|---|
| 399 | static DeoptReason reason_null_check(bool speculative) { | 
|---|
| 400 | return speculative ? Deoptimization::Reason_speculate_null_check : Deoptimization::Reason_null_check; | 
|---|
| 401 | } | 
|---|
| 402 |  | 
|---|
| 403 | static DeoptReason reason_class_check(bool speculative) { | 
|---|
| 404 | return speculative ? Deoptimization::Reason_speculate_class_check : Deoptimization::Reason_class_check; | 
|---|
| 405 | } | 
|---|
| 406 |  | 
|---|
| 407 | static DeoptReason reason_null_assert(bool speculative) { | 
|---|
| 408 | return speculative ? Deoptimization::Reason_speculate_null_assert : Deoptimization::Reason_null_assert; | 
|---|
| 409 | } | 
|---|
| 410 |  | 
|---|
| 411 | static uint per_method_trap_limit(int reason) { | 
|---|
| 412 | return reason_is_speculate(reason) ? (uint)PerMethodSpecTrapLimit : (uint)PerMethodTrapLimit; | 
|---|
| 413 | } | 
|---|
| 414 |  | 
|---|
| 415 | static const char* trap_reason_name(int reason); | 
|---|
| 416 | static const char* trap_action_name(int action); | 
|---|
| 417 | // Format like reason='foo' action='bar' index='123'. | 
|---|
| 418 | // This is suitable both for XML and for tty output. | 
|---|
| 419 | static const char* format_trap_request(char* buf, size_t buflen, | 
|---|
| 420 | int trap_request); | 
|---|
| 421 |  | 
|---|
| 422 | static jint total_deoptimization_count(); | 
|---|
| 423 |  | 
|---|
| 424 | // JVMTI PopFrame support | 
|---|
| 425 |  | 
|---|
| 426 | // Preserves incoming arguments to the popped frame when it is | 
|---|
| 427 | // returning to a deoptimized caller | 
|---|
| 428 | static void popframe_preserve_args(JavaThread* thread, int bytes_to_save, void* start_address); | 
|---|
| 429 |  | 
|---|
| 430 | static MethodData* get_method_data(JavaThread* thread, const methodHandle& m, bool create_if_missing); | 
|---|
| 431 | private: | 
|---|
| 432 | // Update the mdo's count and per-BCI reason bits, returning previous state: | 
|---|
| 433 | static ProfileData* query_update_method_data(MethodData* trap_mdo, | 
|---|
| 434 | int trap_bci, | 
|---|
| 435 | DeoptReason reason, | 
|---|
| 436 | bool update_total_trap_count, | 
|---|
| 437 | #if INCLUDE_JVMCI | 
|---|
| 438 | bool is_osr, | 
|---|
| 439 | #endif | 
|---|
| 440 | Method* compiled_method, | 
|---|
| 441 | //outputs: | 
|---|
| 442 | uint& ret_this_trap_count, | 
|---|
| 443 | bool& ret_maybe_prior_trap, | 
|---|
| 444 | bool& ret_maybe_prior_recompile); | 
|---|
| 445 | // class loading support for uncommon trap | 
|---|
| 446 | static void load_class_by_index(const constantPoolHandle& constant_pool, int index, TRAPS); | 
|---|
| 447 | static void load_class_by_index(const constantPoolHandle& constant_pool, int index); | 
|---|
| 448 |  | 
|---|
| 449 | static UnrollBlock* fetch_unroll_info_helper(JavaThread* thread, int exec_mode); | 
|---|
| 450 |  | 
|---|
| 451 | static DeoptAction _unloaded_action; // == Action_reinterpret; | 
|---|
| 452 | static const char* _trap_reason_name[]; | 
|---|
| 453 | static const char* _trap_action_name[]; | 
|---|
| 454 |  | 
|---|
| 455 | static juint _deoptimization_hist[Reason_LIMIT][1+Action_LIMIT][BC_CASE_LIMIT]; | 
|---|
| 456 | // Note:  Histogram array size is 1-2 Kb. | 
|---|
| 457 |  | 
|---|
| 458 | public: | 
|---|
| 459 | static void update_method_data_from_interpreter(MethodData* trap_mdo, int trap_bci, int reason); | 
|---|
| 460 | }; | 
|---|
| 461 |  | 
|---|
| 462 | class DeoptimizationMarker : StackObj {  // for profiling | 
|---|
| 463 | static bool _is_active; | 
|---|
| 464 | public: | 
|---|
| 465 | DeoptimizationMarker()  { _is_active = true; } | 
|---|
| 466 | ~DeoptimizationMarker() { _is_active = false; } | 
|---|
| 467 | static bool is_active() { return _is_active; } | 
|---|
| 468 | }; | 
|---|
| 469 |  | 
|---|
| 470 | #endif // SHARE_RUNTIME_DEOPTIMIZATION_HPP | 
|---|
| 471 |  | 
|---|