]> git.cworth.org Git - apitrace/blob - common/trace_model.hpp
Introduce call flags.
[apitrace] / common / trace_model.hpp
1 /**************************************************************************
2  *
3  * Copyright 2010 VMware, Inc.
4  * All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  *
24  **************************************************************************/
25
26 /*
27  * Object hierarchy for describing the traces in memory.
28  */
29
30 #ifndef _TRACE_MODEL_HPP_
31 #define _TRACE_MODEL_HPP_
32
33
34 #include <assert.h>
35
36 #include <map>
37 #include <vector>
38 #include <iostream>
39
40
41 namespace trace {
42
43
44 typedef unsigned Id;
45
46
47 struct FunctionSig {
48     Id id;
49     const char *name;
50     unsigned num_args;
51     const char **arg_names;
52 };
53
54
55 struct StructSig {
56     Id id;
57     const char *name;
58     unsigned num_members;
59     const char **member_names;
60 };
61
62
63 struct EnumSig {
64     Id id;
65     const char *name;
66     signed long long value;
67 };
68
69
70 struct BitmaskFlag {
71     const char *name;
72     unsigned long long value;
73 };
74
75
76 struct BitmaskSig {
77     Id id;
78     unsigned num_flags;
79     const BitmaskFlag *flags;
80 };
81
82
83 class Visitor;
84
85
86 class Value
87 {
88 public:
89     virtual ~Value() {}
90     virtual void visit(Visitor &visitor) = 0;
91
92     virtual bool toBool(void) const = 0;
93     virtual signed long long toSInt(void) const;
94     virtual unsigned long long toUInt(void) const;
95     virtual float toFloat(void) const;
96     virtual double toDouble(void) const;
97
98     virtual void *toPointer(void) const;
99     virtual void *toPointer(bool bind);
100     virtual unsigned long long toUIntPtr(void) const;
101     virtual const char *toString(void) const;
102
103     const Value & operator[](size_t index) const;
104
105     void dump(std::ostream &os, bool color=true);
106 };
107
108
109 class Null : public Value
110 {
111 public:
112     bool toBool(void) const;
113     signed long long toSInt(void) const;
114     unsigned long long toUInt(void) const;
115     virtual float toFloat(void) const;
116     virtual double toDouble(void) const;
117     void *toPointer(void) const;
118     void *toPointer(bool bind);
119     unsigned long long toUIntPtr(void) const;
120     const char *toString(void) const;
121     void visit(Visitor &visitor);
122 };
123
124
125 class Bool : public Value
126 {
127 public:
128     Bool(bool _value) : value(_value) {}
129
130     bool toBool(void) const;
131     signed long long toSInt(void) const;
132     unsigned long long toUInt(void) const;
133     virtual float toFloat(void) const;
134     virtual double toDouble(void) const;
135     void visit(Visitor &visitor);
136
137     bool value;
138 };
139
140
141 class SInt : public Value
142 {
143 public:
144     SInt(signed long long _value) : value(_value) {}
145
146     bool toBool(void) const;
147     signed long long toSInt(void) const;
148     unsigned long long toUInt(void) const;
149     virtual float toFloat(void) const;
150     virtual double toDouble(void) const;
151     void visit(Visitor &visitor);
152
153     signed long long value;
154 };
155
156
157 class UInt : public Value
158 {
159 public:
160     UInt(unsigned long long _value) : value(_value) {}
161
162     bool toBool(void) const;
163     signed long long toSInt(void) const;
164     unsigned long long toUInt(void) const;
165     virtual float toFloat(void) const;
166     virtual double toDouble(void) const;
167     void visit(Visitor &visitor);
168
169     unsigned long long value;
170 };
171
172
173 class Float : public Value
174 {
175 public:
176     Float(float _value) : value(_value) {}
177
178     bool toBool(void) const;
179     signed long long toSInt(void) const;
180     unsigned long long toUInt(void) const;
181     virtual float toFloat(void) const;
182     virtual double toDouble(void) const;
183     void visit(Visitor &visitor);
184
185     float value;
186 };
187
188
189 class Double : public Value
190 {
191 public:
192     Double(double _value) : value(_value) {}
193
194     bool toBool(void) const;
195     signed long long toSInt(void) const;
196     unsigned long long toUInt(void) const;
197     virtual float toFloat(void) const;
198     virtual double toDouble(void) const;
199     void visit(Visitor &visitor);
200
201     double value;
202 };
203
204
205 class String : public Value
206 {
207 public:
208     String(const char * _value) : value(_value) {}
209     ~String();
210
211     bool toBool(void) const;
212     const char *toString(void) const;
213     void visit(Visitor &visitor);
214
215     const char * value;
216 };
217
218
219 class Enum : public Value
220 {
221 public:
222     Enum(const EnumSig *_sig) : sig(_sig) {}
223
224     bool toBool(void) const;
225     signed long long toSInt(void) const;
226     unsigned long long toUInt(void) const;
227     virtual float toFloat(void) const;
228     virtual double toDouble(void) const;
229     void visit(Visitor &visitor);
230
231     const EnumSig *sig;
232 };
233
234
235 class Bitmask : public UInt
236 {
237 public:
238     Bitmask(const BitmaskSig *_sig, unsigned long long _value) : UInt(_value), sig(_sig) {}
239
240     void visit(Visitor &visitor);
241
242     const BitmaskSig *sig;
243 };
244
245
246 class Struct : public Value
247 {
248 public:
249     Struct(StructSig *_sig) : sig(_sig), members(_sig->num_members) { }
250     ~Struct();
251
252     bool toBool(void) const;
253     void visit(Visitor &visitor);
254
255     const StructSig *sig;
256     std::vector<Value *> members;
257 };
258
259
260 class Array : public Value
261 {
262 public:
263     Array(size_t len) : values(len) {}
264     ~Array();
265
266     bool toBool(void) const;
267     void visit(Visitor &visitor);
268
269     std::vector<Value *> values;
270 };
271
272
273 class Blob : public Value
274 {
275 public:
276     Blob(size_t _size) {
277         size = _size;
278         buf = new char[_size];
279         bound = false;
280     }
281
282     ~Blob();
283
284     bool toBool(void) const;
285     void *toPointer(void) const;
286     void *toPointer(bool bind);
287     void visit(Visitor &visitor);
288
289     size_t size;
290     char *buf;
291     bool bound;
292 };
293
294
295 class Pointer : public UInt
296 {
297 public:
298     Pointer(unsigned long long value) : UInt(value) {}
299
300     bool toBool(void) const;
301     void *toPointer(void) const;
302     void *toPointer(bool bind);
303     unsigned long long toUIntPtr(void) const;
304     void visit(Visitor &visitor);
305 };
306
307
308 class Visitor
309 {
310 public:
311     virtual void visit(Null *);
312     virtual void visit(Bool *);
313     virtual void visit(SInt *);
314     virtual void visit(UInt *);
315     virtual void visit(Float *);
316     virtual void visit(Double *);
317     virtual void visit(String *);
318     virtual void visit(Enum *);
319     virtual void visit(Bitmask *);
320     virtual void visit(Struct *);
321     virtual void visit(Array *);
322     virtual void visit(Blob *);
323     virtual void visit(Pointer *);
324
325 protected:
326     inline void _visit(Value *value) {
327         if (value) { 
328             value->visit(*this); 
329         }
330     }
331 };
332
333
334 inline std::ostream & operator <<(std::ostream &os, Value *value) {
335     if (value) {
336         value->dump(os);
337     }
338     return os;
339 }
340
341
342 typedef unsigned CallFlags;
343
344 /**
345  * Call flags.
346  *
347  * TODO: It might be better to to record some of these (but not all) into the
348  * trace file.
349  */
350 enum {
351
352     /**
353      * Whether a call was really done by the application or not.
354      *
355      * This flag is set for fake calls -- calls not truly done by the application
356      * but emitted and recorded for completeness, to provide contextual information
357      * necessary for retracing, that would not be available through other ways.
358      *
359      * XXX: This one definetely needs to go into the trace file.
360      */
361     CALL_FLAG_FAKE                      = (1 << 0),
362
363     /**
364      * Whether this call should be retraced or ignored.
365      *
366      * This flag is set for calls which can't be safely replayed (due to incomplete
367      * information) or that have no sideffects.
368      *
369      * Some incomplete calls are unreproduceable, but not all.
370      */
371     CALL_FLAG_NON_REPRODUCIBLE         = (1 << 1),
372     
373     /**
374      * Whether this call has no side-effects, therefore don't need to be
375      * retraced.
376      *
377      * This flag is set for calls that merely query information which is not
378      * needed for posterior calls.
379      */
380     CALL_FLAG_NO_SIDE_EFFECTS            = (1 << 2),
381
382     /**
383      * Whether this call renders into the bound rendertargets.
384      */
385     CALL_FLAG_RENDER                    = (1 << 3),
386
387     /**
388      * Whether this call causes render target to be swapped.
389      *
390      * This does not mark frame termination by itself -- that's solely the
391      * responsibility of `endOfFrame` bit. 
392      *
393      * This mean that snapshots should be take prior to the call, and not
394      * after.
395      */
396     CALL_FLAG_SWAP_RENDERTARGET         = (1 << 4),
397         
398     /**
399      * Whether this call terminates a frame.
400      *
401      * XXX: This can't always be determined by the function name, so it should also
402      * go into the trace file eventually.
403      */
404     CALL_FLAG_END_FRAME                 = (1 << 5),
405
406     /**
407      * Whether this call is incomplete, i.e., it never returned.
408      */
409     CALL_FLAG_INCOMPLETE                = (1 << 6),
410
411     /**
412      * Whether this call is verbose (i.e., not usually interesting).
413      */
414     CALL_FLAG_VERBOSE                  = (1 << 7),
415 };
416
417
418
419 class Call
420 {
421 public:
422     unsigned no;
423     const FunctionSig *sig;
424     std::vector<Value *> args;
425     Value *ret;
426
427     CallFlags flags;
428
429     Call(FunctionSig *_sig, const CallFlags &_flags) :
430         sig(_sig), 
431         args(_sig->num_args), 
432         ret(0),
433         flags(_flags) {
434     }
435
436     ~Call();
437
438     inline const char * name(void) const {
439         return sig->name;
440     }
441
442     inline Value & arg(unsigned index) {
443         assert(index < args.size());
444         return *(args[index]);
445     }
446
447     void dump(std::ostream &os, bool color=true);
448 };
449
450
451 inline std::ostream & operator <<(std::ostream &os, Call &call) {
452     call.dump(os);
453     return os;
454 }
455
456
457 } /* namespace trace */
458
459 #endif /* _TRACE_MODEL_HPP_ */