1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2011 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 #ifndef ART_RUNTIME_TRACE_H_
18*795d594fSAndroid Build Coastguard Worker #define ART_RUNTIME_TRACE_H_
19*795d594fSAndroid Build Coastguard Worker
20*795d594fSAndroid Build Coastguard Worker #include <bitset>
21*795d594fSAndroid Build Coastguard Worker #include <map>
22*795d594fSAndroid Build Coastguard Worker #include <memory>
23*795d594fSAndroid Build Coastguard Worker #include <ostream>
24*795d594fSAndroid Build Coastguard Worker #include <set>
25*795d594fSAndroid Build Coastguard Worker #include <string>
26*795d594fSAndroid Build Coastguard Worker #include <unordered_map>
27*795d594fSAndroid Build Coastguard Worker #include <vector>
28*795d594fSAndroid Build Coastguard Worker
29*795d594fSAndroid Build Coastguard Worker #include "base/atomic.h"
30*795d594fSAndroid Build Coastguard Worker #include "base/locks.h"
31*795d594fSAndroid Build Coastguard Worker #include "base/macros.h"
32*795d594fSAndroid Build Coastguard Worker #include "base/mutex.h"
33*795d594fSAndroid Build Coastguard Worker #include "base/os.h"
34*795d594fSAndroid Build Coastguard Worker #include "base/safe_map.h"
35*795d594fSAndroid Build Coastguard Worker #include "class_linker.h"
36*795d594fSAndroid Build Coastguard Worker #include "instrumentation.h"
37*795d594fSAndroid Build Coastguard Worker #include "runtime_globals.h"
38*795d594fSAndroid Build Coastguard Worker #include "thread_pool.h"
39*795d594fSAndroid Build Coastguard Worker
40*795d594fSAndroid Build Coastguard Worker namespace unix_file {
41*795d594fSAndroid Build Coastguard Worker class FdFile;
42*795d594fSAndroid Build Coastguard Worker } // namespace unix_file
43*795d594fSAndroid Build Coastguard Worker
44*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN {
45*795d594fSAndroid Build Coastguard Worker
46*795d594fSAndroid Build Coastguard Worker class ArtField;
47*795d594fSAndroid Build Coastguard Worker class ArtMethod;
48*795d594fSAndroid Build Coastguard Worker class DexFile;
49*795d594fSAndroid Build Coastguard Worker class ShadowFrame;
50*795d594fSAndroid Build Coastguard Worker class Thread;
51*795d594fSAndroid Build Coastguard Worker
52*795d594fSAndroid Build Coastguard Worker struct MethodTraceRecord;
53*795d594fSAndroid Build Coastguard Worker
54*795d594fSAndroid Build Coastguard Worker using DexIndexBitSet = std::bitset<65536>;
55*795d594fSAndroid Build Coastguard Worker
56*795d594fSAndroid Build Coastguard Worker enum TracingMode {
57*795d594fSAndroid Build Coastguard Worker kTracingInactive,
58*795d594fSAndroid Build Coastguard Worker kMethodTracingActive, // Trace activity synchronous with method progress.
59*795d594fSAndroid Build Coastguard Worker kSampleProfilingActive, // Trace activity captured by sampling thread.
60*795d594fSAndroid Build Coastguard Worker };
61*795d594fSAndroid Build Coastguard Worker std::ostream& operator<<(std::ostream& os, TracingMode rhs);
62*795d594fSAndroid Build Coastguard Worker
63*795d594fSAndroid Build Coastguard Worker // File format:
64*795d594fSAndroid Build Coastguard Worker // header
65*795d594fSAndroid Build Coastguard Worker // record 0
66*795d594fSAndroid Build Coastguard Worker // record 1
67*795d594fSAndroid Build Coastguard Worker // ...
68*795d594fSAndroid Build Coastguard Worker //
69*795d594fSAndroid Build Coastguard Worker // Header format:
70*795d594fSAndroid Build Coastguard Worker // u4 magic ('SLOW')
71*795d594fSAndroid Build Coastguard Worker // u2 version
72*795d594fSAndroid Build Coastguard Worker // u2 offset to data
73*795d594fSAndroid Build Coastguard Worker // u8 start date/time in usec
74*795d594fSAndroid Build Coastguard Worker // u2 record size in bytes (version >= 2 only)
75*795d594fSAndroid Build Coastguard Worker // ... padding to 32 bytes
76*795d594fSAndroid Build Coastguard Worker //
77*795d594fSAndroid Build Coastguard Worker // Record format v1:
78*795d594fSAndroid Build Coastguard Worker // u1 thread ID
79*795d594fSAndroid Build Coastguard Worker // u4 method ID | method action
80*795d594fSAndroid Build Coastguard Worker // u4 time delta since start, in usec
81*795d594fSAndroid Build Coastguard Worker //
82*795d594fSAndroid Build Coastguard Worker // Record format v2:
83*795d594fSAndroid Build Coastguard Worker // u2 thread ID
84*795d594fSAndroid Build Coastguard Worker // u4 method ID | method action
85*795d594fSAndroid Build Coastguard Worker // u4 time delta since start, in usec
86*795d594fSAndroid Build Coastguard Worker //
87*795d594fSAndroid Build Coastguard Worker // Record format v3:
88*795d594fSAndroid Build Coastguard Worker // u2 thread ID
89*795d594fSAndroid Build Coastguard Worker // u4 method ID | method action
90*795d594fSAndroid Build Coastguard Worker // u4 time delta since start, in usec
91*795d594fSAndroid Build Coastguard Worker // u4 wall time since start, in usec (when clock == "dual" only)
92*795d594fSAndroid Build Coastguard Worker //
93*795d594fSAndroid Build Coastguard Worker // 32 bits of microseconds is 70 minutes.
94*795d594fSAndroid Build Coastguard Worker //
95*795d594fSAndroid Build Coastguard Worker // All values are stored in little-endian order.
96*795d594fSAndroid Build Coastguard Worker
97*795d594fSAndroid Build Coastguard Worker enum TraceAction {
98*795d594fSAndroid Build Coastguard Worker kTraceMethodEnter = 0x00, // method entry
99*795d594fSAndroid Build Coastguard Worker kTraceMethodExit = 0x01, // method exit
100*795d594fSAndroid Build Coastguard Worker kTraceUnroll = 0x02, // method exited by exception unrolling
101*795d594fSAndroid Build Coastguard Worker // 0x03 currently unused
102*795d594fSAndroid Build Coastguard Worker kTraceMethodActionMask = 0x03, // two bits
103*795d594fSAndroid Build Coastguard Worker };
104*795d594fSAndroid Build Coastguard Worker
105*795d594fSAndroid Build Coastguard Worker enum class TraceOutputMode {
106*795d594fSAndroid Build Coastguard Worker kFile,
107*795d594fSAndroid Build Coastguard Worker kDDMS,
108*795d594fSAndroid Build Coastguard Worker kStreaming
109*795d594fSAndroid Build Coastguard Worker };
110*795d594fSAndroid Build Coastguard Worker
111*795d594fSAndroid Build Coastguard Worker // We need 3 entries to store 64-bit timestamp counter as two 32-bit values on 32-bit architectures.
112*795d594fSAndroid Build Coastguard Worker static constexpr uint32_t kNumEntriesForWallClock =
113*795d594fSAndroid Build Coastguard Worker (kRuntimePointerSize == PointerSize::k64) ? 2 : 3;
114*795d594fSAndroid Build Coastguard Worker static constexpr uint32_t kNumEntriesForDualClock = kNumEntriesForWallClock + 1;
115*795d594fSAndroid Build Coastguard Worker
116*795d594fSAndroid Build Coastguard Worker // These define offsets in bytes for the individual fields of a trace entry. These are used by the
117*795d594fSAndroid Build Coastguard Worker // JITed code when storing a trace entry.
118*795d594fSAndroid Build Coastguard Worker static constexpr int32_t kMethodOffsetInBytes = 0;
119*795d594fSAndroid Build Coastguard Worker static constexpr int32_t kTimestampOffsetInBytes = 1 * static_cast<uint32_t>(kRuntimePointerSize);
120*795d594fSAndroid Build Coastguard Worker // On 32-bit architectures we store 64-bit timestamp as two 32-bit values.
121*795d594fSAndroid Build Coastguard Worker // kHighTimestampOffsetInBytes is only relevant on 32-bit architectures.
122*795d594fSAndroid Build Coastguard Worker static constexpr int32_t kHighTimestampOffsetInBytes =
123*795d594fSAndroid Build Coastguard Worker 2 * static_cast<uint32_t>(kRuntimePointerSize);
124*795d594fSAndroid Build Coastguard Worker
125*795d594fSAndroid Build Coastguard Worker static constexpr uintptr_t kMaskTraceAction = ~0b11;
126*795d594fSAndroid Build Coastguard Worker
127*795d594fSAndroid Build Coastguard Worker // Packet type encoding for the new method tracing format.
128*795d594fSAndroid Build Coastguard Worker static constexpr int kThreadInfoHeaderV2 = 0;
129*795d594fSAndroid Build Coastguard Worker static constexpr int kMethodInfoHeaderV2 = 1;
130*795d594fSAndroid Build Coastguard Worker static constexpr int kEntryHeaderV2 = 2;
131*795d594fSAndroid Build Coastguard Worker static constexpr int kSummaryHeaderV2 = 3;
132*795d594fSAndroid Build Coastguard Worker
133*795d594fSAndroid Build Coastguard Worker // Packet sizes for the new method tracing format.
134*795d594fSAndroid Build Coastguard Worker static constexpr uint16_t kTraceHeaderLengthV2 = 32;
135*795d594fSAndroid Build Coastguard Worker static constexpr uint16_t kTraceRecordSizeSingleClockV2 = 6;
136*795d594fSAndroid Build Coastguard Worker static constexpr uint16_t kTraceRecordSizeDualClockV2 = kTraceRecordSizeSingleClockV2 + 2;
137*795d594fSAndroid Build Coastguard Worker static constexpr uint16_t kEntryHeaderSizeV2 = 12;
138*795d594fSAndroid Build Coastguard Worker
139*795d594fSAndroid Build Coastguard Worker static constexpr uint16_t kTraceVersionSingleClockV2 = 4;
140*795d594fSAndroid Build Coastguard Worker static constexpr uint16_t kTraceVersionDualClockV2 = 5;
141*795d594fSAndroid Build Coastguard Worker
142*795d594fSAndroid Build Coastguard Worker // TODO(mythria): Consider adding checks to guard agaist OOB access for Append*LE methods.
143*795d594fSAndroid Build Coastguard Worker // Currently the onus is on the callers to ensure there is sufficient space in the buffer.
144*795d594fSAndroid Build Coastguard Worker // TODO: put this somewhere with the big-endian equivalent used by JDWP.
Append2LE(uint8_t * buf,uint16_t val)145*795d594fSAndroid Build Coastguard Worker static inline void Append2LE(uint8_t* buf, uint16_t val) {
146*795d594fSAndroid Build Coastguard Worker *buf++ = static_cast<uint8_t>(val);
147*795d594fSAndroid Build Coastguard Worker *buf++ = static_cast<uint8_t>(val >> 8);
148*795d594fSAndroid Build Coastguard Worker }
149*795d594fSAndroid Build Coastguard Worker
150*795d594fSAndroid Build Coastguard Worker // TODO: put this somewhere with the big-endian equivalent used by JDWP.
Append3LE(uint8_t * buf,uint16_t val)151*795d594fSAndroid Build Coastguard Worker static inline void Append3LE(uint8_t* buf, uint16_t val) {
152*795d594fSAndroid Build Coastguard Worker *buf++ = static_cast<uint8_t>(val);
153*795d594fSAndroid Build Coastguard Worker *buf++ = static_cast<uint8_t>(val >> 8);
154*795d594fSAndroid Build Coastguard Worker *buf++ = static_cast<uint8_t>(val >> 16);
155*795d594fSAndroid Build Coastguard Worker }
156*795d594fSAndroid Build Coastguard Worker
157*795d594fSAndroid Build Coastguard Worker // TODO: put this somewhere with the big-endian equivalent used by JDWP.
Append4LE(uint8_t * buf,uint32_t val)158*795d594fSAndroid Build Coastguard Worker static inline void Append4LE(uint8_t* buf, uint32_t val) {
159*795d594fSAndroid Build Coastguard Worker *buf++ = static_cast<uint8_t>(val);
160*795d594fSAndroid Build Coastguard Worker *buf++ = static_cast<uint8_t>(val >> 8);
161*795d594fSAndroid Build Coastguard Worker *buf++ = static_cast<uint8_t>(val >> 16);
162*795d594fSAndroid Build Coastguard Worker *buf++ = static_cast<uint8_t>(val >> 24);
163*795d594fSAndroid Build Coastguard Worker }
164*795d594fSAndroid Build Coastguard Worker
165*795d594fSAndroid Build Coastguard Worker // TODO: put this somewhere with the big-endian equivalent used by JDWP.
Append8LE(uint8_t * buf,uint64_t val)166*795d594fSAndroid Build Coastguard Worker static inline void Append8LE(uint8_t* buf, uint64_t val) {
167*795d594fSAndroid Build Coastguard Worker *buf++ = static_cast<uint8_t>(val);
168*795d594fSAndroid Build Coastguard Worker *buf++ = static_cast<uint8_t>(val >> 8);
169*795d594fSAndroid Build Coastguard Worker *buf++ = static_cast<uint8_t>(val >> 16);
170*795d594fSAndroid Build Coastguard Worker *buf++ = static_cast<uint8_t>(val >> 24);
171*795d594fSAndroid Build Coastguard Worker *buf++ = static_cast<uint8_t>(val >> 32);
172*795d594fSAndroid Build Coastguard Worker *buf++ = static_cast<uint8_t>(val >> 40);
173*795d594fSAndroid Build Coastguard Worker *buf++ = static_cast<uint8_t>(val >> 48);
174*795d594fSAndroid Build Coastguard Worker *buf++ = static_cast<uint8_t>(val >> 56);
175*795d594fSAndroid Build Coastguard Worker }
176*795d594fSAndroid Build Coastguard Worker
177*795d594fSAndroid Build Coastguard Worker class TraceWriterThreadPool : public ThreadPool {
178*795d594fSAndroid Build Coastguard Worker public:
Create(const char * name)179*795d594fSAndroid Build Coastguard Worker static TraceWriterThreadPool* Create(const char* name) {
180*795d594fSAndroid Build Coastguard Worker TraceWriterThreadPool* pool = new TraceWriterThreadPool(name);
181*795d594fSAndroid Build Coastguard Worker pool->CreateThreads();
182*795d594fSAndroid Build Coastguard Worker return pool;
183*795d594fSAndroid Build Coastguard Worker }
184*795d594fSAndroid Build Coastguard Worker
185*795d594fSAndroid Build Coastguard Worker uintptr_t* FinishTaskAndClaimBuffer(size_t tid);
186*795d594fSAndroid Build Coastguard Worker
187*795d594fSAndroid Build Coastguard Worker private:
TraceWriterThreadPool(const char * name)188*795d594fSAndroid Build Coastguard Worker explicit TraceWriterThreadPool(const char* name)
189*795d594fSAndroid Build Coastguard Worker : ThreadPool(name,
190*795d594fSAndroid Build Coastguard Worker /* num_threads= */ 1,
191*795d594fSAndroid Build Coastguard Worker /* create_peers= */ false,
192*795d594fSAndroid Build Coastguard Worker /* worker_stack_size= */ ThreadPoolWorker::kDefaultStackSize) {}
193*795d594fSAndroid Build Coastguard Worker };
194*795d594fSAndroid Build Coastguard Worker
195*795d594fSAndroid Build Coastguard Worker class TraceWriter {
196*795d594fSAndroid Build Coastguard Worker public:
197*795d594fSAndroid Build Coastguard Worker TraceWriter(File* trace_file,
198*795d594fSAndroid Build Coastguard Worker TraceOutputMode output_mode,
199*795d594fSAndroid Build Coastguard Worker TraceClockSource clock_source,
200*795d594fSAndroid Build Coastguard Worker size_t buffer_size,
201*795d594fSAndroid Build Coastguard Worker int num_trace_buffers,
202*795d594fSAndroid Build Coastguard Worker int trace_format_version,
203*795d594fSAndroid Build Coastguard Worker uint32_t clock_overhead_ns);
204*795d594fSAndroid Build Coastguard Worker
205*795d594fSAndroid Build Coastguard Worker // This encodes all the events in the per-thread trace buffer and writes it to the trace file /
206*795d594fSAndroid Build Coastguard Worker // buffer. This acquires streaming lock to prevent any other threads writing concurrently. It is
207*795d594fSAndroid Build Coastguard Worker // required to serialize these since each method is encoded with a unique id which is assigned
208*795d594fSAndroid Build Coastguard Worker // when the method is seen for the first time in the recoreded events. So we need to serialize
209*795d594fSAndroid Build Coastguard Worker // these flushes across threads.
210*795d594fSAndroid Build Coastguard Worker void FlushBuffer(Thread* thread, bool is_sync, bool free_buffer)
211*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!trace_writer_lock_);
212*795d594fSAndroid Build Coastguard Worker
213*795d594fSAndroid Build Coastguard Worker // This is called when the per-thread buffer is full and a new entry needs to be recorded. This
214*795d594fSAndroid Build Coastguard Worker // returns a pointer to the new buffer where the entries should be recorded.
215*795d594fSAndroid Build Coastguard Worker // In streaming mode, we just flush the per-thread buffer. The buffer is flushed asynchronously
216*795d594fSAndroid Build Coastguard Worker // on a thread pool worker. This creates a new buffer and updates the per-thread buffer pointer
217*795d594fSAndroid Build Coastguard Worker // and returns a pointer to the newly created buffer.
218*795d594fSAndroid Build Coastguard Worker // In non-streaming mode, buffers from all threads are flushed to see if there's enough room
219*795d594fSAndroid Build Coastguard Worker // in the centralized buffer before recording new entries. We just flush these buffers
220*795d594fSAndroid Build Coastguard Worker // synchronously and reuse the existing buffer. Since this mode is mostly deprecated we want to
221*795d594fSAndroid Build Coastguard Worker // keep the implementation simple here.
222*795d594fSAndroid Build Coastguard Worker uintptr_t* PrepareBufferForNewEntries(Thread* thread) REQUIRES_SHARED(Locks::mutator_lock_)
223*795d594fSAndroid Build Coastguard Worker REQUIRES(!trace_writer_lock_);
224*795d594fSAndroid Build Coastguard Worker
225*795d594fSAndroid Build Coastguard Worker // Creates a summary packet which includes some meta information like number of events, clock
226*795d594fSAndroid Build Coastguard Worker // overhead, trace version in human readable form. This is used to dump the summary at the end
227*795d594fSAndroid Build Coastguard Worker // of tracing..
228*795d594fSAndroid Build Coastguard Worker std::string CreateSummary(int flags) REQUIRES(!trace_writer_lock_)
229*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_);
230*795d594fSAndroid Build Coastguard Worker // Flushes all per-thread buffer and also write a summary entry.
231*795d594fSAndroid Build Coastguard Worker void FinishTracing(int flags, bool flush_entries) REQUIRES(!trace_writer_lock_)
232*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_);
233*795d594fSAndroid Build Coastguard Worker
234*795d594fSAndroid Build Coastguard Worker void PreProcessTraceForMethodInfos(uintptr_t* buffer,
235*795d594fSAndroid Build Coastguard Worker size_t num_entries,
236*795d594fSAndroid Build Coastguard Worker std::unordered_map<ArtMethod*, std::string>& method_infos)
237*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!trace_writer_lock_);
238*795d594fSAndroid Build Coastguard Worker
239*795d594fSAndroid Build Coastguard Worker // Flush buffer to the file (for streaming) or to the common buffer (for non-streaming). In
240*795d594fSAndroid Build Coastguard Worker // non-streaming case it returns false if all the contents couldn't be flushed.
241*795d594fSAndroid Build Coastguard Worker void FlushBuffer(uintptr_t* buffer,
242*795d594fSAndroid Build Coastguard Worker size_t num_entries,
243*795d594fSAndroid Build Coastguard Worker size_t tid,
244*795d594fSAndroid Build Coastguard Worker const std::unordered_map<ArtMethod*, std::string>& method_infos)
245*795d594fSAndroid Build Coastguard Worker REQUIRES(!trace_writer_lock_);
246*795d594fSAndroid Build Coastguard Worker
247*795d594fSAndroid Build Coastguard Worker // This is called when we see the first entry from the thread to record the information about the
248*795d594fSAndroid Build Coastguard Worker // thread.
249*795d594fSAndroid Build Coastguard Worker void RecordThreadInfo(Thread* thread) REQUIRES(!trace_writer_lock_);
250*795d594fSAndroid Build Coastguard Worker
251*795d594fSAndroid Build Coastguard Worker // Records information about all methods in the newly loaded class in the buffer. If the buffer
252*795d594fSAndroid Build Coastguard Worker // doesn't have enough space to record the entry, then it adds a task to flush the buffer
253*795d594fSAndroid Build Coastguard Worker // contents and uses a new buffer to record the information.
254*795d594fSAndroid Build Coastguard Worker // buffer is the pointer to buffer that is used to record method info and the offset is the
255*795d594fSAndroid Build Coastguard Worker // offset in the buffer to start recording method info. If *buffer is nullptr then a new one is
256*795d594fSAndroid Build Coastguard Worker // allocated and buffer is updated to point to the newly allocated one.
257*795d594fSAndroid Build Coastguard Worker void RecordMethodInfoV2(mirror::Class* klass, uint8_t** buffer, size_t* offset)
258*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!trace_writer_lock_);
259*795d594fSAndroid Build Coastguard Worker
HasOverflow()260*795d594fSAndroid Build Coastguard Worker bool HasOverflow() { return overflow_; }
GetOutputMode()261*795d594fSAndroid Build Coastguard Worker TraceOutputMode GetOutputMode() { return trace_output_mode_; }
GetBufferSize()262*795d594fSAndroid Build Coastguard Worker size_t GetBufferSize() { return buffer_size_; }
263*795d594fSAndroid Build Coastguard Worker
264*795d594fSAndroid Build Coastguard Worker // Performs the initialization for the buffer pool. It marks all buffers as free by storing 0
265*795d594fSAndroid Build Coastguard Worker // as the owner tid. This also allocates the buffer pool.
266*795d594fSAndroid Build Coastguard Worker void InitializeTraceBuffers();
267*795d594fSAndroid Build Coastguard Worker
268*795d594fSAndroid Build Coastguard Worker // Releases the trace buffer and signals any waiting threads about a free buffer.
269*795d594fSAndroid Build Coastguard Worker void ReleaseBuffer(int index);
270*795d594fSAndroid Build Coastguard Worker
271*795d594fSAndroid Build Coastguard Worker // Release the trace buffer of the thread. This is called to release the buffer without flushing
272*795d594fSAndroid Build Coastguard Worker // the entries. See a comment in ThreadList::Unregister for more detailed explanation.
273*795d594fSAndroid Build Coastguard Worker void ReleaseBufferForThread(Thread* self);
274*795d594fSAndroid Build Coastguard Worker
275*795d594fSAndroid Build Coastguard Worker // Tries to find a free buffer (which has owner of 0) from the pool. If there are no free buffers
276*795d594fSAndroid Build Coastguard Worker // then it just waits for a free buffer. To prevent any deadlocks, we only wait if the number of
277*795d594fSAndroid Build Coastguard Worker // pending tasks are greater than the number of waiting threads. Allocates a new buffer if it
278*795d594fSAndroid Build Coastguard Worker // isn't safe to wait.
279*795d594fSAndroid Build Coastguard Worker uintptr_t* AcquireTraceBuffer(size_t tid) REQUIRES_SHARED(Locks::mutator_lock_)
280*795d594fSAndroid Build Coastguard Worker REQUIRES(!trace_writer_lock_);
281*795d594fSAndroid Build Coastguard Worker
282*795d594fSAndroid Build Coastguard Worker // Returns the index corresponding to the start of the current_buffer. We allocate one large
283*795d594fSAndroid Build Coastguard Worker // buffer and assign parts of it for each thread.
284*795d594fSAndroid Build Coastguard Worker int GetMethodTraceIndex(uintptr_t* current_buffer);
285*795d594fSAndroid Build Coastguard Worker
GetTraceFormatVersion()286*795d594fSAndroid Build Coastguard Worker int GetTraceFormatVersion() { return trace_format_version_; }
287*795d594fSAndroid Build Coastguard Worker
288*795d594fSAndroid Build Coastguard Worker // Ensures that there are no threads suspended waiting for a free buffer. It signals threads
289*795d594fSAndroid Build Coastguard Worker // waiting for a free buffer and waits for all the threads to respond to the signal.
290*795d594fSAndroid Build Coastguard Worker void StopTracing();
291*795d594fSAndroid Build Coastguard Worker
292*795d594fSAndroid Build Coastguard Worker // Adds a task to write method info to the file. The buffer is already in the
293*795d594fSAndroid Build Coastguard Worker // right format and it just adds a new task which takes the ownership of the
294*795d594fSAndroid Build Coastguard Worker // buffer and returns a new buffer that can be used. If release is set to true
295*795d594fSAndroid Build Coastguard Worker // then it doesn't fetch a new buffer.
296*795d594fSAndroid Build Coastguard Worker uint8_t* AddMethodInfoWriteTask(uint8_t* buffer, size_t offset, size_t tid, bool release)
297*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!trace_writer_lock_);
298*795d594fSAndroid Build Coastguard Worker
299*795d594fSAndroid Build Coastguard Worker // Writes buffer contents to the file.
300*795d594fSAndroid Build Coastguard Worker void WriteToFile(uint8_t* buffer, size_t offset);
301*795d594fSAndroid Build Coastguard Worker
302*795d594fSAndroid Build Coastguard Worker private:
303*795d594fSAndroid Build Coastguard Worker void ReadValuesFromRecord(uintptr_t* method_trace_entries,
304*795d594fSAndroid Build Coastguard Worker size_t record_index,
305*795d594fSAndroid Build Coastguard Worker MethodTraceRecord& record,
306*795d594fSAndroid Build Coastguard Worker bool has_thread_cpu_clock,
307*795d594fSAndroid Build Coastguard Worker bool has_wall_clock);
308*795d594fSAndroid Build Coastguard Worker
309*795d594fSAndroid Build Coastguard Worker void FlushEntriesFormatV2(uintptr_t* method_trace_entries,
310*795d594fSAndroid Build Coastguard Worker size_t tid,
311*795d594fSAndroid Build Coastguard Worker size_t num_records,
312*795d594fSAndroid Build Coastguard Worker size_t* current_index,
313*795d594fSAndroid Build Coastguard Worker uint8_t* init_buffer_ptr) REQUIRES(trace_writer_lock_);
314*795d594fSAndroid Build Coastguard Worker
315*795d594fSAndroid Build Coastguard Worker void FlushEntriesFormatV1(uintptr_t* method_trace_entries,
316*795d594fSAndroid Build Coastguard Worker size_t tid,
317*795d594fSAndroid Build Coastguard Worker const std::unordered_map<ArtMethod*, std::string>& method_infos,
318*795d594fSAndroid Build Coastguard Worker size_t end_offset,
319*795d594fSAndroid Build Coastguard Worker size_t* current_index,
320*795d594fSAndroid Build Coastguard Worker uint8_t* buffer_ptr) REQUIRES(trace_writer_lock_);
321*795d594fSAndroid Build Coastguard Worker // Get a 32-bit id for the method and specify if the method hasn't been seen before. If this is
322*795d594fSAndroid Build Coastguard Worker // the first time we see this method record information (like method name, declaring class etc.,)
323*795d594fSAndroid Build Coastguard Worker // about the method.
324*795d594fSAndroid Build Coastguard Worker std::pair<uint32_t, bool> GetMethodEncoding(ArtMethod* method) REQUIRES(trace_writer_lock_);
325*795d594fSAndroid Build Coastguard Worker bool HasMethodEncoding(ArtMethod* method) REQUIRES(trace_writer_lock_);
326*795d594fSAndroid Build Coastguard Worker
327*795d594fSAndroid Build Coastguard Worker // Get a 16-bit id for the thread. We don't want to use thread ids directly since they can be
328*795d594fSAndroid Build Coastguard Worker // more than 16-bit.
329*795d594fSAndroid Build Coastguard Worker uint16_t GetThreadEncoding(pid_t thread_id) REQUIRES(trace_writer_lock_);
330*795d594fSAndroid Build Coastguard Worker
331*795d594fSAndroid Build Coastguard Worker // Get the information about the method.
332*795d594fSAndroid Build Coastguard Worker std::string GetMethodLine(const std::string& method_line, uint32_t method_id);
333*795d594fSAndroid Build Coastguard Worker std::string GetMethodInfoLine(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_);
334*795d594fSAndroid Build Coastguard Worker
335*795d594fSAndroid Build Coastguard Worker // Helper function to record method information when processing the events. These are used by
336*795d594fSAndroid Build Coastguard Worker // streaming output mode. Non-streaming modes dump the methods and threads list at the end of
337*795d594fSAndroid Build Coastguard Worker // tracing.
338*795d594fSAndroid Build Coastguard Worker void RecordMethodInfoV1(const std::string& method_line, uint64_t method_id)
339*795d594fSAndroid Build Coastguard Worker REQUIRES(trace_writer_lock_);
340*795d594fSAndroid Build Coastguard Worker
341*795d594fSAndroid Build Coastguard Worker // Encodes the trace event. This assumes that there is enough space reserved to encode the entry.
342*795d594fSAndroid Build Coastguard Worker void EncodeEventEntry(uint8_t* ptr,
343*795d594fSAndroid Build Coastguard Worker uint16_t thread_id,
344*795d594fSAndroid Build Coastguard Worker uint32_t method_index,
345*795d594fSAndroid Build Coastguard Worker TraceAction action,
346*795d594fSAndroid Build Coastguard Worker uint32_t thread_clock_diff,
347*795d594fSAndroid Build Coastguard Worker uint32_t wall_clock_diff) REQUIRES(trace_writer_lock_);
348*795d594fSAndroid Build Coastguard Worker
349*795d594fSAndroid Build Coastguard Worker // Encodes the header for the events block. This assumes that there is enough space reserved to
350*795d594fSAndroid Build Coastguard Worker // encode the entry.
351*795d594fSAndroid Build Coastguard Worker void EncodeEventBlockHeader(uint8_t* ptr, uint32_t thread_id, uint32_t num_records)
352*795d594fSAndroid Build Coastguard Worker REQUIRES(trace_writer_lock_);
353*795d594fSAndroid Build Coastguard Worker
354*795d594fSAndroid Build Coastguard Worker // Ensures there is sufficient space in the buffer to record the requested_size. If there is not
355*795d594fSAndroid Build Coastguard Worker // enough sufficient space the current contents of the buffer are written to the file and
356*795d594fSAndroid Build Coastguard Worker // current_index is reset to 0. This doesn't check if buffer_size is big enough to hold the
357*795d594fSAndroid Build Coastguard Worker // requested size.
358*795d594fSAndroid Build Coastguard Worker void EnsureSpace(uint8_t* buffer,
359*795d594fSAndroid Build Coastguard Worker size_t* current_index,
360*795d594fSAndroid Build Coastguard Worker size_t buffer_size,
361*795d594fSAndroid Build Coastguard Worker size_t required_size);
362*795d594fSAndroid Build Coastguard Worker
363*795d594fSAndroid Build Coastguard Worker // Flush tracing buffers from all the threads.
364*795d594fSAndroid Build Coastguard Worker void FlushAllThreadBuffers() REQUIRES(!Locks::thread_list_lock_) REQUIRES(!trace_writer_lock_);
365*795d594fSAndroid Build Coastguard Worker
366*795d594fSAndroid Build Coastguard Worker
367*795d594fSAndroid Build Coastguard Worker // Methods to output traced methods and threads.
368*795d594fSAndroid Build Coastguard Worker void DumpMethodList(std::ostream& os) REQUIRES_SHARED(Locks::mutator_lock_)
369*795d594fSAndroid Build Coastguard Worker REQUIRES(!trace_writer_lock_);
370*795d594fSAndroid Build Coastguard Worker void DumpThreadList(std::ostream& os) REQUIRES(!Locks::thread_list_lock_, !trace_writer_lock_);
371*795d594fSAndroid Build Coastguard Worker
372*795d594fSAndroid Build Coastguard Worker // File to write trace data out to, null if direct to ddms.
373*795d594fSAndroid Build Coastguard Worker std::unique_ptr<File> trace_file_;
374*795d594fSAndroid Build Coastguard Worker
375*795d594fSAndroid Build Coastguard Worker // The kind of output for this tracing.
376*795d594fSAndroid Build Coastguard Worker const TraceOutputMode trace_output_mode_;
377*795d594fSAndroid Build Coastguard Worker
378*795d594fSAndroid Build Coastguard Worker // The clock source for this tracing.
379*795d594fSAndroid Build Coastguard Worker const TraceClockSource clock_source_;
380*795d594fSAndroid Build Coastguard Worker
381*795d594fSAndroid Build Coastguard Worker // Map of thread ids and names. This is used only in non-streaming mode, since we have to dump
382*795d594fSAndroid Build Coastguard Worker // information about all threads in one block. In streaming mode, thread info is recorded directly
383*795d594fSAndroid Build Coastguard Worker // in the file when we see the first even from this thread.
384*795d594fSAndroid Build Coastguard Worker SafeMap<uint16_t, std::string> threads_list_;
385*795d594fSAndroid Build Coastguard Worker
386*795d594fSAndroid Build Coastguard Worker // Map from ArtMethod* to index.
387*795d594fSAndroid Build Coastguard Worker std::unordered_map<ArtMethod*, uint32_t> art_method_id_map_ GUARDED_BY(trace_writer_lock_);
388*795d594fSAndroid Build Coastguard Worker uint32_t current_method_index_ = 0;
389*795d594fSAndroid Build Coastguard Worker
390*795d594fSAndroid Build Coastguard Worker // Map from thread_id to a 16-bit identifier.
391*795d594fSAndroid Build Coastguard Worker std::unordered_map<pid_t, uint16_t> thread_id_map_ GUARDED_BY(trace_writer_lock_);
392*795d594fSAndroid Build Coastguard Worker uint16_t current_thread_index_;
393*795d594fSAndroid Build Coastguard Worker
394*795d594fSAndroid Build Coastguard Worker // Buffer used when generating trace data from the raw entries.
395*795d594fSAndroid Build Coastguard Worker // In streaming mode, the trace data is flushed to file when the per-thread buffer gets full.
396*795d594fSAndroid Build Coastguard Worker // In non-streaming mode, this data is flushed at the end of tracing. If the buffer gets full
397*795d594fSAndroid Build Coastguard Worker // we stop tracing and following trace events are ignored. The size of this buffer is
398*795d594fSAndroid Build Coastguard Worker // specified by the user in non-streaming mode.
399*795d594fSAndroid Build Coastguard Worker std::unique_ptr<uint8_t[]> buf_;
400*795d594fSAndroid Build Coastguard Worker
401*795d594fSAndroid Build Coastguard Worker // The cur_offset_ into the buf_. Accessed only in SuspendAll scope when flushing data from the
402*795d594fSAndroid Build Coastguard Worker // thread local buffers to buf_.
403*795d594fSAndroid Build Coastguard Worker size_t cur_offset_ GUARDED_BY(trace_writer_lock_);
404*795d594fSAndroid Build Coastguard Worker
405*795d594fSAndroid Build Coastguard Worker // Size of buf_.
406*795d594fSAndroid Build Coastguard Worker const size_t buffer_size_;
407*795d594fSAndroid Build Coastguard Worker
408*795d594fSAndroid Build Coastguard Worker // Version of trace output
409*795d594fSAndroid Build Coastguard Worker const int trace_format_version_;
410*795d594fSAndroid Build Coastguard Worker
411*795d594fSAndroid Build Coastguard Worker // Time trace was created.
412*795d594fSAndroid Build Coastguard Worker const uint64_t start_time_;
413*795d594fSAndroid Build Coastguard Worker
414*795d594fSAndroid Build Coastguard Worker // Did we overflow the buffer recording traces?
415*795d594fSAndroid Build Coastguard Worker bool overflow_;
416*795d594fSAndroid Build Coastguard Worker
417*795d594fSAndroid Build Coastguard Worker // Total number of records flushed to file.
418*795d594fSAndroid Build Coastguard Worker size_t num_records_;
419*795d594fSAndroid Build Coastguard Worker
420*795d594fSAndroid Build Coastguard Worker // Clock overhead.
421*795d594fSAndroid Build Coastguard Worker const uint32_t clock_overhead_ns_;
422*795d594fSAndroid Build Coastguard Worker
423*795d594fSAndroid Build Coastguard Worker std::vector<std::atomic<size_t>> owner_tids_;
424*795d594fSAndroid Build Coastguard Worker std::unique_ptr<uintptr_t[]> trace_buffer_;
425*795d594fSAndroid Build Coastguard Worker
426*795d594fSAndroid Build Coastguard Worker Mutex buffer_pool_lock_;
427*795d594fSAndroid Build Coastguard Worker ConditionVariable buffer_available_ GUARDED_BY(buffer_pool_lock_);
428*795d594fSAndroid Build Coastguard Worker ConditionVariable num_waiters_zero_cond_ GUARDED_BY(buffer_pool_lock_);
429*795d594fSAndroid Build Coastguard Worker std::atomic<size_t> num_waiters_for_buffer_;
430*795d594fSAndroid Build Coastguard Worker std::atomic<bool> finish_tracing_ = false;
431*795d594fSAndroid Build Coastguard Worker
432*795d594fSAndroid Build Coastguard Worker // Lock to protect common data structures accessed from multiple threads like
433*795d594fSAndroid Build Coastguard Worker // art_method_id_map_, thread_id_map_.
434*795d594fSAndroid Build Coastguard Worker Mutex trace_writer_lock_;
435*795d594fSAndroid Build Coastguard Worker
436*795d594fSAndroid Build Coastguard Worker // Thread pool to flush the trace entries to file.
437*795d594fSAndroid Build Coastguard Worker std::unique_ptr<TraceWriterThreadPool> thread_pool_;
438*795d594fSAndroid Build Coastguard Worker };
439*795d594fSAndroid Build Coastguard Worker
440*795d594fSAndroid Build Coastguard Worker // Class for recording event traces. Trace data is either collected
441*795d594fSAndroid Build Coastguard Worker // synchronously during execution (TracingMode::kMethodTracingActive),
442*795d594fSAndroid Build Coastguard Worker // or by a separate sampling thread (TracingMode::kSampleProfilingActive).
443*795d594fSAndroid Build Coastguard Worker class Trace final : public instrumentation::InstrumentationListener, public ClassLoadCallback {
444*795d594fSAndroid Build Coastguard Worker public:
445*795d594fSAndroid Build Coastguard Worker enum TraceFlag {
446*795d594fSAndroid Build Coastguard Worker kTraceCountAllocs = 0x001,
447*795d594fSAndroid Build Coastguard Worker kTraceClockSourceWallClock = 0x010,
448*795d594fSAndroid Build Coastguard Worker kTraceClockSourceThreadCpu = 0x100,
449*795d594fSAndroid Build Coastguard Worker };
450*795d594fSAndroid Build Coastguard Worker
451*795d594fSAndroid Build Coastguard Worker static const int kFormatV1 = 0;
452*795d594fSAndroid Build Coastguard Worker static const int kFormatV2 = 1;
453*795d594fSAndroid Build Coastguard Worker static const int kTraceFormatVersionFlagMask = 0b110;
454*795d594fSAndroid Build Coastguard Worker static const int kTraceFormatVersionShift = 1;
455*795d594fSAndroid Build Coastguard Worker
456*795d594fSAndroid Build Coastguard Worker enum class TraceMode {
457*795d594fSAndroid Build Coastguard Worker kMethodTracing,
458*795d594fSAndroid Build Coastguard Worker kSampling
459*795d594fSAndroid Build Coastguard Worker };
460*795d594fSAndroid Build Coastguard Worker
461*795d594fSAndroid Build Coastguard Worker // Temporary code for debugging b/342768977
462*795d594fSAndroid Build Coastguard Worker static std::string GetDebugInformation();
463*795d594fSAndroid Build Coastguard Worker
464*795d594fSAndroid Build Coastguard Worker static void SetDefaultClockSource(TraceClockSource clock_source);
465*795d594fSAndroid Build Coastguard Worker
466*795d594fSAndroid Build Coastguard Worker static void Start(const char* trace_filename,
467*795d594fSAndroid Build Coastguard Worker size_t buffer_size,
468*795d594fSAndroid Build Coastguard Worker int flags,
469*795d594fSAndroid Build Coastguard Worker TraceOutputMode output_mode,
470*795d594fSAndroid Build Coastguard Worker TraceMode trace_mode,
471*795d594fSAndroid Build Coastguard Worker int interval_us)
472*795d594fSAndroid Build Coastguard Worker REQUIRES(!Locks::mutator_lock_, !Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_,
473*795d594fSAndroid Build Coastguard Worker !Locks::trace_lock_);
474*795d594fSAndroid Build Coastguard Worker static void Start(int trace_fd,
475*795d594fSAndroid Build Coastguard Worker size_t buffer_size,
476*795d594fSAndroid Build Coastguard Worker int flags,
477*795d594fSAndroid Build Coastguard Worker TraceOutputMode output_mode,
478*795d594fSAndroid Build Coastguard Worker TraceMode trace_mode,
479*795d594fSAndroid Build Coastguard Worker int interval_us)
480*795d594fSAndroid Build Coastguard Worker REQUIRES(!Locks::mutator_lock_, !Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_,
481*795d594fSAndroid Build Coastguard Worker !Locks::trace_lock_);
482*795d594fSAndroid Build Coastguard Worker static void Start(std::unique_ptr<unix_file::FdFile>&& file,
483*795d594fSAndroid Build Coastguard Worker size_t buffer_size,
484*795d594fSAndroid Build Coastguard Worker int flags,
485*795d594fSAndroid Build Coastguard Worker TraceOutputMode output_mode,
486*795d594fSAndroid Build Coastguard Worker TraceMode trace_mode,
487*795d594fSAndroid Build Coastguard Worker int interval_us)
488*795d594fSAndroid Build Coastguard Worker REQUIRES(!Locks::mutator_lock_, !Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_,
489*795d594fSAndroid Build Coastguard Worker !Locks::trace_lock_);
490*795d594fSAndroid Build Coastguard Worker static void StartDDMS(size_t buffer_size,
491*795d594fSAndroid Build Coastguard Worker int flags,
492*795d594fSAndroid Build Coastguard Worker TraceMode trace_mode,
493*795d594fSAndroid Build Coastguard Worker int interval_us)
494*795d594fSAndroid Build Coastguard Worker REQUIRES(!Locks::mutator_lock_, !Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_,
495*795d594fSAndroid Build Coastguard Worker !Locks::trace_lock_);
496*795d594fSAndroid Build Coastguard Worker
497*795d594fSAndroid Build Coastguard Worker // Stop tracing. This will finish the trace and write it to file/send it via DDMS.
498*795d594fSAndroid Build Coastguard Worker static void Stop()
499*795d594fSAndroid Build Coastguard Worker REQUIRES(!Locks::mutator_lock_, !Locks::thread_list_lock_, !Locks::trace_lock_);
500*795d594fSAndroid Build Coastguard Worker // Abort tracing. This will just stop tracing and *not* write/send the collected data.
501*795d594fSAndroid Build Coastguard Worker static void Abort()
502*795d594fSAndroid Build Coastguard Worker REQUIRES(!Locks::mutator_lock_, !Locks::thread_list_lock_, !Locks::trace_lock_);
503*795d594fSAndroid Build Coastguard Worker static void Shutdown()
504*795d594fSAndroid Build Coastguard Worker REQUIRES(!Locks::mutator_lock_, !Locks::thread_list_lock_, !Locks::trace_lock_);
505*795d594fSAndroid Build Coastguard Worker
506*795d594fSAndroid Build Coastguard Worker static TracingMode GetMethodTracingMode() REQUIRES(!Locks::trace_lock_);
507*795d594fSAndroid Build Coastguard Worker
508*795d594fSAndroid Build Coastguard Worker // Flush the per-thread buffer. This is called when the thread is about to detach.
509*795d594fSAndroid Build Coastguard Worker static void FlushThreadBuffer(Thread* thread) REQUIRES_SHARED(Locks::mutator_lock_)
510*795d594fSAndroid Build Coastguard Worker REQUIRES(!Locks::trace_lock_) NO_THREAD_SAFETY_ANALYSIS;
511*795d594fSAndroid Build Coastguard Worker
512*795d594fSAndroid Build Coastguard Worker // Release per-thread buffer without flushing any entries. This is used when a new trace buffer is
513*795d594fSAndroid Build Coastguard Worker // allocated while the thread is terminating. See ThreadList::Unregister for more details.
514*795d594fSAndroid Build Coastguard Worker static void ReleaseThreadBuffer(Thread* thread)
515*795d594fSAndroid Build Coastguard Worker REQUIRES(!Locks::trace_lock_) NO_THREAD_SAFETY_ANALYSIS;
516*795d594fSAndroid Build Coastguard Worker
517*795d594fSAndroid Build Coastguard Worker // Removes any listeners installed for method tracing. This is used in non-streaming case
518*795d594fSAndroid Build Coastguard Worker // when we no longer record any events once the buffer is full. In other cases listeners are
519*795d594fSAndroid Build Coastguard Worker // removed only when tracing stops. This is expected to be called in SuspendAll scope.
520*795d594fSAndroid Build Coastguard Worker static void RemoveListeners() REQUIRES(Locks::mutator_lock_);
521*795d594fSAndroid Build Coastguard Worker
522*795d594fSAndroid Build Coastguard Worker void MeasureClockOverhead();
523*795d594fSAndroid Build Coastguard Worker uint32_t GetClockOverheadNanoSeconds();
524*795d594fSAndroid Build Coastguard Worker
525*795d594fSAndroid Build Coastguard Worker void CompareAndUpdateStackTrace(Thread* thread, std::vector<ArtMethod*>* stack_trace)
526*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_);
527*795d594fSAndroid Build Coastguard Worker
528*795d594fSAndroid Build Coastguard Worker // InstrumentationListener implementation.
529*795d594fSAndroid Build Coastguard Worker void MethodEntered(Thread* thread, ArtMethod* method)
530*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) override;
531*795d594fSAndroid Build Coastguard Worker void MethodExited(Thread* thread,
532*795d594fSAndroid Build Coastguard Worker ArtMethod* method,
533*795d594fSAndroid Build Coastguard Worker instrumentation::OptionalFrame frame,
534*795d594fSAndroid Build Coastguard Worker JValue& return_value) REQUIRES_SHARED(Locks::mutator_lock_) override;
535*795d594fSAndroid Build Coastguard Worker void MethodUnwind(Thread* thread, ArtMethod* method, uint32_t dex_pc)
536*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) override;
537*795d594fSAndroid Build Coastguard Worker void DexPcMoved(Thread* thread,
538*795d594fSAndroid Build Coastguard Worker Handle<mirror::Object> this_object,
539*795d594fSAndroid Build Coastguard Worker ArtMethod* method,
540*795d594fSAndroid Build Coastguard Worker uint32_t new_dex_pc) REQUIRES_SHARED(Locks::mutator_lock_) override;
541*795d594fSAndroid Build Coastguard Worker void FieldRead(Thread* thread,
542*795d594fSAndroid Build Coastguard Worker Handle<mirror::Object> this_object,
543*795d594fSAndroid Build Coastguard Worker ArtMethod* method,
544*795d594fSAndroid Build Coastguard Worker uint32_t dex_pc,
545*795d594fSAndroid Build Coastguard Worker ArtField* field) REQUIRES_SHARED(Locks::mutator_lock_) override;
546*795d594fSAndroid Build Coastguard Worker void FieldWritten(Thread* thread,
547*795d594fSAndroid Build Coastguard Worker Handle<mirror::Object> this_object,
548*795d594fSAndroid Build Coastguard Worker ArtMethod* method,
549*795d594fSAndroid Build Coastguard Worker uint32_t dex_pc,
550*795d594fSAndroid Build Coastguard Worker ArtField* field,
551*795d594fSAndroid Build Coastguard Worker const JValue& field_value) REQUIRES_SHARED(Locks::mutator_lock_) override;
552*795d594fSAndroid Build Coastguard Worker void ExceptionThrown(Thread* thread, Handle<mirror::Throwable> exception_object)
553*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) override;
554*795d594fSAndroid Build Coastguard Worker void ExceptionHandled(Thread* thread, Handle<mirror::Throwable> exception_object)
555*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) override;
556*795d594fSAndroid Build Coastguard Worker void Branch(Thread* thread, ArtMethod* method, uint32_t dex_pc, int32_t dex_pc_offset)
557*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) override;
558*795d594fSAndroid Build Coastguard Worker void WatchedFramePop(Thread* thread, const ShadowFrame& frame)
559*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) override;
560*795d594fSAndroid Build Coastguard Worker
561*795d594fSAndroid Build Coastguard Worker // ClassLoadCallback implementation
ClassLoad(Handle<mirror::Class> klass)562*795d594fSAndroid Build Coastguard Worker void ClassLoad([[maybe_unused]] Handle<mirror::Class> klass)
563*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) override {}
564*795d594fSAndroid Build Coastguard Worker void ClassPrepare(Handle<mirror::Class> temp_klass, Handle<mirror::Class> klass)
565*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) override;
566*795d594fSAndroid Build Coastguard Worker
GetClockSource()567*795d594fSAndroid Build Coastguard Worker TraceClockSource GetClockSource() { return clock_source_; }
568*795d594fSAndroid Build Coastguard Worker
569*795d594fSAndroid Build Coastguard Worker // Reuse an old stack trace if it exists, otherwise allocate a new one.
570*795d594fSAndroid Build Coastguard Worker static std::vector<ArtMethod*>* AllocStackTrace();
571*795d594fSAndroid Build Coastguard Worker // Clear and store an old stack trace for later use.
572*795d594fSAndroid Build Coastguard Worker static void FreeStackTrace(std::vector<ArtMethod*>* stack_trace);
573*795d594fSAndroid Build Coastguard Worker
574*795d594fSAndroid Build Coastguard Worker static TraceOutputMode GetOutputMode() REQUIRES(!Locks::trace_lock_);
575*795d594fSAndroid Build Coastguard Worker static TraceMode GetMode() REQUIRES(!Locks::trace_lock_);
576*795d594fSAndroid Build Coastguard Worker static size_t GetBufferSize() REQUIRES(!Locks::trace_lock_);
577*795d594fSAndroid Build Coastguard Worker static int GetFlags() REQUIRES(!Locks::trace_lock_);
578*795d594fSAndroid Build Coastguard Worker static int GetIntervalInMillis() REQUIRES(!Locks::trace_lock_);
579*795d594fSAndroid Build Coastguard Worker
580*795d594fSAndroid Build Coastguard Worker // Used by class linker to prevent class unloading.
581*795d594fSAndroid Build Coastguard Worker static bool IsTracingEnabled() REQUIRES(!Locks::trace_lock_);
582*795d594fSAndroid Build Coastguard Worker
583*795d594fSAndroid Build Coastguard Worker // Used by the profiler to see if there is any ongoing tracing.
584*795d594fSAndroid Build Coastguard Worker static bool IsTracingEnabledLocked() REQUIRES(Locks::trace_lock_);
585*795d594fSAndroid Build Coastguard Worker
586*795d594fSAndroid Build Coastguard Worker // Callback for each class prepare event to record information about the newly created methods.
587*795d594fSAndroid Build Coastguard Worker static void ClassPrepare(Handle<mirror::Class> klass) REQUIRES_SHARED(Locks::mutator_lock_);
588*795d594fSAndroid Build Coastguard Worker
GetTraceWriter()589*795d594fSAndroid Build Coastguard Worker TraceWriter* GetTraceWriter() { return trace_writer_.get(); }
590*795d594fSAndroid Build Coastguard Worker
591*795d594fSAndroid Build Coastguard Worker private:
592*795d594fSAndroid Build Coastguard Worker Trace(File* trace_file,
593*795d594fSAndroid Build Coastguard Worker size_t buffer_size,
594*795d594fSAndroid Build Coastguard Worker int flags,
595*795d594fSAndroid Build Coastguard Worker TraceOutputMode output_mode,
596*795d594fSAndroid Build Coastguard Worker TraceMode trace_mode);
597*795d594fSAndroid Build Coastguard Worker
598*795d594fSAndroid Build Coastguard Worker // The sampling interval in microseconds is passed as an argument.
599*795d594fSAndroid Build Coastguard Worker static void* RunSamplingThread(void* arg) REQUIRES(!Locks::trace_lock_);
600*795d594fSAndroid Build Coastguard Worker
601*795d594fSAndroid Build Coastguard Worker static void StopTracing(bool flush_entries)
602*795d594fSAndroid Build Coastguard Worker REQUIRES(!Locks::mutator_lock_, !Locks::thread_list_lock_, !Locks::trace_lock_)
603*795d594fSAndroid Build Coastguard Worker // There is an annoying issue with static functions that create a new object and call into
604*795d594fSAndroid Build Coastguard Worker // that object that causes them to not be able to tell that we don't currently hold the lock.
605*795d594fSAndroid Build Coastguard Worker // This causes the negative annotations to incorrectly have a false positive. TODO: Figure out
606*795d594fSAndroid Build Coastguard Worker // how to annotate this.
607*795d594fSAndroid Build Coastguard Worker NO_THREAD_SAFETY_ANALYSIS;
608*795d594fSAndroid Build Coastguard Worker
609*795d594fSAndroid Build Coastguard Worker void ReadClocks(Thread* thread, uint32_t* thread_clock_diff, uint64_t* timestamp_counter);
610*795d594fSAndroid Build Coastguard Worker
611*795d594fSAndroid Build Coastguard Worker void LogMethodTraceEvent(Thread* thread,
612*795d594fSAndroid Build Coastguard Worker ArtMethod* method,
613*795d594fSAndroid Build Coastguard Worker TraceAction action,
614*795d594fSAndroid Build Coastguard Worker uint32_t thread_clock_diff,
615*795d594fSAndroid Build Coastguard Worker uint64_t timestamp_counter) REQUIRES_SHARED(Locks::mutator_lock_);
616*795d594fSAndroid Build Coastguard Worker
617*795d594fSAndroid Build Coastguard Worker // Singleton instance of the Trace or null when no method tracing is active.
618*795d594fSAndroid Build Coastguard Worker static Trace* the_trace_ GUARDED_BY(Locks::trace_lock_);
619*795d594fSAndroid Build Coastguard Worker
620*795d594fSAndroid Build Coastguard Worker // The default profiler clock source.
621*795d594fSAndroid Build Coastguard Worker static TraceClockSource default_clock_source_;
622*795d594fSAndroid Build Coastguard Worker
623*795d594fSAndroid Build Coastguard Worker // Sampling thread, non-zero when sampling.
624*795d594fSAndroid Build Coastguard Worker static pthread_t sampling_pthread_;
625*795d594fSAndroid Build Coastguard Worker
626*795d594fSAndroid Build Coastguard Worker // Used to remember an unused stack trace to avoid re-allocation during sampling.
627*795d594fSAndroid Build Coastguard Worker static std::unique_ptr<std::vector<ArtMethod*>> temp_stack_trace_;
628*795d594fSAndroid Build Coastguard Worker
629*795d594fSAndroid Build Coastguard Worker // Flags enabling extra tracing of things such as alloc counts.
630*795d594fSAndroid Build Coastguard Worker const int flags_;
631*795d594fSAndroid Build Coastguard Worker
632*795d594fSAndroid Build Coastguard Worker // The tracing method.
633*795d594fSAndroid Build Coastguard Worker const TraceMode trace_mode_;
634*795d594fSAndroid Build Coastguard Worker
635*795d594fSAndroid Build Coastguard Worker const TraceClockSource clock_source_;
636*795d594fSAndroid Build Coastguard Worker
637*795d594fSAndroid Build Coastguard Worker // Sampling profiler sampling interval.
638*795d594fSAndroid Build Coastguard Worker int interval_us_;
639*795d594fSAndroid Build Coastguard Worker
640*795d594fSAndroid Build Coastguard Worker // A flag to indicate to the sampling thread whether to stop tracing
641*795d594fSAndroid Build Coastguard Worker bool stop_tracing_;
642*795d594fSAndroid Build Coastguard Worker
643*795d594fSAndroid Build Coastguard Worker std::unique_ptr<TraceWriter> trace_writer_;
644*795d594fSAndroid Build Coastguard Worker
645*795d594fSAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(Trace);
646*795d594fSAndroid Build Coastguard Worker };
647*795d594fSAndroid Build Coastguard Worker
648*795d594fSAndroid Build Coastguard Worker } // namespace art
649*795d594fSAndroid Build Coastguard Worker
650*795d594fSAndroid Build Coastguard Worker #endif // ART_RUNTIME_TRACE_H_
651