1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2018 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker *
4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker *
8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker *
10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker */
16*795d594fSAndroid Build Coastguard Worker
17*795d594fSAndroid Build Coastguard Worker #include "android-base/macros.h"
18*795d594fSAndroid Build Coastguard Worker #include "gc/scoped_gc_critical_section.h"
19*795d594fSAndroid Build Coastguard Worker #include "instrumentation.h"
20*795d594fSAndroid Build Coastguard Worker #include "runtime.h"
21*795d594fSAndroid Build Coastguard Worker #include "runtime_callbacks.h"
22*795d594fSAndroid Build Coastguard Worker #include "scoped_thread_state_change-inl.h"
23*795d594fSAndroid Build Coastguard Worker #include "thread-inl.h"
24*795d594fSAndroid Build Coastguard Worker #include "thread_list.h"
25*795d594fSAndroid Build Coastguard Worker
26*795d594fSAndroid Build Coastguard Worker namespace tracefast {
27*795d594fSAndroid Build Coastguard Worker
28*795d594fSAndroid Build Coastguard Worker #if ((!defined(TRACEFAST_INTERPRETER) && !defined(TRACEFAST_TRAMPOLINE)) || \
29*795d594fSAndroid Build Coastguard Worker (defined(TRACEFAST_INTERPRETER) && defined(TRACEFAST_TRAMPOLINE)))
30*795d594fSAndroid Build Coastguard Worker #error Must set one of TRACEFAST_TRAMPOLINE or TRACEFAST_INTERPRETER during build
31*795d594fSAndroid Build Coastguard Worker #endif
32*795d594fSAndroid Build Coastguard Worker
33*795d594fSAndroid Build Coastguard Worker
34*795d594fSAndroid Build Coastguard Worker #ifdef TRACEFAST_INTERPRETER
35*795d594fSAndroid Build Coastguard Worker static constexpr const char* kTracerInstrumentationKey = "tracefast_INTERPRETER";
36*795d594fSAndroid Build Coastguard Worker static constexpr bool kNeedsInterpreter = true;
37*795d594fSAndroid Build Coastguard Worker #else // defined(TRACEFAST_TRAMPOLINE)
38*795d594fSAndroid Build Coastguard Worker static constexpr const char* kTracerInstrumentationKey = "tracefast_TRAMPOLINE";
39*795d594fSAndroid Build Coastguard Worker static constexpr bool kNeedsInterpreter = false;
40*795d594fSAndroid Build Coastguard Worker #endif // TRACEFAST_INITERPRETER
41*795d594fSAndroid Build Coastguard Worker
42*795d594fSAndroid Build Coastguard Worker class Tracer final : public art::instrumentation::InstrumentationListener {
43*795d594fSAndroid Build Coastguard Worker public:
Tracer()44*795d594fSAndroid Build Coastguard Worker Tracer() {}
45*795d594fSAndroid Build Coastguard Worker
MethodEntered(art::Thread * thread,art::ArtMethod * method)46*795d594fSAndroid Build Coastguard Worker void MethodEntered([[maybe_unused]] art::Thread* thread,
47*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] art::ArtMethod* method) override
48*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(art::Locks::mutator_lock_) {}
49*795d594fSAndroid Build Coastguard Worker
MethodExited(art::Thread * thread,art::ArtMethod * method,art::instrumentation::OptionalFrame frame,art::MutableHandle<art::mirror::Object> & return_value)50*795d594fSAndroid Build Coastguard Worker void MethodExited([[maybe_unused]] art::Thread* thread,
51*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] art::ArtMethod* method,
52*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] art::instrumentation::OptionalFrame frame,
53*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] art::MutableHandle<art::mirror::Object>& return_value) override
54*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(art::Locks::mutator_lock_) {}
55*795d594fSAndroid Build Coastguard Worker
MethodExited(art::Thread * thread,art::ArtMethod * method,art::instrumentation::OptionalFrame frame,art::JValue & return_value)56*795d594fSAndroid Build Coastguard Worker void MethodExited([[maybe_unused]] art::Thread* thread,
57*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] art::ArtMethod* method,
58*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] art::instrumentation::OptionalFrame frame,
59*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] art::JValue& return_value) override
60*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(art::Locks::mutator_lock_) {}
61*795d594fSAndroid Build Coastguard Worker
MethodUnwind(art::Thread * thread,art::ArtMethod * method,uint32_t dex_pc)62*795d594fSAndroid Build Coastguard Worker void MethodUnwind([[maybe_unused]] art::Thread* thread,
63*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] art::ArtMethod* method,
64*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] uint32_t dex_pc) override
65*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(art::Locks::mutator_lock_) {}
66*795d594fSAndroid Build Coastguard Worker
DexPcMoved(art::Thread * thread,art::Handle<art::mirror::Object> this_object,art::ArtMethod * method,uint32_t new_dex_pc)67*795d594fSAndroid Build Coastguard Worker void DexPcMoved([[maybe_unused]] art::Thread* thread,
68*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] art::Handle<art::mirror::Object> this_object,
69*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] art::ArtMethod* method,
70*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] uint32_t new_dex_pc) override
71*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(art::Locks::mutator_lock_) {}
72*795d594fSAndroid Build Coastguard Worker
FieldRead(art::Thread * thread,art::Handle<art::mirror::Object> this_object,art::ArtMethod * method,uint32_t dex_pc,art::ArtField * field)73*795d594fSAndroid Build Coastguard Worker void FieldRead([[maybe_unused]] art::Thread* thread,
74*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] art::Handle<art::mirror::Object> this_object,
75*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] art::ArtMethod* method,
76*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] uint32_t dex_pc,
77*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] art::ArtField* field) override
78*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(art::Locks::mutator_lock_) {}
79*795d594fSAndroid Build Coastguard Worker
FieldWritten(art::Thread * thread,art::Handle<art::mirror::Object> this_object,art::ArtMethod * method,uint32_t dex_pc,art::ArtField * field,art::Handle<art::mirror::Object> field_value)80*795d594fSAndroid Build Coastguard Worker void FieldWritten([[maybe_unused]] art::Thread* thread,
81*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] art::Handle<art::mirror::Object> this_object,
82*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] art::ArtMethod* method,
83*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] uint32_t dex_pc,
84*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] art::ArtField* field,
85*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] art::Handle<art::mirror::Object> field_value) override
86*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(art::Locks::mutator_lock_) {}
87*795d594fSAndroid Build Coastguard Worker
FieldWritten(art::Thread * thread,art::Handle<art::mirror::Object> this_object,art::ArtMethod * method,uint32_t dex_pc,art::ArtField * field,const art::JValue & field_value)88*795d594fSAndroid Build Coastguard Worker void FieldWritten([[maybe_unused]] art::Thread* thread,
89*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] art::Handle<art::mirror::Object> this_object,
90*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] art::ArtMethod* method,
91*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] uint32_t dex_pc,
92*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] art::ArtField* field,
93*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] const art::JValue& field_value) override
94*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(art::Locks::mutator_lock_) {}
95*795d594fSAndroid Build Coastguard Worker
ExceptionThrown(art::Thread * thread,art::Handle<art::mirror::Throwable> exception_object)96*795d594fSAndroid Build Coastguard Worker void ExceptionThrown([[maybe_unused]] art::Thread* thread,
97*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] art::Handle<art::mirror::Throwable> exception_object)
98*795d594fSAndroid Build Coastguard Worker override REQUIRES_SHARED(art::Locks::mutator_lock_) {}
99*795d594fSAndroid Build Coastguard Worker
ExceptionHandled(art::Thread * self,art::Handle<art::mirror::Throwable> throwable)100*795d594fSAndroid Build Coastguard Worker void ExceptionHandled([[maybe_unused]] art::Thread* self,
101*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] art::Handle<art::mirror::Throwable> throwable) override
102*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(art::Locks::mutator_lock_) {}
103*795d594fSAndroid Build Coastguard Worker
Branch(art::Thread * thread,art::ArtMethod * method,uint32_t dex_pc,int32_t dex_pc_offset)104*795d594fSAndroid Build Coastguard Worker void Branch([[maybe_unused]] art::Thread* thread,
105*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] art::ArtMethod* method,
106*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] uint32_t dex_pc,
107*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] int32_t dex_pc_offset) override
108*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(art::Locks::mutator_lock_) {}
109*795d594fSAndroid Build Coastguard Worker
WatchedFramePop(art::Thread * thread,const art::ShadowFrame & frame)110*795d594fSAndroid Build Coastguard Worker void WatchedFramePop([[maybe_unused]] art::Thread* thread,
111*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] const art::ShadowFrame& frame) override
112*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(art::Locks::mutator_lock_) {}
113*795d594fSAndroid Build Coastguard Worker
114*795d594fSAndroid Build Coastguard Worker private:
115*795d594fSAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(Tracer);
116*795d594fSAndroid Build Coastguard Worker };
117*795d594fSAndroid Build Coastguard Worker
118*795d594fSAndroid Build Coastguard Worker Tracer gEmptyTracer;
119*795d594fSAndroid Build Coastguard Worker
StartTracing()120*795d594fSAndroid Build Coastguard Worker static void StartTracing() REQUIRES(!art::Locks::mutator_lock_,
121*795d594fSAndroid Build Coastguard Worker !art::Locks::thread_list_lock_,
122*795d594fSAndroid Build Coastguard Worker !art::Locks::thread_suspend_count_lock_) {
123*795d594fSAndroid Build Coastguard Worker art::Thread* self = art::Thread::Current();
124*795d594fSAndroid Build Coastguard Worker art::Runtime* runtime = art::Runtime::Current();
125*795d594fSAndroid Build Coastguard Worker art::gc::ScopedGCCriticalSection gcs(self,
126*795d594fSAndroid Build Coastguard Worker art::gc::kGcCauseInstrumentation,
127*795d594fSAndroid Build Coastguard Worker art::gc::kCollectorTypeInstrumentation);
128*795d594fSAndroid Build Coastguard Worker art::ScopedSuspendAll ssa("starting fast tracing");
129*795d594fSAndroid Build Coastguard Worker runtime->GetInstrumentation()->AddListener(&gEmptyTracer,
130*795d594fSAndroid Build Coastguard Worker art::instrumentation::Instrumentation::kMethodEntered |
131*795d594fSAndroid Build Coastguard Worker art::instrumentation::Instrumentation::kMethodExited |
132*795d594fSAndroid Build Coastguard Worker art::instrumentation::Instrumentation::kMethodUnwind);
133*795d594fSAndroid Build Coastguard Worker runtime->GetInstrumentation()->EnableMethodTracing(
134*795d594fSAndroid Build Coastguard Worker kTracerInstrumentationKey, &gEmptyTracer, kNeedsInterpreter);
135*795d594fSAndroid Build Coastguard Worker }
136*795d594fSAndroid Build Coastguard Worker
137*795d594fSAndroid Build Coastguard Worker class TraceFastPhaseCB : public art::RuntimePhaseCallback {
138*795d594fSAndroid Build Coastguard Worker public:
TraceFastPhaseCB()139*795d594fSAndroid Build Coastguard Worker TraceFastPhaseCB() {}
140*795d594fSAndroid Build Coastguard Worker
NextRuntimePhase(art::RuntimePhaseCallback::RuntimePhase phase)141*795d594fSAndroid Build Coastguard Worker void NextRuntimePhase(art::RuntimePhaseCallback::RuntimePhase phase)
142*795d594fSAndroid Build Coastguard Worker override REQUIRES_SHARED(art::Locks::mutator_lock_) {
143*795d594fSAndroid Build Coastguard Worker if (phase == art::RuntimePhaseCallback::RuntimePhase::kInit) {
144*795d594fSAndroid Build Coastguard Worker art::ScopedThreadSuspension sts(art::Thread::Current(),
145*795d594fSAndroid Build Coastguard Worker art::ThreadState::kWaitingForMethodTracingStart);
146*795d594fSAndroid Build Coastguard Worker StartTracing();
147*795d594fSAndroid Build Coastguard Worker }
148*795d594fSAndroid Build Coastguard Worker }
149*795d594fSAndroid Build Coastguard Worker };
150*795d594fSAndroid Build Coastguard Worker TraceFastPhaseCB gPhaseCallback;
151*795d594fSAndroid Build Coastguard Worker
152*795d594fSAndroid Build Coastguard Worker // The plugin initialization function.
ArtPlugin_Initialize()153*795d594fSAndroid Build Coastguard Worker extern "C" bool ArtPlugin_Initialize() {
154*795d594fSAndroid Build Coastguard Worker art::Runtime* runtime = art::Runtime::Current();
155*795d594fSAndroid Build Coastguard Worker art::ScopedThreadStateChange stsc(art::Thread::Current(),
156*795d594fSAndroid Build Coastguard Worker art::ThreadState::kWaitingForMethodTracingStart);
157*795d594fSAndroid Build Coastguard Worker art::ScopedSuspendAll ssa("Add phase callback");
158*795d594fSAndroid Build Coastguard Worker runtime->GetRuntimeCallbacks()->AddRuntimePhaseCallback(&gPhaseCallback);
159*795d594fSAndroid Build Coastguard Worker return true;
160*795d594fSAndroid Build Coastguard Worker }
161*795d594fSAndroid Build Coastguard Worker
ArtPlugin_Deinitialize()162*795d594fSAndroid Build Coastguard Worker extern "C" bool ArtPlugin_Deinitialize() {
163*795d594fSAndroid Build Coastguard Worker // Don't need to bother doing anything.
164*795d594fSAndroid Build Coastguard Worker return true;
165*795d594fSAndroid Build Coastguard Worker }
166*795d594fSAndroid Build Coastguard Worker
167*795d594fSAndroid Build Coastguard Worker } // namespace tracefast
168