Backed out 9 changesets (bug 1578661) for lints failure at ServoCSSPropList.py a=backout
authorAndreea Pavel <apavel@mozilla.com>
Wed, 18 Sep 2019 13:53:34 +0300
changeset 493715 a3a081ae714f1123bdc23c9d9ef53dfaa783a8de
parent 493713 ce04e402c705c8ee9d491c3cef11a3876af2680f
child 493716 d14a75760af232fd3565237b01a85e0c76017c32
child 493783 96ee513793ff925352ebffa3b7539755d1fa123d
push id114098
push usermalexandru@mozilla.com
push dateWed, 18 Sep 2019 11:50:32 +0000
treeherdermozilla-inbound@d14a75760af2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbackout
bugs1578661
milestone71.0a1
backs outd16463e5698c360909016b15ed01d867bf59eb2d
c6d64ac858ba342075b60571f8ad3617a555c9e3
db306f1467f7fdcce65b22936069c694f5cb01db
273535aab82dde60d12b49fae4dd0e9079ad31b5
f643262a8c250b10b5a0632af407bead6a0feb75
b0db409ada967d9d45ede4b2132932710bffb067
dc96d13728e0d0ae81b7f674700b415f484e7784
11e1e8f0a1b772213a5fdf53df2cb1996334dd5e
6dd7a0d914d9a514fc2a28dbb9de47bfb66b1939
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out 9 changesets (bug 1578661) for lints failure at ServoCSSPropList.py a=backout Backed out changeset d16463e5698c (bug 1578661) Backed out changeset c6d64ac858ba (bug 1578661) Backed out changeset db306f1467f7 (bug 1578661) Backed out changeset 273535aab82d (bug 1578661) Backed out changeset f643262a8c25 (bug 1578661) Backed out changeset b0db409ada96 (bug 1578661) Backed out changeset dc96d13728e0 (bug 1578661) Backed out changeset 11e1e8f0a1b7 (bug 1578661) Backed out changeset 6dd7a0d914d9 (bug 1578661)
dom/base/Document.cpp
dom/base/Document.h
dom/base/UseCounter.h
dom/base/UseCounters.conf
dom/base/gen-usecounters.py
dom/base/moz.build
dom/base/test/browser.ini
dom/base/test/browser_use_counters.js
dom/base/test/file_use_counter_style.html
dom/base/usecounters.py
dom/svg/SVGElement.cpp
layout/style/GenerateCountedUnknownProperties.py
layout/style/moz.build
layout/style/nsCSSPropertyID.h.in
layout/style/nsCSSProps.cpp
layout/style/nsCSSProps.h
servo/components/style/properties/properties.mako.rs
servo/ports/geckolib/cbindgen.toml
servo/ports/geckolib/glue.rs
toolkit/components/telemetry/build_scripts/gen_histogram_phf.py
toolkit/components/telemetry/build_scripts/mozparsers/parse_histograms.py
toolkit/components/telemetry/docs/collection/use-counters.rst
toolkit/components/telemetry/moz.build
--- a/dom/base/Document.cpp
+++ b/dom/base/Document.cpp
@@ -14415,17 +14415,16 @@ void Document::PropagateUseCounters(Docu
   // starting with aParentDocument, we need to find the toplevel content
   // document, and propagate our use counters into its
   // mChildDocumentUseCounters.
   Document* contentParent = aParentDocument->GetTopLevelContentDocument();
   if (!contentParent) {
     return;
   }
 
-  SetCssUseCounterBits();
   contentParent->mChildDocumentUseCounters |= mUseCounters;
   contentParent->mChildDocumentUseCounters |= mChildDocumentUseCounters;
 }
 
 bool Document::HasScriptsBlockedBySandbox() {
   return mSandboxFlags & SANDBOXED_SCRIPTS;
 }
 
@@ -14444,71 +14443,16 @@ bool Document::InlineScriptAllowedByCSP(
         0,              // aLineNumber
         0,              // aColumnNumber
         &allowsInlineScript);
     NS_ENSURE_SUCCESS(rv, true);
   }
   return allowsInlineScript;
 }
 
