diff --git a/js/src/TraceLogging.cpp b/js/src/TraceLogging.cpp index 898044b4653..6ff75ebd942 100644 --- a/js/src/TraceLogging.cpp +++ b/js/src/TraceLogging.cpp @@ -89,14 +89,16 @@ const char* const TraceLogging::type_name[] = { TraceLogging* TraceLogging::_defaultLogger = NULL; TraceLogging::TraceLogging() - : loggingTime(0), - startupTime(rdtsc()), + : startupTime(rdtsc()), + loggingTime(0), + nextTextId(1), entries(NULL), curEntry(0), numEntries(1000000), fileno(0), out(NULL) { + textMap.init(); } TraceLogging::~TraceLogging() @@ -130,24 +132,36 @@ TraceLogging::grow() } void -TraceLogging::log(Type type, const char* file, unsigned int lineno) +TraceLogging::log(Type type, const char* text /* = NULL */, unsigned int number /* = 0 */) { uint64_t now = rdtsc() - startupTime; // Create array containing the entries if not existing. - if (entries == NULL) { + if (!entries) { entries = (Entry*) malloc(numEntries*sizeof(Entry)); - if (entries == NULL) + if (!entries) return; } - // Copy the logging information, - // because original could already be freed before writing the log file. - char *copy = NULL; - if (file != NULL) - copy = strdup(file); + uint32_t textId = 0; + char *text_ = NULL; - entries[curEntry++] = Entry(now - loggingTime, copy, lineno, type); + if (text) { + TextHashMap::AddPtr p = textMap.lookupForAdd(text); + if (!p) { + // Copy the text, because original could already be freed before writing the log file. + text_ = strdup(text); + if (!text_) + return; + textId = nextTextId++; + if (!textMap.add(p, text, textId)) + return; + } else { + textId = p->value; + } + } + + entries[curEntry++] = Entry(now - loggingTime, text_, textId, number, type); // Increase length when not enough place in the array if (curEntry >= numEntries) @@ -177,12 +191,6 @@ TraceLogging::log(const char* log) this->log(INFO, log, 0); } -void -TraceLogging::log(Type type) -{ - this->log(type, NULL, 0); -} - void TraceLogging::flush() { @@ -192,20 +200,29 @@ TraceLogging::flush() // Print all log entries into the file for (unsigned int i = 0; i < curEntry; i++) { + Entry entry = entries[i]; int written; - if (entries[i].type() == INFO) { - written = fprintf(out, "I,%s\n", entries[i].file()); + if (entry.type() == INFO) { + written = fprintf(out, "I,%s\n", entry.text()); } else { - if (entries[i].file() == NULL) { - written = fprintf(out, "%llu,%s\n", - (unsigned long long)entries[i].tick(), - type_name[entries[i].type()]); + if (entry.textId() > 0) { + if (entry.text()) { + written = fprintf(out, "%llu,%s,%s,%d\n", + (unsigned long long)entry.tick(), + type_name[entry.type()], + entry.text(), + entry.lineno()); + } else { + written = fprintf(out, "%llu,%s,%d,%d\n", + (unsigned long long)entry.tick(), + type_name[entry.type()], + entry.textId(), + entry.lineno()); + } } else { - written = fprintf(out, "%llu,%s,%s:%d\n", - (unsigned long long)entries[i].tick(), - type_name[entries[i].type()], - entries[i].file(), - entries[i].lineno()); + written = fprintf(out, "%llu,%s\n", + (unsigned long long)entry.tick(), + type_name[entry.type()]); } } @@ -224,9 +241,9 @@ TraceLogging::flush() continue; } - if (entries[i].file() != NULL) { - free(entries[i].file()); - entries[i].file_ = NULL; + if (entries[i].text() != NULL) { + free(entries[i].text()); + entries[i].text_ = NULL; } } curEntry = 0; diff --git a/js/src/TraceLogging.h b/js/src/TraceLogging.h index 0de77f176ba..f1b0ff12aef 100644 --- a/js/src/TraceLogging.h +++ b/js/src/TraceLogging.h @@ -10,6 +10,9 @@ #include #include +#include "jsalloc.h" + +#include "js/HashTable.h" #include "js/TypeDecls.h" namespace JS { @@ -47,21 +50,34 @@ class TraceLogging private: struct Entry { uint64_t tick_; - char* file_; + char* text_; + uint32_t textId_; uint32_t lineno_; uint8_t type_; - Entry(uint64_t tick, char* file, uint32_t lineno, Type type) - : tick_(tick), file_(file), lineno_(lineno), type_((uint8_t)type) {} + Entry(uint64_t tick, char* text, uint32_t textId, uint32_t lineno, Type type) + : tick_(tick), + text_(text), + textId_(textId), + lineno_(lineno), + type_((uint8_t)type) {} uint64_t tick() const { return tick_; } - char *file() const { return file_; } + char *text() const { return text_; } + uint32_t textId() const { return textId_; } uint32_t lineno() const { return lineno_; } Type type() const { return (Type) type_; } }; + typedef HashMap, + SystemAllocPolicy> TextHashMap; + uint64_t startupTime; uint64_t loggingTime; + TextHashMap textMap; + uint32_t nextTextId; Entry *entries; unsigned int curEntry; unsigned int numEntries; @@ -74,11 +90,10 @@ class TraceLogging TraceLogging(); ~TraceLogging(); - void log(Type type, const char* filename, unsigned int line); + void log(Type type, const char* text = NULL, unsigned int number = 0); void log(Type type, const JS::CompileOptions &options); void log(Type type, JSScript* script); void log(const char* log); - void log(Type type); void flush(); static TraceLogging* defaultLogger();