Backed out 5 changesets (bug 790732) for talos-other hangs/crashes on a CLOSED TREE.
authorRyan VanderMeulen <ryanvm@gmail.com>
Tue, 05 Mar 2013 15:44:15 -0500
changeset 123872 bef7c417aa938643582034e2abb606b79c2d3710
parent 123871 bdf1f0890e2fa363b28d42c08b6a15a615f870c9
child 123873 06b6880a8241ab6c05f93ad422c23f2d5d5a5d8f
push id1401
push userpastithas@mozilla.com
push dateThu, 07 Mar 2013 07:26:45 +0000
treeherderfx-team@ee4879719f78 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs790732
milestone22.0a1
Backed out 5 changesets (bug 790732) for talos-other hangs/crashes on a CLOSED TREE.
content/base/public/nsDeprecatedOperationList.h
dom/base/nsGlobalWindow.cpp
dom/locales/en-US/chrome/dom/dom.properties
js/xpconnect/src/XPCComponents.cpp
js/xpconnect/src/XPCJSRuntime.cpp
js/xpconnect/src/nsXPConnect.cpp
js/xpconnect/src/xpcprivate.h
js/xpconnect/tests/chrome/Makefile.in
js/xpconnect/tests/chrome/test_bug795275.xul
js/xpconnect/tests/mochitest/Makefile.in
js/xpconnect/tests/mochitest/file_bug795275.html
js/xpconnect/tests/mochitest/file_bug795275.xml
toolkit/components/passwordmgr/test/test_prompt.html
toolkit/components/satchel/test/test_form_autocomplete.html
toolkit/components/telemetry/Histograms.json
--- a/content/base/public/nsDeprecatedOperationList.h
+++ b/content/base/public/nsDeprecatedOperationList.h
@@ -20,9 +20,10 @@ DEPRECATED_OPERATION(NodeValue)
 DEPRECATED_OPERATION(TextContent)
 DEPRECATED_OPERATION(EnablePrivilege)
 DEPRECATED_OPERATION(InputEncoding)
 DEPRECATED_OPERATION(MozBeforePaint)
 DEPRECATED_OPERATION(DOMExceptionCode)
 DEPRECATED_OPERATION(NoExposedProps)
 DEPRECATED_OPERATION(MutationEvent)
 DEPRECATED_OPERATION(MozSlice)
+DEPRECATED_OPERATION(Components)
 DEPRECATED_OPERATION(PrefixedVisibilityAPI)
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -1941,26 +1941,20 @@ CreateNativeGlobalForInner(JSContext* aC
   MOZ_ASSERT(aNewInner);
   MOZ_ASSERT(aNewInner->IsInnerWindow());
   MOZ_ASSERT(aPrincipal);
   MOZ_ASSERT(aNativeGlobal);
   MOZ_ASSERT(aHolder);
 
   nsIXPConnect* xpc = nsContentUtils::XPConnect();
 
-  // If we've got XBL scopes enabled, we can now turn off the Components object
-  // for content.
-  bool usingXBLScope = !nsContentUtils::IsSystemPrincipal(aPrincipal) &&
-                       Preferences::GetBool("dom.xbl_scopes",  true);
-  uint32_t flags = usingXBLScope ? nsIXPConnect::OMIT_COMPONENTS_OBJECT : 0;
-
   nsRefPtr<nsIXPConnectJSObjectHolder> jsholder;
   nsresult rv = xpc->InitClassesWithNewWrappedGlobal(
     aCx, ToSupports(aNewInner),
-    aPrincipal, flags, getter_AddRefs(jsholder));
+    aPrincipal, 0, getter_AddRefs(jsholder));
   NS_ENSURE_SUCCESS(rv, rv);
 
   MOZ_ASSERT(jsholder);
   jsholder->GetJSObject(aNativeGlobal);
   jsholder.forget(aHolder);
 
   // Set the location information for the new global, so that tools like
   // about:memory may use that information