-// Some use-counter sanity-checking.
-static_assert(size_t(eUseCounter_EndCSSProperties) -
-                      size_t(eUseCounter_FirstCSSProperty) ==
-                  size_t(eCSSProperty_COUNT_with_aliases),
-              "We should have the right amount of CSS property use counters");
-static_assert(size_t(eUseCounter_Count) -
-                      size_t(eUseCounter_FirstCountedUnknownProperty) ==
-                  size_t(CountedUnknownProperty::Count),
-              "We should have the right amount of counted unknown properties"
-              " use counters");
-static_assert(size_t(eUseCounter_Count) * 2 ==
-                  size_t(Telemetry::HistogramUseCounterCount),
-              "There should be two histograms (document and page)"
-              " for each use counter");
-
-#define ASSERT_CSS_COUNTER(id_, method_)                        \
-  static_assert(size_t(eUseCounter_property_##method_) -        \
-                        size_t(eUseCounter_FirstCSSProperty) == \
-                    size_t(id_),                                \
-                "Order for CSS counters and CSS property id should match");
-#define CSS_PROP_PUBLIC_OR_PRIVATE(publicname_, privatename_) privatename_
-#define CSS_PROP_LONGHAND(name_, id_, method_, ...) \
-  ASSERT_CSS_COUNTER(eCSSProperty_##id_, method_)
-#define CSS_PROP_SHORTHAND(name_, id_, method_, ...) \
-  ASSERT_CSS_COUNTER(eCSSProperty_##id_, method_)
-#define CSS_PROP_ALIAS(name_, aliasid_, id_, method_, ...) \
-  ASSERT_CSS_COUNTER(eCSSPropertyAlias_##aliasid_, method_)
-#include "mozilla/ServoCSSPropList.h"
-#undef CSS_PROP_ALIAS
-#undef CSS_PROP_SHORTHAND
-#undef CSS_PROP_LONGHAND
-#undef CSS_PROP_PUBLIC_OR_PRIVATE
-#undef ASSERT_CSS_COUNTER
-
-void Document::SetCssUseCounterBits() {
-  if (!mStyleUseCounters) {
-    return;
-  }
-
-  for (size_t i = 0; i < eCSSProperty_COUNT_with_aliases; ++i) {
-    auto id = nsCSSPropertyID(i);
-    if (Servo_IsPropertyIdRecordedInUseCounter(mStyleUseCounters.get(), id)) {
-      SetUseCounter(nsCSSProps::UseCounterFor(id));
-    }
-  }
-
-  for (size_t i = 0; i < size_t(CountedUnknownProperty::Count); ++i) {
-    if (Servo_IsUnknownPropertyRecordedInUseCounter(
-          mStyleUseCounters.get(), CountedUnknownProperty(i))) {
-      SetUseCounter(UseCounter(eUseCounter_FirstCountedUnknownProperty + i));
-    }
-  }
-}
-
-
 void Document::PropagateUseCountersToPage() {
   if (mDisplayDocument) {
     // If we are a resource document, we won't have a docshell and so we won't
     // record any page use counters on this document.  Instead, we should
     // forward it up to the document that loaded us.
     MOZ_ASSERT(!mDocumentContainer);
     return PropagateUseCounters(mDisplayDocument);
   }
@@ -14536,17 +14480,16 @@ void Document::PropagateUseCountersToPag
 void Document::ReportUseCounters() {
   static const bool kDebugUseCounters = false;
 
   if (mReportedUseCounters) {
     return;
   }
 
   mReportedUseCounters = true;
-  SetCssUseCounterBits();
 
   // Call ReportUseCounters in all our outstanding subdocuments and resources
   // and such. This needs to be here so that all our sub documents propagate our
   // counters to us if needed.
   //
   // We need to do this explicitly (rather than, e.g., moving the
   // ReportUseCounters() call after DestroyContent(), which destroys the frame
   // loaders) because subdocument destruction may be (and is generally) async
--- a/dom/base/Document.h
+++ b/dom/base/Document.h
@@ -4034,20 +4034,16 @@ class Document : public nsINode,
    * dimensions/scale to be treated as if "width=device-width" had in fact been
    * specified.
    */
   virtual bool UseWidthDeviceWidthFallbackViewport() const;
 
  private:
   void InitializeLocalization(nsTArray<nsString>& aResourceIds);
 
-  // Takes the bits from mStyleUseCounters if appropriate, and sets them in
-  // mUseCounters.
-  void SetCssUseCounterBits();
-
   // Returns true if there is any valid value in the viewport meta tag.
   bool ParseWidthAndHeightInMetaViewport(const nsAString& aWidthString,
                                          const nsAString& aHeightString,
                                          bool aIsAutoScale);
 
   // Parse scale values in viewport meta tag for a given |aHeaderField| which
   // represents the scale property and returns the scale value if it's valid.
   Maybe<LayoutDeviceToScreenScale> ParseScaleInHeader(nsAtom* aHeaderField);
--- a/dom/base/UseCounter.h
+++ b/dom/base/UseCounter.h
@@ -12,52 +12,26 @@ namespace mozilla {
 
 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_FirstCSSProperty,
-  __reset_hack = eUseCounter_FirstCSSProperty - 1,
-
-// Need an extra level of macro nesting to force expansion of method_
-// params before they get pasted.
-#define CSS_PROP_USE_COUNTER(method_) eUseCounter_property_##method_,
-#define CSS_PROP_PUBLIC_OR_PRIVATE(publicname_, privatename_) privatename_
-#define CSS_PROP_LONGHAND(name_, id_, method_, ...) \
-  CSS_PROP_USE_COUNTER(method_)
-#define CSS_PROP_SHORTHAND(name_, id_, method_, ...) \
-  CSS_PROP_USE_COUNTER(method_)
-#define CSS_PROP_ALIAS(name_, aliasid_, id_, method_, ...) \
-  CSS_PROP_USE_COUNTER(method_)
-#include "mozilla/ServoCSSPropList.h"
-#undef CSS_PROP_ALIAS
-#undef CSS_PROP_SHORTHAND
-#undef CSS_PROP_LONGHAND
-#undef CSS_PROP_PUBLIC_OR_PRIVATE
-#undef CSS_PROP_USE_COUNTER
-
-  eUseCounter_EndCSSProperties,
-  eUseCounter_FirstCountedUnknownProperty = eUseCounter_EndCSSProperties,
-  __reset_hack_2 = eUseCounter_FirstCountedUnknownProperty - 1,
-
-#define COUNTED_UNKNOWN_PROPERTY(name_, method_) eUseCounter_unknown_property_##method_,
-#include "mozilla/CountedUnknownProperties.h"
-#undef COUNTED_UNKNOWN_PROPERTY
-
   eUseCounter_Count
 };
 
 }  // namespace mozilla
 
 #endif
--- a/dom/base/UseCounters.conf
+++ b/dom/base/UseCounters.conf
@@ -11,36 +11,44 @@
 //   (a) a blank line
 //
 //   (b) a comment, which is a line that begins with "//"
 //
 //   (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 CamelCase form of the property
+// name with -moz- and -x- prefix removed.
+//
 // 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 (including whitespace).
 //
 // To actually cause use counters to be incremented, DOM methods
 // and attributes must have a [UseCounter] extended attribute in
-// the Web IDL file.
-// Custom counters are incremented when
+// the Web IDL file.  CSS properties require no special treatment
+// beyond being listed below.  Custom counters are incremented when
 // SetUseCounter(eUseCounter_custom_MyName) is called on a 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.
+// 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.
 
 method SVGSVGElement.getElementById
 attribute SVGSVGElement.currentScale
+property Fill
+property FillOpacity
 attribute XMLDocument.async
 
 // Push API
 method PushManager.subscribe
 method PushSubscription.unsubscribe
 
 // window.sidebar
 attribute Window.sidebar
--- a/dom/base/gen-usecounters.py
+++ b/dom/base/gen-usecounters.py
@@ -31,26 +31,57 @@ def generate_list(f, counters):
 #undef %(name)s
 #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_
+  // Need an extra level of macro nesting to force expansion of method_
+  // params before they get pasted.
+  #define CSS_PROP_USE_COUNTER(method_) \\
+    USE_COUNTER_FOR_CSS_PROPERTY_##method_ = eUseCounter_UNKNOWN,
+  #define CSS_PROP_LONGHAND(name_, id_, method_, ...) \\
+    CSS_PROP_USE_COUNTER(method_)
+  #include "mozilla/ServoCSSPropList.h"
+  #undef CSS_PROP_LONGHAND
+  #undef CSS_PROP_USE_COUNTER
+  #undef CSS_PROP_PUBLIC_OR_PRIVATE
+};
+''', file=f)
+    for counter in counters:
+        if counter['type'] == 'property':
+            prop = counter['property_name']
+            print('#define USE_COUNTER_FOR_CSS_PROPERTY_%s eUseCounter_property_%s' % (prop, prop), file=f)
+
 def use_counter_list(output_header, conf_filename):
     counters = usecounters.read_conf(conf_filename)
     generate_list(output_header, counters)
+
+def property_map(output_map, conf_filename):
+    counters = usecounters.read_conf(conf_filename)
+    generate_property_map(output_map, counters)
--- a/dom/base/moz.build
+++ b/dom/base/moz.build
@@ -535,17 +535,22 @@ FINAL_LIBRARY = 'xul'
 
 if CONFIG['MOZ_BUILD_APP'] in ['browser', 'mobile/android', 'xulrunner']:
     DEFINES['HAVE_SIDEBAR'] = True
 
 if CONFIG['MOZ_X11']:
     CXXFLAGS += CONFIG['TK_CFLAGS']
 
 GENERATED_FILES += [
+    'PropertyUseCounterMap.inc',
     'UseCounterList.h',
 ]
 
+countermap = GENERATED_FILES['PropertyUseCounterMap.inc']
+countermap.script = 'gen-usecounters.py:property_map'
+countermap.inputs = ['UseCounters.conf']
+
 counterlist = GENERATED_FILES['UseCounterList.h']
 counterlist.script = 'gen-usecounters.py:use_counter_list'
 counterlist.inputs = ['UseCounters.conf']
 
 if CONFIG['CC_TYPE'] in ('clang', 'gcc'):
     CXXFLAGS += ['-Wno-error=shadow']
--- a/dom/base/test/browser.ini
+++ b/dom/base/test/browser.ini
@@ -19,17 +19,16 @@ support-files =
   file_bug1303838_target_baz.html
   file_bug1303838_target_ifoo.html
   file_bug1303838_target_ibar.html
   file_bug1303838_target_ibaz.html
   file_bug1303838_with_iframe.html
   file_messagemanager_unload.html
   file_pluginAudio.html
   file_use_counter_outer.html
-  file_use_counter_style.html
   file_use_counter_svg_getElementById.svg
   file_use_counter_svg_currentScale.svg
   file_use_counter_svg_fill_pattern_definition.svg
   file_use_counter_svg_fill_pattern.svg
   file_use_counter_svg_fill_pattern_internal.svg
   file_use_counter_svg_fill_pattern_data.svg
   file_webaudioLoop.html
   file_webaudio_startstop.html
--- a/dom/base/test/browser_use_counters.js
+++ b/dom/base/test/browser_use_counters.js
@@ -46,40 +46,16 @@ add_task(async function() {
     "file_use_counter_svg_currentScale.svg",
     "SVGSVGELEMENT_CURRENTSCALE_getter"
   );
   await check_use_counter_iframe(
     "file_use_counter_svg_currentScale.svg",
     "SVGSVGELEMENT_CURRENTSCALE_setter"
   );
 
-  // Check for longhands.
-  await check_use_counter_iframe(
-    "file_use_counter_style.html",
-    "CSS_PROPERTY_BackgroundImage"
-  );
-
-  // Check for shorthands.
-  await check_use_counter_iframe(
-    "file_use_counter_style.html",
-    "CSS_PROPERTY_Padding"
-  );
-
-  // Check for aliases.
-  await check_use_counter_iframe(
-    "file_use_counter_style.html",
-    "CSS_PROPERTY_MozTransform"
-  );
-
-  // Check for counted unknown properties.
-  await check_use_counter_iframe(
-    "file_use_counter_style.html",
-    "CSS_PROPERTY_WebkitPaddingStart"
-  );
-
   // Check that even loads from the imglib cache update use counters.  The
   // images should still be there, because we just loaded them in the last
   // set of tests.  But we won't get updated counts for the document
   // counters, because we won't be re-parsing the SVG documents.
   await check_use_counter_iframe(
     "file_use_counter_svg_getElementById.svg",
     "SVGSVGELEMENT_GETELEMENTBYID",
     false
@@ -95,38 +71,37 @@ add_task(async function() {
     false
   );
 
   // Check that use counters are incremented by SVGs loaded as images.
   // Note that SVG images are not permitted to execute script, so we can only
   // check for properties here.
   await check_use_counter_img(
     "file_use_counter_svg_getElementById.svg",
-    "CSS_PROPERTY_Fill"
+    "PROPERTY_FILL"
   );
   await check_use_counter_img(
     "file_use_counter_svg_currentScale.svg",
-    "CSS_PROPERTY_Fill"
+    "PROPERTY_FILL"
   );
 
   // Check that use counters are incremented by directly loading SVGs
   // that reference patterns defined in another SVG file.
   await check_use_counter_direct(
     "file_use_counter_svg_fill_pattern.svg",
-    "CSS_PROPERTY_FillOpacity",
+    "PROPERTY_FILLOPACITY",
     /*xfail=*/ true
   );
 
   // Check that use counters are incremented by directly loading SVGs
   // that reference patterns defined in the same file or in data: URLs.
   await check_use_counter_direct(
     "file_use_counter_svg_fill_pattern_internal.svg",
-    "CSS_PROPERTY_FillOpacity"
+    "PROPERTY_FILLOPACITY"
   );
-
   // data: URLs don't correctly propagate to their referring document yet.
   //yield check_use_counter_direct("file_use_counter_svg_fill_pattern_data.svg",
   //                               "PROPERTY_FILL_OPACITY");
 });
 
 add_task(async function() {
   let Telemetry = Cc["@mozilla.org/base/telemetry;1"].getService(
     Ci.nsITelemetry
deleted file mode 100644
--- a/dom/base/test/file_use_counter_style.html
+++ /dev/null
@@ -1,12 +0,0 @@
-<!doctype html>
-<style>
-  div {
-    background-image: none;
-    padding: 10px;
-    -moz-transform: scale(10);
-    /* Just a property we're unlikely to implement */
-    -webkit-padding-start: 58.5;
-  }
-</style>
-<!-- We currently count even if we don't match it, but well just in case we change that... -->
-<div></div>
--- a/dom/base/usecounters.py
+++ b/dom/base/usecounters.py
@@ -27,16 +27,22 @@ def read_conf(conf_filename):
                 continue
             m = re.match(r'attribute ([A-Za-z0-9]+)\.([A-Za-z0-9]+)$', line)
             if m:
                 interface_name, attribute_name = m.groups()
                 yield { 'type': 'attribute',
                         'interface_name': interface_name,
                         '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))
@@ -60,12 +66,15 @@ def generate_histograms(filename):
         if counter['type'] == 'method':
             method = '%s.%s' % (counter['interface_name'], counter['method_name'])
             append_counters(method.replace('.', '_').upper(), 'called %s' % method)
         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
--- a/dom/svg/SVGElement.cpp
+++ b/dom/svg/SVGElement.cpp
@@ -1122,23 +1122,33 @@ void MappedAttrParser::ParseMappedAttrVa
 
     RefPtr<URLExtraData> data =
         new URLExtraData(mBaseURI, referrerInfo, mElement->NodePrincipal());
     changed = Servo_DeclarationBlock_SetPropertyById(
         mDecl->Raw(), propertyID, &value, false, data,
         ParsingMode::AllowUnitlessLength,
         mElement->OwnerDoc()->GetCompatibilityMode(), mLoader, {});
 
-    // TODO(emilio): If we want to record these from CSSOM more generally, we
-    // can pass the document use counters down the FFI call. For now manually
-    // count them for compat with the old code, which is used for testing.
     if (changed) {
-      UseCounter useCounter = nsCSSProps::UseCounterFor(propertyID);
-      MOZ_ASSERT(useCounter != eUseCounter_UNKNOWN);
-      mElement->OwnerDoc()->SetUseCounter(useCounter);
+      // The normal reporting of use counters by the nsCSSParser won't happen
+      // since it doesn't have a sheet.
+      if (nsCSSProps::IsShorthand(propertyID)) {
+        CSSPROPS_FOR_SHORTHAND_SUBPROPERTIES(subprop, propertyID,
+                                             CSSEnabledState::ForAllContent) {
+          UseCounter useCounter = nsCSSProps::UseCounterFor(*subprop);
+          if (useCounter != eUseCounter_UNKNOWN) {
+            mElement->OwnerDoc()->SetUseCounter(useCounter);
+          }
+        }
+      } else {
+        UseCounter useCounter = nsCSSProps::UseCounterFor(propertyID);
+        if (useCounter != eUseCounter_UNKNOWN) {
+          mElement->OwnerDoc()->SetUseCounter(useCounter);
+        }
+      }
     }
     return;
   }
   MOZ_ASSERT(aMappedAttrName == nsGkAtoms::lang,
              "Only 'lang' should be unrecognized!");
   // nsCSSParser doesn't know about 'lang', so we need to handle it specially.
   if (aMappedAttrName == nsGkAtoms::lang) {
     propertyID = eCSSProperty__x_lang;
deleted file mode 100644
--- a/layout/style/GenerateCountedUnknownProperties.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-import re
-import runpy
-import string
-
-
-def to_camel_case(ident):
-    return re.sub("(^|_|-)([a-z0-9])", lambda m: m.group(2).upper(), ident.strip("_").strip("-"))
-
-
-def generate(output, prop_file):
-    properties = runpy.run_path(prop_file)["COUNTED_UNKNOWN_PROPERTIES"]
-
-    output.write("/* THIS IS AN AUTOGENERATED FILE.  DO NOT EDIT */\n\n")
-
-    for prop in properties:
-        output.write("COUNTED_UNKNOWN_PROPERTY({}, {})\n".format(prop, to_camel_case(prop)))
--- a/layout/style/moz.build
+++ b/layout/style/moz.build
@@ -280,40 +280,32 @@ servo_props = GENERATED_FILES['ServoCSSP
 servo_props.script = 'GenerateServoCSSPropList.py:generate_data'
 servo_props.inputs = [
     'ServoCSSPropList.mako.py',
 ]
 
 if CONFIG['COMPILE_ENVIRONMENT']:
     GENERATED_FILES += [
         'CompositorAnimatableProperties.h',
-        'CountedUnknownProperties.h',
         'nsComputedDOMStyleGenerated.inc',
         'nsCSSPropsGenerated.inc',
         'ServoStyleConsts.h',
     ]
 
     EXPORTS.mozilla += [
         '!CompositorAnimatableProperties.h',
-        '!CountedUnknownProperties.h',
         '!ServoStyleConsts.h',
     ]
 
     compositor = GENERATED_FILES['CompositorAnimatableProperties.h']
     compositor.script = 'GenerateCompositorAnimatableProperties.py:generate'
     compositor.inputs = [
         '!ServoCSSPropList.py',
     ]
 
-    counted_unknown = GENERATED_FILES['CountedUnknownProperties.h']
-    counted_unknown.script = 'GenerateCountedUnknownProperties.py:generate'
-    counted_unknown.inputs = [
-        '/servo/components/style/properties/counted_unknown_properties.py',
-    ]
-
     computed = GENERATED_FILES['nsComputedDOMStyleGenerated.inc']
     computed.script = 'GenerateComputedDOMStyleGenerated.py:generate'
     computed.inputs = [
         '!ServoCSSPropList.py',
     ]
 
     css_props = GENERATED_FILES['nsCSSPropsGenerated.inc']
     css_props.script = 'GenerateCSSPropsGenerated.py:generate'
--- a/layout/style/nsCSSPropertyID.h.in
+++ b/layout/style/nsCSSPropertyID.h.in
@@ -71,20 +71,9 @@ enum nsCSSFontDesc {
 enum nsCSSCounterDesc {
   eCSSCounterDesc_UNKNOWN = -1,
 #define CSS_COUNTER_DESC(name_, method_) eCSSCounterDesc_##method_,
 #include "nsCSSCounterDescList.h"
 #undef CSS_COUNTER_DESC
   eCSSCounterDesc_COUNT
 };
 
-namespace mozilla {
-
-enum class CountedUnknownProperty : uint8_t {
-#define COUNTED_UNKNOWN_PROPERTY(name_, method_) method_,
-#include "mozilla/CountedUnknownProperties.h"
-#undef COUNTED_UNKNOWN_PROPERTY
-  Count,
-};
-
-} // namespace mozilla
-
 #endif /* nsCSSPropertyID_h___ */
--- a/layout/style/nsCSSProps.cpp
+++ b/layout/style/nsCSSProps.cpp
@@ -332,9 +332,26 @@ bool nsCSSProps::gPropertyEnabled[eCSSPr
 #include "mozilla/ServoCSSPropList.h"
 #undef CSS_PROP_ALIAS
 #undef CSS_PROP_SHORTHAND
 #undef CSS_PROP_LONGHAND
 
 #undef IS_ENABLED_BY_DEFAULT
 };
 
+#include "../../dom/base/PropertyUseCounterMap.inc"
+
+/* static */ const UseCounter
+    nsCSSProps::gPropertyUseCounter[eCSSProperty_COUNT_no_shorthands] = {
+#define CSS_PROP_PUBLIC_OR_PRIVATE(publicname_, privatename_) privatename_
+// Need an extra level of macro nesting to force expansion of method_
+// params before they get pasted.
+#define CSS_PROP_USE_COUNTER(method_) \
+  static_cast<UseCounter>(USE_COUNTER_FOR_CSS_PROPERTY_##method_),
+#define CSS_PROP_LONGHAND(name_, id_, method_, ...) \
+  CSS_PROP_USE_COUNTER(method_)
+#include "mozilla/ServoCSSPropList.h"
+#undef CSS_PROP_LONGHAND
+#undef CSS_PROP_USE_COUNTER
+#undef CSS_PROP_PUBLIC_OR_PRIVATE
+};
+
 #include "nsCSSPropsGenerated.inc"
--- a/layout/style/nsCSSProps.h
+++ b/layout/style/nsCSSProps.h
@@ -15,19 +15,19 @@
 #include <limits>
 #include <ostream>
 #include <type_traits>
 
 #include "nsString.h"
 #include "nsCSSPropertyID.h"
 #include "nsStyleStructFwd.h"
 #include "nsCSSKeywords.h"
-#include "mozilla/UseCounter.h"
 #include "mozilla/CSSEnabledState.h"
 #include "mozilla/CSSPropFlags.h"
+#include "mozilla/UseCounter.h"
 #include "mozilla/EnumTypeTraits.h"
 #include "mozilla/Preferences.h"
 #include "nsXULAppAPI.h"
 
 // Length of the "--" prefix on custom names (such as custom property names,
 // and, in the future, custom media query names).
 #define CSS_CUSTOM_NAME_PREFIX_LENGTH 2
 
@@ -106,24 +106,16 @@ class nsCSSProps {
     MOZ_ASSERT(0 <= aProperty && aProperty < eCSSProperty_COUNT,
                "out of range");
     return (aProperty >= eCSSProperty_COUNT_no_shorthands);
   }
 
   // Same but for @font-face descriptors
   static nsCSSFontDesc LookupFontDesc(const nsAString& aProperty);
 
-  // The relevant invariants are asserted in Document.cpp
-  static mozilla::UseCounter UseCounterFor(nsCSSPropertyID aProperty) {
-    MOZ_ASSERT(0 <= aProperty && aProperty < eCSSProperty_COUNT_with_aliases,
-               "out of range");
-    return mozilla::UseCounter(size_t(mozilla::eUseCounter_FirstCSSProperty) +
-                               size_t(aProperty));
-  }
-
   // Given a property enum, get the string value
   //
   // This string is static.
   static const nsDependentCSubstring GetStringValue(nsCSSPropertyID aProperty) {
     uint32_t len;
     const uint8_t* chars = Servo_Property_GetName(aProperty, &len);
     return nsDependentCSubstring(reinterpret_cast<const char*>(chars), len);
   }
@@ -242,17 +234,28 @@ class nsCSSProps {
                "out of range");
     // In the child process, assert that we're not trying to parse stylesheets
     // before we've gotten all our prefs.
     MOZ_ASSERT_IF(!XRE_IsParentProcess(),
                   mozilla::Preferences::ArePrefsInitedInContentProcess());
     return gPropertyEnabled[aProperty];
   }
 
+  // A table for the use counter associated with each CSS property.  If a
+  // property does not have a use counter defined in UseCounters.conf, then
+  // its associated entry is |eUseCounter_UNKNOWN|.
+  static const mozilla::UseCounter
+      gPropertyUseCounter[eCSSProperty_COUNT_no_shorthands];
+
  public:
+  static mozilla::UseCounter UseCounterFor(nsCSSPropertyID aProperty) {
+    MOZ_ASSERT(0 <= aProperty && aProperty < eCSSProperty_COUNT_no_shorthands,
+               "out of range");
+    return gPropertyUseCounter[aProperty];
+  }
 
   static bool IsEnabled(nsCSSPropertyID aProperty, EnabledState aEnabled) {
     if (IsEnabled(aProperty)) {
       return true;
     }
     if (aEnabled == EnabledState::IgnoreEnabledState) {
       return true;
     }
--- a/servo/components/style/properties/properties.mako.rs
+++ b/servo/components/style/properties/properties.mako.rs
@@ -1788,17 +1788,17 @@ impl ToCss for PropertyId {
                 dest.write_str("--")?;
                 serialize_atom_name(name, dest)
             }
         }
     }
 }
 
 /// The counted unknown property list which is used for css use counters.
-#[derive(Clone, Copy, Debug, Eq, FromPrimitive, Hash, PartialEq)]
+#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
 #[repr(u8)]
 pub enum CountedUnknownProperty {
     % for prop in data.counted_unknown_properties:
     /// ${prop.name}
     ${prop.camel_case},
     % endfor
 }
 
--- a/servo/ports/geckolib/cbindgen.toml
+++ b/servo/ports/geckolib/cbindgen.toml
@@ -190,17 +190,16 @@ renaming_overrides_prefixing = true
 "SharedFontList" = "SharedFontList"
 "nsSimpleContentList" = "nsSimpleContentList"
 "nsACString" = "nsACString"
 "nsAString" = "nsAString"
 "nsString" = "nsString"
 "nsTArray" = "nsTArray"
 "nsPresContext" = "nsPresContext"
 "ComputedTiming" = "ComputedTiming"
-"CountedUnknownProperty" = "CountedUnknownProperty"
 "RefPtr" = "RefPtr"
 "nsCSSPropertyID" = "nsCSSPropertyID"
 "nsCSSPropertyIDSet" = "nsCSSPropertyIDSet"
 "nsCSSValueSharedList" = "nsCSSValueSharedList"
 "AnimationPropertySegment" = "AnimationPropertySegment"
 "RawServoAnimationValueMap" = "RawServoAnimationValueMap"
 "RawServoAnimationValueTable" = "RawServoAnimationValueTable"
 "nsCSSUnit" = "nsCSSUnit"
--- a/servo/ports/geckolib/glue.rs
+++ b/servo/ports/geckolib/glue.rs
@@ -6548,33 +6548,16 @@ pub unsafe extern "C" fn Servo_UseCounte
 pub unsafe extern "C" fn Servo_UseCounters_Merge(
     doc_counters: &UseCounters,
     sheet_counters: &UseCounters,
 ) {
     doc_counters.merge(sheet_counters)
 }
 
 #[no_mangle]
-pub unsafe extern "C" fn Servo_IsPropertyIdRecordedInUseCounter(
-    use_counters: &UseCounters,
-    id: nsCSSPropertyID,
-) -> bool {
-    let id = NonCustomPropertyId::from_nscsspropertyid(id).unwrap();
-    use_counters.non_custom_properties.recorded(id)
-}
-
-#[no_mangle]
-pub unsafe extern "C" fn Servo_IsUnknownPropertyRecordedInUseCounter(
-    use_counters: &UseCounters,
-    p: CountedUnknownProperty,
-) -> bool {
-    use_counters.counted_unknown_properties.recorded(p)
-}
-
-#[no_mangle]
 pub unsafe extern "C" fn Servo_IsCssPropertyRecordedInUseCounter(
     use_counters: &UseCounters,
     property: *const nsACString,
     known_prop: *mut bool,
 ) -> bool {
     *known_prop = false;
     let prop_name = property.as_ref().unwrap().as_str_unchecked();
     let non_custom_id = match PropertyId::parse_enabled_for_all_content(prop_name) {
--- a/toolkit/components/telemetry/build_scripts/gen_histogram_phf.py
+++ b/toolkit/components/telemetry/build_scripts/gen_histogram_phf.py
@@ -1,17 +1,17 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 from __future__ import print_function
 from mozparsers.shared_telemetry_utils import ParserError
 from perfecthash import PerfectHash
 
-PHFSIZE = 1024
+PHFSIZE = 512
 
 from mozparsers import parse_histograms
 import sys
 import buildconfig
 
 
 banner = """/* This file is auto-generated, see gen_histogram_phf.py.  */
 """
--- a/toolkit/components/telemetry/build_scripts/mozparsers/parse_histograms.py
+++ b/toolkit/components/telemetry/build_scripts/mozparsers/parse_histograms.py
@@ -3,17 +3,16 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 import collections
 import itertools
 import json
 import math
 import os
 import re
-import runpy
 import sys
 import atexit
 import shared_telemetry_utils as utils
 
 from ctypes import c_int
 from shared_telemetry_utils import ParserError
 from collections import OrderedDict
 atexit.register(ParserError.exit_func)
@@ -727,62 +726,19 @@ def from_nsDeprecatedOperationList(filen
                     'description': 'Whether a %s used %s' % (context, op)
                 }
             add_counter('document')
             add_counter('page')
 
     return histograms
 
 
-def to_camel_case(property_name):
-    return re.sub("(^|_|-)([a-z0-9])",
-                  lambda m: m.group(2).upper(),
-                  property_name.strip("_").strip("-"))
-
-
-def add_css_property_counters(histograms, property_name):
-    def add_counter(context):
-        name = 'USE_COUNTER2_CSS_PROPERTY_%s_%s' % (to_camel_case(property_name), context.upper())
-        histograms[name] = {
-            'expires_in_version': 'never',
-            'kind': 'boolean',
-            'description': 'Whether a %s used the CSS property %s' % (context, property_name)
-        }
-
-    add_counter('document')
-    add_counter('page')
-
-
-def from_ServoCSSPropList(filename, strict_type_checks):
-    histograms = collections.OrderedDict()
-    properties = runpy.run_path(filename)["data"]
-    for prop in properties:
-        add_css_property_counters(histograms, prop.name)
-    return histograms
-
-
-def from_counted_unknown_properties(filename, strict_type_checks):
-    histograms = collections.OrderedDict()
-    properties = runpy.run_path(filename)["COUNTED_UNKNOWN_PROPERTIES"]
-
-    # NOTE(emilio): Unlike ServoCSSProperties, `prop` here is just the property
-    # name.
-    #
-    # We use the same naming as CSS properties so that we don't get
-    # discontinuity when we implement or prototype them.
-    for prop in properties:
-        add_css_property_counters(histograms, prop)
-    return histograms
-
-
 FILENAME_PARSERS = [
     (lambda x: from_json if x.endswith('.json') else None),
     (lambda x: from_nsDeprecatedOperationList if x == 'nsDeprecatedOperationList.h' else None),
-    (lambda x: from_ServoCSSPropList if x == 'ServoCSSPropList.py' else None),
-    (lambda x: from_counted_unknown_properties if x == 'counted_unknown_properties.py' else None),
 ]
 
 # Similarly to the dance above with buildconfig, usecounters may not be
 # available, so handle that gracefully.
 try:
     import usecounters
 
     FILENAME_PARSERS.append(lambda x: from_UseCounters_conf if x == 'UseCounters.conf' else None)
--- a/toolkit/components/telemetry/docs/collection/use-counters.rst
+++ b/toolkit/components/telemetry/docs/collection/use-counters.rst
@@ -31,58 +31,59 @@ Deprecated DOM operations
 -------------------------
 Use counters for deprecated DOM operations are declared in the `nsDeprecatedOperationList.h <https://dxr.mozilla.org/mozilla-central/source/dom/base/nsDeprecatedOperationList.h>`_ file. The counters are
 registered through the ``DEPRECATED_OPERATION(DeprecationReference)`` macro. The provided
 parameter must have the same value of the deprecation note added to the *IDL* file.
 
 See this `changeset <https://hg.mozilla.org/mozilla-central/rev/e30a357b25f1>`_ for a sample
 deprecated operation.
 
-CSS Properties
-~~~~~~~~~~~~~~
-
-Use counters for CSS properties are generated for every property Gecko supports automatically, and are counted via StyleUseCounters (`Rust code <https://searchfox.org/mozilla-central/rev/7ed8e2d3d1d7a1464ba42763a33fd2e60efcaedc/servo/components/style/use_counters/mod.rs>`_, `C++ code <https://searchfox.org/mozilla-central/rev/7ed8e2d3d1d7a1464ba42763a33fd2e60efcaedc/dom/base/Document.h#5077>`_).
-
 The UseCounters registry
 ------------------------
-Use counters for WebIDL methods/attributes are registered in the `UseCounters.conf <https://dxr.mozilla.org/mozilla-central/source/dom/base/UseCounters.conf>`_ file.  The format of this file is very strict. Each line can be:
+Use counters for WebIDL methods/attributes and CSS properties are registered in the `UseCounters.conf <https://dxr.mozilla.org/mozilla-central/source/dom/base/UseCounters.conf>`_ file.  The format of this file is very strict. Each line can be:
 
 1. a blank line
 2. a comment, which is a line that begins with ``//``
 3. 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>``
 
+CSS properties
+~~~~~~~~~~~~~~
+The CSS property method name should be identical to the ``method`` argument of ``CSS_PROP()`` and related macros. The only differences are that all hyphens are removed and CamelCase naming is used.  See `ServoCSSPropList.h <https://searchfox.org/mozilla-central/source/__GENERATED__/layout/style/ServoCSSPropList.h>`_ for further details.
+
 Custom use counters
 ~~~~~~~~~~~~~~~~~~~
-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 (including whitespace).  Custom counters are incremented when SetUseCounter(eUseCounter_custom_MyName) is called on a Document object.
+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 (including whitespace).  Custom counters are incremented when SetDocumentAndPageUseCounter(eUseCounter_custom_MyName) is called on an ns(I)Document object.
 
 WebIDL methods and attributes
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 Additionally to having a new entry added to the `UseCounters.conf <https://dxr.mozilla.org/mozilla-central/source/dom/base/UseCounters.conf>`_ file, WebIDL methods and attributes must have a ``[UseCounter]`` extended attribute in the Web IDL file in order for the counters to be incremented.
 
-Both additions are required because generating things from bindings codegen and ensuring all the dependencies are correct would have been rather difficult.
+Both additions are required because generating things from bindings codegen and ensuring all the dependencies are 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.
 
 The processor script
 ====================
 The definition files are processed twice:
 
 - once to generate two C++ headers files, included by the web platform components (e.g. DOM) that own the features to be tracked;
 - the other time by the Telemetry component, to generate the histogram definitions that make the collection system work.
 
 .. note::
 
     The histograms that are generated out of use counters are set to *never* expire and are collected from Firefox release. Note that before Firefox 65 they were only collected on pre-release.
 
 gen-usecounters.py
 ------------------
 This script is called by the build system to generate:
 
+- the ``PropertyUseCounterMap.inc`` C++ header for the CSS properties;
 - the ``UseCounterList.h`` header for the WebIDL, out of the definition files.
 
 Interpreting the data
 =====================
 The histogram as accumulated on the client only puts values into the 1 bucket, meaning that
 the use counter directly reports if a feature was used but it does not directly report if
 it isn't used.
 The values accumulated within a use counter should be considered proportional to
--- a/toolkit/components/telemetry/moz.build
+++ b/toolkit/components/telemetry/moz.build
@@ -152,18 +152,16 @@ GENERATED_FILES = [
     'TelemetryScalarEnums.h',
 ]
 
 # Generate histogram files.
 histogram_files = [
     'Histograms.json',
     '/dom/base/UseCounters.conf',
     '/dom/base/nsDeprecatedOperationList.h',
-    '!/layout/style/ServoCSSPropList.py',
-    '/servo/components/style/properties/counted_unknown_properties.py',
 ]
 if CONFIG['MOZ_TELEMETRY_EXTRA_HISTOGRAM_FILES']:
     histogram_files.extend(CONFIG['MOZ_TELEMETRY_EXTRA_HISTOGRAM_FILES'])
 
 data = GENERATED_FILES['TelemetryHistogramData.inc']
 data.script = 'build_scripts/gen_histogram_data.py'
 data.inputs = histogram_files