Bug 1175033 - Support custom use counters that can be incremented from C++; r?froydnj draft
authorAryeh Gregor <ayg@aryeh.name>
Tue, 08 Aug 2017 17:01:27 +0300
changeset 645327 e35a30bb2af8c559cfd013e4650c215b75f20ff9
parent 619581 52285ea5e54c73d3ed824544cef2ee3f195f05e6
child 725900 05a591f47df30c562f941d221309857ee1b9a3b0
push id73750
push userbmo:ayg@aryeh.name
push dateSat, 12 Aug 2017 19:31:34 +0000
reviewersfroydnj
bugs1175033
milestone57.0a1
Bug 1175033 - Support custom use counters that can be incremented from C++; r?froydnj MozReview-Commit-ID: 7uFDgmM2zqs
dom/base/UseCounter.h
dom/base/UseCounters.conf
dom/base/gen-usecounters.py
dom/base/usecounters.py
--- a/dom/base/UseCounter.h
+++ b/dom/base/UseCounter.h
@@ -13,20 +13,23 @@ enum UseCounter : int16_t {
   eUseCounter_UNKNOWN = -1,
 #define USE_COUNTER_DOM_METHOD(interface_, name_) \
     eUseCounter_##interface_##_##name_,
 #define USE_COUNTER_DOM_ATTRIBUTE(interface_, name_) \
     eUseCounter_##interface_##_##name_##_getter, \
     eUseCounter_##interface_##_##name_##_setter,
 #define USE_COUNTER_CSS_PROPERTY(name_, id_) \
     eUseCounter_property_##id_,
+#define USE_COUNTER_CUSTOM(name_, desc_) \
+    eUseCounter_custom_##name_,
 #include "mozilla/dom/UseCounterList.h"
 #undef USE_COUNTER_DOM_METHOD
 #undef USE_COUNTER_DOM_ATTRIBUTE
 #undef USE_COUNTER_CSS_PROPERTY
+#undef USE_COUNTER_CUSTOM
 
 #define DEPRECATED_OPERATION(op_) \
   eUseCounter_##op_,
 #include "nsDeprecatedOperationList.h"
 #undef DEPRECATED_OPERATION
 
   eUseCounter_Count
 };
--- a/dom/base/UseCounters.conf
+++ b/dom/base/UseCounters.conf
@@ -7,32 +7,40 @@
 // through Telemetry.
 //
 // The format of this file is very strict.  Each line can be:
 //
 //   (a) a blank line
 //
 //   (b) a comment, which is a line that begins with "//"
 //
-//   (c) one of three possible use counter declarations:
+//   (c) one of four possible use counter declarations:
 //
 //         method <IDL interface name>.<IDL operation name>
 //         attribute <IDL interface name>.<IDL attribute name>
 //         property <CSS property method name>
+//         custom <any valid identifier> <description>
 //
 // The |CSS property method name| should be identical to the |method|
 // argument to CSS_PROP and related macros.  The method name is
 // identical to the name of the property, except that all hyphens are
 // removed and CamelCase naming is used.  See nsCSSPropList.h for
 // further details.
 //
+// The <description> for custom counters will be appended to "When a document "
+// or "When a page ", so phrase it appropriately.  For instance, "constructs a
+// Foo object" or "calls Document.bar('some value')".  It may contain any
+// character.
+//
 // To actually cause use counters to be incremented, DOM methods
 // and attributes must have a [UseCounter] extended attribute in
 // the Web IDL file.  CSS properties require no special treatment
-// beyond being listed below.
+// beyond being listed below.  Custom counters are incremented when
+// SetDocumentAndPageUseCounter(eUseCounter_custom_MyName) is called on an
+// ns(I)Document object.
 //
 // You might reasonably ask why we have this file and we require
 // annotating things with [UseCounter] in the relevant WebIDL file as
 // well.  Generating things from bindings codegen and ensuring all the
 // dependencies were correct would have been rather difficult, and
 // annotating the WebIDL files does nothing for identifying CSS
 // property usage, which we would also like to track.
 