--- a/dom/locales/en-US/chrome/dom/dom.properties
+++ b/dom/locales/en-US/chrome/dom/dom.properties
@@ -113,16 +113,18 @@ MediaLoadDecodeError=Media resource %S c
 # LOCALIZATION NOTE: Do not translate "DOMException", "code" and "name"
 DOMExceptionCodeWarning=Use of DOMException's code attribute is deprecated. Use name instead.
 # LOCALIZATION NOTE: Do not translate "__exposedProps__"
 NoExposedPropsWarning=Exposing chrome JS objects to content without __exposedProps__ is insecure and deprecated. See https://developer.mozilla.org/en/XPConnect_wrappers for more information.
 # LOCALIZATION NOTE: Do not translate "Mutation Event" and "MutationObserver"
 MutationEventWarning=Use of Mutation Events is deprecated. Use MutationObserver instead.
 # LOCALIZATION NOTE: Do not translate "Blob", "mozSlice", or "slice"
 MozSliceWarning=Use of mozSlice on the Blob object is deprecated.  Use slice instead.
+# LOCALIZATION NOTE: Do not translate "Components"
+ComponentsWarning=The Components object is deprecated. It will soon be removed.
 PluginHangUITitle=Warning: Unresponsive plugin
 PluginHangUIMessage=%S may be busy, or it may have stopped responding. You can stop the plugin now, or you can continue to see if the plugin will complete.
 PluginHangUIWaitButton=Continue
 PluginHangUIStopButton=Stop plugin
 # LOCALIZATION NOTE: Do not translate "mozHidden", "mozVisibilityState", "hidden", or "visibilityState"
 PrefixedVisibilityApiWarning='mozHidden' and 'mozVisibilityState' are deprecated.  Please use the unprefixed 'hidden' and 'visibilityState' instead.
 # LOCALIZATION NOTE: Do not translate "X-Content-Security-Policy", "X-Content-Security-Policy-Report-Only",  "Content-Security-Policy" or "Content-Security-Policy-Report-Only"
 OldCSPHeaderDeprecated=The X-Content-Security-Policy and X-Content-Security-Report-Only headers will be deprecated in the future. Please use the Content-Security-Policy and Content-Security-Report-Only headers with CSP spec compliant syntax instead.
--- a/js/xpconnect/src/XPCComponents.cpp
+++ b/js/xpconnect/src/XPCComponents.cpp
@@ -28,16 +28,17 @@
 #include "AccessCheck.h"
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/Preferences.h"
 #include "nsPrincipal.h"
 #include "mozilla/Attributes.h"
 #include "nsIScriptContext.h"
 #include "nsJSEnvironment.h"
 #include "nsXMLHttpRequest.h"
+#include "mozilla/Telemetry.h"
 #include "nsDOMClassInfoID.h"
 
 using namespace mozilla;
 using namespace js;
 using namespace xpc;
 
 using mozilla::dom::DestroyProtoAndIfaceCache;
 
@@ -4798,31 +4799,66 @@ nsXPCComponents::SetProperty(nsIXPConnec
             return NS_SUCCESS_I_DID_SOMETHING;
         }
         return NS_ERROR_FAILURE;
     }
 
     return NS_ERROR_XPC_CANT_MODIFY_PROP_ON_WN;
 }
 
+static JSBool
+ContentComponentsGetterOp(JSContext *cx, JSHandleObject obj, JSHandleId id,
+                          JSMutableHandleValue vp)
+{
+    // If chrome is accessing the Components object of content, allow.
+    MOZ_ASSERT(nsContentUtils::GetCurrentJSContext() == cx);
+    if (nsContentUtils::IsCallerChrome())
+        return true;
+
+    // If the caller is XBL, this is ok.
+    if (nsContentUtils::IsCallerXBL())
+        return true;
+
+    // Do Telemetry on how often this happens.
+    Telemetry::Accumulate(Telemetry::COMPONENTS_OBJECT_ACCESSED_BY_CONTENT, true);
+
+    // Warn once.
+    JSAutoCompartment ac(cx, obj);
+    nsCOMPtr<nsPIDOMWindow> win =
+        do_QueryInterface(nsJSUtils::GetStaticScriptGlobal(obj));
+    if (win) {
+        nsCOMPtr<nsIDocument> doc =
+            do_QueryInterface(win->GetExtantDocument());
+        if (doc)
+            doc->WarnOnceAbout(nsIDocument::eComponents, /* asError = */ true);
+    }
+
+    return true;
+}
+
 // static
 JSBool
 nsXPCComponents::AttachComponentsObject(XPCCallContext& ccx,
-                                        XPCWrappedNativeScope* aScope)
+                                        XPCWrappedNativeScope* aScope,
+                                        JSObject* aTarget)
 {
     JSObject *components = aScope->GetComponentsJSObject(ccx);
     if (!components)
         return false;
 
     JSObject *global = aScope->GetGlobalJSObject();
     MOZ_ASSERT(js::IsObjectInContextCompartment(global, ccx));
+    if (!aTarget)
+        aTarget = global;
 
     jsid id = ccx.GetRuntime()->GetStringID(XPCJSRuntime::IDX_COMPONENTS);
-    return JS_DefinePropertyById(ccx, global, id, js::ObjectValue(*components),
-                                 JS_PropertyStub, JS_StrictPropertyStub, JSPROP_PERMANENT | JSPROP_READONLY);
+    JSPropertyOp getter = AccessCheck::isChrome(global) ? nullptr
+                                                        : &ContentComponentsGetterOp;
+    return JS_DefinePropertyById(ccx, aTarget, id, js::ObjectValue(*components),
+                                 getter, nullptr, JSPROP_PERMANENT | JSPROP_READONLY);
 }
 
 /* void lookupMethod (); */
 NS_IMETHODIMP
 nsXPCComponents::LookupMethod(const JS::Value& object,
                               const JS::Value& name,
                               JSContext *cx,
                               JS::Value *retval)
