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