diff options
-rw-r--r-- | runtime/Android.bp | 2 | ||||
-rw-r--r-- | runtime/base/mutex.cc | 6 | ||||
-rw-r--r-- | runtime/base/mutex.h | 6 | ||||
-rw-r--r-- | runtime/debugger.cc | 10 | ||||
-rw-r--r-- | runtime/debugger.h | 21 | ||||
-rw-r--r-- | runtime/runtime.cc | 1 | ||||
-rw-r--r-- | runtime/runtime.h | 8 | ||||
-rw-r--r-- | runtime/runtime_callbacks.cc | 48 | ||||
-rw-r--r-- | runtime/runtime_callbacks.h | 49 | ||||
-rw-r--r-- | runtime/runtime_callbacks_test.cc | 201 | ||||
-rw-r--r-- | runtime/thread.cc | 15 | ||||
-rw-r--r-- | runtime/thread.h | 8 |
12 files changed, 8 insertions, 367 deletions
diff --git a/runtime/Android.bp b/runtime/Android.bp index dd91249e25..86019bf71c 100644 --- a/runtime/Android.bp +++ b/runtime/Android.bp @@ -184,7 +184,6 @@ cc_defaults { "reference_table.cc", "reflection.cc", "runtime.cc", - "runtime_callbacks.cc", "runtime_options.cc", "signal_catcher.cc", "stack.cc", @@ -564,7 +563,6 @@ art_cc_test { "parsed_options_test.cc", "prebuilt_tools_test.cc", "reference_table_test.cc", - "runtime_callbacks_test.cc", "thread_pool_test.cc", "transaction_test.cc", "type_lookup_table_test.cc", diff --git a/runtime/base/mutex.cc b/runtime/base/mutex.cc index edb58c4eb7..9116097604 100644 --- a/runtime/base/mutex.cc +++ b/runtime/base/mutex.cc @@ -61,7 +61,6 @@ Mutex* Locks::reference_queue_finalizer_references_lock_ = nullptr; Mutex* Locks::reference_queue_phantom_references_lock_ = nullptr; Mutex* Locks::reference_queue_soft_references_lock_ = nullptr; Mutex* Locks::reference_queue_weak_references_lock_ = nullptr; -ReaderWriterMutex* Locks::runtime_callbacks_lock_ = nullptr; Mutex* Locks::runtime_shutdown_lock_ = nullptr; Mutex* Locks::cha_lock_ = nullptr; Mutex* Locks::thread_list_lock_ = nullptr; @@ -968,7 +967,6 @@ void Locks::Init() { DCHECK(trace_lock_ != nullptr); DCHECK(unexpected_signal_lock_ != nullptr); DCHECK(dex_lock_ != nullptr); - DCHECK(runtime_callbacks_lock_ != nullptr); } else { // Create global locks in level order from highest lock level to lowest. LockLevel current_lock_level = kInstrumentEntrypointsLock; @@ -1000,10 +998,6 @@ void Locks::Init() { DCHECK(runtime_shutdown_lock_ == nullptr); runtime_shutdown_lock_ = new Mutex("runtime shutdown lock", current_lock_level); - UPDATE_CURRENT_LOCK_LEVEL(kRuntimeCallbacksLock); - DCHECK(runtime_callbacks_lock_ == nullptr); - runtime_callbacks_lock_ = new ReaderWriterMutex("runtime callbacks lock", current_lock_level); - UPDATE_CURRENT_LOCK_LEVEL(kProfilerLock); DCHECK(profiler_lock_ == nullptr); profiler_lock_ = new Mutex("profiler lock", current_lock_level); diff --git a/runtime/base/mutex.h b/runtime/base/mutex.h index e44bdb89cc..2adeb8cc97 100644 --- a/runtime/base/mutex.h +++ b/runtime/base/mutex.h @@ -111,7 +111,6 @@ enum LockLevel { kJdwpEventListLock, kJdwpAttachLock, kJdwpStartLock, - kRuntimeCallbacksLock, kRuntimeShutdownLock, kTraceLock, kHeapBitmapLock, @@ -616,11 +615,8 @@ class Locks { // Guards shutdown of the runtime. static Mutex* runtime_shutdown_lock_ ACQUIRED_AFTER(heap_bitmap_lock_); - // Guards accesses to runtime callback lists. - static ReaderWriterMutex* runtime_callbacks_lock_ ACQUIRED_AFTER(runtime_shutdown_lock_); - // Guards background profiler global state. - static Mutex* profiler_lock_ ACQUIRED_AFTER(runtime_callbacks_lock_); + static Mutex* profiler_lock_ ACQUIRED_AFTER(runtime_shutdown_lock_); // Guards trace (ie traceview) requests. static Mutex* trace_lock_ ACQUIRED_AFTER(profiler_lock_); diff --git a/runtime/debugger.cc b/runtime/debugger.cc index c97c4e4f5b..df4413d52c 100644 --- a/runtime/debugger.cc +++ b/runtime/debugger.cc @@ -320,8 +320,6 @@ size_t Dbg::field_write_event_ref_count_ = 0; size_t Dbg::exception_catch_event_ref_count_ = 0; uint32_t Dbg::instrumentation_events_ = 0; -Dbg::DbgThreadLifecycleCallback Dbg::thread_lifecycle_callback_; - // Breakpoints. static std::vector<Breakpoint> gBreakpoints GUARDED_BY(Locks::breakpoint_lock_); @@ -5139,12 +5137,4 @@ void Dbg::VisitRoots(RootVisitor* visitor) { } } -void Dbg::DbgThreadLifecycleCallback::ThreadStart(Thread* self) { - Dbg::PostThreadStart(self); -} - -void Dbg::DbgThreadLifecycleCallback::ThreadDeath(Thread* self) { - Dbg::PostThreadDeath(self); -} - } // namespace art diff --git a/runtime/debugger.h b/runtime/debugger.h index 01359907d9..3b4a5e16b0 100644 --- a/runtime/debugger.h +++ b/runtime/debugger.h @@ -502,6 +502,10 @@ class Dbg { REQUIRES_SHARED(Locks::mutator_lock_); static void PostException(mirror::Throwable* exception) REQUIRES_SHARED(Locks::mutator_lock_); + static void PostThreadStart(Thread* t) + REQUIRES_SHARED(Locks::mutator_lock_); + static void PostThreadDeath(Thread* t) + REQUIRES_SHARED(Locks::mutator_lock_); static void PostClassPrepare(mirror::Class* c) REQUIRES_SHARED(Locks::mutator_lock_); @@ -703,10 +707,6 @@ class Dbg { return instrumentation_events_; } - static ThreadLifecycleCallback* GetThreadLifecycleCallback() { - return &thread_lifecycle_callback_; - } - private: static void ExecuteMethodWithoutPendingException(ScopedObjectAccess& soa, DebugInvokeReq* pReq) REQUIRES_SHARED(Locks::mutator_lock_); @@ -725,11 +725,6 @@ class Dbg { REQUIRES(!Locks::thread_list_lock_) REQUIRES_SHARED(Locks::mutator_lock_); static void DdmBroadcast(bool connect) REQUIRES_SHARED(Locks::mutator_lock_); - - static void PostThreadStart(Thread* t) - REQUIRES_SHARED(Locks::mutator_lock_); - static void PostThreadDeath(Thread* t) - REQUIRES_SHARED(Locks::mutator_lock_); static void PostThreadStartOrStop(Thread*, uint32_t) REQUIRES_SHARED(Locks::mutator_lock_); @@ -794,14 +789,6 @@ class Dbg { static size_t exception_catch_event_ref_count_ GUARDED_BY(Locks::deoptimization_lock_); static uint32_t instrumentation_events_ GUARDED_BY(Locks::mutator_lock_); - class DbgThreadLifecycleCallback : public ThreadLifecycleCallback { - public: - void ThreadStart(Thread* self) OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_); - void ThreadDeath(Thread* self) OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_); - }; - - static DbgThreadLifecycleCallback thread_lifecycle_callback_; - DISALLOW_COPY_AND_ASSIGN(Dbg); }; diff --git a/runtime/runtime.cc b/runtime/runtime.cc index 6ef5f26ce5..55e1852c0c 100644 --- a/runtime/runtime.cc +++ b/runtime/runtime.cc @@ -1100,7 +1100,6 @@ bool Runtime::Init(RuntimeArgumentMap&& runtime_options_in) { if (runtime_options.Exists(Opt::JdwpOptions)) { Dbg::ConfigureJdwp(runtime_options.GetOrDefault(Opt::JdwpOptions)); } - callbacks_.AddThreadLifecycleCallback(Dbg::GetThreadLifecycleCallback()); jit_options_.reset(jit::JitOptions::CreateFromRuntimeArguments(runtime_options)); if (IsAotCompiler()) { diff --git a/runtime/runtime.h b/runtime/runtime.h index 0c5de4eedf..a87e1c136b 100644 --- a/runtime/runtime.h +++ b/runtime/runtime.h @@ -28,7 +28,6 @@ #include "arch/instruction_set.h" #include "base/macros.h" -#include "base/mutex.h" #include "dex_file_types.h" #include "experimental_flags.h" #include "gc_root.h" @@ -40,7 +39,6 @@ #include "offsets.h" #include "process_state.h" #include "quick/quick_method_frame_info.h" -#include "runtime_callbacks.h" #include "runtime_stats.h" #include "safe_map.h" @@ -662,10 +660,6 @@ class Runtime { void AttachAgent(const std::string& agent_arg); - RuntimeCallbacks& GetRuntimeCallbacks() { - return callbacks_; - } - private: static void InitPlatformSignalHandlers(); @@ -923,8 +917,6 @@ class Runtime { ClassHierarchyAnalysis* cha_; - RuntimeCallbacks callbacks_; - DISALLOW_COPY_AND_ASSIGN(Runtime); }; std::ostream& operator<<(std::ostream& os, const Runtime::CalleeSaveType& rhs); diff --git a/runtime/runtime_callbacks.cc b/runtime/runtime_callbacks.cc deleted file mode 100644 index a523ddfa44..0000000000 --- a/runtime/runtime_callbacks.cc +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "runtime_callbacks.h" - -#include <algorithm> - -#include "thread.h" - -namespace art { - -void RuntimeCallbacks::AddThreadLifecycleCallback(ThreadLifecycleCallback* cb) { - thread_callbacks_.push_back(cb); -} - -void RuntimeCallbacks::RemoveThreadLifecycleCallback(ThreadLifecycleCallback* cb) { - auto it = std::find(thread_callbacks_.begin(), thread_callbacks_.end(), cb); - if (it != thread_callbacks_.end()) { - thread_callbacks_.erase(it); - } -} - -void RuntimeCallbacks::ThreadStart(Thread* self) { - for (ThreadLifecycleCallback* cb : thread_callbacks_) { - cb->ThreadStart(self); - } -} - -void RuntimeCallbacks::ThreadDeath(Thread* self) { - for (ThreadLifecycleCallback* cb : thread_callbacks_) { - cb->ThreadDeath(self); - } -} - -} // namespace art diff --git a/runtime/runtime_callbacks.h b/runtime/runtime_callbacks.h deleted file mode 100644 index 39eef3bb20..0000000000 --- a/runtime/runtime_callbacks.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ART_RUNTIME_RUNTIME_CALLBACKS_H_ -#define ART_RUNTIME_RUNTIME_CALLBACKS_H_ - -#include <vector> - -#include "base/macros.h" -#include "base/mutex.h" - -namespace art { - -class Thread; -class ThreadLifecycleCallback; - -class RuntimeCallbacks { - public: - void AddThreadLifecycleCallback(ThreadLifecycleCallback* cb) - REQUIRES(Locks::runtime_callbacks_lock_); - void RemoveThreadLifecycleCallback(ThreadLifecycleCallback* cb) - REQUIRES(Locks::runtime_callbacks_lock_); - - void ThreadStart(Thread* self) - REQUIRES_SHARED(Locks::mutator_lock_, Locks::runtime_callbacks_lock_); - void ThreadDeath(Thread* self) - REQUIRES_SHARED(Locks::mutator_lock_, Locks::runtime_callbacks_lock_); - - private: - std::vector<ThreadLifecycleCallback*> thread_callbacks_ - GUARDED_BY(Locks::runtime_callbacks_lock_); -}; - -} // namespace art - -#endif // ART_RUNTIME_RUNTIME_CALLBACKS_H_ diff --git a/runtime/runtime_callbacks_test.cc b/runtime/runtime_callbacks_test.cc deleted file mode 100644 index 00a4062065..0000000000 --- a/runtime/runtime_callbacks_test.cc +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "runtime_callbacks.h" - -#include "jni.h" -#include <memory> -#include <string> - -#include "art_method-inl.h" -#include "base/mutex.h" -#include "mirror/class-inl.h" -#include "common_runtime_test.h" -#include "mem_map.h" -#include "obj_ptr.h" -#include "runtime.h" -#include "ScopedLocalRef.h" -#include "thread-inl.h" -#include "well_known_classes.h" - -namespace art { - -class RuntimeCallbacksTest : public CommonRuntimeTest { - protected: - void SetUp() OVERRIDE { - CommonRuntimeTest::SetUp(); - - WriterMutexLock mu(Thread::Current(), *Locks::runtime_callbacks_lock_); - AddListener(); - } - - void TearDown() OVERRIDE { - { - WriterMutexLock mu(Thread::Current(), *Locks::runtime_callbacks_lock_); - RemoveListener(); - } - - CommonRuntimeTest::TearDown(); - } - - virtual void AddListener() REQUIRES(Locks::runtime_callbacks_lock_) = 0; - virtual void RemoveListener() REQUIRES(Locks::runtime_callbacks_lock_) = 0; - - void MakeExecutable(ObjPtr<mirror::Class> klass) REQUIRES_SHARED(Locks::mutator_lock_) { - CHECK(klass != nullptr); - PointerSize pointer_size = class_linker_->GetImagePointerSize(); - for (auto& m : klass->GetMethods(pointer_size)) { - if (!m.IsAbstract()) { - class_linker_->SetEntryPointsToInterpreter(&m); - } - } - } -}; - -class ThreadLifecycleCallbackRuntimeCallbacksTest : public RuntimeCallbacksTest { - public: - static void* PthreadsCallback(void* arg ATTRIBUTE_UNUSED) { - // Attach. - Runtime* runtime = Runtime::Current(); - CHECK(runtime->AttachCurrentThread("ThreadLifecycle test thread", true, nullptr, false)); - - // Detach. - runtime->DetachCurrentThread(); - - // Die... - return nullptr; - } - - protected: - void AddListener() OVERRIDE REQUIRES(Locks::runtime_callbacks_lock_) { - Runtime::Current()->GetRuntimeCallbacks().AddThreadLifecycleCallback(&cb_); - } - void RemoveListener() OVERRIDE REQUIRES(Locks::runtime_callbacks_lock_) { - Runtime::Current()->GetRuntimeCallbacks().RemoveThreadLifecycleCallback(&cb_); - } - - enum CallbackState { - kBase, - kStarted, - kDied, - kWrongStart, - kWrongDeath, - }; - - struct Callback : public ThreadLifecycleCallback { - void ThreadStart(Thread* self) OVERRIDE { - if (state == CallbackState::kBase) { - state = CallbackState::kStarted; - stored_self = self; - } else { - state = CallbackState::kWrongStart; - } - } - - void ThreadDeath(Thread* self) OVERRIDE { - if (state == CallbackState::kStarted && self == stored_self) { - state = CallbackState::kDied; - } else { - state = CallbackState::kWrongDeath; - } - } - - Thread* stored_self; - CallbackState state = CallbackState::kBase; - }; - - Callback cb_; -}; - - -TEST_F(ThreadLifecycleCallbackRuntimeCallbacksTest, ThreadLifecycleCallbackJava) { - Thread* self = Thread::Current(); - - self->TransitionFromSuspendedToRunnable(); - bool started = runtime_->Start(); - ASSERT_TRUE(started); - - cb_.state = CallbackState::kBase; // Ignore main thread attach. - - { - ScopedObjectAccess soa(self); - MakeExecutable(soa.Decode<mirror::Class>(WellKnownClasses::java_lang_Thread)); - } - - JNIEnv* env = self->GetJniEnv(); - - ScopedLocalRef<jobject> thread_name(env, - env->NewStringUTF("ThreadLifecycleCallback test thread")); - ASSERT_TRUE(thread_name.get() != nullptr); - - ScopedLocalRef<jobject> thread(env, env->AllocObject(WellKnownClasses::java_lang_Thread)); - ASSERT_TRUE(thread.get() != nullptr); - - env->CallNonvirtualVoidMethod(thread.get(), - WellKnownClasses::java_lang_Thread, - WellKnownClasses::java_lang_Thread_init, - runtime_->GetMainThreadGroup(), - thread_name.get(), - kMinThreadPriority, - JNI_FALSE); - ASSERT_FALSE(env->ExceptionCheck()); - - jmethodID start_id = env->GetMethodID(WellKnownClasses::java_lang_Thread, "start", "()V"); - ASSERT_TRUE(start_id != nullptr); - - env->CallVoidMethod(thread.get(), start_id); - ASSERT_FALSE(env->ExceptionCheck()); - - jmethodID join_id = env->GetMethodID(WellKnownClasses::java_lang_Thread, "join", "()V"); - ASSERT_TRUE(join_id != nullptr); - - env->CallVoidMethod(thread.get(), join_id); - ASSERT_FALSE(env->ExceptionCheck()); - - EXPECT_TRUE(cb_.state == CallbackState::kDied) << static_cast<int>(cb_.state); -} - -TEST_F(ThreadLifecycleCallbackRuntimeCallbacksTest, ThreadLifecycleCallbackAttach) { - std::string error_msg; - std::unique_ptr<MemMap> stack(MemMap::MapAnonymous("ThreadLifecycleCallback Thread", - nullptr, - 128 * kPageSize, // Just some small stack. - PROT_READ | PROT_WRITE, - false, - false, - &error_msg)); - ASSERT_FALSE(stack == nullptr) << error_msg; - - const char* reason = "ThreadLifecycleCallback test thread"; - pthread_attr_t attr; - CHECK_PTHREAD_CALL(pthread_attr_init, (&attr), reason); - CHECK_PTHREAD_CALL(pthread_attr_setstack, (&attr, stack->Begin(), stack->Size()), reason); - pthread_t pthread; - CHECK_PTHREAD_CALL(pthread_create, - (&pthread, - &attr, - &ThreadLifecycleCallbackRuntimeCallbacksTest::PthreadsCallback, - this), - reason); - CHECK_PTHREAD_CALL(pthread_attr_destroy, (&attr), reason); - - CHECK_PTHREAD_CALL(pthread_join, (pthread, nullptr), "ThreadLifecycleCallback test shutdown"); - - // Detach is not a ThreadDeath event, so we expect to be in state Started. - EXPECT_TRUE(cb_.state == CallbackState::kStarted) << static_cast<int>(cb_.state); -} - -} // namespace art diff --git a/runtime/thread.cc b/runtime/thread.cc index bf69e1010d..40b6d73d94 100644 --- a/runtime/thread.cc +++ b/runtime/thread.cc @@ -431,10 +431,7 @@ void* Thread::CreateCallback(void* arg) { ArtField* priorityField = jni::DecodeArtField(WellKnownClasses::java_lang_Thread_priority); self->SetNativePriority(priorityField->GetInt(self->tlsPtr_.opeer)); - { - ReaderMutexLock mu(self, *Locks::runtime_callbacks_lock_); - runtime->GetRuntimeCallbacks().ThreadStart(self); - } + Dbg::PostThreadStart(self); // Invoke the 'run' method of our java.lang.Thread. ObjPtr<mirror::Object> receiver = self->tlsPtr_.opeer; @@ -796,8 +793,7 @@ Thread* Thread::Attach(const char* thread_name, bool as_daemon, jobject thread_g { ScopedObjectAccess soa(self); - ReaderMutexLock mu(self, *Locks::runtime_callbacks_lock_); - runtime->GetRuntimeCallbacks().ThreadStart(self); + Dbg::PostThreadStart(self); } return self; @@ -1933,12 +1929,7 @@ void Thread::Destroy() { jni::DecodeArtField(WellKnownClasses::java_lang_Thread_nativePeer) ->SetLong<false>(tlsPtr_.opeer, 0); } - Runtime* runtime = Runtime::Current(); - if (runtime != nullptr) { - ReaderMutexLock mu(self, *Locks::runtime_callbacks_lock_); - runtime->GetRuntimeCallbacks().ThreadDeath(self); - } - + Dbg::PostThreadDeath(self); // Thread.join() is implemented as an Object.wait() on the Thread.lock object. Signal anyone // who is waiting. diff --git a/runtime/thread.h b/runtime/thread.h index 166ed217d0..2b451bcaee 100644 --- a/runtime/thread.h +++ b/runtime/thread.h @@ -1704,14 +1704,6 @@ class ScopedTransitioningToRunnable : public ValueObject { Thread* const self_; }; -class ThreadLifecycleCallback { - public: - virtual ~ThreadLifecycleCallback() {} - - virtual void ThreadStart(Thread* self) REQUIRES_SHARED(Locks::mutator_lock_) = 0; - virtual void ThreadDeath(Thread* self) REQUIRES_SHARED(Locks::mutator_lock_) = 0; -}; - std::ostream& operator<<(std::ostream& os, const Thread& thread); std::ostream& operator<<(std::ostream& os, const StackedShadowFrameType& thread); |