Bug 1518490 Part 2/3: Measure xul.dll load duration r=aklotz
authorCarl Corcoran <ccorcoran@mozilla.com>
Tue, 15 Jan 2019 22:29:28 +0000
changeset 514080 1b8f7dd09d842bf97fa58840d48904a7f38eb4ac
parent 514079 400434070f20f902659434c8e7d437f800613e35
child 514081 1b1fe5815dffcacf40731336a114a8c2fcc2adf7
push id1953
push userffxbld-merge
push dateMon, 11 Mar 2019 12:10:20 +0000
treeherdermozilla-release@9c35dcbaa899 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersaklotz
bugs1518490
milestone66.0a1
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
Bug 1518490 Part 2/3: Measure xul.dll load duration r=aklotz In order to help unify DLL timings across machines with different performance characteristics, this change collects the load duration of xul.dll. Because xul.dll is always loaded, it can serve as a control value for DLL load times. Differential Revision: https://phabricator.services.mozilla.com/D16012
toolkit/xre/ModuleEvaluator_windows.cpp
toolkit/xre/ModuleEvaluator_windows.h
toolkit/xre/WinDllServices.cpp
toolkit/xre/WinDllServices.h
--- a/toolkit/xre/ModuleEvaluator_windows.cpp
+++ b/toolkit/xre/ModuleEvaluator_windows.cpp
@@ -259,16 +259,23 @@ Maybe<bool> ModuleEvaluator::IsModuleTru
       }
 
       if (!mExeDirectory.IsEmpty() &&
           StringBeginsWith(dllFullPath, mExeDirectory,
                            nsCaseInsensitiveStringComparator())) {
         score += 50;
         aDllInfo.mTrustFlags |= ModuleTrustFlags::FirefoxDirectory;
 
+        if (dllLeafLower.EqualsLiteral("xul.dll")) {
+          // The caller wants to know if this DLL is xul.dll, but this flag
+          // doesn't need to affect trust score. Xul will be considered trusted
+          // by other measures.
+          aDllInfo.mTrustFlags |= ModuleTrustFlags::Xul;
+        }
+
         // If it's in the Firefox directory, does it also share the Firefox
         // version info? We only care about this inside the app directory.
         if (mExeVersion.isSome() &&
             (vi.mFileVersion.Version64() == mExeVersion.value())) {
           aDllInfo.mTrustFlags |= ModuleTrustFlags::FirefoxDirectoryAndVersion;
           score += 50;
         }
       }
