diff options
| -rw-r--r-- | runtime/openjdkjvmti/ti_thread.cc | 39 | ||||
| -rw-r--r-- | runtime/openjdkjvmti/ti_thread.h | 3 | ||||
| -rw-r--r-- | runtime/thread.h | 12 |
3 files changed, 54 insertions, 0 deletions
diff --git a/runtime/openjdkjvmti/ti_thread.cc b/runtime/openjdkjvmti/ti_thread.cc index f7f63bd19c..2bcdd8cda1 100644 --- a/runtime/openjdkjvmti/ti_thread.cc +++ b/runtime/openjdkjvmti/ti_thread.cc @@ -35,11 +35,14 @@ #include "art_jvmti.h" #include "base/logging.h" #include "base/mutex.h" +#include "gc/system_weak.h" +#include "gc_root-inl.h" #include "jni_internal.h" #include "mirror/class.h" #include "mirror/object-inl.h" #include "mirror/string.h" #include "obj_ptr.h" +#include "runtime.h" #include "scoped_thread_state_change-inl.h" #include "thread-inl.h" #include "thread_list.h" @@ -400,7 +403,43 @@ jvmtiError ThreadUtil::GetAllThreads(jvmtiEnv* env, *threads_count_ptr = static_cast<jint>(peers.size()); *threads_ptr = threads; } + return ERR(NONE); +} + +jvmtiError ThreadUtil::SetThreadLocalStorage(jvmtiEnv* env ATTRIBUTE_UNUSED, + jthread thread, + const void* data) { + art::ScopedObjectAccess soa(art::Thread::Current()); + art::Thread* self = GetNativeThread(thread, soa); + if (self == nullptr && thread == nullptr) { + return ERR(INVALID_THREAD); + } + if (self == nullptr) { + return ERR(THREAD_NOT_ALIVE); + } + + self->SetCustomTLS(data); + + return ERR(NONE); +} + +jvmtiError ThreadUtil::GetThreadLocalStorage(jvmtiEnv* env ATTRIBUTE_UNUSED, + jthread thread, + void** data_ptr) { + if (data_ptr == nullptr) { + return ERR(NULL_POINTER); + } + + art::ScopedObjectAccess soa(art::Thread::Current()); + art::Thread* self = GetNativeThread(thread, soa); + if (self == nullptr && thread == nullptr) { + return ERR(INVALID_THREAD); + } + if (self == nullptr) { + return ERR(THREAD_NOT_ALIVE); + } + *data_ptr = const_cast<void*>(self->GetCustomTLS()); return ERR(NONE); } diff --git a/runtime/openjdkjvmti/ti_thread.h b/runtime/openjdkjvmti/ti_thread.h index fca42ad2b5..290e9d49b2 100644 --- a/runtime/openjdkjvmti/ti_thread.h +++ b/runtime/openjdkjvmti/ti_thread.h @@ -46,6 +46,9 @@ class ThreadUtil { static jvmtiError GetThreadInfo(jvmtiEnv* env, jthread thread, jvmtiThreadInfo* info_ptr); static jvmtiError GetThreadState(jvmtiEnv* env, jthread thread, jint* thread_state_ptr); + + static jvmtiError SetThreadLocalStorage(jvmtiEnv* env, jthread thread, const void* data); + static jvmtiError GetThreadLocalStorage(jvmtiEnv* env, jthread thread, void** data_ptr); }; } // namespace openjdkjvmti diff --git a/runtime/thread.h b/runtime/thread.h index d54a80df99..3958c10d57 100644 --- a/runtime/thread.h +++ b/runtime/thread.h @@ -1140,6 +1140,14 @@ class Thread { return debug_disallow_read_barrier_; } + const void* GetCustomTLS() const { + return custom_tls_; + } + + void SetCustomTLS(const void* data) { + custom_tls_ = data; + } + // Returns true if the current thread is the jit sensitive thread. bool IsJitSensitiveThread() const { return this == jit_sensitive_thread_; @@ -1600,6 +1608,10 @@ class Thread { // Pending extra checkpoints if checkpoint_function_ is already used. std::list<Closure*> checkpoint_overflow_ GUARDED_BY(Locks::thread_suspend_count_lock_); + // Custom TLS field that can be used by plugins. + // TODO: Generalize once we have more plugins. + const void* custom_tls_; + // True if the thread is allowed to call back into java (for e.g. during class resolution). // By default this is true. bool can_call_into_java_; |