@@ -4860,25 +4896,37 @@ nsXPCComponents::CanCreateWrapper(const 
 }
 
 /* string canCallMethod (in nsIIDPtr iid, in wstring methodName); */
 NS_IMETHODIMP
 nsXPCComponents::CanCallMethod(const nsIID * iid, const PRUnichar *methodName, char **_retval)
 {
     static const char* allowed[] = { "isSuccessCode", "lookupMethod", nullptr };
     *_retval = xpc_CheckAccessList(methodName, allowed);
+    if (*_retval &&
+        methodName[0] == 'l' &&
+        !nsContentUtils::IsCallerXBL())
+    {
+        Telemetry::Accumulate(Telemetry::COMPONENTS_LOOKUPMETHOD_ACCESSED_BY_CONTENT, true);
+    }
     return NS_OK;
 }
 
 /* string canGetProperty (in nsIIDPtr iid, in wstring propertyName); */
 NS_IMETHODIMP
 nsXPCComponents::CanGetProperty(const nsIID * iid, const PRUnichar *propertyName, char **_retval)
 {
     static const char* allowed[] = { "interfaces", "interfacesByID", "results", nullptr};
     *_retval = xpc_CheckAccessList(propertyName, allowed);
+    if (*_retval &&
+        propertyName[0] == 'i' &&
+        !nsContentUtils::IsCallerXBL())
+    {
+        Telemetry::Accumulate(Telemetry::COMPONENTS_INTERFACES_ACCESSED_BY_CONTENT, true);
+    }
     return NS_OK;
 }
 
 /* string canSetProperty (in nsIIDPtr iid, in wstring propertyName); */
 NS_IMETHODIMP
 nsXPCComponents::CanSetProperty(const nsIID * iid, const PRUnichar *propertyName, char **_retval)
 {
     // If you have to ask, then the answer is NO
--- a/js/xpconnect/src/XPCJSRuntime.cpp
+++ b/js/xpconnect/src/XPCJSRuntime.cpp
@@ -277,28 +277,18 @@ EnableUniversalXPConnect(JSContext *cx)
         return true;
     CompartmentPrivate *priv = GetCompartmentPrivate(compartment);
     if (!priv)
         return true;
     priv->universalXPConnectEnabled = true;
 
     // Recompute all the cross-compartment wrappers leaving the newly-privileged
     // compartment.
-    bool ok = js::RecomputeWrappers(cx, js::SingleCompartment(compartment),
-                                    js::AllCompartments());
-    NS_ENSURE_TRUE(ok, false);
-
-    // The Components object normally isn't defined for unprivileged web content,
-    // but we define it when UniversalXPConnect is enabled to support legacy
-    // tests.
-    XPCWrappedNativeScope *scope = priv->scope;
-    if (!scope)
-        return true;
-    XPCCallContext ccx(NATIVE_CALLER, cx);
-    return nsXPCComponents::AttachComponentsObject(ccx, scope);
+    return js::RecomputeWrappers(cx, js::SingleCompartment(compartment),
+                                 js::AllCompartments());
 }
 
 }
 
 static void
 CompartmentDestroyedCallback(JSFreeOp *fop, JSCompartment *compartment)
 {
     XPCJSRuntime* self = nsXPConnect::GetRuntimeInstance();
--- a/js/xpconnect/src/nsXPConnect.cpp
+++ b/js/xpconnect/src/nsXPConnect.cpp
@@ -941,16 +941,19 @@ nsXPConnect::InitClasses(JSContext * aJS
     XPCWrappedNativeScope* scope =
         XPCWrappedNativeScope::GetNewOrUsed(ccx, aGlobalJSObj);
 
     if (!scope)
         return UnexpectedFailure(NS_ERROR_FAILURE);
 
     scope->RemoveWrappedNativeProtos();
 
+    if (!nsXPCComponents::AttachComponentsObject(ccx, scope))
+        return UnexpectedFailure(NS_ERROR_FAILURE);
+
     if (!XPCNativeWrapper::AttachNewConstructorObject(ccx, aGlobalJSObj))
         return UnexpectedFailure(NS_ERROR_FAILURE);
 
     return NS_OK;
 }
 
 #ifdef DEBUG
 struct VerifyTraceXPCGlobalCalledTracer
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -3713,19 +3713,23 @@ class nsXPCComponents : public nsIXPCCom
 public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSIXPCCOMPONENTS
     NS_DECL_NSIXPCSCRIPTABLE
     NS_DECL_NSICLASSINFO
     NS_DECL_NSISECURITYCHECKEDCOMPONENT
 
 public:
+    // The target is the object upon which |Components| will be defined. If
+    // aTarget is left null, a default object will be computed. This is usually
+    // the right thing to do.
     static JSBool
     AttachComponentsObject(XPCCallContext& ccx,
-                           XPCWrappedNativeScope* aScope);
+                           XPCWrappedNativeScope* aScope,
+                           JSObject* aTarget = NULL);
 
     void SystemIsBeingShutDown() {ClearMembers();}
 
     virtual ~nsXPCComponents();
 
 private:
     nsXPCComponents(XPCWrappedNativeScope* aScope);
     void ClearMembers();
