< prev index next >

src/hotspot/share/runtime/deoptimization.hpp

Print this page
rev 56101 : 8227745: Enable Escape Analysis for better performance when debugging
Reviewed-by: ???

*** 34,48 **** --- 34,50 ---- class MonitorValue; class ObjectValue; class AutoBoxObjectValue; class ScopeValue; class compiledVFrame; + class JVMTIEscapeBarrier; template<class E> class GrowableArray; class Deoptimization : AllStatic { friend class VMStructs; + friend class JVMTIEscapeBarrier; public: // What condition caused the deoptimization? enum DeoptReason { Reason_many = -1, // indicates presence of several reasons
*** 132,142 **** enum UnpackType { Unpack_deopt = 0, // normal deoptimization, use pc computed in unpack_vframe_on_stack Unpack_exception = 1, // exception is pending Unpack_uncommon_trap = 2, // redo last byte code (C2 only) Unpack_reexecute = 3, // reexecute bytecode (C1 only) ! Unpack_LIMIT = 4 }; // Checks all compiled methods. Invalid methods are deleted and // corresponding activations are deoptimized. static int deoptimize_dependents(); --- 134,145 ---- enum UnpackType { Unpack_deopt = 0, // normal deoptimization, use pc computed in unpack_vframe_on_stack Unpack_exception = 1, // exception is pending Unpack_uncommon_trap = 2, // redo last byte code (C2 only) Unpack_reexecute = 3, // reexecute bytecode (C1 only) ! Unpack_none = 4, // not deoptimizing the frame, just reallocating/relocking for JVMTI ! Unpack_LIMIT = 5 }; // Checks all compiled methods. Invalid methods are deleted and // corresponding activations are deoptimized. static int deoptimize_dependents();
*** 145,155 **** static void deoptimize(JavaThread* thread, frame fr, RegisterMap *reg_map); static void deoptimize(JavaThread* thread, frame fr, RegisterMap *reg_map, DeoptReason reason); #if INCLUDE_JVMCI static address deoptimize_for_missing_exception_handler(CompiledMethod* cm); ! static oop get_cached_box(AutoBoxObjectValue* bv, frame* fr, RegisterMap* reg_map, TRAPS); #endif private: // Does the actual work for deoptimizing a single frame static void deoptimize_single_frame(JavaThread* thread, frame fr, DeoptReason reason); --- 148,158 ---- static void deoptimize(JavaThread* thread, frame fr, RegisterMap *reg_map); static void deoptimize(JavaThread* thread, frame fr, RegisterMap *reg_map, DeoptReason reason); #if INCLUDE_JVMCI static address deoptimize_for_missing_exception_handler(CompiledMethod* cm); ! static oop get_cached_box(AutoBoxObjectValue* bv, frame* fr, const RegisterMap* reg_map, TRAPS); #endif private: // Does the actual work for deoptimizing a single frame static void deoptimize_single_frame(JavaThread* thread, frame fr, DeoptReason reason);
*** 157,174 **** // 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); #if COMPILER2_OR_JVMCI JVMCI_ONLY(public:) // Support for restoring non-escaping objects ! static bool realloc_objects(JavaThread* thread, frame* fr, RegisterMap* reg_map, 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_OR_JVMCI public: --- 160,181 ---- // 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); #if COMPILER2_OR_JVMCI + // Deoptimize objects, that is reallocate and relock them. Deoptimize holding frame. + static bool deoptimize_objects(JavaThread* thread, GrowableArray<compiledVFrame*>* chunk, bool& realloc_failures, int exec_mode); + JVMCI_ONLY(public:) // Support for restoring non-escaping objects ! static bool realloc_objects(JavaThread* thread, frame* fr, const RegisterMap* reg_map, GrowableArray<ScopeValue*>* objects, TRAPS); ! static void reassign_type_array_elements(frame* fr, const RegisterMap* reg_map, ObjectValue* sv, typeArrayOop obj, BasicType type); ! static void reassign_object_array_elements(frame* fr, const RegisterMap* reg_map, ObjectValue* sv, objArrayOop obj); ! static void reassign_fields(frame* fr, const RegisterMap* reg_map, GrowableArray<ScopeValue*>* objects, bool realloc_failures, bool skip_internal); ! static bool relock_objects(JavaThread* thread, GrowableArray<MonitorInfo*>* monitors, ! JavaThread* deoptee_thread, frame* fr, int exec_mode, 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_OR_JVMCI public:
*** 455,464 **** --- 462,555 ---- static juint _deoptimization_hist[Reason_LIMIT][1+Action_LIMIT][BC_CASE_LIMIT]; // Note: Histogram array size is 1-2 Kb. public: static void update_method_data_from_interpreter(MethodData* trap_mdo, int trap_bci, int reason); + + #if defined(ASSERT) && COMPILER2_OR_JVMCI + // Revert optimizations based on escape analysis for all compiled frames of all Java threads. + static void deoptimize_objects_alot_loop(); + #endif // defined(ASSERT) && COMPILER2_OR_JVMCI + }; + + // JVMTIEscapeBarriers should be put on execution paths, where JVMTI agents can access object + // references helt by java threads. + // They provide means to revert optimizations based on escape analysis in a well synchronized manner + // just before local references escape through JVMTI. + class JVMTIEscapeBarrier : StackObj { + #if COMPILER2_OR_JVMCI + JavaThread* const _calling_thread; + JavaThread* const _deoptee_thread; + bool const _barrier_active; + + static bool _deoptimizing_objects_for_all_threads; + static bool _self_deoptimization_in_progress; + + void sync_and_suspend_one(); + void sync_and_suspend_all(); + void resume_one(); + void resume_all(); + + // Deoptimize the given frame and deoptimize objects with optimizations based on escape analysis. + bool deoptimize_objects(JavaThread* deoptee, frame fr, const RegisterMap *reg_map); + + public: + // Revert ea based optimizations for given deoptee thread + JVMTIEscapeBarrier(JavaThread* calling_thread, JavaThread* deoptee_thread, bool barrier_active) + : _calling_thread(calling_thread), _deoptee_thread(deoptee_thread), _barrier_active(barrier_active) + { + if (_barrier_active) sync_and_suspend_one(); + } + + // Revert ea based optimizations for all java threads + JVMTIEscapeBarrier(JavaThread* calling_thread, bool barrier_active) + : _calling_thread(calling_thread), _deoptee_thread(NULL), _barrier_active(barrier_active) + { + if (_barrier_active) sync_and_suspend_all(); + } + #else + public: + JVMTIEscapeBarrier(JavaThread* calling_thread, JavaThread* deoptee_thread, bool barrier_active) { } + JVMTIEscapeBarrier(JavaThread* calling_thread, bool barrier_active) { } + #endif // COMPILER2_OR_JVMCI + + // Deoptimize objects, i.e. reallocate and relock them. The target frames are deoptimized. + // The methods return false iff at least one reallocation failed. + bool deoptimize_objects(compiledVFrame* cvf) NOT_COMPILER2_OR_JVMCI_RETURN_(true); + bool deoptimize_objects(intptr_t* fr_id) NOT_COMPILER2_OR_JVMCI_RETURN_(true); + bool deoptimize_objects(int depth) NOT_COMPILER2_OR_JVMCI_RETURN_(true); + // Find and deoptimize non escaping objects and the holding frames on all stacks. + bool deoptimize_objects_all_threads() NOT_COMPILER2_OR_JVMCI_RETURN_(true); + + // Used to prevent that new threads pop up, until the triggering operation has completed. + static bool deoptimizing_objects_for_all_threads() NOT_COMPILER2_OR_JVMCI_RETURN_(false); + static void set_deoptimizing_objects_for_all_threads(bool v) NOT_COMPILER2_OR_JVMCI_RETURN; + + #if COMPILER2_OR_JVMCI + // Returns true iff objects were reallocated and relocked because of access through JVMTI + static bool objs_are_deoptimized(JavaThread* thread, intptr_t* fr_id); + // Remember that objects were reallocated and relocked for the compiled frame with the given id + static void set_objs_are_deoptimized(JavaThread* thread, intptr_t* fr_id); + + ~JVMTIEscapeBarrier() { + if (!barrier_active()) return; + if (all_threads()) { + resume_all(); + } else { + resume_one(); + } + } + + + bool all_threads() const { return _deoptee_thread == NULL; } // Should revert optimizations for all threads. + bool self_deopt() const { return _calling_thread == _deoptee_thread; } // Current thread deoptimizes its own objects. + bool barrier_active() const { return _barrier_active; } // Inactive barriers are created if no local objects can escape. + + // accessors + JavaThread* calling_thread() const { return _calling_thread; } + JavaThread* deoptee_thread() const { return _deoptee_thread; } + #endif // COMPILER2_OR_JVMCI }; class DeoptimizationMarker : StackObj { // for profiling static bool _is_active; public:
< prev index next >