]> git.cworth.org Git - apitrace/commitdiff
More efficient bitmask representation.
authorJosé Fonseca <jfonseca@vmware.com>
Fri, 26 Nov 2010 14:14:45 +0000 (14:14 +0000)
committerJosé Fonseca <jfonseca@vmware.com>
Fri, 26 Nov 2010 14:14:45 +0000 (14:14 +0000)
trace.py
trace_model.cpp
trace_model.hpp
trace_parser.hpp
trace_write.cpp
trace_write.hpp

index 388729a95d9d1d676134b673ee71a1cc084d4d63..95e84b5e732cc8cbd676e36fe9de35b43efd7939 100644 (file)
--- a/trace.py
+++ b/trace.py
@@ -81,18 +81,14 @@ class DumpDeclarator(stdapi.OnceVisitor):
         print
 
     def visit_bitmask(self, bitmask):
-        print 'static void __traceBitmask%s(%s value) {' % (bitmask.id, bitmask.type)
-        print '    Trace::BeginBitmask();'
+        print 'static const Trace::BitmaskVal __bitmask%s_vals[] = {' % (bitmask.id)
         for value in bitmask.values:
-            print '    if((value & %s) == %s) {' % (value, value)
-            print '        Trace::LiteralNamedConstant("%s", %s);' % (value, value)
-            print '        value &= ~%s;' % value
-            print '    }'
-        print '    if(value) {'
-        dump_instance(bitmask.type, "value");
-        print '    }'
-        print '    Trace::EndBitmask();'
-        print '}'
+            print '   {"%s", %s},' % (value, value)
+        print '};'
+        print
+        print 'static const Trace::BitmaskSig __bitmask%s_sig = {' % (bitmask.id)
+        print '   %u, %u, __bitmask%s_vals' % (int(bitmask.id), len(bitmask.values), bitmask.id)
+        print '};'
         print
 
     def visit_pointer(self, pointer):
@@ -150,7 +146,7 @@ class DumpImplementer(stdapi.Visitor):
         print '    __traceEnum%s(%s);' % (enum.id, instance)
 
     def visit_bitmask(self, bitmask, instance):
-        print '    __traceBitmask%s(%s);' % (bitmask.id, instance)
+        print '    Trace::LiteralBitmask(__bitmask%s_sig, %s);' % (bitmask.id, instance)
 
     def visit_pointer(self, pointer, instance):
         print '    if(%s) {' % instance
index 760093c780a4d1279ffd36bb88b1f04e891ee029..e6ec467ad10bd3cbae8eaeaae030f41ba2b3f982 100644 (file)
@@ -59,6 +59,10 @@ void Const::visit(Visitor &visitor) {
    visitor.visit(this);
 }
 
+void Bitmask::visit(Visitor &visitor) {
+   visitor.visit(this);
+}
+
 void Array::visit(Visitor &visitor) {
    visitor.visit(this);
 }
@@ -129,6 +133,29 @@ public:
       os << literal << node->name << normal;
    }
 