--- a/js/xpconnect/tests/chrome/Makefile.in
+++ b/js/xpconnect/tests/chrome/Makefile.in
@@ -38,16 +38,17 @@ MOCHITEST_CHROME_FILES = \
 		test_bug760076.xul \
 		test_bug760109.xul \
 		test_bug760131.html \
 		test_bug763343.xul \
 		test_bug771429.xul \
 		test_bug773962.xul \
 		test_bug792280.xul \
 		test_bug793433.xul \
+		test_bug795275.xul \
 		test_bug799348.xul \
 		test_bug801241.xul \
 		test_bug812415.xul \
 		test_APIExposer.xul \
 		test_chrometoSource.xul \
 		outoflinexulscript.js \
 		subscript.js \
 		utf8_subscript.js \
new file mode 100644
--- /dev/null
+++ b/js/xpconnect/tests/chrome/test_bug795275.xul
@@ -0,0 +1,82 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
+<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=795275
+-->
+<window title="Mozilla Bug 795275"
+        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
+
+  <!-- test results are displayed in the html:body -->
+  <body xmlns="http://www.w3.org/1999/xhtml">
+  <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=795275"
+     target="_blank">Mozilla Bug 795275</a>
+  </body>
+
+  <!-- test code goes here -->
+  <script type="application/javascript">
+  <![CDATA[
+  /** Test for Warning in content scopes about Components. **/
+
+  SimpleTest.waitForExplicitFinish();
+
+  // Set up our console listener.
+  var gWarnings = 0;
+  function onWarning(consoleMessage) {
+    if (/soon be removed/.test(consoleMessage.message))
+      gWarnings++;
+  }
+  var gListener = {
+    observe: onWarning,
+    QueryInterface: function (iid) {
+      if (!iid.equals(Components.interfaces.nsIConsoleListener) &&
+          !iid.equals(Components.interfaces.nsISupports)) {
+        throw Components.results.NS_ERROR_NO_INTERFACE;
+      }
+      return this;
+    }
+  };
+  var gConsoleService = Components.classes["@mozilla.org/consoleservice;1"]
+                                  .getService(Components.interfaces.nsIConsoleService);
+  gConsoleService.registerListener(gListener);
+
+  // Wait for all four child frame to load.
+  var gLoadCount = 0;
+  function frameLoaded() {
+    if (++gLoadCount == document.getElementsByTagName('iframe').length)
+      go();
+  }
+
+  function getWin(id) { return document.getElementById(id).contentWindow.wrappedJSObject; }
+  function go() {
+    getWin('frame1').touchComponents();
+    getWin('frame2').touchInterfaces();
+    getWin('frame3').touchLookupMethod();
+    getWin('frame4').touchComponents();
+    getWin('frame4').touchInterfaces();
+    getWin('frame4').touchLookupMethod();
+    // This shouldn't warn.
+    getWin('frame5').touchViaXBL();
+
+    // Warnings are dispatched async, so stick ourselves at the end of the event
+    // queue.
+    setTimeout(done, 0);
+  }
+
+  function done() {
+    gConsoleService.unregisterListener(gListener);
+    is(gWarnings, 4, "Got the right number of warnings");
+    SimpleTest.finish();
+  }
+
+  ]]>
+
+  </script>
+  <iframe id="frame1" onload="frameLoaded();" type="content" src="http://mochi.test:8888/tests/js/xpconnect/tests/mochitest/file_bug795275.html" />
+  <iframe id="frame2" onload="frameLoaded();" type="content" src="http://mochi.test:8888/tests/js/xpconnect/tests/mochitest/file_bug795275.html" />
+  <iframe id="frame3" onload="frameLoaded();" type="content" src="http://mochi.test:8888/tests/js/xpconnect/tests/mochitest/file_bug795275.html" />
+  <iframe id="frame4" onload="frameLoaded();" type="content" src="http://mochi.test:8888/tests/js/xpconnect/tests/mochitest/file_bug795275.html" />
+  <iframe id="frame5" onload="frameLoaded();" type="content" src="http://mochi.test:8888/tests/js/xpconnect/tests/mochitest/file_bug795275.html" />
+
+</window>
--- a/js/xpconnect/tests/mochitest/Makefile.in
+++ b/js/xpconnect/tests/mochitest/Makefile.in
@@ -76,16 +76,18 @@ MOCHITEST_FILES =	chrome_wrappers_helper
 		file_bug760131.html \
 		test_bug764389.html \
 		test_bug772288.html \
 		test_bug781476.html \
 		file_bug781476.html \
 		test_bug785096.html \
 		test_bug789713.html \
 		test_bug793969.html \
