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