1 /* Copyright (C) 2017 The Android Open Source Project 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * 4 * This file implements interfaces from the file jvmti.h. This implementation 5 * is licensed under the same terms as the file jvmti.h. The 6 * copyright and license information for the file jvmti.h follows. 7 * 8 * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. 9 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 10 * 11 * This code is free software; you can redistribute it and/or modify it 12 * under the terms of the GNU General Public License version 2 only, as 13 * published by the Free Software Foundation. Oracle designates this 14 * particular file as subject to the "Classpath" exception as provided 15 * by Oracle in the LICENSE file that accompanied this code. 16 * 17 * This code is distributed in the hope that it will be useful, but WITHOUT 18 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 19 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 20 * version 2 for more details (a copy is included in the LICENSE file that 21 * accompanied this code). 22 * 23 * You should have received a copy of the GNU General Public License version 24 * 2 along with this work; if not, write to the Free Software Foundation, 25 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 26 * 27 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 28 * or visit www.oracle.com if you need additional information or have any 29 * questions. 30 */ 31 32 #ifndef ART_OPENJDKJVMTI_TI_THREAD_H_ 33 #define ART_OPENJDKJVMTI_TI_THREAD_H_ 34 35 #include "jni.h" 36 #include "jvmti.h" 37 38 #include "base/macros.h" 39 #include "base/mutex.h" 40 41 namespace art { 42 class ArtField; 43 class ScopedObjectAccessAlreadyRunnable; 44 class Thread; 45 class Closure; 46 } // namespace art 47 48 namespace openjdkjvmti { 49 50 class EventHandler; 51 52 class ThreadUtil { 53 public: 54 static void Register(EventHandler* event_handler); 55 static void Unregister(); 56 57 // To be called when it is safe to cache data. This means that we have at least entered the 58 // RuntimePhase::kInit but we might or might not have already called VMInit event. 59 static void CacheData(); 60 61 // Called just after we have sent the VMInit callback so that ThreadUtil can do final setup. This 62 // ensures that there are no timing issues between the two callbacks. 63 static void VMInitEventSent() REQUIRES_SHARED(art::Locks::mutator_lock_); 64 65 // Handle a jvmtiEnv going away. 66 static void RemoveEnvironment(jvmtiEnv* env); 67 68 static jvmtiError GetAllThreads(jvmtiEnv* env, jint* threads_count_ptr, jthread** threads_ptr); 69 70 static jvmtiError GetCurrentThread(jvmtiEnv* env, jthread* thread_ptr); 71 72 static jvmtiError GetThreadInfo(jvmtiEnv* env, jthread thread, jvmtiThreadInfo* info_ptr); 73 74 static jvmtiError GetThreadState(jvmtiEnv* env, jthread thread, jint* thread_state_ptr); 75 76 static jvmtiError SetThreadLocalStorage(jvmtiEnv* env, jthread thread, const void* data); 77 static jvmtiError GetThreadLocalStorage(jvmtiEnv* env, jthread thread, void** data_ptr); 78 79 static jvmtiError RunAgentThread(jvmtiEnv* env, 80 jthread thread, 81 jvmtiStartFunction proc, 82 const void* arg, 83 jint priority); 84 85 static jvmtiError SuspendThread(jvmtiEnv* env, jthread thread); 86 static jvmtiError ResumeThread(jvmtiEnv* env, jthread thread); 87 88 static jvmtiError SuspendThreadList(jvmtiEnv* env, 89 jint request_count, 90 const jthread* threads, 91 jvmtiError* results); 92 static jvmtiError ResumeThreadList(jvmtiEnv* env, 93 jint request_count, 94 const jthread* threads, 95 jvmtiError* results); 96 97 static jvmtiError StopThread(jvmtiEnv* env, jthread thr, jobject exception); 98 static jvmtiError InterruptThread(jvmtiEnv* env, jthread thr); 99 100 // Returns true if we decoded the thread and it is alive, false otherwise with an appropriate 101 // error placed into 'err'. A thread is alive if it has had it's 'start' function called and has 102 // (or at least could have) executed managed code and has not yet returned past it's first managed 103 // frame. This means that the thread returned might have IsStillStarting() return true. Code that 104 // does not consider that alive should check manually. 105 static bool GetAliveNativeThread(jthread thread, 106 const art::ScopedObjectAccessAlreadyRunnable& soa, 107 /*out*/ art::Thread** thr, 108 /*out*/ jvmtiError* err) 109 REQUIRES_SHARED(art::Locks::mutator_lock_) 110 REQUIRES(art::Locks::thread_list_lock_); 111 112 // Returns true if we decoded the thread, false otherwise with an appropriate error placed into 113 // 'err' 114 static bool GetNativeThread(jthread thread, 115 const art::ScopedObjectAccessAlreadyRunnable& soa, 116 /*out*/ art::Thread** thr, 117 /*out*/ jvmtiError* err) 118 REQUIRES_SHARED(art::Locks::mutator_lock_) 119 REQUIRES(art::Locks::thread_list_lock_); 120 121 // Go to sleep if this thread is suspended. 122 static void SuspendCheck(art::Thread* self) 123 REQUIRES(!art::Locks::mutator_lock_, !art::Locks::user_code_suspension_lock_); 124 125 // Returns true if the thread would be suspended if it locks the mutator-lock or calls 126 // SuspendCheck. This function is called with the user_code_suspension_lock already held. 127 static bool WouldSuspendForUserCodeLocked(art::Thread* self) 128 REQUIRES(art::Locks::user_code_suspension_lock_, 129 !art::Locks::thread_suspend_count_lock_); 130 131 // Returns true if this thread would go to sleep if it locks the mutator-lock or calls 132 // SuspendCheck. 133 static bool WouldSuspendForUserCode(art::Thread* self) 134 REQUIRES(!art::Locks::user_code_suspension_lock_, 135 !art::Locks::thread_suspend_count_lock_); 136 137 private: 138 // We need to make sure only one thread tries to suspend threads at a time so we can get the 139 // 'suspend-only-once' behavior the spec requires. Internally, ART considers suspension to be a 140 // counted state, allowing a single thread to be suspended multiple times by different users. This 141 // makes mapping into the JVMTI idea of thread suspension difficult. We have decided to split the 142 // difference and ensure that JVMTI tries to treat suspension as the boolean flag as much as 143 // possible with the suspend/resume methods but only do best effort. On the other hand 144 // GetThreadState will be totally accurate as much as possible. This means that calling 145 // ResumeThread on a thread that has state JVMTI_THREAD_STATE_SUSPENDED will not necessarily 146 // cause the thread to wake up if the thread is suspended for the debugger or gc or something. 147 static jvmtiError SuspendSelf(art::Thread* self) 148 REQUIRES(!art::Locks::mutator_lock_, !art::Locks::user_code_suspension_lock_); 149 static jvmtiError SuspendOther(art::Thread* self, jthread target_jthread) 150 REQUIRES(!art::Locks::mutator_lock_, !art::Locks::user_code_suspension_lock_); 151 152 static art::ArtField* context_class_loader_; 153 }; 154 155 } // namespace openjdkjvmti 156 157 #endif // ART_OPENJDKJVMTI_TI_THREAD_H_ 158