From f84c70e16aaf953f8984981456f5baf8eada7153 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 26 Nov 2010 15:26:14 +0000 Subject: [PATCH] More efficient enum representation. --- stdapi.py | 6 +++++- trace.py | 13 ++++++++++--- trace_format.hpp | 2 +- trace_model.cpp | 6 +++--- trace_model.hpp | 6 +++--- trace_parser.hpp | 25 +++++++++++++++++++------ trace_write.cpp | 21 +++++++++------------ trace_write.hpp | 8 +++++++- 8 files changed, 57 insertions(+), 30 deletions(-) diff --git a/stdapi.py b/stdapi.py index c22d88f..8dca958 100644 --- a/stdapi.py +++ b/stdapi.py @@ -254,9 +254,13 @@ def ConstPointer(type): class Enum(Concrete): + __vid = 0 + def __init__(self, name, values): Concrete.__init__(self, name) - self.values = values + self.vid = Enum.__vid + Enum.__vid += len(values) + self.values = list(values) def visit(self, visitor, *args, **kwargs): return visitor.visit_enum(self, *args, **kwargs) diff --git a/trace.py b/trace.py index da7f9ce..47360a8 100644 --- a/trace.py +++ b/trace.py @@ -68,15 +68,22 @@ class DumpDeclarator(stdapi.OnceVisitor): def visit_enum(self, enum): print 'static void __traceEnum%s(const %s value) {' % (enum.id, enum.expr) + n = len(enum.values) + for i in range(n): + value = enum.values[i] + print ' static const Trace::EnumSig sig%u = {%u, "%s", %s};' % (i, enum.vid + i, value, value) + print ' const Trace::EnumSig *sig;' print ' switch(value) {' - for value in enum.values: + for i in range(n): + value = enum.values[i] print ' case %s:' % value - print ' Trace::LiteralNamedConstant("%s", %s);' % (value, value) + print ' sig = &sig%u;' % i print ' break;' print ' default:' print ' Trace::LiteralSInt(value);' - print ' break;' + print ' return;' print ' }' + print ' Trace::LiteralEnum(sig);' print '}' print diff --git a/trace_format.hpp b/trace_format.hpp index 1f5871e..43efa0f 100644 --- a/trace_format.hpp +++ b/trace_format.hpp @@ -53,7 +53,7 @@ enum Type { TYPE_DOUBLE, TYPE_STRING, // Null terminated, human readible string TYPE_BLOB, // Block of bytes - TYPE_CONST, + TYPE_ENUM, TYPE_BITMASK, TYPE_ARRAY, TYPE_STRUCT, diff --git a/trace_model.cpp b/trace_model.cpp index b0e5158..fb25826 100644 --- a/trace_model.cpp +++ b/trace_model.cpp @@ -55,7 +55,7 @@ void String::visit(Visitor &visitor) { visitor.visit(this); } -void Const::visit(Visitor &visitor) { +void Enum::visit(Visitor &visitor) { visitor.visit(this); } @@ -129,7 +129,7 @@ public: os << literal << '"' << node->value << '"' << normal; } - void visit(Const *node) { + void visit(Enum *node) { os << literal << node->name << normal; } @@ -205,7 +205,7 @@ std::ostream & operator <<(std::ostream &os, Value *value) { static inline const Value *unwrap(const Value *node) { - const Const *c = dynamic_cast(node); + const Enum *c = dynamic_cast(node); if (c) return c->value; return node; diff --git a/trace_model.hpp b/trace_model.hpp index 9e2ae97..5c162bc 100644 --- a/trace_model.hpp +++ b/trace_model.hpp @@ -159,10 +159,10 @@ public: }; -class Const : public Value +class Enum : public Value { public: - Const(std::string _name, Value *_value) : name(_name), value(_value) {} + Enum(std::string &_name, Value *_value) : name(_name), value(_value) {} void visit(Visitor &visitor); @@ -224,7 +224,7 @@ public: virtual void visit(UInt *) {assert(0);} virtual void visit(Float *) {assert(0);} virtual void visit(String *) {assert(0);} - virtual void visit(Const *) {assert(0);} + virtual void visit(Enum *) {assert(0);} virtual void visit(Bitmask *bitmask) {visit(static_cast(bitmask));} virtual void visit(Array *) {assert(0);} virtual void visit(Blob *) {assert(0);} diff --git a/trace_parser.hpp b/trace_parser.hpp index 5d51315..254141c 100644 --- a/trace_parser.hpp +++ b/trace_parser.hpp @@ -59,6 +59,9 @@ protected: typedef std::map FunctionMap; FunctionMap functions; + typedef std::map EnumMap; + EnumMap enums; + typedef std::map BitmaskMap; BitmaskMap bitmasks; @@ -207,8 +210,8 @@ public: return parse_double(); case Trace::TYPE_STRING: return parse_string(); - case Trace::TYPE_CONST: - return parse_const(); + case Trace::TYPE_ENUM: + return parse_enum(); case Trace::TYPE_BITMASK: return parse_bitmask(); case Trace::TYPE_ARRAY: @@ -250,10 +253,20 @@ public: return new String(read_string()); } - Value *parse_const() { - std::string name = read_name(); - Value *value = parse_value(); - return new Const(name, value); + Value *parse_enum() { + size_t id = read_uint(); + Enum *sig; + EnumMap::const_iterator it = enums.find(id); + if (it == enums.end()) { + std::string name = read_string(); + Value *value = parse_value(); + sig = new Enum(name, value); + enums[id] = sig; + } else { + sig = it->second; + } + assert(sig); + return sig; } Value *parse_bitmask() { diff --git a/trace_write.cpp b/trace_write.cpp index 3860e31..cdc3892 100644 --- a/trace_write.cpp +++ b/trace_write.cpp @@ -171,6 +171,7 @@ void Close(void) { static unsigned call_no = 0; static std::map functions; +static std::map enums; static std::map bitmasks; @@ -231,14 +232,6 @@ void BeginMember(const char *name) { WriteName(name); } -void BeginBitmask(void) { - WriteByte(Trace::TYPE_BITMASK); -} - -void EndBitmask(void) { - WriteByte(Trace::TYPE_NULL); -} - void LiteralBool(bool value) { WriteByte(value ? Trace::TYPE_TRUE : Trace::TYPE_FALSE); } @@ -308,10 +301,14 @@ void LiteralBlob(const void *data, size_t size) { } } -void LiteralNamedConstant(const char *name, long long value) { - WriteByte(Trace::TYPE_CONST); - WriteName(name); - LiteralSInt(value); +void LiteralEnum(const EnumSig *sig) { + WriteByte(Trace::TYPE_ENUM); + WriteUInt(sig->id); + if (!enums[sig->id]) { + WriteString(sig->name); + LiteralSInt(sig->value); + enums[sig->id] = true; + } } void LiteralBitmask(const BitmaskSig &bitmask, unsigned long long value) { diff --git a/trace_write.hpp b/trace_write.hpp index 9f9acdb..428b30f 100644 --- a/trace_write.hpp +++ b/trace_write.hpp @@ -37,6 +37,12 @@ namespace Trace { const char **args; }; + struct EnumSig { + Id id; + const char *name; + signed long long value; + }; + struct BitmaskVal { const char *name; unsigned long long value; @@ -84,7 +90,7 @@ namespace Trace { void LiteralString(const char *str, size_t size); void LiteralWString(const wchar_t *str); void LiteralBlob(const void *data, size_t size); - void LiteralNamedConstant(const char *name, long long value); + void LiteralEnum(const EnumSig *sig); void LiteralBitmask(const BitmaskSig &bitmask, unsigned long long value); void LiteralNull(void); void LiteralOpaque(const void *ptr); -- 2.45.2