Bug 1374631 - Switch generated data to "constexpr" instead of "const" where possible
Update the telemetry Python scripts which output C++ code to use
'constexpr' instead of 'const'. Except on Windows, where
we still use 'const'.
MozReview-Commit-ID: 3i6g4h5ZxE8
--- a/toolkit/components/telemetry/gen_event_data.py
+++ b/toolkit/components/telemetry/gen_event_data.py
@@ -30,18 +30,18 @@ file_footer = """\
"""
def write_extra_table(events, output, string_table):
table_name = "gExtraKeysTable"
extra_table = []
extra_count = 0
- print("const uint32_t %s[] = {" % table_name, file=output)
-
+ print("#ifdef XP_WIN\n const uint32_t %s[] = {\n#else\nconstexpr uint32_t %s[] = {\n#endif\n"
+ % (table_name, table_name), file=output)
for e in events:
extra_index = 0
extra_keys = e.extra_keys
if len(extra_keys) > 0:
extra_index = extra_count
extra_count += len(extra_keys)
indexes = string_table.stringIndexes(extra_keys)
@@ -61,17 +61,19 @@ def write_extra_table(events, output, st
"index overflow")
return extra_table
def write_common_event_table(events, output, string_table, extra_table):
table_name = "gCommonEventInfo"
- print("const CommonEventInfo %s[] = {" % table_name, file=output)
+ print("#ifdef XP_WIN\nconst CommonEventInfo %s[] = {\n#else\n\
+constexpr CommonEventInfo %s[] = {\n#endif" % (table_name, table_name), file=output)
+
for e, extras in zip(events, extra_table):
# Write a comment to make the file human-readable.
print(" // category: %s" % e.category, file=output)
print(" // methods: [%s]" % ", ".join(e.methods), file=output)
print(" // objects: [%s]" % ", ".join(e.objects), file=output)
# Write the common info structure
print(" {%d, %d, %d, %d, %s, %s}," %
@@ -85,17 +87,18 @@ def write_common_event_table(events, out
print("};", file=output)
static_assert(output, "sizeof(%s) <= UINT32_MAX" % table_name,
"index overflow")
def write_event_table(events, output, string_table):
table_name = "gEventInfo"
- print("const EventInfo %s[] = {" % table_name, file=output)
+ print("#ifdef XP_WIN\nconst EventInfo %s[] = {\n#else\n constexpr EventInfo %s[] = {\n#endif"
+ % (table_name, table_name), file=output)
for common_info_index, e in enumerate(events):
for method_name, object_name in itertools.product(e.methods, e.objects):
print(" // category: %s, method: %s, object: %s" %
(e.category, method_name, object_name),
file=output)
print(" {gCommonEventInfo[%d], %d, %d}," %
--- a/toolkit/components/telemetry/gen_event_enum.py
+++ b/toolkit/components/telemetry/gen_event_enum.py
@@ -67,15 +67,16 @@ def main(output, *filenames):
print("#if defined(%s)" % cpp_guard, file=output)
for offset, label in enumerate(e.enum_labels):
print(" %s = %d," % (label, event_index + offset), file=output)
if cpp_guard:
print("#endif", file=output)
print("};\n", file=output)
- print("const uint32_t EventCount = %d;\n" % index, file=output)
+ print("#ifdef XP_WIN\nconst uint32_t EventCount = %d;\n#else\n\
+constexpr uint32_t EventCount = %d;\n#endif" % (index, index), file=output)
print(file_footer, file=output)
if __name__ == '__main__':
main(sys.stdout, *sys.argv[1:])
--- a/toolkit/components/telemetry/gen_histogram_data.py
+++ b/toolkit/components/telemetry/gen_histogram_data.py
@@ -41,16 +41,17 @@ def print_array_entry(output, histogram,
def write_histogram_table(output, histograms):
string_table = StringTable()
label_table = []
label_count = 0
keys_table = []
keys_count = 0
print("constexpr HistogramInfo gHistogramInfos[] = {", file=output)
+
for histogram in histograms:
name_index = string_table.stringIndex(histogram.name())
exp_index = string_table.stringIndex(histogram.expiration())
labels = histogram.labels()
label_index = 0
if len(labels) > 0:
label_index = label_count
@@ -68,22 +69,24 @@ def write_histogram_table(output, histog
label_index, len(labels), key_index, len(keys))
print("};\n", file=output)
strtab_name = "gHistogramStringTable"
string_table.writeDefinition(output, strtab_name)
static_assert(output, "sizeof(%s) <= UINT32_MAX" % strtab_name,
"index overflow")
- print("\nconst uint32_t gHistogramLabelTable[] = {", file=output)
+ print("\n#ifdef XP_WIN\nconst uint32_t gHistogramLabelTable[] = {\n#else\n\
+constexpr uint32_t gHistogramLabelTable[] = {\n#endif", file=output)
for name, indexes in label_table:
print("/* %s */ %s," % (name, ", ".join(map(str, indexes))), file=output)
print("};", file=output)
- print("\nconst uint32_t gHistogramKeyTable[] = {", file=output)
+ print("\n#ifdef XP_WIN\nconst uint32_t gHistogramKeyTable[] = {\n#else\n\
+constexpr uint32_t gHistogramKeyTable[] = {\n#endif", file=output)
for name, indexes in keys_table:
print("/* %s */ %s," % (name, ", ".join(map(str, indexes))), file=output)
print("};", file=output)
# Write out static asserts for histogram data. We'd prefer to perform
# these checks in this script itself, but since several histograms
# (generally enumerated histograms) use compile-time constants for
@@ -152,17 +155,18 @@ def write_histogram_static_asserts(outpu
def write_histogram_ranges(output, histograms):
# This generates static data to avoid costly initialization of histograms
# (especially exponential ones which require log and exp calls) at runtime.
# The format must exactly match that required in histogram.cc, which is
# 0, buckets..., INT_MAX. Additionally, the list ends in a 0 to aid asserts
# that validate that the length of the ranges list is correct.U cache miss.
- print("const int gHistogramBucketLowerBounds[] = {", file=output)
+ print("#ifdef XP_WIN\nconst int gHistogramBucketLowerBounds[] = {\n#else\n\
+constexpr int gHistogramBucketLowerBounds[] = {\n#endif", file=output)
# Print the dummy buckets for expired histograms, and set the offset to match.
print("0,1,2,INT_MAX,", file=output)
offset = 4
ranges_offsets = {}
for histogram in histograms:
ranges = tuple(histogram.ranges())
@@ -172,17 +176,18 @@ def write_histogram_ranges(output, histo
# expected format.
offset += len(ranges) + 1
print(','.join(map(str, ranges)), ',INT_MAX,', file=output)
print("0};", file=output)
if offset > 32767:
raise Exception('Histogram offsets exceeded maximum value for an int16_t.')
- print("const int16_t gHistogramBucketLowerBoundIndex[] = {", file=output)
+ print("#ifdef XP_WIN\nconst int16_t gHistogramBucketLowerBoundIndex[] = {\n#else\n\
+constexpr int16_t gHistogramBucketLowerBoundIndex[] = {\n#endif", file=output)
for histogram in histograms:
cpp_guard = histogram.cpp_guard()
if cpp_guard:
print("#if defined(%s)" % cpp_guard, file=output)
our_offset = ranges_offsets[tuple(histogram.ranges())]
print("%d," % our_offset, file=output)
--- a/toolkit/components/telemetry/shared_telemetry_utils.py
+++ b/toolkit/components/telemetry/shared_telemetry_utils.py
@@ -65,17 +65,17 @@ class StringTable:
def stringIndexes(self, strings):
""" Returns a list of indexes for the provided list of strings.
Adds the strings to the table if they are not in it yet.
:param strings: list of strings to put into the table.
"""
return [self.stringIndex(s) for s in strings]
def writeDefinition(self, f, name):
- """Writes the string table to a file as a C const char array.
+ """Writes the string table to a file as a C constexpr char array.
This writes out the string table as one single C char array for memory
size reasons, separating the individual strings with '\0' characters.
This way we can index directly into the string array and avoid the additional
storage costs for the pointers to them (and potential extra relocations for those).
:param f: the output stream.
:param name: the name of the output array.
@@ -88,17 +88,18 @@ class StringTable:
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)
+ f.write("#ifdef XP_WIN\nconst char %s[] = {\n#else\nconstexpr char %s[] = {\n#endif\n"
+ % (name, name))
for (string, offset) in entries:
if "*/" in string:
raise ValueError("String in string table contains unexpected sequence '*/': %s" %
string)
e = explodeToCharArray(string)
if e:
f.write(" /* %5d - \"%s\" */ %s, '\\0',\n"