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 #include "ti_monitor.h"
33 
34 #include <atomic>
35 #include <chrono>
36 #include <condition_variable>
37 #include <mutex>
38 
39 #include "art_jvmti.h"
40 #include "gc_root-inl.h"
41 #include "mirror/object-inl.h"
42 #include "monitor.h"
43 #include "runtime.h"
44 #include "scoped_thread_state_change-inl.h"
45 #include "thread-current-inl.h"
46 #include "ti_thread.h"
47 #include "thread.h"
48 #include "thread_pool.h"
49 
50 namespace openjdkjvmti {
51 
52 // We cannot use ART monitors, as they require the mutator lock for contention locking. We
53 // also cannot use pthread mutexes and condition variables (or C++11 abstractions) directly,
54 // as the do not have the right semantics for recursive mutexes and waiting (wait only unlocks
55 // the mutex once).
56 // So go ahead and use a wrapper that does the counting explicitly.
57 
58 class JvmtiMonitor {
59  public:
JvmtiMonitor()60   JvmtiMonitor() : owner_(nullptr), count_(0) { }
61 
Destroy(art::Thread * self,JvmtiMonitor * monitor)62   static bool Destroy(art::Thread* self, JvmtiMonitor* monitor) NO_THREAD_SAFETY_ANALYSIS {
63     // Check whether this thread holds the monitor, or nobody does.
64     art::Thread* owner_thread = monitor->owner_.load(std::memory_order_relaxed);
65     if (owner_thread != nullptr && self != owner_thread) {
66       return false;
67     }
68 
69     if (monitor->count_ > 0) {
70       monitor->count_ = 0;
71       monitor->owner_.store(nullptr, std::memory_order_relaxed);
72       monitor->mutex_.unlock();
73     }
74 
75     delete monitor;
76     return true;
77   }
78 
MonitorEnter(art::Thread * self,bool suspend)79   void MonitorEnter(art::Thread* self, bool suspend) NO_THREAD_SAFETY_ANALYSIS {
80     // Perform a suspend-check. The spec doesn't require this but real-world agents depend on this
81     // behavior. We do this by performing a suspend-check then retrying if the thread is suspended
82     // before or after locking the internal mutex.
83     do {
84       if (suspend) {
85         ThreadUtil::SuspendCheck(self);
86         if (ThreadUtil::WouldSuspendForUserCode(self)) {
87           continue;
88         }
89       }
90 
91       // Check for recursive enter.
92       if (IsOwner(self)) {
93         count_++;
94         return;
95       }
96 
97       // Checking for user-code suspension takes acquiring 2 art::Mutexes so we want to avoid doing
98       // that if possible. To avoid it we try to get the internal mutex without sleeping. If we do
99       // this we don't bother doing another suspend check since it can linearize after the lock.
100       if (mutex_.try_lock()) {
101         break;
102       } else {
103         // Lock with sleep. We will need to check for suspension after this to make sure that agents
104         // won't deadlock.
105         mutex_.lock();
106         if (!suspend || !ThreadUtil::WouldSuspendForUserCode(self)) {
107           break;
108         } else {
109           // We got suspended in the middle of waiting for the mutex. We should release the mutex
110           // and try again so we can get it while not suspended. This lets some other
111           // (non-suspended) thread acquire the mutex in case it's waiting to wake us up.
112           mutex_.unlock();
113           continue;
114         }
115       }
116     } while (true);
117 
118     DCHECK(owner_.load(std::memory_order_relaxed) == nullptr);
119     owner_.store(self, std::memory_order_relaxed);
120     DCHECK_EQ(0u, count_);
121     count_ = 1;
122   }
123 
MonitorExit(art::Thread * self)124   bool MonitorExit(art::Thread* self) NO_THREAD_SAFETY_ANALYSIS {
125     if (!IsOwner(self)) {
126       return false;
127     }
128 
129     --count_;
130     if (count_ == 0u) {
131       owner_.store(nullptr, std::memory_order_relaxed);
132       mutex_.unlock();
133     }
134 
135     return true;
136   }
137 
Wait(art::Thread * self)138   bool Wait(art::Thread* self) {
139     auto wait_without_timeout = [&](std::unique_lock<std::mutex>& lk) {
140       cond_.wait(lk);
141     };
142     return Wait(self, wait_without_timeout);
143   }
144 
Wait(art::Thread * self,uint64_t timeout_in_ms)145   bool Wait(art::Thread* self, uint64_t timeout_in_ms) {
146     auto wait_with_timeout = [&](std::unique_lock<std::mutex>& lk) {
147       cond_.wait_for(lk, std::chrono::milliseconds(timeout_in_ms));
148     };
149     return Wait(self, wait_with_timeout);
150   }
151 
Notify(art::Thread * self)152   bool Notify(art::Thread* self) {
153     return Notify(self, [&]() { cond_.notify_one(); });
154   }
155 
NotifyAll(art::Thread * self)156   bool NotifyAll(art::Thread* self) {
157     return Notify(self, [&]() { cond_.notify_all(); });
158   }
159 
160  private:
IsOwner(art::Thread * self) const161   bool IsOwner(art::Thread* self) const {
162     // There's a subtle correctness argument here for a relaxed load outside the critical section.
163     // A thread is guaranteed to see either its own latest store or another thread's store. If a
164     // thread sees another thread's store than it cannot be holding the lock.
165     art::Thread* owner_thread = owner_.load(std::memory_order_relaxed);
166     return self == owner_thread;
167   }
168 
169   template <typename T>
Wait(art::Thread * self,T how_to_wait)170   bool Wait(art::Thread* self, T how_to_wait) {
171     if (!IsOwner(self)) {
172       return false;
173     }
174 
175     size_t old_count = count_;
176     DCHECK_GT(old_count, 0u);
177 
178     count_ = 0;
179     owner_.store(nullptr, std::memory_order_relaxed);
180 
181     {
182       std::unique_lock<std::mutex> lk(mutex_, std::adopt_lock);
183       how_to_wait(lk);
184       // Here we release the mutex. We will get it back below. We first need to do a suspend-check
185       // without holding it however. This is done in the MonitorEnter function.
186       // TODO We could do this more efficiently.
187       // We hold the mutex_ but the overall monitor is not owned at this point.
188       CHECK(owner_.load(std::memory_order_relaxed) == nullptr);
189       DCHECK_EQ(0u, count_);
190     }
191 
192     // Reaquire the mutex/monitor, also go to sleep if we were suspended.
193     // TODO Give an extension to wait without suspension as well.
194     MonitorEnter(self, /*suspend=*/ true);
195     CHECK(owner_.load(std::memory_order_relaxed) == self);
196     DCHECK_EQ(1u, count_);
197     // Reset the count.
198     count_ = old_count;
199 
200     return true;
201   }
202 
203   template <typename T>
Notify(art::Thread * self,T how_to_notify)204   bool Notify(art::Thread* self, T how_to_notify) {
205     if (!IsOwner(self)) {
206       return false;
207     }
208 
209     how_to_notify();
210 
211     return true;
212   }
213 
214   std::mutex mutex_;
215   std::condition_variable cond_;
216   std::atomic<art::Thread*> owner_;
217   size_t count_;
218 };
219 
EncodeMonitor(JvmtiMonitor * monitor)220 static jrawMonitorID EncodeMonitor(JvmtiMonitor* monitor) {
221   return reinterpret_cast<jrawMonitorID>(monitor);
222 }
223 
DecodeMonitor(jrawMonitorID id)224 static JvmtiMonitor* DecodeMonitor(jrawMonitorID id) {
225   return reinterpret_cast<JvmtiMonitor*>(id);
226 }
227 
CreateRawMonitor(jvmtiEnv * env ATTRIBUTE_UNUSED,const char * name,jrawMonitorID * monitor_ptr)228 jvmtiError MonitorUtil::CreateRawMonitor(jvmtiEnv* env ATTRIBUTE_UNUSED,
229                                          const char* name,
230                                          jrawMonitorID* monitor_ptr) {
231   if (name == nullptr || monitor_ptr == nullptr) {
232     return ERR(NULL_POINTER);
233   }
234 
235   JvmtiMonitor* monitor = new JvmtiMonitor();
236   *monitor_ptr = EncodeMonitor(monitor);
237 
238   return ERR(NONE);
239 }
240 
DestroyRawMonitor(jvmtiEnv * env ATTRIBUTE_UNUSED,jrawMonitorID id)241 jvmtiError MonitorUtil::DestroyRawMonitor(jvmtiEnv* env ATTRIBUTE_UNUSED, jrawMonitorID id) {
242   if (id == nullptr) {
243     return ERR(INVALID_MONITOR);
244   }
245 
246   JvmtiMonitor* monitor = DecodeMonitor(id);
247   art::Thread* self = art::Thread::Current();
248 
249   if (!JvmtiMonitor::Destroy(self, monitor)) {
250     return ERR(NOT_MONITOR_OWNER);
251   }
252 
253   return ERR(NONE);
254 }
255 
RawMonitorEnterNoSuspend(jvmtiEnv * env ATTRIBUTE_UNUSED,jrawMonitorID id)256 jvmtiError MonitorUtil::RawMonitorEnterNoSuspend(jvmtiEnv* env ATTRIBUTE_UNUSED, jrawMonitorID id) {
257   if (id == nullptr) {
258     return ERR(INVALID_MONITOR);
259   }
260 
261   JvmtiMonitor* monitor = DecodeMonitor(id);
262   art::Thread* self = art::Thread::Current();
263 
264   monitor->MonitorEnter(self, /*suspend=*/false);
265 
266   return ERR(NONE);
267 }
268 
RawMonitorEnter(jvmtiEnv * env ATTRIBUTE_UNUSED,jrawMonitorID id)269 jvmtiError MonitorUtil::RawMonitorEnter(jvmtiEnv* env ATTRIBUTE_UNUSED, jrawMonitorID id) {
270   if (id == nullptr) {
271     return ERR(INVALID_MONITOR);
272   }
273 
274   JvmtiMonitor* monitor = DecodeMonitor(id);
275   art::Thread* self = art::Thread::Current();
276 
277   monitor->MonitorEnter(self, /*suspend=*/true);
278 
279   return ERR(NONE);
280 }
281 
RawMonitorExit(jvmtiEnv * env ATTRIBUTE_UNUSED,jrawMonitorID id)282 jvmtiError MonitorUtil::RawMonitorExit(jvmtiEnv* env ATTRIBUTE_UNUSED, jrawMonitorID id) {
283   if (id == nullptr) {
284     return ERR(INVALID_MONITOR);
285   }
286 
287   JvmtiMonitor* monitor = DecodeMonitor(id);
288   art::Thread* self = art::Thread::Current();
289 
290   if (!monitor->MonitorExit(self)) {
291     return ERR(NOT_MONITOR_OWNER);
292   }
293 
294   return ERR(NONE);
295 }
296 
RawMonitorWait(jvmtiEnv * env ATTRIBUTE_UNUSED,jrawMonitorID id,jlong millis)297 jvmtiError MonitorUtil::RawMonitorWait(jvmtiEnv* env ATTRIBUTE_UNUSED,
298                                        jrawMonitorID id,
299                                        jlong millis) {
300   if (id == nullptr) {
301     return ERR(INVALID_MONITOR);
302   }
303 
304   JvmtiMonitor* monitor = DecodeMonitor(id);
305   art::Thread* self = art::Thread::Current();
306 
307   // What millis < 0 means is not defined in the spec. Real world agents seem to assume that it is a
308   // valid call though. We treat it as though it was 0 and wait indefinitely.
309   bool result = (millis > 0)
310       ? monitor->Wait(self, static_cast<uint64_t>(millis))
311       : monitor->Wait(self);
312 
313   if (!result) {
314     return ERR(NOT_MONITOR_OWNER);
315   }
316 
317   // TODO: Make sure that is really what we should be checking here.
318   if (self->IsInterrupted()) {
319     return ERR(INTERRUPT);
320   }
321 
322   return ERR(NONE);
323 }
324 
RawMonitorNotify(jvmtiEnv * env ATTRIBUTE_UNUSED,jrawMonitorID id)325 jvmtiError MonitorUtil::RawMonitorNotify(jvmtiEnv* env ATTRIBUTE_UNUSED, jrawMonitorID id) {
326   if (id == nullptr) {
327     return ERR(INVALID_MONITOR);
328   }
329 
330   JvmtiMonitor* monitor = DecodeMonitor(id);
331   art::Thread* self = art::Thread::Current();
332 
333   if (!monitor->Notify(self)) {
334     return ERR(NOT_MONITOR_OWNER);
335   }
336 
337   return ERR(NONE);
338 }
339 
RawMonitorNotifyAll(jvmtiEnv * env ATTRIBUTE_UNUSED,jrawMonitorID id)340 jvmtiError MonitorUtil::RawMonitorNotifyAll(jvmtiEnv* env ATTRIBUTE_UNUSED, jrawMonitorID id) {
341   if (id == nullptr) {
342     return ERR(INVALID_MONITOR);
343   }
344 
345   JvmtiMonitor* monitor = DecodeMonitor(id);
346   art::Thread* self = art::Thread::Current();
347 
348   if (!monitor->NotifyAll(self)) {
349     return ERR(NOT_MONITOR_OWNER);
350   }
351 
352   return ERR(NONE);
353 }
354 
GetCurrentContendedMonitor(jvmtiEnv * env ATTRIBUTE_UNUSED,jthread thread,jobject * monitor)355 jvmtiError MonitorUtil::GetCurrentContendedMonitor(jvmtiEnv* env ATTRIBUTE_UNUSED,
356                                                    jthread thread,
357                                                    jobject* monitor) {
358   if (monitor == nullptr) {
359     return ERR(NULL_POINTER);
360   }
361   art::Thread* self = art::Thread::Current();
362   art::ScopedObjectAccess soa(self);
363   art::Locks::thread_list_lock_->ExclusiveLock(self);
364   art::Thread* target = nullptr;
365   jvmtiError err = ERR(INTERNAL);
366   if (!ThreadUtil::GetAliveNativeThread(thread, soa, &target, &err)) {
367     art::Locks::thread_list_lock_->ExclusiveUnlock(self);
368     return err;
369   }
370   struct GetContendedMonitorClosure : public art::Closure {
371    public:
372     GetContendedMonitorClosure() : out_(nullptr) {}
373 
374     void Run(art::Thread* target_thread) override REQUIRES_SHARED(art::Locks::mutator_lock_) {
375       art::ScopedAssertNoThreadSuspension sants("GetContendedMonitorClosure::Run");
376       switch (target_thread->GetState()) {
377         // These three we are actually currently waiting on a monitor and have sent the appropriate
378         // events (if anyone is listening).
379         case art::kBlocked:
380         case art::kTimedWaiting:
381         case art::kWaiting: {
382           out_ = art::GcRoot<art::mirror::Object>(art::Monitor::GetContendedMonitor(target_thread));
383           return;
384         }
385         case art::kTerminated:
386         case art::kRunnable:
387         case art::kSleeping:
388         case art::kWaitingForLockInflation:
389         case art::kWaitingForTaskProcessor:
390         case art::kWaitingForGcToComplete:
391         case art::kWaitingForCheckPointsToRun:
392         case art::kWaitingPerformingGc:
393         case art::kWaitingForDebuggerSend:
394         case art::kWaitingForDebuggerToAttach:
395         case art::kWaitingInMainDebuggerLoop:
396         case art::kWaitingForDebuggerSuspension:
397         case art::kWaitingForJniOnLoad:
398         case art::kWaitingForSignalCatcherOutput:
399         case art::kWaitingInMainSignalCatcherLoop:
400         case art::kWaitingForDeoptimization:
401         case art::kWaitingForMethodTracingStart:
402         case art::kWaitingForVisitObjects:
403         case art::kWaitingForGetObjectsAllocated:
404         case art::kWaitingWeakGcRootRead:
405         case art::kWaitingForGcThreadFlip:
406         case art::kNativeForAbort:
407         case art::kStarting:
408         case art::kNative:
409         case art::kSuspended: {
410           // We aren't currently (explicitly) waiting for a monitor so just return null.
411           return;
412         }
413       }
414     }
415 
416     jobject GetResult() REQUIRES_SHARED(art::Locks::mutator_lock_) {
417       return out_.IsNull()
418           ? nullptr
419           : art::Thread::Current()->GetJniEnv()->AddLocalReference<jobject>(out_.Read());
420     }
421 
422    private:
423     art::GcRoot<art::mirror::Object> out_;
424   };
425   art::ScopedAssertNoThreadSuspension sants("Performing GetCurrentContendedMonitor");
426   GetContendedMonitorClosure closure;
427   // RequestSynchronousCheckpoint releases the thread_list_lock_ as a part of its execution.  We
428   // need to avoid suspending as we wait for the checkpoint to occur since we are (potentially)
429   // transfering a GcRoot across threads.
430   if (!target->RequestSynchronousCheckpoint(&closure, art::ThreadState::kRunnable)) {
431     return ERR(THREAD_NOT_ALIVE);
432   }
433   *monitor = closure.GetResult();
434   return OK;
435 }
436 
437 }  // namespace openjdkjvmti
438