--- a/dom/base/gen-usecounters.py
+++ b/dom/base/gen-usecounters.py
@@ -32,29 +32,34 @@ def generate_list(f, counters):
 #endif
 ''' % { 'name': name }, file=f)
 
     print(AUTOGENERATED_WARNING_COMMENT, file=f)
 
     print_optional_macro_declare('USE_COUNTER_DOM_METHOD')
     print_optional_macro_declare('USE_COUNTER_DOM_ATTRIBUTE')
     print_optional_macro_declare('USE_COUNTER_CSS_PROPERTY')
+    print_optional_macro_declare('USE_COUNTER_CUSTOM')
 
     for counter in counters:
         if counter['type'] == 'method':
             print('USE_COUNTER_DOM_METHOD(%s, %s)' % (counter['interface_name'], counter['method_name']), file=f)
         elif counter['type'] == 'attribute':
             print('USE_COUNTER_DOM_ATTRIBUTE(%s, %s)' % (counter['interface_name'], counter['attribute_name']), file=f)
         elif counter['type'] == 'property':
             prop = counter['property_name']
             print('USE_COUNTER_CSS_PROPERTY(%s, %s)' % (prop, prop), file=f)
+        elif counter['type'] == 'custom':
+            desc = counter['desc'].replace('\\', r'\\').replace('"', r'\"')
+            print('USE_COUNTER_CUSTOM(%s, "%s")' % (counter['name'], desc), file=f)
 
     print_optional_macro_undeclare('USE_COUNTER_DOM_METHOD')
     print_optional_macro_undeclare('USE_COUNTER_DOM_ATTRIBUTE')
     print_optional_macro_undeclare('USE_COUNTER_CSS_PROPERTY')
+    print_optional_macro_undeclare('USE_COUNTER_CUSTOM')
 
 def generate_property_map(f, counters):
     print(AUTOGENERATED_WARNING_COMMENT, file=f)
     print('''
 enum {
   #define CSS_PROP_PUBLIC_OR_PRIVATE(publicname_, privatename_) privatename_
   #define CSS_PROP_LIST_INCLUDE_LOGICAL
   #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_,     \\
--- a/dom/base/usecounters.py
+++ b/dom/base/usecounters.py
@@ -33,16 +33,23 @@ def read_conf(conf_filename):
                         'attribute_name': attribute_name }
                 continue
             m = re.match(r'property ([A-Za-z0-9]+)$', line)
             if m:
                 property_name = m.group(1)
                 yield { 'type': 'property',
                         'property_name': property_name }
                 continue
+            m = re.match(r'custom ([A-Za-z0-9_]+) (.*)$', line)
+            if m:
+                name, desc = m.groups()
+                yield { 'type': 'custom',
+                        'name': name,
+                        'desc': desc }
+                continue
             raise ValueError('error parsing %s at line %d' % (conf_filename, line_num))
 
     return parse_counters(stream)
 
 def generate_histograms(filename):
     # The mapping for use counters to telemetry histograms depends on the
     # ordering of items in the dictionary.
     items = collections.OrderedDict()
@@ -62,10 +69,12 @@ def generate_histograms(filename):
         elif counter['type'] == 'attribute':
             attr = '%s.%s' % (counter['interface_name'], counter['attribute_name'])
             counter_name = attr.replace('.', '_').upper()
             append_counters('%s_getter' % counter_name, 'got %s' % attr)
             append_counters('%s_setter' % counter_name, 'set %s' % attr)
         elif counter['type'] == 'property':
             prop = counter['property_name']
             append_counters('PROPERTY_%s' % prop.replace('-', '_').upper(), "used the '%s' property" % prop)
+        elif counter['type'] == 'custom':
+            append_counters(counter['name'].upper(), counter['desc'])
 
     return items