diff options
Diffstat (limited to 'runtime/thread.h')
| -rw-r--r-- | runtime/thread.h | 88 |
1 files changed, 62 insertions, 26 deletions
diff --git a/runtime/thread.h b/runtime/thread.h index 3f0d0a59a9..0e71c08b07 100644 --- a/runtime/thread.h +++ b/runtime/thread.h @@ -74,6 +74,7 @@ class ClassLinker; class Closure; class Context; struct DebugInvokeReq; +class DeoptimizationReturnValueRecord; class DexFile; class JavaVMExt; struct JNIEnvExt; @@ -82,6 +83,7 @@ class Runtime; class ScopedObjectAccessAlreadyRunnable; class ShadowFrame; class SingleStepControl; +class StackedShadowFrameRecord; class Thread; class ThreadList; @@ -99,6 +101,11 @@ enum ThreadFlag { kCheckpointRequest = 2 // Request that the thread do some checkpoint work and then continue. }; +enum class StackedShadowFrameType { + kShadowFrameUnderConstruction, + kDeoptimizationShadowFrame +}; + static constexpr size_t kNumRosAllocThreadLocalSizeBrackets = 34; // Thread's stack layout for implicit stack overflow checks: @@ -774,15 +781,14 @@ class Thread { void DeactivateSingleStepControl(); // Sets debug invoke request for debugging. When the thread is resumed, - // it executes the method described by this request then suspends itself. - // The thread does not take ownership of the given DebugInvokeReq*, it is - // owned by the JDWP thread which is waiting for the execution of the - // method. + // it executes the method described by this request then sends the reply + // before suspending itself. The thread takes the ownership of the given + // DebugInvokeReq*. It is deleted by a call to ClearDebugInvokeReq. void SetDebugInvokeReq(DebugInvokeReq* req); // Clears debug invoke request for debugging. When the thread completes - // method invocation, it clears its debug invoke request, signals the - // JDWP thread and suspends itself. + // method invocation, it deletes its debug invoke request and suspends + // itself. void ClearDebugInvokeReq(); // Returns the fake exception used to activate deoptimization. @@ -790,21 +796,25 @@ class Thread { return reinterpret_cast<mirror::Throwable*>(-1); } - void SetDeoptimizationShadowFrame(ShadowFrame* sf); - void SetDeoptimizationReturnValue(const JValue& ret_val); - - ShadowFrame* GetAndClearDeoptimizationShadowFrame(JValue* ret_val); - - bool HasDeoptimizationShadowFrame() const { - return tlsPtr_.deoptimization_shadow_frame != nullptr; + // Currently deoptimization invokes verifier which can trigger class loading + // and execute Java code, so there might be nested deoptimizations happening. + // We need to save the ongoing deoptimization shadow frames and return + // values on stacks. + void SetDeoptimizationReturnValue(const JValue& ret_val, bool is_reference) { + tls64_.deoptimization_return_value.SetJ(ret_val.GetJ()); + tls32_.deoptimization_return_value_is_reference = is_reference; } - - void SetShadowFrameUnderConstruction(ShadowFrame* sf); - void ClearShadowFrameUnderConstruction(); - - bool HasShadowFrameUnderConstruction() const { - return tlsPtr_.shadow_frame_under_construction != nullptr; + bool IsDeoptimizationReturnValueReference() { + return tls32_.deoptimization_return_value_is_reference; + } + void ClearDeoptimizationReturnValue() { + tls64_.deoptimization_return_value.SetJ(0); + tls32_.deoptimization_return_value_is_reference = false; } + void PushAndClearDeoptimizationReturnValue(); + JValue PopDeoptimizationReturnValue(); + void PushStackedShadowFrame(ShadowFrame* sf, StackedShadowFrameType type); + ShadowFrame* PopStackedShadowFrame(StackedShadowFrameType type); std::deque<instrumentation::InstrumentationStackFrame>* GetInstrumentationStack() { return tlsPtr_.instrumentation_stack; @@ -1048,7 +1058,8 @@ class Thread { explicit tls_32bit_sized_values(bool is_daemon) : suspend_count(0), debug_suspend_count(0), thin_lock_thread_id(0), tid(0), daemon(is_daemon), throwing_OutOfMemoryError(false), no_thread_suspension(0), - thread_exit_check_count(0), handling_signal_(false), suspended_at_suspend_check(false), + thread_exit_check_count(0), handling_signal_(false), + deoptimization_return_value_is_reference(false), suspended_at_suspend_check(false), ready_for_debug_invoke(false), debug_method_entry_(false) { } @@ -1089,6 +1100,10 @@ class Thread { // True if signal is being handled by this thread. bool32_t handling_signal_; + // True if the return value for interpreter after deoptimization is a reference. + // For gc purpose. + bool32_t deoptimization_return_value_is_reference; + // True if the thread is suspended in FullSuspendCheck(). This is // used to distinguish runnable threads that are suspended due to // a normal suspend check from other threads. @@ -1124,8 +1139,9 @@ class Thread { stack_trace_sample(nullptr), wait_next(nullptr), monitor_enter_object(nullptr), top_handle_scope(nullptr), class_loader_override(nullptr), long_jump_context(nullptr), instrumentation_stack(nullptr), debug_invoke_req(nullptr), single_step_control(nullptr), - deoptimization_shadow_frame(nullptr), shadow_frame_under_construction(nullptr), name(nullptr), - pthread_self(0), last_no_thread_suspension_cause(nullptr), thread_local_start(nullptr), + stacked_shadow_frame_record(nullptr), deoptimization_return_value_stack(nullptr), + name(nullptr), pthread_self(0), + last_no_thread_suspension_cause(nullptr), thread_local_start(nullptr), thread_local_pos(nullptr), thread_local_end(nullptr), thread_local_objects(0), thread_local_alloc_stack_top(nullptr), thread_local_alloc_stack_end(nullptr), nested_signal_state(nullptr), flip_function(nullptr), method_verifier(nullptr) { @@ -1201,11 +1217,13 @@ class Thread { // JDWP single-stepping support. SingleStepControl* single_step_control; - // Shadow frame stack that is used temporarily during the deoptimization of a method. - ShadowFrame* deoptimization_shadow_frame; + // For gc purpose, a shadow frame record stack that keeps track of: + // 1) shadow frames under construction. + // 2) deoptimization shadow frames. + StackedShadowFrameRecord* stacked_shadow_frame_record; - // Shadow frame stack that is currently under construction but not yet on the stack - ShadowFrame* shadow_frame_under_construction; + // Deoptimization return value record stack. + DeoptimizationReturnValueRecord* deoptimization_return_value_stack; // A cached copy of the java.lang.Thread's name. std::string* name; @@ -1293,7 +1311,25 @@ class ScopedAssertNoThreadSuspension { const char* const old_cause_; }; +class ScopedStackedShadowFramePusher { + public: + ScopedStackedShadowFramePusher(Thread* self, ShadowFrame* sf, StackedShadowFrameType type) + : self_(self), type_(type) { + self_->PushStackedShadowFrame(sf, type); + } + ~ScopedStackedShadowFramePusher() { + self_->PopStackedShadowFrame(type_); + } + + private: + Thread* const self_; + const StackedShadowFrameType type_; + + DISALLOW_COPY_AND_ASSIGN(ScopedStackedShadowFramePusher); +}; + std::ostream& operator<<(std::ostream& os, const Thread& thread); +std::ostream& operator<<(std::ostream& os, const StackedShadowFrameType& thread); } // namespace art |