Bug 1374631 - Switch generated data to "constexpr" instead of "const" where possible draft
authorSamathy Barratt <samathy@sbarratt.co.uk>
Fri, 08 Dec 2017 18:58:35 +0000
changeset 720109 f1e082901ba5f43f066878aa3294d7110f19c61d
parent 709139 66c12fc2afd2e2b542627db864de8ac66a5eb91f
child 745977 f7a3baab973d16e5ceef20d7c196cfbc44364b08
push id95449
push userbmo:samathy@sbarratt.co.uk
push dateSat, 13 Jan 2018 21:28:02 +0000
bugs1374631
milestone59.0a1
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
toolkit/components/telemetry/gen_event_data.py
toolkit/components/telemetry/gen_event_enum.py
toolkit/components/telemetry/gen_histogram_data.py
toolkit/components/telemetry/shared_telemetry_utils.py
--- 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"