Bug 988386 - Collect telemetry on <script> elements' JS language versions. r=mrbkap r=till
authorChris Peterson <cpeterson@mozilla.com>
Wed, 23 Apr 2014 22:27:13 -0700
changeset 183664 14a82a4878a84fd2e144aaf4753915983db56bf7
parent 183663 df3b325443700ccf6653e2084d6326ddd2cb66fc
child 183665 d18b1b320eeabeef854efe6e5b750b1f91941526
push id6844
push userphilringnalda@gmail.com
push dateSun, 18 May 2014 01:12:08 +0000
treeherderfx-team@41a54c8add09 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmrbkap, till
bugs988386
milestone32.0a1
Bug 988386 - Collect telemetry on <script> elements' JS language versions. r=mrbkap r=till
content/base/src/nsScriptLoader.cpp
toolkit/components/telemetry/Histograms.json
--- a/content/base/src/nsScriptLoader.cpp
+++ b/content/base/src/nsScriptLoader.cpp
@@ -49,16 +49,17 @@
 #include "nsCrossSiteListenerProxy.h"
 #include "nsSandboxFlags.h"
 #include "nsContentTypeParser.h"
 #include "nsINetworkSeer.h"
 #include "mozilla/dom/EncodingUtils.h"
 
 #include "mozilla/CORSMode.h"
 #include "mozilla/Attributes.h"
+#include "mozilla/Telemetry.h"
 #include "mozilla/unused.h"
 
 #ifdef PR_LOGGING
 static PRLogModuleInfo* gCspPRLog;
 #endif
 
 using namespace mozilla;
 using namespace mozilla::dom;
@@ -81,19 +82,17 @@ public:
       mJSVersion(aVersion),
       mLineNo(1),
       mCORSMode(aCORSMode)
   {
   }
 
   ~nsScriptLoadRequest()
   {
-    if (mScriptTextBuf) {
-      js_free(mScriptTextBuf);
-    }
+    js_free(mScriptTextBuf);
   }
 
   NS_DECL_THREADSAFE_ISUPPORTS
 
   void FireScriptAvailable(nsresult aResult)
   {
     mElement->ScriptAvailable(aResult, mElement, mIsInline, mURI, mLineNo);
   }
@@ -428,17 +427,17 @@ ParseTypeAttribute(const nsAString& aTyp
     *aVersion = nsContentUtils::ParseJavascriptVersion(versionName);
   } else if (rv != NS_ERROR_INVALID_ARG) {
     return false;
   }
 
   return true;
 }
 
-bool
+static bool
 CSPAllowsInlineScript(nsIScriptElement *aElement, nsIDocument *aDocument)
 {
   nsCOMPtr<nsIContentSecurityPolicy> csp;
   nsresult rv = aDocument->NodePrincipal()->GetCsp(getter_AddRefs(csp));
   NS_ENSURE_SUCCESS(rv, false);
 
   if (!csp) {
     // no CSP --> allow
@@ -535,16 +534,53 @@ CSPAllowsInlineScript(nsIScriptElement *
   if (!allowInlineScript) {
     NS_ASSERTION(!violations.IsEmpty(),
         "CSP blocked inline script but is not reporting a violation");
    return false;
   }
   return true;
 }
 
+static void
+AccumulateJavaScriptVersionTelemetry(nsIScriptElement* aElement,
+                                     JSVersion aVersion)
+{
+  uint32_t minorVersion;
+  switch (aVersion) {
+    case JSVERSION_DEFAULT: minorVersion = 5; break;
+    case JSVERSION_1_6:     minorVersion = 6; break;
+    case JSVERSION_1_7:     minorVersion = 7; break;
+    case JSVERSION_1_8:     minorVersion = 8; break;
+    default:                MOZ_ASSERT_UNREACHABLE("Unexpected JSVersion");
+    case JSVERSION_UNKNOWN: minorVersion = 0; break;
+  }
+
+  // Only report SpiderMonkey's nonstandard JS versions: 1.6, 1.7, and 1.8.
+  if (minorVersion < 6) {
+    return;
+  }
+
+  nsCOMPtr<nsIURI> scriptURI = aElement->GetScriptURI();
+  if (!scriptURI) {
+    return;
+  }
+
+  // We only care about web content, not chrome or add-on JS versions.
+  bool chrome = false;
+  scriptURI->SchemeIs("chrome", &chrome);
+  if (!chrome) {
+    scriptURI->SchemeIs("resource", &chrome);
+  }
+  if (chrome) {
+    return;
+  }
+
+  Telemetry::Accumulate(Telemetry::JS_MINOR_VERSION, minorVersion);
+}
+
 bool
 nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
 {
   // We need a document to evaluate scripts.
   NS_ENSURE_TRUE(mDocument, false);
 
   // Check to see if scripts has been turned off.
   if (!mEnabled || !mDocument->IsScriptEnabled()) {
@@ -563,16 +599,17 @@ nsScriptLoader::ProcessScriptElement(nsI
   JSVersion version = JSVERSION_DEFAULT;
 
   // Check the type attribute to determine language and version.
   // If type exists, it trumps the deprecated 'language='
   nsAutoString type;
   aElement->GetScriptType(type);
   if (!type.IsEmpty()) {
     NS_ENSURE_TRUE(ParseTypeAttribute(type, &version), false);
+    AccumulateJavaScriptVersionTelemetry(aElement, version);
   } else {
     // no 'type=' element
     // "language" is a deprecated attribute of HTML, so we check it only for
     // HTML script elements.
     if (scriptContent->IsHTML()) {
       nsAutoString language;
       scriptContent->GetAttr(kNameSpaceID_None, nsGkAtoms::language, language);
       if (!language.IsEmpty()) {
--- a/toolkit/components/telemetry/Histograms.json
+++ b/toolkit/components/telemetry/Histograms.json
@@ -308,16 +308,22 @@
     "n_buckets": 200,  
     "description": "Location accuracy"
   },
   "GEOLOCATION_ERROR": {
     "expires_in_version": "never",
     "kind": "flag",
     "description": "Has seen location error"
   },
+  "JS_MINOR_VERSION": {
+    "expires_in_version": "never",
+    "kind": "enumerated",
+    "n_values": 10,
+    "description": "JavaScript version in web content (1.x)"
+  },
   "TELEMETRY_PING": {
     "expires_in_version": "never",
     "kind": "exponential",
     "high": "3000",
     "n_buckets": 10,
     "extended_statistics_ok": true,
     "description": "Time taken to submit telemetry info (ms)"
   },