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