#include <stdlib.h>
#include <string.h>
+#include <map>
+
#include <zlib.h>
#include "os.hpp"
Write(str, len);
}
+typedef std::map<const char *, size_t> namemap;
+static namemap names;
+
+static inline void
+WriteName(const char *name) {
+ namemap::iterator it = names.find(name);
+ if (it == names.end()) {
+ size_t name_id = names.size();
+ WriteUInt(name_id);
+ WriteString(name);
+ names[name] = name_id;
+ } else {
+ WriteUInt(it->second);
+ }
+}
+
void Open(void) {
if (!g_gzFile) {
_Open("trace");
OS::AcquireMutex();
Open();
++reentrancy;
- WriteString(function);
+ WriteName(function);
}
void EndCall(void) {
void BeginArg(unsigned index, const char *name) {
WriteByte(Trace::CALL_ARG);
WriteUInt(index);
- WriteString(name);
+ WriteName(name);
}
void BeginReturn(void) {
WriteUInt(length);
}
-void BeginStruct(const char *name) {
+void BeginStruct(size_t length) {
WriteByte(Trace::TYPE_STRUCT);
- (void)name;
-}
-
-void EndStruct(void) {
- WriteString("");
+ WriteUInt(length);
}
void BeginMember(const char *name) {
- WriteString(name);
+ WriteName(name);
}
void BeginBitmask(void) {
void LiteralNamedConstant(const char *name, long long value) {
WriteByte(Trace::TYPE_CONST);
- WriteString(name);
+ WriteName(name);
LiteralSInt(value);
}
inline void BeginElement(void) {}
inline void EndElement(void) {}
- void BeginStruct(const char *name);
- void EndStruct(void);
+ void BeginStruct(size_t length);
+ inline void EndStruct(void) {}
void BeginMember(const char *name);
inline void EndMember(void) {}
for type, name in struct.members:
self.visit(type)
print 'static void __traceStruct%s(const %s &value) {' % (struct.id, struct.expr)
- print ' Log::BeginStruct("%s");' % struct.name
+ print ' Log::BeginStruct(%u);' % len(struct.members)
for type, name in struct.members:
print ' Log::BeginMember("%s");' % (name,)
dump_instance(type, 'value.%s' % (name,))
#include <cassert>
#include <iostream>
+#include <map>
+#include <string>
#include <zlib.h>
{
protected:
gzFile file;
+
+ typedef std::map<size_t, std::string> namemap;
+ namemap names;
+
public:
Parser() {
file = NULL;
Call *parse_call(void) {
Call *call = new Call;
- call->name = read_string();
+ call->name = read_name();
do {
int c = read_byte();
switch(c) {
void parse_arg(Call *call) {
unsigned index = read_uint();
- std::string name = read_string();
+ std::string name = read_name();
Value *value = parse_value();
if (index >= call->args.size()) {
call->args.resize(index + 1);
}
Value *parse_const() {
- std::string name = read_string();
+ std::string name = read_name();
Value *value = parse_value();
return new Const(name, value);
}
value |= read_uint();
break;
case Trace::TYPE_CONST:
- read_string();
+ read_name();
break;
case Trace::TYPE_NULL:
goto done;
}
Value *parse_struct() {
- std::string name;
+ size_t length = read_uint();
/* XXX */
- name = read_string();
- while(name.length()) {
+ for (size_t i; i < length; ++i) {
+ std::string name = read_name();
Value *value = parse_value();
std::cout << " " << name << " = " << value << "\n";
- name = read_string();
}
return NULL;
}
/* XXX */
return new UInt(addr);
}
+
+ std::string read_name(void) {
+ std::string name;
+ size_t id = read_uint();
+ if (id >= names.size()) {
+ name = read_string();
+ names[id] = name;
+ return name;
+ } else {
+ return names[id];
+ }
+ }
std::string read_string(void) {
size_t len = read_uint();