--- a/toolkit/xre/ModuleEvaluator_windows.h
+++ b/toolkit/xre/ModuleEvaluator_windows.h
@@ -25,16 +25,17 @@ enum class ModuleTrustFlags : uint32_t {
   MicrosoftWindowsSignature = 2,
   MicrosoftVersion = 4,
   FirefoxDirectory = 8,
   FirefoxDirectoryAndVersion = 0x10,
   SystemDirectory = 0x20,
   KeyboardLayout = 0x40,
   JitPI = 0x80,
   WinSxSDirectory = 0x100,
+  Xul = 0x200,
 };
 
 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(ModuleTrustFlags);
 
 // This class is very similar to mozilla::glue::ModuleLoadEvent, except this is
 // more Gecko-friendly, and has a few more fields that enable us to evaluate
 // trustworthiness.
 class ModuleLoadEvent {
--- a/toolkit/xre/WinDllServices.cpp
+++ b/toolkit/xre/WinDllServices.cpp
@@ -62,16 +62,17 @@ class UntrustedModulesManager {
   // outside the loader.
   Mutex mMutex;
 
   // We want to only process startup modules once, so keep track of that here.
   bool mHasProcessedStartupModules = false;
 
   ModuleEvaluator mEvaluator;
   int mErrorModules = 0;
+  Maybe<double> mXULLoadDurationMS;
 
   // In order to get a list of modules loaded at startup, we take a list of
   // currently-loaded modules, and subtract:
   // - Modules in mProcessedEvents, which have been considered untrusted,
   // - Modules in mTrustedModuleHistory, which have been seen but discarded
   // The resulting list is a list of modules that we haven't seen before at all
   // and are (likely) still loaded.
   //
@@ -172,23 +173,30 @@ class UntrustedModulesManager {
 
     // Process queued events, weeding out trusted items as we go.
     for (auto& e : queuedEvents) {
       // Create a copy of the event without its modules; we'll then fill them
       // in, filtering out any trusted modules we can ignore.
       ModuleLoadEvent eventCopy(
           e, ModuleLoadEvent::CopyOption::CopyWithoutModules);
       for (auto& m : e.mModules) {
-        Maybe<bool> ret =
+        Maybe<bool> maybeIsTrusted =
             mEvaluator.IsModuleTrusted(m, eventCopy, dllSvcRef.get());
-        if (ret.isNothing()) {
+
+        // Save xul.dll load timing for the ping payload.
+        if ((m.mTrustFlags & ModuleTrustFlags::Xul) &&
+            mXULLoadDurationMS.isNothing()) {
+          mXULLoadDurationMS = m.mLoadDurationMS;
+        }
+
+        if (maybeIsTrusted.isNothing()) {
           // If there was an error, assume the DLL is trusted to avoid
           // flooding the telemetry packet, but record that an error occurred.
           errorModules++;
-        } else if (*ret) {
+        } else if (maybeIsTrusted.value()) {
           // Module is trusted. If we haven't yet processed startup modules,
           // we need to remember it.
           if (!aHasProcessedStartupModules) {
             Unused << newTrustedModuleBases.put(m.mBase);
           }
         } else {
           // Module is untrusted; record it.
           Unused << eventCopy.mModules.append(std::move(m));
@@ -351,16 +359,17 @@ class UntrustedModulesManager {
     bool hasProcessedStartupModules = false;
     ProcessQueuedEvents(hasProcessedStartupModules);
     if (ProcessStartupModules(hasProcessedStartupModules)) {
       // New events were added; process those too.
       ProcessQueuedEvents(hasProcessedStartupModules);
     }
 
     aOut.mErrorModules = mErrorModules;
+    aOut.mXULLoadDurationMS = mXULLoadDurationMS;
 
     // Lock mProcessedEvents and mProcessedStacks to make a copy for the caller.
     // Only trivial (loader lock friendly) code allowed here!
     MutexAutoLock lock(mMutex);
 
     aOut.mStacks = mProcessedStacks;
     for (auto& e : mProcessedEvents) {
       Unused << aOut.mEvents.append(e);
--- a/toolkit/xre/WinDllServices.h
+++ b/toolkit/xre/WinDllServices.h
@@ -4,16 +4,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_WinDllServices_h
 #define mozilla_WinDllServices_h
 
 #include "mozilla/CombinedStacks.h"
 #include "mozilla/glue/WindowsDllServices.h"
+#include "mozilla/Maybe.h"
 #include "mozilla/ModuleEvaluator_windows.h"
 #include "mozilla/mozalloc.h"
 #include "mozilla/UniquePtr.h"
 #include "mozilla/Vector.h"
 
 namespace mozilla {
 
 // Holds the data that telemetry requests, and will be later converted to the
@@ -25,16 +26,17 @@ class UntrustedModuleLoadTelemetryData {
   UntrustedModuleLoadTelemetryData(UntrustedModuleLoadTelemetryData&&) =
       default;
   UntrustedModuleLoadTelemetryData(
       const UntrustedModuleLoadTelemetryData& aOther) = delete;
 
   Vector<ModuleLoadEvent, 0, InfallibleAllocPolicy> mEvents;
   Telemetry::CombinedStacks mStacks;
   int mErrorModules = 0;
+  Maybe<double> mXULLoadDurationMS;
 };
 
 class UntrustedModulesManager;
 
 class DllServices : public mozilla::glue::DllServices {
  public:
   static DllServices* Get();