blob: aac72333039794b2cf9ee98d58a888dc06cc95ed [file] [log] [blame]
Andreas Gampe319dbe82017-01-09 16:42:21 -08001/* 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>
Igor Murashkin5573c372017-11-16 13:34:30 -080035#include <chrono>
36#include <condition_variable>
37#include <mutex>
Andreas Gampe319dbe82017-01-09 16:42:21 -080038
39#include "art_jvmti.h"
Alex Light318afe62018-03-22 16:50:10 -070040#include "gc_root-inl.h"
Roland Levillaind69003a2018-09-26 19:32:39 +010041#include "mirror/object-inl.h"
Alex Light41006c62017-09-14 09:51:14 -070042#include "monitor.h"
Andreas Gampe319dbe82017-01-09 16:42:21 -080043#include "runtime.h"
44#include "scoped_thread_state_change-inl.h"
Andreas Gampeb486a982017-06-01 13:45:54 -070045#include "thread-current-inl.h"
Alex Light23aa7482017-08-16 10:01:13 -070046#include "ti_thread.h"
Alex Light41006c62017-09-14 09:51:14 -070047#include "thread.h"
48#include "thread_pool.h"
Andreas Gampe319dbe82017-01-09 16:42:21 -080049
50namespace 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
58class JvmtiMonitor {
59 public:
Alex Light23aa7482017-08-16 10:01:13 -070060 JvmtiMonitor() : owner_(nullptr), count_(0) { }
Andreas Gampe319dbe82017-01-09 16:42:21 -080061
David Sehrae3bcac2017-02-03 15:19:00 -080062 static bool Destroy(art::Thread* self, JvmtiMonitor* monitor) NO_THREAD_SAFETY_ANALYSIS {
Andreas Gampe319dbe82017-01-09 16:42:21 -080063 // 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
Alex Lightc98f83e2018-07-26 08:28:36 -070079 void MonitorEnter(art::Thread* self, bool suspend) NO_THREAD_SAFETY_ANALYSIS {
Alex Light23aa7482017-08-16 10:01:13 -070080 // 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 {
Alex Lightc98f83e2018-07-26 08:28:36 -070084 if (suspend) {
85 ThreadUtil::SuspendCheck(self);
86 if (ThreadUtil::WouldSuspendForUserCode(self)) {
87 continue;
88 }
Alex Light23aa7482017-08-16 10:01:13 -070089 }
Andreas Gampe319dbe82017-01-09 16:42:21 -080090
Alex Light23aa7482017-08-16 10:01:13 -070091 // 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();
Alex Lightc98f83e2018-07-26 08:28:36 -0700106 if (!suspend || !ThreadUtil::WouldSuspendForUserCode(self)) {
Alex Light23aa7482017-08-16 10:01:13 -0700107 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);
Andreas Gampe319dbe82017-01-09 16:42:21 -0800117
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
David Sehrae3bcac2017-02-03 15:19:00 -0800124 bool MonitorExit(art::Thread* self) NO_THREAD_SAFETY_ANALYSIS {
Andreas Gampe319dbe82017-01-09 16:42:21 -0800125 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
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
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
152 bool Notify(art::Thread* self) {
153 return Notify(self, [&]() { cond_.notify_one(); });
154 }
155
156 bool NotifyAll(art::Thread* self) {
157 return Notify(self, [&]() { cond_.notify_all(); });
158 }
159
160 private:
Alex Light23aa7482017-08-16 10:01:13 -0700161 bool IsOwner(art::Thread* self) const {
Andreas Gampe319dbe82017-01-09 16:42:21 -0800162 // 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>
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_;
Alex Light4d77daf2018-01-04 11:51:14 -0800176 DCHECK_GT(old_count, 0u);
Andreas Gampe319dbe82017-01-09 16:42:21 -0800177
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);
Alex Light4d77daf2018-01-04 11:51:14 -0800184 // 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_);
Andreas Gampe319dbe82017-01-09 16:42:21 -0800190 }
191
Alex Light4d77daf2018-01-04 11:51:14 -0800192 // Reaquire the mutex/monitor, also go to sleep if we were suspended.
Alex Lightc98f83e2018-07-26 08:28:36 -0700193 // TODO Give an extension to wait without suspension as well.
Andreas Gampe6e897762018-10-16 13:09:32 -0700194 MonitorEnter(self, /*suspend=*/ true);
Alex Light4d77daf2018-01-04 11:51:14 -0800195 CHECK(owner_.load(std::memory_order_relaxed) == self);
196 DCHECK_EQ(1u, count_);
197 // Reset the count.
Andreas Gampe319dbe82017-01-09 16:42:21 -0800198 count_ = old_count;
199
200 return true;
201 }
202
203 template <typename T>
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
220static jrawMonitorID EncodeMonitor(JvmtiMonitor* monitor) {
221 return reinterpret_cast<jrawMonitorID>(monitor);
222}
223
224static JvmtiMonitor* DecodeMonitor(jrawMonitorID id) {
225 return reinterpret_cast<JvmtiMonitor*>(id);
226}
227
228jvmtiError 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
241jvmtiError 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
Alex Lightc98f83e2018-07-26 08:28:36 -0700256jvmtiError 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
Andreas Gampe6e897762018-10-16 13:09:32 -0700264 monitor->MonitorEnter(self, /*suspend=*/false);
Alex Lightc98f83e2018-07-26 08:28:36 -0700265
266 return ERR(NONE);
267}
268
Andreas Gampe319dbe82017-01-09 16:42:21 -0800269jvmtiError 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
Andreas Gampe6e897762018-10-16 13:09:32 -0700277 monitor->MonitorEnter(self, /*suspend=*/true);
Andreas Gampe319dbe82017-01-09 16:42:21 -0800278
279 return ERR(NONE);
280}
281
282jvmtiError 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
297jvmtiError 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
Alex Light6ced0912017-08-16 15:16:13 -0700307 // 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.
Andreas Gampe319dbe82017-01-09 16:42:21 -0800309 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
325jvmtiError 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
340jvmtiError 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
Alex Light41006c62017-09-14 09:51:14 -0700355jvmtiError 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);
Alex Lightb1e31a82017-10-04 16:57:36 -0700363 art::Locks::thread_list_lock_->ExclusiveLock(self);
Alex Light7ddc23d2017-09-22 15:33:41 -0700364 art::Thread* target = nullptr;
365 jvmtiError err = ERR(INTERNAL);
366 if (!ThreadUtil::GetAliveNativeThread(thread, soa, &target, &err)) {
Alex Lightb1e31a82017-10-04 16:57:36 -0700367 art::Locks::thread_list_lock_->ExclusiveUnlock(self);
Alex Light7ddc23d2017-09-22 15:33:41 -0700368 return err;
Alex Light41006c62017-09-14 09:51:14 -0700369 }
370 struct GetContendedMonitorClosure : public art::Closure {
371 public:
Alex Light318afe62018-03-22 16:50:10 -0700372 GetContendedMonitorClosure() : out_(nullptr) {}
Alex Light41006c62017-09-14 09:51:14 -0700373
Andreas Gampefa6a1b02018-09-07 08:11:55 -0700374 void Run(art::Thread* target_thread) override REQUIRES_SHARED(art::Locks::mutator_lock_) {
Alex Light318afe62018-03-22 16:50:10 -0700375 art::ScopedAssertNoThreadSuspension sants("GetContendedMonitorClosure::Run");
Alex Light41006c62017-09-14 09:51:14 -0700376 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: {
Alex Light318afe62018-03-22 16:50:10 -0700382 out_ = art::GcRoot<art::mirror::Object>(art::Monitor::GetContendedMonitor(target_thread));
Alex Light41006c62017-09-14 09:51:14 -0700383 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::kStarting:
407 case art::kNative:
408 case art::kSuspended: {
Alex Light318afe62018-03-22 16:50:10 -0700409 // We aren't currently (explicitly) waiting for a monitor so just return null.
Alex Light41006c62017-09-14 09:51:14 -0700410 return;
411 }
412 }
413 }
414
Alex Light318afe62018-03-22 16:50:10 -0700415 jobject GetResult() REQUIRES_SHARED(art::Locks::mutator_lock_) {
416 return out_.IsNull()
417 ? nullptr
418 : art::Thread::Current()->GetJniEnv()->AddLocalReference<jobject>(out_.Read());
419 }
420
Alex Light41006c62017-09-14 09:51:14 -0700421 private:
Alex Light318afe62018-03-22 16:50:10 -0700422 art::GcRoot<art::mirror::Object> out_;
Alex Light41006c62017-09-14 09:51:14 -0700423 };
Alex Light318afe62018-03-22 16:50:10 -0700424 art::ScopedAssertNoThreadSuspension sants("Performing GetCurrentContendedMonitor");
425 GetContendedMonitorClosure closure;
426 // RequestSynchronousCheckpoint releases the thread_list_lock_ as a part of its execution. We
427 // need to avoid suspending as we wait for the checkpoint to occur since we are (potentially)
428 // transfering a GcRoot across threads.
429 if (!target->RequestSynchronousCheckpoint(&closure, art::ThreadState::kRunnable)) {
Alex Light7ddc23d2017-09-22 15:33:41 -0700430 return ERR(THREAD_NOT_ALIVE);
431 }
Alex Light318afe62018-03-22 16:50:10 -0700432 *monitor = closure.GetResult();
Alex Light41006c62017-09-14 09:51:14 -0700433 return OK;
434}
435
Andreas Gampe319dbe82017-01-09 16:42:21 -0800436} // namespace openjdkjvmti