]> git.cworth.org Git - apitrace/blob - common/trace_model.hpp
Trace enum signatures as a whole.
[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 EnumValue {
64     const char *name;
65     signed long long value;
66 };
67
68
69 struct EnumSig {
70     Id id;
71     unsigned num_values;
72     const EnumValue *values;
73 };
74
75
76 struct BitmaskFlag {
77     const char *name;
78     unsigned long long value;
79 };
80
81
82 struct BitmaskSig {
83     Id id;
84     unsigned num_flags;
85     const BitmaskFlag *flags;
86 };
87
88
89 class Visitor;
90
91
92 class Value
93 {
94 public:
95     virtual ~Value() {}
96     virtual void visit(Visitor &visitor) = 0;
97
98     virtual bool toBool(void) const = 0;
99     virtual signed long long toSInt(void) const;
100     virtual unsigned long long toUInt(void) const;
101     virtual float toFloat(void) const;
102     virtual double toDouble(void) const;
103
104     virtual void *toPointer(void) const;
105     virtual void *toPointer(bool bind);
106     virtual unsigned long long toUIntPtr(void) const;
107     virtual const char *toString(void) const;
108
109     const Value & operator[](size_t index) const;
110
111     void dump(std::ostream &os, bool color=true);
112 };
113
114
115 class Null : public Value
116 {
117 public:
118     bool toBool(void) const;
119     signed long long toSInt(void) const;
120     unsigned long long toUInt(void) const;
121     virtual float toFloat(void) const;
122     virtual double toDouble(void) const;
123     void *toPointer(void) const;
124     void *toPointer(bool bind);
125     unsigned long long toUIntPtr(void) const;
126     const char *toString(void) const;
127     void visit(Visitor &visitor);
128 };
129
130
131 class Bool : public Value
132 {
133 public:
134     Bool(bool _value) : value(_value) {}
135
136     bool toBool(void) const;
137     signed long long toSInt(void) const;
138     unsigned long long toUInt(void) const;
139     virtual float toFloat(void) const;
140     virtual double toDouble(void) const;
141     void visit(Visitor &visitor);
142
143     bool value;
144 };
145
146
147 class SInt : public Value
148 {
149 public:
150     SInt(signed long long _value) : value(_value) {}
151
152     bool toBool(void) const;
153     signed long long toSInt(void) const;
154     unsigned long long toUInt(void) const;
155     virtual float toFloat(void) const;
156     virtual double toDouble(void) const;
157     void visit(Visitor &visitor);
158
159     signed long long value;
160 };
161
162
163 class UInt : public Value
164 {
165 public:
166     UInt(unsigned long long _value) : value(_value) {}
167
168     bool toBool(void) const;
169     signed long long toSInt(void) const;
170     unsigned long long toUInt(void) const;
171     virtual float toFloat(void) const;
172     virtual double toDouble(void) const;
173     void visit(Visitor &visitor);
174
175     unsigned long long value;
176 };
177
178
179 class Float : public Value
180 {
181 public:
182     Float(float _value) : value(_value) {}
183
184     bool toBool(void) const;
185     signed long long toSInt(void) const;
186     unsigned long long toUInt(void) const;
187     virtual float toFloat(void) const;
188     virtual double toDouble(void) const;
189     void visit(Visitor &visitor);
190
191     float value;
192 };
193
194
195 class Double : public Value
196 {
197 public:
198     Double(double _value) : value(_value) {}
199
200     bool toBool(void) const;
201     signed long long toSInt(void) const;
202     unsigned long long toUInt(void) const;
203     virtual float toFloat(void) const;
204     virtual double toDouble(void) const;
205     void visit(Visitor &visitor);
206
207     double value;
208 };
209
210
211 class String : public Value
212 {
213 public:
214     String(const char * _value) : value(_value) {}
215     ~String();
216
217     bool toBool(void) const;
218     const char *toString(void) const;
219     void visit(Visitor &visitor);
220
221     const char * value;
222 };
223
224
225 class Enum : public SInt
226 {
227 public:
228     Enum(const EnumSig *_sig, signed long long _value) : SInt(_value), sig(_sig) {}
229
230     void visit(Visitor &visitor);
231
232     const EnumSig *sig;
233 };
234
235
236 class Bitmask : public UInt
237 {
238 public:
239     Bitmask(const BitmaskSig *_sig, unsigned long long _value) : UInt(_value), sig(_sig) {}
240
241     void visit(Visitor &visitor);
242
243     const BitmaskSig *sig;
244 };
245
246
247 class Struct : public Value
248 {
249 public:
250     Struct(StructSig *_sig) : sig(_sig), members(_sig->num_members) { }
251     ~Struct();
252
253     bool toBool(void) const;
254     void visit(Visitor &visitor);
255
256     const StructSig *sig;
257     std::vector<Value *> members;
258 };
259
260
261 class Array : public Value
262 {
263 public:
264     Array(size_t len) : values(len) {}
265     ~Array();
266
267     bool toBool(void) const;
268     void visit(Visitor &visitor);
269
270     std::vector<Value *> values;
271 };
272
273
274 class Blob : public Value
275 {
276 public:
277     Blob(size_t _size) {
278         size = _size;
279         buf = new char[_size];
280         bound = false;
281     }
282
283     ~Blob();
284
285     bool toBool(void) const;
286     void *toPointer(void) const;
287     void *toPointer(bool bind);
288     void visit(Visitor &visitor);
289
290     size_t size;
291     char *buf;
292     bool bound;
293 };
294
295
296 class Pointer : public UInt
297 {
298 public:
299     Pointer(unsigned long long value) : UInt(value) {}
300
301     bool toBool(void) const;
302     void *toPointer(void) const;
303     void *toPointer(bool bind);
304     unsigned long long toUIntPtr(void) const;
305     void visit(Visitor &visitor);
306 };
307
308
309 class Visitor
310 {
311 public:
312     virtual void visit(Null *);
313     virtual void visit(Bool *);
314     virtual void visit(SInt *);
315     virtual void visit(UInt *);
316     virtual void visit(Float *);
317     virtual void visit(Double *);
318     virtual void visit(String *);
319     virtual void visit(Enum *);
320     virtual void visit(Bitmask *);
321     virtual void visit(Struct *);
322     virtual void visit(Array *);
323     virtual void visit(Blob *);
324     virtual void visit(Pointer *);
325
326 protected:
327     inline void _visit(Value *value) {
328         if (value) { 
329             value->visit(*this); 
330         }
331     }
332 };
333
334
335 inline std::ostream & operator <<(std::ostream &os, Value *value) {
336     if (value) {
337         value->dump(os);
338     }
339     return os;
340 }
341
342
343 typedef unsigned CallFlags;
344
345 /**
346  * Call flags.
347  *
348  * TODO: It might be better to to record some of these (but not all) into the
349  * trace file.
350  */
351 enum {
352
353     /**
354      * Whether a call was really done by the application or not.
355      *
356      * This flag is set for fake calls -- calls not truly done by the application
357      * but emitted and recorded for completeness, to provide contextual information
358      * necessary for retracing, that would not be available through other ways.
359      *
360      * XXX: This one definetely needs to go into the trace file.
361      */
362     CALL_FLAG_FAKE                      = (1 << 0),
363
364     /**
365      * Whether this call should be retraced or ignored.
366      *
367      * This flag is set for calls which can't be safely replayed (due to incomplete
368      * information) or that have no sideffects.
369      *
370      * Some incomplete calls are unreproduceable, but not all.
371      */
372     CALL_FLAG_NON_REPRODUCIBLE         = (1 << 1),
373     
374     /**
375      * Whether this call has no side-effects, therefore don't need to be
376      * retraced.
377      *
378      * This flag is set for calls that merely query information which is not
379      * needed for posterior calls.
380      */
381     CALL_FLAG_NO_SIDE_EFFECTS            = (1 << 2),
382
383     /**
384      * Whether this call renders into the bound rendertargets.
385      */
386     CALL_FLAG_RENDER                    = (1 << 3),
387
388     /**
389      * Whether this call causes render target to be swapped.
390      *
391      * This does not mark frame termination by itself -- that's solely the
392      * responsibility of `endOfFrame` bit. 
393      *
394      * This mean that snapshots should be take prior to the call, and not
395      * after.
396      */
397     CALL_FLAG_SWAP_RENDERTARGET         = (1 << 4),
398         
399     /**
400      * Whether this call terminates a frame.
401      *
402      * XXX: This can't always be determined by the function name, so it should also
403      * go into the trace file eventually.
404      */
405     CALL_FLAG_END_FRAME                 = (1 << 5),
406
407     /**
408      * Whether this call is incomplete, i.e., it never returned.
409      */
410     CALL_FLAG_INCOMPLETE                = (1 << 6),
411
412     /**
413      * Whether this call is verbose (i.e., not usually interesting).
414      */
415     CALL_FLAG_VERBOSE                  = (1 << 7),
416 };
417
418
419
420 class Call
421 {
422 public:
423     unsigned no;
424     const FunctionSig *sig;
425     std::vector<Value *> args;
426     Value *ret;
427
428     CallFlags flags;
429
430     Call(FunctionSig *_sig, const CallFlags &_flags) :
431         sig(_sig), 
432         args(_sig->num_args), 
433         ret(0),
434         flags(_flags) {
435     }
436
437     ~Call();
438
439     inline const char * name(void) const {
440         return sig->name;
441     }
442
443     inline Value & arg(unsigned index) {
444         assert(index < args.size());
445         return *(args[index]);
446     }
447
448     void dump(std::ostream &os, bool color=true);
449 };
450
451
452 inline std::ostream & operator <<(std::ostream &os, Call &call) {
453     call.dump(os);
454     return os;
455 }
456
457
458 } /* namespace trace */
459
460 #endif /* _TRACE_MODEL_HPP_ */