+   void visit(Bitmask *bitmask) {
+      unsigned long long value = bitmask->value;
+      const Bitmask::Signature *sig = bitmask->sig;
+      bool first = true;
+      for (Bitmask::Signature::const_iterator it = sig->begin(); value != 0 && it != sig->end(); ++it) {
+          assert(it->second);
+          if ((value & it->second) == it->second) {
+              if (!first) {
+                  os << " | ";
+              }
+              os << literal << it->first << normal;
+              value &= ~it->second;
+              first = false;
+          }
+      }
+      if (value || first) {
+          if (!first) {
+              os << " | ";
+          }
+          os << literal << std::hex << value << std::dec << normal;
+      }
+   }
+
    void visit(Array *array) {
       if (array->values.size() == 1) {
          os << "&";
index 8a87e0f65ed8443eef840252ce4dee7627817586..0bcd1804be03791df0ffbbfa4fb4d76074ad6d2f 100644 (file)
@@ -171,6 +171,20 @@ public:
 };
 
 
+class Bitmask : public UInt
+{
+public:
+   typedef std::pair<std::string, unsigned long long> Pair;
+   typedef std::vector<Pair> Signature;
+
+   Bitmask(const Signature *_sig, unsigned long long _value) : UInt(_value), sig(_sig) {}
+
+   void visit(Visitor &visitor);
+
+   const Signature *sig;
+};
+
+
 class Array : public Value
 {
 public:
@@ -211,6 +225,7 @@ public:
    virtual void visit(Float *) {assert(0);}
    virtual void visit(String *) {assert(0);}
    virtual void visit(Const *) {assert(0);}
+   virtual void visit(Bitmask *bitmask) {visit(static_cast<UInt *>(bitmask));}
    virtual void visit(Array *) {assert(0);}
    virtual void visit(Blob *) {assert(0);}
 
index 850dc8de821cd17d0f437a70b2522ce2d4ad07cc..b77fc3ec68853709dc42cdcdacacee9919f79205 100644 (file)
@@ -56,6 +56,9 @@ protected:
    typedef std::map<unsigned, Call *> callmap;
    callmap calls;
 
+   typedef std::map<size_t, Bitmask::Signature *> BitmaskMap;
+   BitmaskMap bitmasks;
+
    unsigned next_call_no;
 
 public:
@@ -235,30 +238,26 @@ public:
    }
    
    Value *parse_bitmask() {
-      unsigned long long value = 0;
-      int c;
-      do {
-         c = read_byte();
-         switch(c) {
-         case Trace::TYPE_SINT:
-            value |= -(signed long long)read_uint();
-            break;
-         case Trace::TYPE_UINT:
-            value |= read_uint();
-            break;
-         case Trace::TYPE_CONST:
-            read_name();
-            break;
-         case Trace::TYPE_NULL:
-            goto done;
-         default:
-            std::cerr << "error: uexpected type " << c << "\n";
-            assert(0);
-            return NULL;
-         }
-      } while(true);
-done:
-      return new UInt(value);
+      size_t id = read_uint();
+      Bitmask::Signature *sig;
+      BitmaskMap::const_iterator it = bitmasks.find(id);
+      if (it == bitmasks.end()) {
+          size_t size = read_uint();
+          sig = new Bitmask::Signature(size);
+          for (Bitmask::Signature::iterator it = sig->begin(); it != sig->end(); ++it) {
+              it->first = read_string();
+              it->second = read_uint();
+              assert(it->second);
+          }
+          bitmasks[id] = sig;
+      } else {
+          sig = it->second;
+      }
+      assert(sig);
+
+      unsigned long long value = read_uint();
+
+      return new Bitmask(sig, value);
    }
 
    Value *parse_array(void) {
index 054303b597f22dbd1a872de69efccf90cc2c7134..912824e012d936db5ef8bc0b478771c7608788d0 100644 (file)
@@ -303,6 +303,22 @@ void LiteralNamedConstant(const char *name, long long value) {
    LiteralSInt(value);
 }
 
+static std::map<Id, bool> bitmasks;
+
+void LiteralBitmask(const BitmaskSig &bitmask, unsigned long long value) {
+   WriteByte(Trace::TYPE_BITMASK);
+   WriteUInt(bitmask.id);
+   if (!bitmasks[bitmask.id]) {
+      WriteUInt(bitmask.count);
+      for (unsigned i = 0; i < bitmask.count; ++i) {
+         WriteString(bitmask.values[i].name);
+         WriteUInt(bitmask.values[i].value);
+      }
+      bitmasks[bitmask.id] = true;
+   }
+   WriteUInt(value);
+}
+
 void LiteralNull(void) {
    WriteByte(Trace::TYPE_NULL);
 }
index 7b494e4126620bed70c1c114abfe0c1df54a0e5b..faa36a5eef44c61698c262b11a558caefab284ff 100644 (file)
  *
  **************************************************************************/
 
-#ifndef _TRACE_HPP_
-#define _TRACE_HPP_
+#ifndef _TRACE_WRITE_HPP_
+#define _TRACE_WRITE_HPP_
 
 namespace Trace {
 
+    typedef unsigned Id;
+
+    struct BitmaskVal {
+        const char *name;
+        unsigned long long value;
+    };
+
+    struct BitmaskSig {
+        Id id;
+        unsigned count;
+        const BitmaskVal *values;
+    };
+
     void Open(void);
     void Close(void);
     
@@ -55,9 +68,6 @@ namespace Trace {
     void BeginMember(const char *name);
     inline void EndMember(void) {}
 
-    void BeginBitmask(void);
-    void EndBitmask(void);
-
     void LiteralBool(bool value);
     void LiteralSInt(signed long long value);
     void LiteralUInt(unsigned long long value);
@@ -68,10 +78,11 @@ namespace Trace {
     void LiteralWString(const wchar_t *str);
     void LiteralBlob(const void *data, size_t size);
     void LiteralNamedConstant(const char *name, long long value);
+    void LiteralBitmask(const BitmaskSig &bitmask, unsigned long long value);
     void LiteralNull(void);
     void LiteralOpaque(const void *ptr);
 
     void Abort(void);
 }
 
-#endif /* _TRACE_HPP_ */
+#endif /* _TRACE_WRITE_HPP_ */