diff options
author | 2017-07-26 14:17:14 -0700 | |
---|---|---|
committer | 2017-07-31 07:38:43 -0700 | |
commit | 06c42a571358b5e5adb69104b183af8f32f4c07d (patch) | |
tree | 7b218fdb67fef74cdcbc2e3665757485ef89918b /openjdkjvmti/ti_phase.cc | |
parent | 7f14c2ec37c70010d99cab6806d85018df56c555 (diff) |
ART: Move openjdkjvmti to art/
Move libopenjdkjvmti out of the runtime directory. Let's not
pollute the runtime library.
Test: m test-art-host
Change-Id: Idb6b9cebcd61777bd3200437a2ae584a63a4a341
Diffstat (limited to 'openjdkjvmti/ti_phase.cc')
-rw-r--r-- | openjdkjvmti/ti_phase.cc | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/openjdkjvmti/ti_phase.cc b/openjdkjvmti/ti_phase.cc new file mode 100644 index 0000000000..8893c9b4aa --- /dev/null +++ b/openjdkjvmti/ti_phase.cc @@ -0,0 +1,155 @@ +/* Copyright (C) 2017 The Android Open Source Project + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This file implements interfaces from the file jvmti.h. This implementation + * is licensed under the same terms as the file jvmti.h. The + * copyright and license information for the file jvmti.h follows. + * + * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#include "ti_phase.h" + +#include "art_jvmti.h" +#include "base/macros.h" +#include "events-inl.h" +#include "nativehelper/ScopedLocalRef.h" +#include "runtime.h" +#include "runtime_callbacks.h" +#include "scoped_thread_state_change-inl.h" +#include "thread-current-inl.h" +#include "thread_list.h" +#include "ti_thread.h" + +namespace openjdkjvmti { + +jvmtiPhase PhaseUtil::current_phase_ = static_cast<jvmtiPhase>(0); + +struct PhaseUtil::PhaseCallback : public art::RuntimePhaseCallback { + inline static JNIEnv* GetJniEnv() { + return reinterpret_cast<JNIEnv*>(art::Thread::Current()->GetJniEnv()); + } + + inline static jthread GetCurrentJThread() { + art::ScopedObjectAccess soa(art::Thread::Current()); + return soa.AddLocalReference<jthread>(soa.Self()->GetPeer()); + } + + void NextRuntimePhase(RuntimePhase phase) REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE { + switch (phase) { + case RuntimePhase::kInitialAgents: + PhaseUtil::current_phase_ = JVMTI_PHASE_PRIMORDIAL; + break; + case RuntimePhase::kStart: + { + art::ScopedThreadSuspension sts(art::Thread::Current(), art::ThreadState::kNative); + event_handler->DispatchEvent<ArtJvmtiEvent::kVmStart>(nullptr, GetJniEnv()); + PhaseUtil::current_phase_ = JVMTI_PHASE_START; + } + break; + case RuntimePhase::kInit: + { + ThreadUtil::CacheData(); + ScopedLocalRef<jthread> thread(GetJniEnv(), GetCurrentJThread()); + art::ScopedThreadSuspension sts(art::Thread::Current(), art::ThreadState::kNative); + event_handler->DispatchEvent<ArtJvmtiEvent::kVmInit>(nullptr, GetJniEnv(), thread.get()); + PhaseUtil::current_phase_ = JVMTI_PHASE_LIVE; + } + break; + case RuntimePhase::kDeath: + { + art::ScopedThreadSuspension sts(art::Thread::Current(), art::ThreadState::kNative); + event_handler->DispatchEvent<ArtJvmtiEvent::kVmDeath>(nullptr, GetJniEnv()); + PhaseUtil::current_phase_ = JVMTI_PHASE_DEAD; + } + // TODO: Block events now. + break; + } + } + + EventHandler* event_handler = nullptr; +}; + +PhaseUtil::PhaseCallback gPhaseCallback; + +jvmtiError PhaseUtil::GetPhase(jvmtiEnv* env ATTRIBUTE_UNUSED, jvmtiPhase* phase_ptr) { + if (phase_ptr == nullptr) { + return ERR(NULL_POINTER); + } + jvmtiPhase now = PhaseUtil::current_phase_; + DCHECK(now == JVMTI_PHASE_ONLOAD || + now == JVMTI_PHASE_PRIMORDIAL || + now == JVMTI_PHASE_START || + now == JVMTI_PHASE_LIVE || + now == JVMTI_PHASE_DEAD); + *phase_ptr = now; + return ERR(NONE); +} + +bool PhaseUtil::IsLivePhase() { + jvmtiPhase now = PhaseUtil::current_phase_; + DCHECK(now == JVMTI_PHASE_ONLOAD || + now == JVMTI_PHASE_PRIMORDIAL || + now == JVMTI_PHASE_START || + now == JVMTI_PHASE_LIVE || + now == JVMTI_PHASE_DEAD); + return now == JVMTI_PHASE_LIVE; +} + +void PhaseUtil::SetToOnLoad() { + DCHECK_EQ(0u, static_cast<size_t>(PhaseUtil::current_phase_)); + PhaseUtil::current_phase_ = JVMTI_PHASE_ONLOAD; +} + +void PhaseUtil::SetToPrimordial() { + DCHECK_EQ(static_cast<size_t>(JVMTI_PHASE_ONLOAD), static_cast<size_t>(PhaseUtil::current_phase_)); + PhaseUtil::current_phase_ = JVMTI_PHASE_ONLOAD; +} + +void PhaseUtil::SetToLive() { + DCHECK_EQ(static_cast<size_t>(0), static_cast<size_t>(PhaseUtil::current_phase_)); + ThreadUtil::CacheData(); + PhaseUtil::current_phase_ = JVMTI_PHASE_LIVE; +} + +void PhaseUtil::Register(EventHandler* handler) { + gPhaseCallback.event_handler = handler; + art::ScopedThreadStateChange stsc(art::Thread::Current(), + art::ThreadState::kWaitingForDebuggerToAttach); + art::ScopedSuspendAll ssa("Add phase callback"); + art::Runtime::Current()->GetRuntimeCallbacks()->AddRuntimePhaseCallback(&gPhaseCallback); +} + +void PhaseUtil::Unregister() { + art::ScopedThreadStateChange stsc(art::Thread::Current(), + art::ThreadState::kWaitingForDebuggerToAttach); + art::ScopedSuspendAll ssa("Remove phase callback"); + art::Runtime::Current()->GetRuntimeCallbacks()->RemoveRuntimePhaseCallback(&gPhaseCallback); +} + +jvmtiPhase PhaseUtil::GetPhaseUnchecked() { + return PhaseUtil::current_phase_; +} + +} // namespace openjdkjvmti |