• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  // Copyright 2006 The Android Open Source Project
2  
3  #ifndef TRACE_READER_BASE_H
4  #define TRACE_READER_BASE_H
5  
6  #include <inttypes.h>
7  #include "trace_common.h"
8  #include "hash_table.h"
9  
10  class BBReader;
11  class InsnReader;
12  class AddrReader;
13  class ExcReader;
14  class PidReader;
15  class MethodReader;
16  
17  struct StaticRec {
18      uint64_t    bb_num;
19      uint32_t    bb_addr;
20      uint32_t    num_insns;
21  };
22  
23  struct StaticBlock {
24      StaticRec   rec;
25      uint32_t    *insns;
26  };
27  
28  struct BBEvent {
29      uint64_t    time;
30      uint64_t    bb_num;
31      uint32_t    bb_addr;
32      uint32_t    *insns;
33      int         num_insns;
34      int         pid;
35      int         is_thumb;
36  };
37  
38  struct PidEvent {
39      uint64_t    time;
40      int         rec_type;       // record type: fork, context switch, exit ...
41      int         tgid;           // thread group id
42      int         pid;            // for fork: child pid; for switch: next pid;
43                                  //   for exit: exit value
44      uint32_t    vstart;         // virtual start address (only used with mmap)
45      uint32_t    vend;           // virtual end address (only used with mmap)
46      uint32_t    offset;         // virtual file offset (only used with mmap)
47  
48      // Dynamically allocated path to executable (or lib). In the case of
49      // an mmapped dex file, the path is modified to be more useful for
50      // comparing against the output of dexlist.  For example, instead of this:
51      //   /data/dalvik-cache/system@app@TestHarness.apk@classes.dex
52      // We convert to this:
53      //   /system/app/TestHarness.apk
54      char        *path;
55      char        *mmap_path;     // unmodified mmap path
56      int         argc;           // number of args
57      char        **argv;         // dynamically allocated array of args
58  };
59  
60  struct MethodRec {
61      uint64_t    time;
62      uint32_t    addr;
63      int         pid;
64      int         flags;
65  };
66  
67  struct DexSym {
68      uint32_t    addr;
69      int         len;
70      char        *name;
71  };
72  
73  struct DexFileList {
74      char        *path;
75      int         nsymbols;
76      DexSym      *symbols;
77  };
78  
79  class TraceReaderBase {
80    public:
81      TraceReaderBase();
82      virtual ~TraceReaderBase();
83  
84      friend class BBReader;
85  
86      void                Open(const char *filename);
87      void                Close();
88      void                WriteHeader(TraceHeader *header);
89      inline bool         ReadBB(BBEvent *event);
90      int                 ReadStatic(StaticRec *rec);
91      int                 ReadStaticInsns(int num, uint32_t *insns);
GetHeader()92      TraceHeader         *GetHeader()                { return header_; }
93      inline uint64_t     ReadInsnTime(uint64_t min_time);
94      void                TruncateLastBlock(uint32_t num_insns);
95      inline bool         ReadAddr(uint64_t *time, uint32_t *addr, int *flags);
96      inline bool         ReadExc(uint64_t *time, uint32_t *current_pc,
97                                  uint64_t *recnum, uint32_t *target_pc,
98                                  uint64_t *bb_num, uint64_t *bb_start_time,
99                                  int *num_insns);
100      inline bool         ReadPidEvent(PidEvent *event);
101      inline bool         ReadMethod(MethodRec *method_record);
GetStaticBlock(uint64_t bb_num)102      StaticBlock         *GetStaticBlock(uint64_t bb_num) { return &blocks_[bb_num]; }
GetInsns(uint64_t bb_num)103      uint32_t            *GetInsns(uint64_t bb_num) { return blocks_[bb_num].insns; }
GetBBAddr(uint64_t bb_num)104      uint32_t            GetBBAddr(uint64_t bb_num) {
105          return blocks_[bb_num].rec.bb_addr & ~1;
106      }
GetIsThumb(uint64_t bb_num)107      int                 GetIsThumb(uint64_t bb_num) {
108          return blocks_[bb_num].rec.bb_addr & 1;
109      }
SetPostProcessing(bool val)110      void                SetPostProcessing(bool val) { post_processing_ = val; }
111  
112    protected:
113      virtual int         FindCurrentPid(uint64_t time);
114      int                 current_pid_;
115      int                 next_pid_;
116      uint64_t            next_pid_switch_time_;
117      PidReader           *internal_pid_reader_;
118      MethodReader        *internal_method_reader_;
119      HashTable<DexFileList*> *dex_hash_;
120  
121    private:
122      int          FindNumInsns(uint64_t bb_num, uint64_t bb_start_time);
123      void         ReadTraceHeader(FILE *fstream, const char *filename,
124                                  const char *tracename, TraceHeader *header);
125      PidEvent     *FindMmapDexFileEvent();
126      void         ParseDexList(const char *filename);
127  
128      char         *static_filename_;
129      FILE         *static_fstream_;
130      TraceHeader  *header_;
131      BBReader     *bb_reader_;
132      InsnReader   *insn_reader_;
133      AddrReader   *load_addr_reader_;
134      AddrReader   *store_addr_reader_;
135      ExcReader    *exc_reader_;
136      PidReader    *pid_reader_;
137      MethodReader *method_reader_;
138      ExcReader    *internal_exc_reader_;
139      StaticBlock  *blocks_;
140      bool         exc_end_;
141      uint64_t     bb_recnum_;
142      uint64_t     exc_recnum_;
143      uint64_t     exc_bb_num_;
144      uint64_t     exc_time_;
145      int          exc_num_insns_;
146      bool         post_processing_;
147  
148      bool         load_eof_;
149      uint64_t     load_time_;
150      uint32_t     load_addr_;
151      bool         store_eof_;
152      uint64_t     store_time_;
153      uint32_t     store_addr_;
154  };
155  
156  class Decoder;
157  
158  class BBReader {
159    public:
160      explicit BBReader(TraceReaderBase *trace);
161      ~BBReader();
162      void     Open(const char *filename);
163      void     Close();
164      bool     ReadBB(BBEvent *event);
165  
166    private:
167      struct TimeRec {
168          BBRec       bb_rec;
169          uint64_t    next_time;
170      };
171  
172      struct Future {
173          Future      *next;
174          TimeRec     bb;
175      };
176  
177      inline Future   *AllocFuture();
178      inline void     FreeFuture(Future *future);
179      inline void     InsertFuture(Future *future);
180      inline int      DecodeNextRec();
181  
182      TimeRec         nextrec_;
183      Future          futures_[kMaxNumBasicBlocks];
184      Future          *head_;
185      Future          *free_;
186      Decoder         *decoder_;
187      bool            is_eof_;
188      TraceReaderBase *trace_;
189  };
190  
191  class InsnReader {
192    public:
193      InsnReader();
194      ~InsnReader();
195  
196      void        Open(const char *filename);
197      void        Close();
198      uint64_t    ReadInsnTime(uint64_t min_time);
199  
200    private:
201      Decoder     *decoder_;
202      uint64_t    prev_time_;
203      uint64_t    time_diff_;
204      int         repeat_;
205  };
206  
207  class AddrReader {
208    public:
209      AddrReader();
210      ~AddrReader();
211  
212      bool        Open(const char *filename, const char *suffix);
213      void        Close();
214      bool        ReadAddr(uint64_t *time, uint32_t *addr);
215  
216    private:
217      Decoder     *decoder_;
218      uint32_t    prev_addr_;
219      uint64_t    prev_time_;
220      bool        opened_;        // true after file is opened
221  };
222  
223  class ExcReader {
224    public:
225      ExcReader();
226      ~ExcReader();
227  
228      void        Open(const char *filename);
229      void        Close();
230      bool        ReadExc(uint64_t *time, uint32_t *current_pc,
231                          uint64_t *recnum, uint32_t *target_pc,
232                          uint64_t *bb_num, uint64_t *bb_start_time,
233                          int *num_insns);
234  
235    private:
236      Decoder     *decoder_;
237      uint64_t    prev_time_;
238      uint64_t    prev_recnum_;
239  };
240  
241  class PidReader {
242    public:
243      PidReader();
244      ~PidReader();
245  
246      void        Open(const char *filename);
247      void        Close();
248      bool        ReadPidEvent(struct PidEvent *event);
249      void        Dispose(struct PidEvent *event);
250  
251    private:
252      Decoder     *decoder_;
253      uint64_t    prev_time_;
254  };
255  
256  class MethodReader {
257    public:
258      MethodReader();
259      ~MethodReader();
260  
261      bool        Open(const char *filename);
262      void        Close();
263      bool        ReadMethod(MethodRec *method_record);
264  
265    private:
266      Decoder     *decoder_;
267      uint64_t    prev_time_;
268      uint32_t    prev_addr_;
269      int32_t     prev_pid_;
270      bool        opened_;        // true after file is opened
271  };
272  
273  // Reads the next dynamic basic block from the trace.
274  // Returns true on end-of-file.
ReadBB(BBEvent * event)275  inline bool TraceReaderBase::ReadBB(BBEvent *event)
276  {
277      bb_recnum_ += 1;
278      return bb_reader_->ReadBB(event);
279  }
280  
ReadInsnTime(uint64_t min_time)281  inline uint64_t TraceReaderBase::ReadInsnTime(uint64_t min_time)
282  {
283      return insn_reader_->ReadInsnTime(min_time);
284  }
285  
ReadAddr(uint64_t * time,uint32_t * addr,int * flags)286  inline bool TraceReaderBase::ReadAddr(uint64_t *time, uint32_t *addr, int *flags)
287  {
288      if (load_eof_ && store_eof_)
289          return true;
290  
291      if (store_eof_ || (!load_eof_ && load_time_ <= store_time_)) {
292          *time = load_time_;
293          *addr = load_addr_;
294          *flags = 0;
295          load_eof_ = load_addr_reader_->ReadAddr(&load_time_, &load_addr_);
296      } else {
297          *time = store_time_;
298          *addr = store_addr_;
299          *flags = 1;
300          store_eof_ = store_addr_reader_->ReadAddr(&store_time_, &store_addr_);
301      }
302      return false;
303  }
304  
ReadExc(uint64_t * time,uint32_t * current_pc,uint64_t * recnum,uint32_t * target_pc,uint64_t * bb_num,uint64_t * bb_start_time,int * num_insns)305  inline bool TraceReaderBase::ReadExc(uint64_t *time, uint32_t *current_pc,
306                                       uint64_t *recnum, uint32_t *target_pc,
307                                       uint64_t *bb_num, uint64_t *bb_start_time,
308                                       int *num_insns)
309  {
310      return exc_reader_->ReadExc(time, current_pc, recnum, target_pc, bb_num,
311                                  bb_start_time, num_insns);
312  }
313  
ReadPidEvent(PidEvent * event)314  inline bool TraceReaderBase::ReadPidEvent(PidEvent *event)
315  {
316      return pid_reader_->ReadPidEvent(event);
317  }
318  
ReadMethod(MethodRec * method_record)319  inline bool TraceReaderBase::ReadMethod(MethodRec *method_record)
320  {
321      return method_reader_->ReadMethod(method_record);
322  }
323  
324  // Duplicates a string, allocating space using new[].
Strdup(const char * src)325  inline char * Strdup(const char *src) {
326      int len = strlen(src);
327      char *copy = new char[len + 1];
328      strcpy(copy, src);
329      return copy;
330  }
331  
332  #endif /* TRACE_READER_BASE_H */
333