+		file_bug795275.html \
+		file_bug795275.xml \
 		file_bug799348.html \
 		test_bug800864.html \
 		test_bug802557.html \
 		file_bug802557.html \
 		test_bug803730.html \
 		test_bug809547.html \
 		file_crosscompartment_weakmap.html \
 		test_crosscompartment_weakmap.html \
new file mode 100644
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/file_bug795275.html
@@ -0,0 +1,31 @@
+<html>
+<head>
+<style>
+  .bound {
+    -moz-binding: url(file_bug795275.xml#xbltest);
+  }
+</style>
+<script type="application/javascript">
+  function touchComponents() {
+    Components;
+  }
+  function touchInterfaces() {
+    Components.interfaces;
+  }
+  function touchLookupMethod() {
+    Components.lookupMethod(document, 'getElementById');
+  }
+
+  function touchViaXBL() {
+    // Make sure none of this warns.
+    var div = document.getElementById('dummy');
+    div.testProp;
+    div.testMethod();
+  }
+
+</script>
+</head>
+<body>
+<div id="dummy" class="bound"></div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/file_bug795275.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<bindings id="xbltestBindings" xmlns="http://www.mozilla.org/xbl"
+          xmlns:html="http://www.w3.org/1999/xhtml">
+<binding id="xbltest">
+<implementation>
+<method name="testMethod">
+<body>
+  Components.interfaces;
+</body>
+</method>
+<property name="testProp" readonly="true"
+          onget="Components; return 3;" />
+<constructor>
+  var foo = Components;
+</constructor>
+</implementation>
+</binding>
+</bindings>
--- a/toolkit/components/passwordmgr/test/test_prompt.html
+++ b/toolkit/components/passwordmgr/test/test_prompt.html
@@ -133,17 +133,17 @@ proxyChannelListener.prototype = {
   onStopRequest: function(request, context, status) { }
 };
 
 var resolveCallback = {
   QueryInterface : function (iid) {
     const interfaces = [Ci.nsIProtocolProxyCallback, Ci.nsISupports];
 
     if (!interfaces.some( function(v) { return iid.equals(v) } ))
-      throw SpecialPowers.Cr.NS_ERROR_NO_INTERFACE;
+      throw Components.results.NS_ERROR_NO_INTERFACE;
     return this;
   },
 
   onProxyAvailable : function (req, uri, pi, status) {
     initLogins(pi);
 
     // I'm cheating a bit here... We should probably do some magic foo to get
     // something implementing nsIProxiedProtocolHandler and then call
@@ -155,20 +155,22 @@ var resolveCallback = {
     // for simplicity.
     proxyChannel = ioService.newChannel(proxiedHost, null, null);
     proxyChannel.asyncOpen(new proxyChannelListener(), null);
   }
 };
 
 function startup() {
   //need to allow for arbitrary network servers defined in PAC instead of a hardcoded moz-proxy.
-  var ios = SpecialPowers.Cc["@mozilla.org/network/io-service;1"].
-    getService(SpecialPowers.Ci.nsIIOService);
+  var ios = SpecialPowers.wrap(Components).
+    classes["@mozilla.org/network/io-service;1"].
+    getService(Components.interfaces.nsIIOService);
 
-  var pps = SpecialPowers.Cc["@mozilla.org/network/protocol-proxy-service;1"].getService();
+  var pps = SpecialPowers.wrap(Components).
+    classes["@mozilla.org/network/protocol-proxy-service;1"].getService();
 
   var uri = ios.newURI("http://example.com", null, null);
   pps.asyncResolve(uri, 0, resolveCallback);
 }
 
 function addNotificationCallback(cb) {
   storageObserver.notificationCallbacks.push(cb);
 }
@@ -176,17 +178,17 @@ function addNotificationCallback(cb) {
 var storageObserver = {
   notificationCallbacks: [],
 
   QueryInterface : function (iid) {
     const interfaces = [Ci.nsIObserver,
                         Ci.nsISupports, Ci.nsISupportsWeakReference];
 
     if (!interfaces.some( function(v) { return iid.equals(v) } ))
-      throw SpecialPowers.Cr.NS_ERROR_NO_INTERFACE;
+      throw SpecialPowers.Components.results.NS_ERROR_NO_INTERFACE;
     return this;
   },
 
   observe : function (subject, topic, data) {
     ok(true, ".");
     ok(true, "observer for " + topic + " / " + data);
     ok(true, "Time is " + (new Date()).toUTCString());
     var wrapped = SpecialPowers.wrap(subject);
--- a/toolkit/components/satchel/test/test_form_autocomplete.html
+++ b/toolkit/components/satchel/test/test_form_autocomplete.html
@@ -117,17 +117,17 @@ Form History test: form field autocomple
 
 /** Test for Form History autocomplete **/
 
 var input = $_(1, "field1");
 const shiftModifier = Event.SHIFT_MASK;
 
 // Get the form history service
 var fh = SpecialPowers.Cc["@mozilla.org/satchel/form-history;1"].
-         getService(SpecialPowers.Ci.nsIFormHistory2);
+         getService(Components.interfaces.nsIFormHistory2);
 ok(fh != null, "got form history service");
 
 fh.removeAllEntries();
 fh.addEntry("field1", "value1");
 fh.addEntry("field1", "value2");
 fh.addEntry("field1", "value3");
 fh.addEntry("field1", "value4");
 fh.addEntry("field2", "value1");
--- a/toolkit/components/telemetry/Histograms.json
+++ b/toolkit/components/telemetry/Histograms.json
@@ -2806,16 +2806,28 @@
     "kind": "boolean",
     "description": "Successfully reading a saved ping file"
   },
   "TOUCH_ENABLED_DEVICE": {
     "kind": "boolean",
     "description": "The device supports touch input",
     "cpp_guard": "XP_WIN"
   },
+  "COMPONENTS_OBJECT_ACCESSED_BY_CONTENT": {
+    "kind": "flag",
+    "description": "Whether content ever accesed the Components object in this session"
+  },
+  "COMPONENTS_LOOKUPMETHOD_ACCESSED_BY_CONTENT": {
+    "kind": "flag",
+    "description": "Whether content ever accesed Components.lookupMethod in this session"
+  },
+  "COMPONENTS_INTERFACES_ACCESSED_BY_CONTENT": {
+    "kind": "flag",
+    "description": "Whether content ever accesed Components.interfaces in this session"
+  },
   "CHECK_ADDONS_MODIFIED_MS": {
     "kind": "exponential",
     "high": "5000",
     "n_buckets": 15,
     "extended_statistics_ok": true,
     "description": "Time (ms) it takes to figure out extension last modified time"
   },
   "TELEMETRY_MEMORY_REPORTER_MS": {