From 49424a7b11152296af87d87dd03a0eaf7c41fbc9 Mon Sep 17 00:00:00 2001 From: Nathan Froyd Date: Tue, 28 Aug 2012 12:55:32 -0400 Subject: [PATCH] Bug 748444 - eliminate relocations from histogram data; r=taras --- toolkit/components/telemetry/Telemetry.cpp | 27 +++++++-- .../telemetry/gen-histogram-data.py | 55 +++++++++++++++++-- 2 files changed, 71 insertions(+), 11 deletions(-) diff --git a/toolkit/components/telemetry/Telemetry.cpp b/toolkit/components/telemetry/Telemetry.cpp index 35a4420f0eca..8829849ab1a9 100644 --- a/toolkit/components/telemetry/Telemetry.cpp +++ b/toolkit/components/telemetry/Telemetry.cpp @@ -187,17 +187,32 @@ StatisticsRecorder gStatisticsRecorder; // Hardcoded probes struct TelemetryHistogram { - const char *id; uint32_t min; uint32_t max; uint32_t bucketCount; uint32_t histogramType; - const char *comment; + uint16_t id_offset; + uint16_t comment_offset; + + const char *id() const; + const char *comment() const; }; #include "TelemetryHistogramData.inc" bool gCorruptHistograms[Telemetry::HistogramCount]; +const char * +TelemetryHistogram::id() const +{ + return &gHistogramStringTable[this->id_offset]; +} + +const char * +TelemetryHistogram::comment() const +{ + return &gHistogramStringTable[this->comment_offset]; +} + bool TelemetryHistogramType(Histogram *h, uint32_t *result) { @@ -268,7 +283,7 @@ GetHistogramByEnumId(Telemetry::ID id, Histogram **ret) } const TelemetryHistogram &p = gHistograms[id]; - nsresult rv = HistogramGet(p.id, p.min, p.max, p.bucketCount, p.histogramType, &h); + nsresult rv = HistogramGet(p.id(), p.min, p.max, p.bucketCount, p.histogramType, &h); if (NS_FAILED(rv)) return rv; @@ -585,7 +600,7 @@ TelemetryImpl::GetHistogramEnumId(const char *name, Telemetry::ID *id) TelemetryImpl::HistogramMapType *map = &sTelemetry->mHistogramMap; if (!map->Count()) { for (uint32_t i = 0; i < Telemetry::HistogramCount; i++) { - CharPtrEntryType *entry = map->PutEntry(gHistograms[i].id); + CharPtrEntryType *entry = map->PutEntry(gHistograms[i].id()); if (NS_UNLIKELY(!entry)) { map->Clear(); return NS_ERROR_OUT_OF_MEMORY; @@ -1153,10 +1168,10 @@ TelemetryImpl::GetRegisteredHistograms(JSContext *cx, jsval *ret) JS::AutoObjectRooter root(cx, info); for (size_t i = 0; i < count; ++i) { - JSString *comment = JS_InternString(cx, gHistograms[i].comment); + JSString *comment = JS_InternString(cx, gHistograms[i].comment()); if (!(comment - && JS_DefineProperty(cx, info, gHistograms[i].id, + && JS_DefineProperty(cx, info, gHistograms[i].id(), STRING_TO_JSVAL(comment), NULL, NULL, JSPROP_ENUMERATE))) { return NS_ERROR_FAILURE; diff --git a/toolkit/components/telemetry/gen-histogram-data.py b/toolkit/components/telemetry/gen-histogram-data.py index db144b836375..d96a84d209b9 100644 --- a/toolkit/components/telemetry/gen-histogram-data.py +++ b/toolkit/components/telemetry/gen-histogram-data.py @@ -16,22 +16,67 @@ banner = """/* This file is auto-generated, see gen-histogram-data.py. */ # Write out the gHistograms array. -def print_array_entry(histogram): +class StringTable: + def __init__(self): + self.current_index = 0; + self.table = {} + + def c_strlen(self, string): + return len(string) + 1 + + def stringIndex(self, string): + if string in self.table: + return self.table[string] + else: + result = self.current_index + self.table[string] = result + self.current_index += self.c_strlen(string) + return result + + def writeDefinition(self, f, name): + entries = self.table.items() + entries.sort(key=lambda x:x[1]) + # Avoid null-in-string warnings with GCC and potentially + # overlong string constants; write everything out the long way. + def explodeToCharArray(string): + def toCChar(s): + if s == "'": + return "'\\''" + else: + return "'%s'" % s + return ", ".join(map(toCChar, string)) + f.write("const char %s[] = {\n" % name) + for (string, offset) in entries[:-1]: + f.write(" /* %5d */ %s, '\\0',\n" + % (offset, explodeToCharArray(string))) + f.write(" /* %5d */ %s, '\\0' };\n\n" + % (entries[-1][1], explodeToCharArray(entries[-1][0]))) + +def print_array_entry(histogram, name_index, desc_index): cpp_guard = histogram.cpp_guard() if cpp_guard: print "#if defined(%s)" % cpp_guard - print " { \"%s\", %s, %s, %s, %s, \"%s\" }," \ - % (histogram.name(), histogram.low(), histogram.high(), + print " { %s, %s, %s, %s, %d, %d }," \ + % (histogram.low(), histogram.high(), histogram.n_buckets(), histogram.nsITelemetry_kind(), - histogram.description()) + name_index, desc_index) if cpp_guard: print "#endif" def write_histogram_table(histograms): + table = StringTable() + print "const TelemetryHistogram gHistograms[] = {" for histogram in histograms: - print_array_entry(histogram) + name_index = table.stringIndex(histogram.name()) + desc_index = table.stringIndex(histogram.description()) + print_array_entry(histogram, name_index, desc_index) print "};" + + strtab_name = "gHistogramStringTable" + table.writeDefinition(sys.stdout, strtab_name) + static_assert("sizeof(%s) <= UINT16_MAX" % strtab_name, + "index overflow") # Write out static asserts for histogram data. We'd prefer to perform # these checks in this script itself, but since several histograms