Backed out changeset 1e9ecba54e7b (bug 1348273) for failing on widget/tests/test_bug1123480.xul
authorNoemi Erli <nerli@mozilla.com>
Sat, 04 Aug 2018 12:39:40 +0300
changeset 487876 4146a5857135b8542858b9e23bc5a71237e05f49
parent 487875 48904c06f28c87a579f8f2c42b931982af353655
child 487901 76b09340b737a4babc322ef57de548ed1dee1407
child 487906 c5feed1e4a18a5ef594c9385927795109b750abf
push id1815
push userffxbld-merge
push dateMon, 15 Oct 2018 10:40:45 +0000
treeherdermozilla-release@18d4c09e9378 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1348273, 1123480
milestone63.0a1
backs out1e9ecba54e7b1e6ee614e323ece9c98c373311a9
first release with
nightly linux32
4146a5857135 / 63.0a1 / 20180804124335 / files
nightly linux64
4146a5857135 / 63.0a1 / 20180804124335 / files
nightly mac
4146a5857135 / 63.0a1 / 20180804124335 / files
nightly win32
4146a5857135 / 63.0a1 / 20180804124335 / files
nightly win64
4146a5857135 / 63.0a1 / 20180804124335 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out changeset 1e9ecba54e7b (bug 1348273) for failing on widget/tests/test_bug1123480.xul
accessible/base/nsAccessibilityService.cpp
accessible/windows/msaa/Compatibility.cpp
accessible/windows/msaa/LazyInstantiator.cpp
accessible/windows/msaa/Platform.cpp
browser/base/content/browser-plugins.js
browser/base/content/browser.js
browser/base/content/test/performance/browser_startup_content.js
docshell/base/nsDocShell.cpp
dom/events/TouchEvent.cpp
dom/ipc/ContentChild.cpp
dom/ipc/ContentParent.cpp
dom/ipc/TabChild.cpp
dom/media/gmp/GMPChild.cpp
dom/media/gmp/GMPParent.cpp
dom/plugins/base/nsPluginHost.cpp
dom/plugins/base/nsPluginsDirDarwin.cpp
dom/plugins/ipc/PluginMessageUtils.h
dom/plugins/ipc/PluginModuleParent.cpp
gfx/ipc/GPUProcessManager.cpp
gfx/src/DriverCrashGuard.cpp
gfx/thebes/DeviceManagerDx.cpp
gfx/thebes/gfxPlatform.cpp
ipc/chromium/src/chrome/common/ipc_channel_posix.cc
ipc/glue/CrashReporterClient.cpp
ipc/glue/CrashReporterClient.h
ipc/glue/CrashReporterHost.cpp
ipc/glue/CrashReporterHost.h
ipc/glue/CrashReporterMetadataShmem.cpp
ipc/glue/CrashReporterMetadataShmem.h
ipc/glue/IPCMessageUtils.h
ipc/glue/MessageChannel.cpp
ipc/glue/MessageLink.cpp
ipc/glue/ProtocolUtils.cpp
ipc/glue/ProtocolUtils.h
ipc/glue/Transport_posix.cpp
ipc/mscom/COMPtrHolder.h
ipc/mscom/ProxyStream.cpp
ipc/mscom/RegistrationAnnotator.cpp
js/xpconnect/loader/mozJSComponentLoader.cpp
layout/style/ServoBindings.cpp
layout/style/ServoBindings.h
layout/style/nsLayoutStylesheetCache.cpp
mobile/android/base/java/org/mozilla/gecko/telemetry/pingbuilders/TelemetryCrashPingBuilder.java
mobile/android/base/moz.build
mobile/android/components/SessionStore.js
mozglue/build/WindowsDllBlocklist.cpp
netwerk/ipc/NeckoMessageUtils.h
storage/mozStorageService.cpp
toolkit/components/asyncshutdown/AsyncShutdown.jsm
toolkit/components/crashes/CrashManager.jsm
toolkit/components/crashes/tests/xpcshell/crash.extra
toolkit/components/gfx/SanityTest.js
toolkit/components/telemetry/TelemetrySend.jsm
toolkit/components/telemetry/TelemetryStartup.js
toolkit/components/telemetry/tests/unit/test_TelemetrySend.js
toolkit/components/terminator/nsTerminator.cpp
toolkit/crashreporter/CrashAnnotations.cpp
toolkit/crashreporter/CrashAnnotations.h.in
toolkit/crashreporter/CrashAnnotations.yaml
toolkit/crashreporter/CrashReporter.jsm.in
toolkit/crashreporter/client/moz.build
toolkit/crashreporter/client/ping.cpp
toolkit/crashreporter/generate_crash_reporter_sources.py
toolkit/crashreporter/moz.build
toolkit/crashreporter/nsDummyExceptionHandler.cpp
toolkit/crashreporter/nsExceptionHandler.cpp
toolkit/crashreporter/nsExceptionHandler.h
toolkit/crashreporter/test/unit/crasher_subprocess_head.js
toolkit/crashreporter/test/unit/head_crashreporter.js
toolkit/crashreporter/test/unit/test_crash_abort.js
toolkit/crashreporter/test/unit/test_crash_after_js_large_allocation_failure.js
toolkit/crashreporter/test/unit/test_crash_after_js_large_allocation_failure_reporting.js
toolkit/crashreporter/test/unit/test_crash_after_js_oom_recovered.js
toolkit/crashreporter/test/unit/test_crash_after_js_oom_reported.js
toolkit/crashreporter/test/unit/test_crash_after_js_oom_reported_2.js
toolkit/crashreporter/test/unit/test_crash_moz_crash.js
toolkit/crashreporter/test/unit/test_crash_oom.js
toolkit/crashreporter/test/unit/test_crash_purevirtual.js
toolkit/crashreporter/test/unit/test_crash_uncaught_exception.js
toolkit/crashreporter/test/unit/test_crashreporter.js
toolkit/crashreporter/test/unit/test_crashreporter_crash.js
toolkit/crashreporter/test/unit/test_event_files.js
toolkit/crashreporter/test/unit/test_oom_annotation_windows.js
toolkit/crashreporter/test/unit_ipc/test_content_annotation.js
toolkit/modules/WebNavigationChild.jsm
toolkit/modules/WebProgressChild.jsm
toolkit/mozapps/extensions/internal/AddonTestUtils.jsm
toolkit/mozapps/extensions/internal/XPIProvider.jsm
toolkit/mozapps/extensions/test/xpcshell/head_addons.js
toolkit/xre/nsAppRunner.cpp
toolkit/xre/nsEmbedFunctions.cpp
widget/android/GfxInfo.cpp
widget/android/jni/Utils.cpp
widget/android/nsAppShell.cpp
widget/cocoa/GfxInfo.mm
widget/windows/GfxInfo.cpp
widget/windows/LSPAnnotator.cpp
xpcom/base/AvailableMemoryTracker.cpp
xpcom/base/CycleCollectedJSRuntime.cpp
xpcom/base/CycleCollectedJSRuntime.h
xpcom/base/nsCycleCollector.cpp
xpcom/base/nsDebugImpl.cpp
xpcom/system/nsICrashReporter.idl
--- a/accessible/base/nsAccessibilityService.cpp
+++ b/accessible/base/nsAccessibilityService.cpp
@@ -1388,17 +1388,17 @@ nsAccessibilityService::Init()
     gApplicationAccessible = new ApplicationAccessible();
 #endif // defined(XP_WIN)
   }
 
   NS_ADDREF(gApplicationAccessible); // will release in Shutdown()
   gApplicationAccessible->Init();
 
   CrashReporter::
-    AnnotateCrashReport(CrashReporter::Annotation::Accessibility,
+    AnnotateCrashReport(NS_LITERAL_CSTRING("Accessibility"),
                         NS_LITERAL_CSTRING("Active"));
 
 #ifdef XP_WIN
   sPendingPlugins = new nsTArray<nsCOMPtr<nsIContent> >;
   sPluginTimers = new nsTArray<nsCOMPtr<nsITimer> >;
 #endif
 
   // Now its safe to start platform accessibility.
--- a/accessible/windows/msaa/Compatibility.cpp
+++ b/accessible/windows/msaa/Compatibility.cpp
@@ -237,17 +237,17 @@ Compatibility::HasKnownNonUiaConsumer()
 
 void
 Compatibility::Init()
 {
   // Note we collect some AT statistics/telemetry here for convenience.
   InitConsumers();
 
   CrashReporter::
-    AnnotateCrashReport(CrashReporter::Annotation::AccessibilityInProcClient,
+    AnnotateCrashReport(NS_LITERAL_CSTRING("AccessibilityInProcClient"),
                         nsPrintfCString("0x%X", sConsumers));
 
   // Gather telemetry
   uint32_t temp = sConsumers;
   for (int i = 0; temp; i++) {
     if (temp & 0x1)
       statistics::A11yConsumers(i);
 
@@ -431,19 +431,18 @@ UseIAccessibleProxyStub()
   // Otherwise we try the proxy/stub
   if (IsIAccessiblePSRegistered()) {
     return true;
   }
 
   // If we reach this point then something is seriously wrong with the
   // IAccessible configuration in the computer's registry. Let's annotate this
   // so that we can easily determine this condition during crash analysis.
-  CrashReporter::AnnotateCrashReport(
-    CrashReporter::Annotation::IAccessibleConfig,
-    NS_LITERAL_CSTRING("NoSystemTypeLibOrPS"));
+  CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("IAccessibleConfig"),
+                                     NS_LITERAL_CSTRING("NoSystemTypeLibOrPS"));
   return false;
 }
 
 #endif // !defined(HAVE_64BIT_BUILD)
 
 uint16_t
 Compatibility::GetActCtxResourceId()
 {
--- a/accessible/windows/msaa/LazyInstantiator.cpp
+++ b/accessible/windows/msaa/LazyInstantiator.cpp
@@ -12,16 +12,17 @@
 #include "mozilla/a11y/Platform.h"
 #include "mozilla/Assertions.h"
 #include "mozilla/mscom/MainThreadRuntime.h"
 #include "mozilla/mscom/Registration.h"
 #include "mozilla/UniquePtr.h"
 #include "nsAccessibilityService.h"
 #include "nsWindowsHelpers.h"
 #include "nsCOMPtr.h"
+#include "nsExceptionHandler.h"
 #include "nsIFile.h"
 #include "nsXPCOM.h"
 #include "RootAccessibleWrap.h"
 #include "WinUtils.h"
 
 #include <oaidl.h>
 
 #if !defined(STATE_SYSTEM_NORMAL)
--- a/accessible/windows/msaa/Platform.cpp
+++ b/accessible/windows/msaa/Platform.cpp
@@ -353,17 +353,17 @@ AccumulateInstantiatorTelemetry(const ns
 
   if (!aValue.IsEmpty()) {
 #if defined(MOZ_TELEMETRY_REPORTING)
     Telemetry::ScalarSet(Telemetry::ScalarID::A11Y_INSTANTIATORS,
                          aValue);
 #endif // defined(MOZ_TELEMETRY_REPORTING)
 #if defined(MOZ_CRASHREPORTER)
     CrashReporter::
-      AnnotateCrashReport(CrashReporter::Annotation::AccessibilityClient,
+      AnnotateCrashReport(NS_LITERAL_CSTRING("AccessibilityClient"),
                           NS_ConvertUTF16toUTF8(aValue));
 #endif // defined(MOZ_CRASHREPORTER)
   }
 }
 
 static void
 GatherInstantiatorTelemetry(nsIFile* aClientExe)
 {
--- a/browser/base/content/browser-plugins.js
+++ b/browser/base/content/browser-plugins.js
@@ -1,20 +1,16 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
  * 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/. */
 
 ChromeUtils.defineModuleGetter(this, "Blocklist",
                                "resource://gre/modules/Blocklist.jsm");
 
-XPCOMUtils.defineLazyModuleGetters(this, {
-  PluginCrashReporter: "resource:///modules/ContentCrashHandlers.jsm",
-});
-
 var gPluginHandler = {
   PREF_SESSION_PERSIST_MINUTES: "plugin.sessionPermissionNow.intervalInMinutes",
   PREF_PERSISTENT_DAYS: "plugin.persistentPermissionAlways.intervalInDays",
   PREF_SHOW_INFOBAR: "plugins.show_infobar",
   PREF_INFOBAR_DISMISSAL_PERMANENT: "plugins.remember_infobar_dismissal",
 
   MESSAGES: [
     "PluginContent:ShowClickToPlayNotification",
@@ -581,17 +577,17 @@ var gPluginHandler = {
     let runID = propertyBag.getPropertyAsUint32("runID");
     let uglyPluginName = propertyBag.getPropertyAsAString("pluginName");
     let pluginName = BrowserUtils.makeNicePluginName(uglyPluginName);
     let pluginDumpID = propertyBag.getPropertyAsAString("pluginDumpID");
 
     // If we don't have a minidumpID, we can't (or didn't) submit anything.
     // This can happen if the plugin is killed from the task manager.
     let state;
-    if (!AppConstants.MOZ_CRASHREPORTER || !CrashReporter.enabled) {
+    if (!AppConstants.MOZ_CRASHREPORTER || !gCrashReporter.enabled) {
       // This state tells the user that crash reporting is disabled, so we
       // cannot send a report.
       state = "noSubmit";
     } else if (!pluginDumpID) {
       // This state tells the user that there is no crash report available.
       state = "noReport";
     } else {
       // This state asks the user to submit a crash report.
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -18,17 +18,16 @@ const {WebExtensionPolicy} = Cu.getGloba
 XPCOMUtils.defineLazyModuleGetters(this, {
   BrowserUsageTelemetry: "resource:///modules/BrowserUsageTelemetry.jsm",
   BrowserUtils: "resource://gre/modules/BrowserUtils.jsm",
   BrowserWindowTracker: "resource:///modules/BrowserWindowTracker.jsm",
   CharsetMenu: "resource://gre/modules/CharsetMenu.jsm",
   Color: "resource://gre/modules/Color.jsm",
   ContentSearch: "resource:///modules/ContentSearch.jsm",
   ContextualIdentityService: "resource://gre/modules/ContextualIdentityService.jsm",
-  CrashReporter: "resource://gre/modules/CrashReporter.jsm",
   CustomizableUI: "resource:///modules/CustomizableUI.jsm",
   Deprecated: "resource://gre/modules/Deprecated.jsm",
   DownloadsCommon: "resource:///modules/DownloadsCommon.jsm",
   E10SUtils: "resource://gre/modules/E10SUtils.jsm",
   ExtensionsUI: "resource:///modules/ExtensionsUI.jsm",
   FormValidationHandler: "resource:///modules/FormValidationHandler.jsm",
   LanguagePrompt: "resource://gre/modules/LanguagePrompt.jsm",
   HomePage: "resource:///modules/HomePage.jsm",
@@ -68,16 +67,21 @@ XPCOMUtils.defineLazyModuleGetters(this,
   Utils: "resource://gre/modules/sessionstore/Utils.jsm",
   Weave: "resource://services-sync/main.js",
   WebNavigationFrames: "resource://gre/modules/WebNavigationFrames.jsm",
   fxAccounts: "resource://gre/modules/FxAccounts.jsm",
   webrtcUI: "resource:///modules/webrtcUI.jsm",
   ZoomUI: "resource:///modules/ZoomUI.jsm",
 });
 
+if (AppConstants.MOZ_CRASHREPORTER) {
+  ChromeUtils.defineModuleGetter(this, "PluginCrashReporter",
+    "resource:///modules/ContentCrashHandlers.jsm");
+}
+
 XPCOMUtils.defineLazyScriptGetter(this, "PlacesTreeView",
                                   "chrome://browser/content/places/treeView.js");
 XPCOMUtils.defineLazyScriptGetter(this, ["PlacesInsertionPoint", "PlacesController",
                                          "PlacesControllerDragHelper"],
                                   "chrome://browser/content/places/controller.js");
 XPCOMUtils.defineLazyScriptGetter(this, "PrintUtils",
                                   "chrome://global/content/printUtils.js");
 XPCOMUtils.defineLazyScriptGetter(this, "ZoomManager",
@@ -136,16 +140,22 @@ XPCOMUtils.defineLazyServiceGetters(this
   gAboutNewTabService: ["@mozilla.org/browser/aboutnewtab-service;1", "nsIAboutNewTabService"],
   gDNSService: ["@mozilla.org/network/dns-service;1", "nsIDNSService"],
   gSerializationHelper: ["@mozilla.org/network/serialization-helper;1", "nsISerializationHelper"],
   Marionette: ["@mozilla.org/remote/marionette;1", "nsIMarionette"],
   SessionStartup: ["@mozilla.org/browser/sessionstartup;1", "nsISessionStartup"],
   WindowsUIUtils: ["@mozilla.org/windows-ui-utils;1", "nsIWindowsUIUtils"],
 });
 
+if (AppConstants.MOZ_CRASHREPORTER) {
+  XPCOMUtils.defineLazyServiceGetter(this, "gCrashReporter",
+                                     "@mozilla.org/xre/app-info;1",
+                                     "nsICrashReporter");
+}
+
 XPCOMUtils.defineLazyGetter(this, "gBrowserBundle", function() {
   return Services.strings.createBundle("chrome://browser/locale/browser.properties");
 });
 XPCOMUtils.defineLazyGetter(this, "gNavigatorBundle", function() {
   // This is a stringbundle-like interface to gBrowserBundle, formerly a getter for
   // the "bundle_browser" element.
   return {
     getString(key) {
@@ -4801,17 +4811,17 @@ var XULBrowserWindow = {
       try {
         // If the current URI contains a username/password, remove it.
         uri = aLocationURI.mutate()
                           .setUserPass("")
                           .finalize();
       } catch (ex) { /* Ignore failures on about: URIs. */ }
 
       try {
-        CrashReporter.addAnnotation(CrashReporter.annotations.URL, uri.spec);
+        gCrashReporter.annotateCrashReport("URL", uri.spec);
       } catch (ex) {
         // Don't make noise when the crash reporter is built but not enabled.
         if (ex.result != Cr.NS_ERROR_NOT_INITIALIZED) {
           throw ex;
         }
       }
     }
   },
--- a/browser/base/content/test/performance/browser_startup_content.js
+++ b/browser/base/content/test/performance/browser_startup_content.js
@@ -23,17 +23,16 @@ const whitelist = {
     "extension-process-script.js",
   ]),
   modules: new Set([
     "chrome://mochikit/content/ShutdownLeaksCollector.jsm",
 
     // General utilities
     "resource://gre/modules/AppConstants.jsm",
     "resource://gre/modules/AsyncShutdown.jsm",
-    "resource://gre/modules/CrashReporter.jsm",
     "resource://gre/modules/DeferredTask.jsm",
     "resource://gre/modules/PromiseUtils.jsm",
     "resource://gre/modules/Services.jsm", // bug 1464542
     "resource://gre/modules/Timer.jsm",
     "resource://gre/modules/XPCOMUtils.jsm",
 
     // Logging related
     "resource://gre/modules/Log.jsm",
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -1697,18 +1697,18 @@ nsDocShell::GetUseRemoteTabs(bool* aUseR
   *aUseRemoteTabs = mUseRemoteTabs;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDocShell::SetRemoteTabs(bool aUseRemoteTabs)
 {
   if (aUseRemoteTabs) {
-    CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::DOMIPCEnabled,
-                                       true);
+    CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("DOMIPCEnabled"),
+                                       NS_LITERAL_CSTRING("1"));
   }
 
   mUseRemoteTabs = aUseRemoteTabs;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDocShell::SetAffectPrivateSessionLifetime(bool aAffectLifetime)
--- a/dom/events/TouchEvent.cpp
+++ b/dom/events/TouchEvent.cpp
@@ -271,18 +271,20 @@ TouchEvent::PrefEnabled(nsIDocShell* aDo
   } else {
     if (sPrefCacheValue == 2) {
       enabled = PlatformSupportsTouch();
 
       static bool firstTime = true;
       // The touch screen data seems to be inaccurate in the parent process,
       // and we really need the crash annotation in child processes.
       if (firstTime && !XRE_IsParentProcess()) {
-        CrashReporter::AnnotateCrashReport(
-          CrashReporter::Annotation::HasDeviceTouchScreen, enabled);
+        CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("HasDeviceTouchScreen"),
+                                           enabled ?
+                                             NS_LITERAL_CSTRING("1") :
+                                             NS_LITERAL_CSTRING("0"));
         firstTime = false;
       }
 
 #if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
       if (enabled && aDocShell) {
         // APZ might be disabled on this particular widget, in which case
         // TouchEvent support will also be disabled. Try to detect that.
         RefPtr<nsPresContext> pc;
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -1766,23 +1766,26 @@ ContentChild::RecvSetProcessSandbox(cons
   }
 #elif defined(XP_WIN)
   mozilla::SandboxTarget::Instance()->StartSandbox();
 #elif defined(XP_MACOSX)
   sandboxEnabled = StartMacOSContentSandbox();
 #endif
 
   CrashReporter::AnnotateCrashReport(
-    CrashReporter::Annotation::ContentSandboxEnabled, sandboxEnabled);
+    NS_LITERAL_CSTRING("ContentSandboxEnabled"),
+    sandboxEnabled? NS_LITERAL_CSTRING("1") : NS_LITERAL_CSTRING("0"));
 #if defined(XP_LINUX) && !defined(OS_ANDROID)
+  nsAutoCString flagsString;
+  flagsString.AppendInt(SandboxInfo::Get().AsInteger());
+
   CrashReporter::AnnotateCrashReport(
-    CrashReporter::Annotation::ContentSandboxCapabilities,
-    static_cast<int>(SandboxInfo::Get().AsInteger()));
+    NS_LITERAL_CSTRING("ContentSandboxCapabilities"), flagsString);
 #endif /* XP_LINUX && !OS_ANDROID */
-  CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::RemoteType,
+  CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("RemoteType"),
                                      NS_ConvertUTF16toUTF8(GetRemoteType()));
 #endif /* MOZ_CONTENT_SANDBOX */
 
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 ContentChild::RecvBidiKeyboardNotify(const bool& aIsLangRTL,
@@ -2434,18 +2437,17 @@ ContentChild::ProcessingError(Result aCo
     case MsgValueError:
       break;
 
     default:
       MOZ_CRASH("not reached");
   }
 
   nsDependentCString reason(aReason);
-  CrashReporter::AnnotateCrashReport(
-    CrashReporter::Annotation::ipc_channel_error, reason);
+  CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("ipc_channel_error"), reason);
 
   MOZ_CRASH("Content child abort due to IPC error");
 }
 
 nsresult
 ContentChild::AddRemoteAlertObserver(const nsString& aData,
                                      nsIObserver* aObserver)
 {
@@ -3110,19 +3112,18 @@ ContentChild::RecvShutdown()
 
 void
 ContentChild::ShutdownInternal()
 {
   // If we receive the shutdown message from within a nested event loop, we want
   // to wait for that event loop to finish. Otherwise we could prematurely
   // terminate an "unload" or "pagehide" event handler (which might be doing a
   // sync XHR, for example).
-  CrashReporter::AnnotateCrashReport(
-    CrashReporter::Annotation::IPCShutdownState,
-    NS_LITERAL_CSTRING("RecvShutdown"));
+  CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("IPCShutdownState"),
+                                     NS_LITERAL_CSTRING("RecvShutdown"));
 
   MOZ_ASSERT(NS_IsMainThread());
   RefPtr<nsThread> mainThread = nsThreadManager::get().GetCurrentThread();
   // Note that we only have to check the recursion count for the current
   // cooperative thread. Since the Shutdown message is not labeled with a
   // SchedulerGroup, there can be no other cooperative threads doing work while
   // we're running.
   if (mainThread && mainThread->RecursionDepth() > 1) {
@@ -3170,21 +3171,20 @@ ContentChild::ShutdownInternal()
   }
 #endif
 
   // Start a timer that will insure we quickly exit after a reasonable
   // period of time. Prevents shutdown hangs after our connection to the
   // parent closes.
   StartForceKillTimer();
 
-  CrashReporter::AnnotateCrashReport(
-    CrashReporter::Annotation::IPCShutdownState,
-    NS_LITERAL_CSTRING("SendFinishShutdown (sending)"));
+  CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("IPCShutdownState"),
+                                     NS_LITERAL_CSTRING("SendFinishShutdown (sending)"));
   bool sent = SendFinishShutdown();
-  CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::IPCShutdownState,
+  CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("IPCShutdownState"),
                                      sent ? NS_LITERAL_CSTRING("SendFinishShutdown (sent)")
                                           : NS_LITERAL_CSTRING("SendFinishShutdown (failed)"));
 }
 
 PBrowserOrId
 ContentChild::GetBrowserOrId(TabChild* aTabChild)
 {
   if (!aTabChild ||
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -3365,21 +3365,23 @@ ContentParent::KillHard(const char* aRea
   // of the parent and child for submission to the crash server.
   if (mCrashReporter) {
     // GeneratePairedMinidump creates two minidumps for us - the main
     // one is for the content process we're about to kill, and the other
     // one is for the main browser process. That second one is the extra
     // minidump tagging along, so we have to tell the crash reporter that
     // it exists and is being appended.
     nsAutoCString additionalDumps("browser");
-    mCrashReporter->AddAnnotation(
-      CrashReporter::Annotation::additional_minidumps, additionalDumps);
+    mCrashReporter->AddNote(
+      NS_LITERAL_CSTRING("additional_minidumps"),
+      additionalDumps);
     nsDependentCString reason(aReason);
-    mCrashReporter->AddAnnotation(CrashReporter::Annotation::ipc_channel_error,
-                                  reason);
+    mCrashReporter->AddNote(
+      NS_LITERAL_CSTRING("ipc_channel_error"),
+      reason);
 
     Telemetry::Accumulate(Telemetry::SUBPROCESS_KILL_HARD, reason, 1);
 
     RefPtr<ContentParent> self = this;
     std::function<void(bool)> callback = [self](bool aResult) {
       self->OnGenerateMinidumpComplete(aResult);
     };
     // Generate the report and insert into the queue for submittal.
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -1168,17 +1168,17 @@ TabChild::RecvLoadURL(const nsCString& a
     WebNavigation()->LoadURI(NS_ConvertUTF8toUTF16(aURI).get(),
                              nsIWebNavigation::LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP |
                              nsIWebNavigation::LOAD_FLAGS_DISALLOW_INHERIT_PRINCIPAL,
                              nullptr, nullptr, nullptr, nsContentUtils::GetSystemPrincipal());
   if (NS_FAILED(rv)) {
       NS_WARNING("WebNavigation()->LoadURI failed. Eating exception, what else can I do?");
   }
 
-  CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::URL, aURI);
+  CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("URL"), aURI);
 
   return IPC_OK();
 }
 
 void
 TabChild::DoFakeShow(const TextureFactoryIdentifier& aTextureFactoryIdentifier,
                      const layers::LayersId& aLayersId,
                      const CompositorOptions& aCompositorOptions,
--- a/dom/media/gmp/GMPChild.cpp
+++ b/dom/media/gmp/GMPChild.cpp
@@ -555,19 +555,18 @@ ToCString(const nsTArray<Pair<nsCString,
 
 mozilla::ipc::IPCResult
 GMPChild::AnswerStartPlugin(const nsString& aAdapter)
 {
   LOGD("%s", __FUNCTION__);
 
   nsCString libPath;
   if (!GetUTF8LibPath(libPath)) {
-    CrashReporter::AnnotateCrashReport(
-      CrashReporter::Annotation::GMPLibraryPath,
-      NS_ConvertUTF16toUTF8(mPluginPath));
+    CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("GMPLibraryPath"),
+                                       NS_ConvertUTF16toUTF8(mPluginPath));
 
 #ifdef XP_WIN
     return IPC_FAIL(
       this,
       nsPrintfCString("Failed to get lib path with error(%d).", GetLastError())
         .get());
 #else
     return IPC_FAIL(
@@ -611,19 +610,18 @@ GMPChild::AnswerStartPlugin(const nsStri
   }
 
   if (!mGMPLoader->Load(libPath.get(),
                         libPath.Length(),
                         platformAPI,
                         adapter)) {
     NS_WARNING("Failed to load GMP");
     delete platformAPI;
-    CrashReporter::AnnotateCrashReport(
-      CrashReporter::Annotation::GMPLibraryPath,
-      NS_ConvertUTF16toUTF8(mPluginPath));
+    CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("GMPLibraryPath"),
+                                       NS_ConvertUTF16toUTF8(mPluginPath));
 
 #ifdef XP_WIN
     return IPC_FAIL(
       this,
       nsPrintfCString("Failed to load GMP with error(%d).", GetLastError())
         .get());
 #else
     return IPC_FAIL(
--- a/dom/media/gmp/GMPParent.cpp
+++ b/dom/media/gmp/GMPParent.cpp
@@ -458,23 +458,20 @@ GMPParent::EnsureProcessLoaded()
   nsresult rv = LoadProcess();
 
   return NS_SUCCEEDED(rv);
 }
 
 void
 GMPParent::WriteExtraDataForMinidump()
 {
-  mCrashReporter->AddAnnotation(CrashReporter::Annotation::GMPPlugin, true);
-  mCrashReporter->AddAnnotation(CrashReporter::Annotation::PluginFilename,
-                                NS_ConvertUTF16toUTF8(mName));
-  mCrashReporter->AddAnnotation(CrashReporter::Annotation::PluginName,
-                                mDisplayName);
-  mCrashReporter->AddAnnotation(CrashReporter::Annotation::PluginVersion,
-                                mVersion);
+  mCrashReporter->AddNote(NS_LITERAL_CSTRING("GMPPlugin"), NS_LITERAL_CSTRING("1"));
+  mCrashReporter->AddNote(NS_LITERAL_CSTRING("PluginFilename"), NS_ConvertUTF16toUTF8(mName));
+  mCrashReporter->AddNote(NS_LITERAL_CSTRING("PluginName"), mDisplayName);
+  mCrashReporter->AddNote(NS_LITERAL_CSTRING("PluginVersion"), mVersion);
 }
 
 bool
 GMPParent::GetCrashID(nsString& aResult)
 {
   if (!mCrashReporter) {
     return false;
   }
--- a/dom/plugins/base/nsPluginHost.cpp
+++ b/dom/plugins/base/nsPluginHost.cpp
@@ -6,16 +6,17 @@
 /* nsPluginHost.cpp - top-level plugin management code */
 
 #include "nscore.h"
 #include "nsPluginHost.h"
 
 #include <cstdlib>
 #include <stdio.h>
 #include "prio.h"
+#include "nsExceptionHandler.h"
 #include "nsNPAPIPlugin.h"
 #include "nsNPAPIPluginStreamListener.h"
 #include "nsNPAPIPluginInstance.h"
 #include "nsPluginInstanceOwner.h"
 #include "nsObjectLoadingContent.h"
 #include "nsIHTTPHeaderListener.h"
 #include "nsIHttpHeaderVisitor.h"
 #include "nsIObserverService.h"
--- a/dom/plugins/base/nsPluginsDirDarwin.cpp
+++ b/dom/plugins/base/nsPluginsDirDarwin.cpp
@@ -405,24 +405,53 @@ nsresult nsPluginFile::GetPluginInfo(nsP
   // First look for data in a bundle plist
   if (bundle) {
     ParsePlistPluginInfo(info, bundle);
     ::CFRelease(bundle);
     if (info.fVariantCount > 0)
       return NS_OK;
   }
 
+  // Don't load "fbplugin" or any plugins whose name starts with "fbplugin_"
+  // (Facebook plugins) if we're running on OS X 10.10 (Yosemite) or later.
+  // A "fbplugin" file crashes on load, in the call to LoadPlugin() below.
+  // See bug 1086977.
+  if (nsCocoaFeatures::OnYosemiteOrLater()) {
+    if (fileName.EqualsLiteral("fbplugin") ||
+        StringBeginsWith(fileName, NS_LITERAL_CSTRING("fbplugin_"))) {
+      nsAutoCString msg;
+      msg.AppendPrintf("Preventing load of %s (see bug 1086977)",
+                       fileName.get());
+      NS_WARNING(msg.get());
+      return NS_ERROR_FAILURE;
+    }
+
+    // The block above assumes that "fbplugin" is the filename of the plugin
+    // to be blocked, or that the filename starts with "fbplugin_".  But we
+    // don't yet know for sure if this is always true.  So for the time being
+    // record extra information in our crash logs.
+    CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("Bug_1086977"),
+                                       fileName);
+  }
+
   // It's possible that our plugin has 2 entry points that'll give us mime type
   // info. Quicktime does this to get around the need of having admin rights to
   // change mime info in the resource fork. We need to use this info instead of
   // the resource. See bug 113464.
 
   // Sadly we have to load the library for this to work.
   rv = LoadPlugin(outLibrary);
 
+  if (nsCocoaFeatures::OnYosemiteOrLater()) {
+    // If we didn't crash in LoadPlugin(), change the previous annotation so we
+    // don't sow confusion.
+    CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("Bug_1086977"),
+                                       NS_LITERAL_CSTRING("Didn't crash, please ignore"));
+  }
+
   if (NS_FAILED(rv))
     return rv;
 
   // Try to get data from NP_GetMIMEDescription
   if (pLibrary) {
     NP_GETMIMEDESCRIPTION pfnGetMimeDesc = (NP_GETMIMEDESCRIPTION)PR_FindFunctionSymbol(pLibrary, NP_GETMIMEDESCRIPTION_NAME);
     if (pfnGetMimeDesc)
       ParsePluginMimeDescription(pfnGetMimeDesc(), info);
--- a/dom/plugins/ipc/PluginMessageUtils.h
+++ b/dom/plugins/ipc/PluginMessageUtils.h
@@ -18,16 +18,17 @@
 #include "gfxipc/ShadowLayerUtils.h"
 
 #include "npapi.h"
 #include "npruntime.h"
 #include "npfunctions.h"
 #include "nsString.h"
 #include "nsTArray.h"
 #include "mozilla/Logging.h"
+#include "nsExceptionHandler.h"
 #include "nsHashKeys.h"
 
 #ifdef XP_MACOSX
 #include "PluginInterposeOSX.h"
 #else
 namespace mac_plugin_interposing { class NSCursorInfo { }; }
 #endif
 using mac_plugin_interposing::NSCursorInfo;
--- a/dom/plugins/ipc/PluginModuleParent.cpp
+++ b/dom/plugins/ipc/PluginModuleParent.cpp
@@ -733,46 +733,36 @@ PluginModuleChromeParent::WriteExtraData
 
     // Get the plugin filename, try to get just the file leafname
     const std::string& pluginFile = mSubprocess->GetPluginFilePath();
     size_t filePos = pluginFile.rfind(FILE_PATH_SEPARATOR);
     if (filePos == std::string::npos)
         filePos = 0;
     else
         filePos++;
-    mCrashReporter->AddAnnotation(CrashReporter::Annotation::PluginFilename,
-                                  cstring(pluginFile.substr(filePos).c_str()));
-    mCrashReporter->AddAnnotation(CrashReporter::Annotation::PluginName,
-                                  mPluginName);
-    mCrashReporter->AddAnnotation(CrashReporter::Annotation::PluginVersion,
-                                  mPluginVersion);
+    mCrashReporter->AddNote(NS_LITERAL_CSTRING("PluginFilename"), cstring(pluginFile.substr(filePos).c_str()));
+
+    mCrashReporter->AddNote(NS_LITERAL_CSTRING("PluginName"), mPluginName);
+    mCrashReporter->AddNote(NS_LITERAL_CSTRING("PluginVersion"), mPluginVersion);
 
     if (mCrashReporter) {
 #ifdef XP_WIN
         if (mPluginCpuUsageOnHang.Length() > 0) {
-            mCrashReporter->AddAnnotation(
-              CrashReporter::Annotation::NumberOfProcessors,
-              PR_GetNumberOfProcessors());
+            mCrashReporter->AddNote(NS_LITERAL_CSTRING("NumberOfProcessors"),
+                                    nsPrintfCString("%d", PR_GetNumberOfProcessors()));
 
             nsCString cpuUsageStr;
             cpuUsageStr.AppendFloat(std::ceil(mPluginCpuUsageOnHang[0] * 100) / 100);
-            mCrashReporter->AddAnnotation(
-              CrashReporter::Annotation::PluginCpuUsage,
-              cpuUsageStr);
+            mCrashReporter->AddNote(NS_LITERAL_CSTRING("PluginCpuUsage"), cpuUsageStr);
 
 #ifdef MOZ_CRASHREPORTER_INJECTOR
-            for (uint32_t i = 1; i < mPluginCpuUsageOnHang.Length(); ++i) {
+            for (uint32_t i=1; i<mPluginCpuUsageOnHang.Length(); ++i) {
                 nsCString tempStr;
                 tempStr.AppendFloat(std::ceil(mPluginCpuUsageOnHang[i] * 100) / 100);
-                // HACK: There can only be at most two flash processes hence
-                // the hardcoded annotations
-                CrashReporter::Annotation annotation =
-                  (i == 1) ? CrashReporter::Annotation::CpuUsageFlashProcess1
-                           : CrashReporter::Annotation::CpuUsageFlashProcess2;
-                mCrashReporter->AddAnnotation(annotation, tempStr);
+                mCrashReporter->AddNote(nsPrintfCString("CpuUsageFlashProcess%d", i), tempStr);
             }
 #endif
         }
 #endif
     }
 }
 
 void
@@ -1249,18 +1239,18 @@ PluginModuleChromeParent::OnTakeFullMini
                 // Include the content process minidump
                 if (CreatePluginMinidump(aContentPid, 0,
                                          pluginDumpFile,
                                          NS_LITERAL_CSTRING("content"))) {
                     additionalDumps.AppendLiteral(",content");
                 }
             }
         }
-        mCrashReporter->AddAnnotation(Annotation::additional_minidumps,
-                                      additionalDumps);
+        mCrashReporter->AddNote(NS_LITERAL_CSTRING("additional_minidumps"),
+                                additionalDumps);
 
         mTakeFullMinidumpCallback.Invoke(mCrashReporter->MinidumpID());
     } else {
         mTakeFullMinidumpCallback.Invoke(EmptyString());
         NS_WARNING("failed to capture paired minidumps from hang");
     }
 }
 
@@ -1311,25 +1301,28 @@ PluginModuleChromeParent::TerminateChild
     mCrashReporterMutex.AssertCurrentThreadIn();
 
     if (!mCrashReporter) {
         // If mCrashReporter is null then the hang has ended, the plugin module
         // is shutting down. There's nothing to do here.
         mTerminateChildProcessCallback.Invoke(true);
         return;
     }
-    mCrashReporter->AddAnnotation(Annotation::PluginHang, true);
-    mCrashReporter->AddAnnotation(Annotation::HangMonitorDescription,
-                                  aMonitorDescription);
+    mCrashReporter->AddNote(NS_LITERAL_CSTRING("PluginHang"),
+                            NS_LITERAL_CSTRING("1"));
+    mCrashReporter->AddNote(NS_LITERAL_CSTRING("HangMonitorDescription"),
+                            aMonitorDescription);
 #ifdef XP_WIN
     if (mHangUIParent) {
         unsigned int hangUIDuration = mHangUIParent->LastShowDurationMs();
         if (hangUIDuration) {
-            mCrashReporter->AddAnnotation(Annotation::PluginHangUIDuration,
-                                          hangUIDuration);
+            nsPrintfCString strHangUIDuration("%u", hangUIDuration);
+            mCrashReporter->AddNote(
+                    NS_LITERAL_CSTRING("PluginHangUIDuration"),
+                    strHangUIDuration);
         }
     }
 #endif // XP_WIN
 
     mozilla::ipc::ScopedProcessHandle geckoChildProcess;
     bool childOpened = base::OpenProcessHandle(OtherPid(),
                                                &geckoChildProcess.rwget());
 
@@ -1585,18 +1578,17 @@ PluginModuleChromeParent::ProcessFirstMi
         NS_WARNING("[PluginModuleParent::ActorDestroy] abnormal shutdown without minidump!");
         return;
     }
 
     PLUGIN_LOG_DEBUG(("got child minidump: %s",
                       NS_ConvertUTF16toUTF8(mCrashReporter->MinidumpID()).get()));
 
     if (!flashProcessType.IsEmpty()) {
-        mCrashReporter->AddAnnotation(Annotation::FlashProcessDump,
-                                      flashProcessType);
+        mCrashReporter->AddNote(NS_LITERAL_CSTRING("FlashProcessDump"), flashProcessType);
     }
     mCrashReporter->FinalizeCrashReport();
 }
 
 void
 PluginModuleParent::ActorDestroy(ActorDestroyReason why)
 {
     switch (why) {
--- a/gfx/ipc/GPUProcessManager.cpp
+++ b/gfx/ipc/GPUProcessManager.cpp
@@ -375,21 +375,22 @@ GPUProcessManager::OnProcessLaunchComple
     DisableGPUProcess("Failed to create PVsyncBridge endpoints");
     return;
   }
 
   mVsyncBridge = VsyncBridgeChild::Create(mVsyncIOThread, mProcessToken, std::move(vsyncChild));
   mGPUChild->SendInitVsyncBridge(std::move(vsyncParent));
 
   CrashReporter::AnnotateCrashReport(
-    CrashReporter::Annotation::GPUProcessStatus, NS_LITERAL_CSTRING("Running"));
+    NS_LITERAL_CSTRING("GPUProcessStatus"),
+    NS_LITERAL_CSTRING("Running"));
 
   CrashReporter::AnnotateCrashReport(
-    CrashReporter::Annotation::GPUProcessLaunchCount,
-    static_cast<int>(mNumProcessAttempts));
+    NS_LITERAL_CSTRING("GPUProcessLaunchCount"),
+    nsPrintfCString("%d", mNumProcessAttempts));
 }
 
 static bool
 ShouldLimitDeviceResets(uint32_t count, int32_t deltaMilliseconds)
 {
   // We decide to limit by comparing the amount of resets that have happened
   // and time since the last reset to two prefs.
   int32_t timeLimit = gfxPrefs::DeviceResetThresholdMilliseconds();
@@ -721,17 +722,17 @@ GPUProcessManager::DestroyProcess()
   mProcess = nullptr;
   mGPUChild = nullptr;
   if (mVsyncBridge) {
     mVsyncBridge->Close();
     mVsyncBridge = nullptr;
   }
 
   CrashReporter::AnnotateCrashReport(
-    CrashReporter::Annotation::GPUProcessStatus,
+    NS_LITERAL_CSTRING("GPUProcessStatus"),
     NS_LITERAL_CSTRING("Destroyed"));
 }
 
 already_AddRefed<CompositorSession>
 GPUProcessManager::CreateTopLevelCompositor(nsBaseWidget* aWidget,
                                             LayerManager* aLayerManager,
                                             CSSToLayoutDeviceScale aScale,
                                             const CompositorOptions& aOptions,
--- a/gfx/src/DriverCrashGuard.cpp
+++ b/gfx/src/DriverCrashGuard.cpp
@@ -160,18 +160,19 @@ DriverCrashGuard::~DriverCrashGuard()
     // proceed to mark the status as okay.
     if (GetStatus() != DriverInitStatus::Crashed) {
       SetStatus(DriverInitStatus::Okay);
     }
   } else {
     dom::ContentChild::GetSingleton()->SendEndDriverCrashGuard(uint32_t(mType));
   }
 
-  CrashReporter::RemoveCrashReportAnnotation(
-    CrashReporter::Annotation::GraphicsStartupTest);
+  // Remove the crash report annotation.
+  CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("GraphicsStartupTest"),
+                                     NS_LITERAL_CSTRING(""));
 }
 
 bool
 DriverCrashGuard::Crashed()
 {
   InitializeIfNeeded();
 
   // Note, we read mCrashDetected instead of GetStatus(), since in child
@@ -204,18 +205,18 @@ void
 DriverCrashGuard::ActivateGuard()
 {
   mGuardActivated = true;
 
   // Anotate crash reports only if we're a real guard. Otherwise, we could
   // attribute a random parent process crash to a graphics problem in a child
   // process.
   if (mMode != Mode::Proxy) {
-    CrashReporter::AnnotateCrashReport(
-      CrashReporter::Annotation::GraphicsStartupTest, true);
+    CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("GraphicsStartupTest"),
+                                       NS_LITERAL_CSTRING("1"));
   }
 
   // If we're in the content process, the rest of the guarding is handled
   // in the parent.
   if (XRE_IsContentProcess()) {
     return;
   }
 
--- a/gfx/thebes/DeviceManagerDx.cpp
+++ b/gfx/thebes/DeviceManagerDx.cpp
@@ -880,18 +880,20 @@ DeviceManagerDx::MaybeResetAndReacquireD
   if (!HasDeviceReset(&resetReason)) {
     return false;
   }
 
   if (resetReason != DeviceResetReason::FORCED_RESET) {
     Telemetry::Accumulate(Telemetry::DEVICE_RESET_REASON, uint32_t(resetReason));
   }
 
+  nsPrintfCString reasonString("%d", int(resetReason));
   CrashReporter::AnnotateCrashReport(
-    CrashReporter::Annotation::DeviceResetReason, int(resetReason));
+    NS_LITERAL_CSTRING("DeviceResetReason"),
+    reasonString);
 
   bool createCompositorDevice = !!mCompositorDevice;
   bool createContentDevice = !!mContentDevice;
 
   ResetDevices();
 
   if (createCompositorDevice && !CreateCompositorDevices()) {
     // Just stop, don't try anything more
--- a/gfx/thebes/gfxPlatform.cpp
+++ b/gfx/thebes/gfxPlatform.cpp
@@ -194,38 +194,38 @@ public:
 /// if the capacity set with the method below is >= 2.  We always retain the
 /// very first critical message, and the latest capacity-1 messages are
 /// rotated through. Note that we don't expect the total number of times
 /// this gets called to be large - it is meant for critical errors only.
 
 class CrashStatsLogForwarder: public mozilla::gfx::LogForwarder
 {
 public:
-  explicit CrashStatsLogForwarder(CrashReporter::Annotation aKey);
+  explicit CrashStatsLogForwarder(const char* aKey);
   void Log(const std::string& aString) override;
   void CrashAction(LogReason aReason) override;
   bool UpdateStringsVector(const std::string& aString) override;
 
   LoggingRecord LoggingRecordCopy() override;
 
   void SetCircularBufferSize(uint32_t aCapacity);
 
 private:
   // Helper for the Log()
   void UpdateCrashReport();
 
 private:
   LoggingRecord mBuffer;
-  CrashReporter::Annotation mCrashCriticalKey;
+  nsCString mCrashCriticalKey;
   uint32_t mMaxCapacity;
   int32_t mIndex;
   Mutex mMutex;
 };
 
-CrashStatsLogForwarder::CrashStatsLogForwarder(CrashReporter::Annotation aKey)
+CrashStatsLogForwarder::CrashStatsLogForwarder(const char* aKey)
   : mBuffer()
   , mCrashCriticalKey(aKey)
   , mMaxCapacity(0)
   , mIndex(-1)
   , mMutex("CrashStatsLogForwarder")
 {
 }
 
@@ -293,23 +293,21 @@ void CrashStatsLogForwarder::UpdateCrash
     break;
   }
 
   for (auto& it : mBuffer) {
     message << logAnnotation << Get<0>(it) << "]" << Get<1>(it) << " (t=" << Get<2>(it) << ") ";
   }
 
   nsCString reportString(message.str().c_str());
-  nsresult annotated = CrashReporter::AnnotateCrashReport(mCrashCriticalKey,
-                                                          reportString);
+  nsresult annotated = CrashReporter::AnnotateCrashReport(mCrashCriticalKey, reportString);
 
   if (annotated != NS_OK) {
     printf("Crash Annotation %s: %s",
-           CrashReporter::AnnotationToString(mCrashCriticalKey),
-           message.str().c_str());
+           mCrashCriticalKey.get(), message.str().c_str());
   }
 }
 
 class LogForwarderEvent : public Runnable
 {
   ~LogForwarderEvent() override = default;
 
 public:
@@ -918,18 +916,17 @@ gfxPlatform::MaxAllocSize()
   // pref or whatnot.
   const int32_t kMinAllocPref = 10000000;
   return std::max(kMinAllocPref, gfxPrefs::MaxAllocSizeDoNotUseDirectly());
 }
 
 /* static */ void
 gfxPlatform::InitMoz2DLogging()
 {
-  auto fwd = new CrashStatsLogForwarder(
-    CrashReporter::Annotation::GraphicsCriticalError);
+  auto fwd = new CrashStatsLogForwarder("GraphicsCriticalError");
   fwd->SetCircularBufferSize(gfxPrefs::GfxLoggingCrashLength());
 
   mozilla::gfx::Config cfg;
   cfg.mLogForwarder = fwd;
   cfg.mMaxTextureSize = gfxPlatform::MaxTextureSize();
   cfg.mMaxAllocSize = gfxPlatform::MaxAllocSize();
 
   gfx::Factory::Init(cfg);
--- a/ipc/chromium/src/chrome/common/ipc_channel_posix.cc
+++ b/ipc/chromium/src/chrome/common/ipc_channel_posix.cc
@@ -243,34 +243,31 @@ bool Channel::ChannelImpl::CreatePipe(co
                                       Mode mode) {
   DCHECK(server_listen_pipe_ == -1 && pipe_ == -1);
 
   // socketpair()
   pipe_name_ = WideToASCII(channel_id);
   if (mode == MODE_SERVER) {
     int pipe_fds[2];
     if (socketpair(AF_UNIX, SOCK_STREAM, 0, pipe_fds) != 0) {
-      mozilla::ipc::AnnotateCrashReportWithErrno(
-        CrashReporter::Annotation::IpcCreatePipeSocketPairErrno, errno);
+      mozilla::ipc::AnnotateCrashReportWithErrno("IpcCreatePipeSocketPairErrno", errno);
       return false;
     }
     // Set both ends to be non-blocking.
     if (fcntl(pipe_fds[0], F_SETFL, O_NONBLOCK) == -1 ||
         fcntl(pipe_fds[1], F_SETFL, O_NONBLOCK) == -1) {
-      mozilla::ipc::AnnotateCrashReportWithErrno(
-        CrashReporter::Annotation::IpcCreatePipeFcntlErrno, errno);
+      mozilla::ipc::AnnotateCrashReportWithErrno("IpcCreatePipeFcntlErrno", errno);
       IGNORE_EINTR(close(pipe_fds[0]));
       IGNORE_EINTR(close(pipe_fds[1]));
       return false;
     }
 
     if (!SetCloseOnExec(pipe_fds[0]) ||
         !SetCloseOnExec(pipe_fds[1])) {
-      mozilla::ipc::AnnotateCrashReportWithErrno(
-        CrashReporter::Annotation::IpcCreatePipeCloExecErrno, errno);
+      mozilla::ipc::AnnotateCrashReportWithErrno("IpcCreatePipeCloExecErrno", errno);
       IGNORE_EINTR(close(pipe_fds[0]));
       IGNORE_EINTR(close(pipe_fds[1]));
       return false;
     }
 
     pipe_ = pipe_fds[0];
     client_pipe_ = pipe_fds[1];
 
--- a/ipc/glue/CrashReporterClient.cpp
+++ b/ipc/glue/CrashReporterClient.cpp
@@ -21,18 +21,17 @@ CrashReporterClient::CrashReporterClient
 }
 
 CrashReporterClient::~CrashReporterClient()
 {
   MOZ_COUNT_DTOR(CrashReporterClient);
 }
 
 void
-CrashReporterClient::AnnotateCrashReport(CrashReporter::Annotation aKey,
-                                         const nsCString& aData)
+CrashReporterClient::AnnotateCrashReport(const nsCString& aKey, const nsCString& aData)
 {
   StaticMutexAutoLock lock(sLock);
   mMetadata->AnnotateCrashReport(aKey, aData);
 }
 
 void
 CrashReporterClient::AppendAppNotes(const nsCString& aData)
 {
--- a/ipc/glue/CrashReporterClient.h
+++ b/ipc/glue/CrashReporterClient.h
@@ -60,18 +60,17 @@ public:
       aOutShmem);
   }
 
   static void InitSingletonWithShmem(const Shmem& aShmem);
 
   static void DestroySingleton();
   static RefPtr<CrashReporterClient> GetSingleton();
 
-  void AnnotateCrashReport(CrashReporter::Annotation aKey,
-                           const nsCString& aData);
+  void AnnotateCrashReport(const nsCString& aKey, const nsCString& aData);
   void AppendAppNotes(const nsCString& aData);
 
 private:
   explicit CrashReporterClient(const Shmem& aShmem);
   ~CrashReporterClient();
 
 private:
   static StaticMutex sLock;
--- a/ipc/glue/CrashReporterHost.cpp
+++ b/ipc/glue/CrashReporterHost.cpp
@@ -60,17 +60,17 @@ CrashReporterHost::AdoptMinidump(nsIFile
 }
 
 bool
 CrashReporterHost::FinalizeCrashReport()
 {
   MOZ_ASSERT(!mFinalized);
   MOZ_ASSERT(HasMinidump());
 
-  CrashReporter::AnnotationTable annotations;
+  CrashReporter::AnnotationTable notes;
 
   nsAutoCString type;
   switch (mProcessType) {
     case GeckoProcessType_Content:
       type = NS_LITERAL_CSTRING("content");
       break;
     case GeckoProcessType_Plugin:
     case GeckoProcessType_GMPlugin:
@@ -78,33 +78,32 @@ CrashReporterHost::FinalizeCrashReport()
       break;
     case GeckoProcessType_GPU:
       type = NS_LITERAL_CSTRING("gpu");
       break;
     default:
       NS_ERROR("unknown process type");
       break;
   }
-  annotations[CrashReporter::Annotation::ProcessType] = type;
+  notes.Put(NS_LITERAL_CSTRING("ProcessType"), type);
 
   char startTime[32];
   SprintfLiteral(startTime, "%lld", static_cast<long long>(mStartTime));
-  annotations[CrashReporter::Annotation::StartupTime] =
-    nsDependentCString(startTime);
+  notes.Put(NS_LITERAL_CSTRING("StartupTime"), nsDependentCString(startTime));
 
   // We might not have shmem (for example, when running crashreporter tests).
   if (mShmem.IsReadable()) {
-    CrashReporterMetadataShmem::ReadAppNotes(mShmem, annotations);
+    CrashReporterMetadataShmem::ReadAppNotes(mShmem, &notes);
   }
-  CrashReporter::AppendExtraData(mDumpID, mExtraAnnotations);
-  CrashReporter::AppendExtraData(mDumpID, annotations);
+  CrashReporter::AppendExtraData(mDumpID, mExtraNotes);
+  CrashReporter::AppendExtraData(mDumpID, notes);
 
-  // Use mExtraAnnotations, since NotifyCrashService looks for "PluginHang"
-  // which is set in the parent process.
-  NotifyCrashService(mProcessType, mDumpID, mExtraAnnotations);
+  // Use mExtraNotes, since NotifyCrashService looks for "PluginHang" which is
+  // set in the parent process.
+  NotifyCrashService(mProcessType, mDumpID, &mExtraNotes);
 
   mFinalized = true;
   return true;
 }
 
 namespace {
 class GenerateMinidumpShutdownBlocker : public nsIAsyncShutdownBlocker {
 public:
@@ -217,21 +216,21 @@ CrashReporterHost::GenerateMinidumpAndPa
                                         getter_AddRefs(mTargetDump),
                                         std::move(callback),
                                         aAsync);
 }
 
 /* static */ void
 CrashReporterHost::NotifyCrashService(GeckoProcessType aProcessType,
                                       const nsString& aChildDumpID,
-                                      const AnnotationTable& aNotes)
+                                      const AnnotationTable* aNotes)
 {
   if (!NS_IsMainThread()) {
     RefPtr<Runnable> runnable = NS_NewRunnableFunction(
-      "ipc::CrashReporterHost::NotifyCrashService", [&]() -> void {
+      "ipc::CrashReporterHost::NotifyCrashService", [=]() -> void {
         CrashReporterHost::NotifyCrashService(
           aProcessType, aChildDumpID, aNotes);
       });
     RefPtr<nsIThread> mainThread = do_GetMainThread();
     SyncRunnable::DispatchToThread(mainThread, runnable);
     return;
   }
 
@@ -251,18 +250,19 @@ CrashReporterHost::NotifyCrashService(Ge
   switch (aProcessType) {
     case GeckoProcessType_Content:
       processType = nsICrashService::PROCESS_TYPE_CONTENT;
       telemetryKey.AssignLiteral("content");
       break;
     case GeckoProcessType_Plugin: {
       processType = nsICrashService::PROCESS_TYPE_PLUGIN;
       telemetryKey.AssignLiteral("plugin");
-      nsCString val = aNotes[CrashReporter::Annotation::PluginHang];
-      if (val.Equals(NS_LITERAL_CSTRING("1"))) {
+      nsAutoCString val;
+      if (aNotes->Get(NS_LITERAL_CSTRING("PluginHang"), &val) &&
+        val.EqualsLiteral("1")) {
         crashType = nsICrashService::CRASH_TYPE_HANG;
         telemetryKey.AssignLiteral("pluginhang");
       }
       break;
     }
     case GeckoProcessType_GMPlugin:
       processType = nsICrashService::PROCESS_TYPE_GMPLUGIN;
       telemetryKey.AssignLiteral("gmplugin");
@@ -277,41 +277,15 @@ CrashReporterHost::NotifyCrashService(Ge
   }
 
   RefPtr<Promise> promise;
   crashService->AddCrash(processType, crashType, aChildDumpID, getter_AddRefs(promise));
   Telemetry::Accumulate(Telemetry::SUBPROCESS_CRASHES_WITH_DUMP, telemetryKey, 1);
 }
 
 void
-CrashReporterHost::AddAnnotation(CrashReporter::Annotation aKey, bool aValue)
-{
-  mExtraAnnotations[aKey] = aValue ? NS_LITERAL_CSTRING("1")
-                                   : NS_LITERAL_CSTRING("0");
-}
-
-void
-CrashReporterHost::AddAnnotation(CrashReporter::Annotation aKey,
-                                 int aValue)
+CrashReporterHost::AddNote(const nsCString& aKey, const nsCString& aValue)
 {
-  nsAutoCString valueString;
-  valueString.AppendInt(aValue);
-  mExtraAnnotations[aKey] = valueString;
-}
-
-void
-CrashReporterHost::AddAnnotation(CrashReporter::Annotation aKey,
-                                 unsigned int aValue)
-{
-  nsAutoCString valueString;
-  valueString.AppendInt(aValue);
-  mExtraAnnotations[aKey] = valueString;
-}
-
-void
-CrashReporterHost::AddAnnotation(CrashReporter::Annotation aKey,
-                                 const nsCString& aValue)
-{
-  mExtraAnnotations[aKey] = aValue;
+  mExtraNotes.Put(aKey, aValue);
 }
 
 } // namespace ipc
 } // namespace mozilla
--- a/ipc/glue/CrashReporterHost.h
+++ b/ipc/glue/CrashReporterHost.h
@@ -125,22 +125,19 @@ public:
   // This is a static helper function to notify the crash service that a
   // crash has occurred. When PCrashReporter is removed, we can make this
   // a member function. This can be called from any thread, and if not
   // called from the main thread, will post a synchronous message to the
   // main thread.
   static void NotifyCrashService(
     GeckoProcessType aProcessType,
     const nsString& aChildDumpID,
-    const AnnotationTable& aNotes);
+    const AnnotationTable* aNotes);
 
-  void AddAnnotation(CrashReporter::Annotation aKey, bool aValue);
-  void AddAnnotation(CrashReporter::Annotation aKey, int aValue);
-  void AddAnnotation(CrashReporter::Annotation aKey, unsigned int aValue);
-  void AddAnnotation(CrashReporter::Annotation aKey, const nsCString& aValue);
+  void AddNote(const nsCString& aKey, const nsCString& aValue);
 
   bool HasMinidump() const {
     return !mDumpID.IsEmpty();
   }
   const nsString& MinidumpID() const {
     MOZ_ASSERT(HasMinidump());
     return mDumpID;
   }
@@ -150,17 +147,17 @@ private:
                             const nsString& aChildDumpID);
 
 private:
   CallbackWrapper<bool> mCreateMinidumpCallback;
   GeckoProcessType mProcessType;
   Shmem mShmem;
   ThreadId mThreadId;
   time_t mStartTime;
-  AnnotationTable mExtraAnnotations;
+  AnnotationTable mExtraNotes;
   nsString mDumpID;
   bool mFinalized;
   nsCOMPtr<nsIFile> mTargetDump;
 };
 
 } // namespace ipc
 } // namespace mozilla
 
--- a/ipc/glue/CrashReporterMetadataShmem.cpp
+++ b/ipc/glue/CrashReporterMetadataShmem.cpp
@@ -1,24 +1,21 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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/. */
 
 #include "CrashReporterMetadataShmem.h"
 #include "mozilla/Attributes.h"
-#include "mozilla/EnumeratedRange.h"
 #include "nsISupportsImpl.h"
 
 namespace mozilla {
 namespace ipc {
 
-using CrashReporter::Annotation;
-
 enum class EntryType : uint8_t {
   None,
   Annotation,
 };
 
 CrashReporterMetadataShmem::CrashReporterMetadataShmem(const Shmem& aShmem)
  : mShmem(aShmem)
 {
@@ -26,42 +23,41 @@ CrashReporterMetadataShmem::CrashReporte
 }
 
 CrashReporterMetadataShmem::~CrashReporterMetadataShmem()
 {
   MOZ_COUNT_DTOR(CrashReporterMetadataShmem);
 }
 
 void
-CrashReporterMetadataShmem::AnnotateCrashReport(Annotation aKey,
-                                                const nsCString& aData)
+CrashReporterMetadataShmem::AnnotateCrashReport(const nsCString& aKey, const nsCString& aData)
 {
-  mAnnotations[aKey] = aData;
+  mNotes.Put(aKey, aData);
   SyncNotesToShmem();
 }
 
 void
 CrashReporterMetadataShmem::AppendAppNotes(const nsCString& aData)
 {
   mAppNotes.Append(aData);
-  mAnnotations[Annotation::Notes] = mAppNotes;
+  mNotes.Put(NS_LITERAL_CSTRING("Notes"), mAppNotes);
   SyncNotesToShmem();
 }
 
 class MOZ_STACK_CLASS MetadataShmemWriter
 {
 public:
   explicit MetadataShmemWriter(const Shmem& aShmem)
    : mCursor(aShmem.get<uint8_t>()),
      mEnd(mCursor + aShmem.Size<uint8_t>())
   {
     *mCursor = uint8_t(EntryType::None);
   }
 
-  MOZ_MUST_USE bool WriteAnnotation(Annotation aKey, const nsCString& aValue) {
+  MOZ_MUST_USE bool WriteAnnotation(const nsCString& aKey, const nsCString& aValue) {
     // This shouldn't happen because Commit() guarantees mCursor < mEnd. But
     // we might as well be safe.
     if (mCursor >= mEnd) {
       return false;
     }
 
     // Save the current position so we can write the entry type if the entire
     // entry fits.
@@ -124,21 +120,21 @@ private:
   uint8_t* mEnd;
 };
 
 void
 CrashReporterMetadataShmem::SyncNotesToShmem()
 {
   MetadataShmemWriter writer(mShmem);
 
-  for (auto key : MakeEnumeratedRange(Annotation::Count)) {
-    if (!mAnnotations[key].IsEmpty()) {
-      if (!writer.WriteAnnotation(key, mAnnotations[key])) {
-        return;
-      }
+  for (auto it = mNotes.Iter(); !it.Done(); it.Next()) {
+    nsCString key = nsCString(it.Key());
+    nsCString value = nsCString(it.Data());
+    if (!writer.WriteAnnotation(key, value)) {
+      return;
     }
   }
 }
 
 // Helper class to iterate over metadata entries encoded in shmem.
 class MOZ_STACK_CLASS MetadataShmemReader
 {
 public:
@@ -161,37 +157,36 @@ public:
   void Next() {
     if (mCursor < mEnd) {
       mEntryType = EntryType(*mCursor++);
     } else {
       mEntryType = EntryType::None;
     }
   }
 
-  template <typename T>
-  bool Read(T* aOut) {
-    return Read(aOut, sizeof(T));
-  }
-
   bool Read(nsCString& aOut) {
     uint32_t length = 0;
     if (!Read(&length)) {
       return false;
     }
 
     const uint8_t* src = Read(length);
     if (!src) {
       return false;
     }
 
     aOut.Assign((const char *)src, length);
     return true;
   }
 
 private:
+  template <typename T>
+  bool Read(T* aOut) {
+    return Read(aOut, sizeof(T));
+  }
   bool Read(void* aOut, size_t aLength) {
     const uint8_t* src = Read(aLength);
     if (!src) {
       return false;
     }
     memcpy(aOut, src, aLength);
     return true;
   }
@@ -209,29 +204,27 @@ private:
 
 private:
   const uint8_t* mCursor;
   const uint8_t* mEnd;
   EntryType mEntryType;
 };
 
 void
-CrashReporterMetadataShmem::ReadAppNotes(const Shmem& aShmem,
-                                         AnnotationTable& aNotes)
+CrashReporterMetadataShmem::ReadAppNotes(const Shmem& aShmem, CrashReporter::AnnotationTable* aNotes)
 {
   for (MetadataShmemReader reader(aShmem); !reader.Done(); reader.Next()) {
     switch (reader.Type()) {
       case EntryType::Annotation: {
-        Annotation key;
-        nsCString value;
-        if (!reader.Read(&key) || !reader.Read(value)) {
+        nsCString key, value;
+        if (!reader.Read(key) || !reader.Read(value)) {
           return;
         }
 
-        aNotes[key] = value;
+        aNotes->Put(key, value);
         break;
       }
       default:
         NS_ASSERTION(false, "Unknown metadata entry type");
         break;
     }
   }
 }
--- a/ipc/glue/CrashReporterMetadataShmem.h
+++ b/ipc/glue/CrashReporterMetadataShmem.h
@@ -20,29 +20,27 @@ class CrashReporterMetadataShmem
   typedef mozilla::ipc::Shmem Shmem;
   typedef CrashReporter::AnnotationTable AnnotationTable;
 
 public:
   explicit CrashReporterMetadataShmem(const Shmem& aShmem);
   ~CrashReporterMetadataShmem();
 
   // Metadata writers. These must only be called in child processes.
-  void AnnotateCrashReport(CrashReporter::Annotation aKey,
-                           const nsCString& aData);
+  void AnnotateCrashReport(const nsCString& aKey, const nsCString& aData);
   void AppendAppNotes(const nsCString& aData);
 
-  static void ReadAppNotes(const Shmem& aShmem,
-                           CrashReporter::AnnotationTable& aNotes);
+  static void ReadAppNotes(const Shmem& aShmem, CrashReporter::AnnotationTable* aNotes);
 
 private:
   void SyncNotesToShmem();
 
 private:
   Shmem mShmem;
 
-  AnnotationTable mAnnotations;
+  AnnotationTable mNotes;
   nsCString mAppNotes;
 };
 
 } // namespace ipc
 } // namespace mozilla
 
 #endif // mozilla_ipc_CrashReporterMetadataShmem_h
--- a/ipc/glue/IPCMessageUtils.h
+++ b/ipc/glue/IPCMessageUtils.h
@@ -132,24 +132,22 @@ struct EnumSerializer {
   static void Write(Message* aMsg, const paramType& aValue) {
     MOZ_RELEASE_ASSERT(EnumValidator::IsLegalValue(aValue));
     WriteParam(aMsg, uintParamType(aValue));
   }
 
   static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult) {
     uintParamType value;
     if (!ReadParam(aMsg, aIter, &value)) {
-      CrashReporter::AnnotateCrashReport(
-        CrashReporter::Annotation::IPCReadErrorReason,
-        NS_LITERAL_CSTRING("Bad iter"));
+      CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("IPCReadErrorReason"),
+                                         NS_LITERAL_CSTRING("Bad iter"));
       return false;
     } else if (!EnumValidator::IsLegalValue(paramType(value))) {
-      CrashReporter::AnnotateCrashReport(
-        CrashReporter::Annotation::IPCReadErrorReason,
-        NS_LITERAL_CSTRING("Illegal value"));
+      CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("IPCReadErrorReason"),
+                                         NS_LITERAL_CSTRING("Illegal value"));
       return false;
     }
     *aResult = paramType(value);
     return true;
   }
 };
 
 template <typename E,
--- a/ipc/glue/MessageChannel.cpp
+++ b/ipc/glue/MessageChannel.cpp
@@ -769,18 +769,19 @@ MessageChannel::CanSend() const
     MonitorAutoLock lock(*mMonitor);
     return Connected();
 }
 
 void
 MessageChannel::WillDestroyCurrentMessageLoop()
 {
 #if defined(DEBUG)
-    CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::IPCFatalErrorProtocol,
-                                       nsDependentCString(mName));
+    CrashReporter::AnnotateCrashReport(
+        NS_LITERAL_CSTRING("IPCFatalErrorProtocol"),
+        nsDependentCString(mName));
     MOZ_CRASH("MessageLoop destroyed before MessageChannel that's bound to it");
 #endif
 
     // Clear mWorkerThread to avoid posting to it in the future.
     MonitorAutoLock lock(*mMonitor);
     mWorkerLoop = nullptr;
 }
 
@@ -798,17 +799,18 @@ MessageChannel::Clear()
     // before mListener.  But just to be safe, mListener is a weak pointer.
 
 #if !defined(ANDROID)
     // KillHard shutdowns can occur with the channel in connected state. We are
     // already collecting crash dump data about KillHard shutdowns and we
     // shouldn't intentionally crash here.
     if (!Unsound_IsClosed() && !mInKillHardShutdown) {
         CrashReporter::AnnotateCrashReport(
-          CrashReporter::Annotation::IPCFatalErrorProtocol, nsDependentCString(mName));
+            NS_LITERAL_CSTRING("IPCFatalErrorProtocol"),
+            nsDependentCString(mName));
         switch (mChannelState) {
             case ChannelOpening:
                 MOZ_CRASH("MessageChannel destroyed without being closed " \
                           "(mChannelState == ChannelOpening).");
                 break;
             case ChannelConnected:
                 MOZ_CRASH("MessageChannel destroyed without being closed " \
                           "(mChannelState == ChannelConnected).");
--- a/ipc/glue/MessageLink.cpp
+++ b/ipc/glue/MessageLink.cpp
@@ -154,22 +154,18 @@ ProcessLink::EchoMessage(Message *msg)
                                            msg));
     // OnEchoMessage takes ownership of |msg|
 }
 
 void
 ProcessLink::SendMessage(Message *msg)
 {
     if (msg->size() > IPC::Channel::kMaximumMessageSize) {
-      CrashReporter::AnnotateCrashReport(
-        CrashReporter::Annotation::IPCMessageName,
-        nsDependentCString(msg->name()));
-      CrashReporter::AnnotateCrashReport(
-        CrashReporter::Annotation::IPCMessageSize,
-        static_cast<int>(msg->size()));
+      CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("IPCMessageName"), nsDependentCString(msg->name()));
+      CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("IPCMessageSize"), nsPrintfCString("%d", msg->size()));
       MOZ_CRASH("IPC message size is too large");
     }
 
     if (!mChan->mIsPostponingSends) {
         mChan->AssertWorkerThread();
     }
     mChan->mMonitor->AssertCurrentThreadOwns();
 
--- a/ipc/glue/ProtocolUtils.cpp
+++ b/ipc/glue/ProtocolUtils.cpp
@@ -206,17 +206,17 @@ bool DuplicateHandle(HANDLE aSourceHandl
 #endif
 
   // Finally, see if we already have access to the process.
   ScopedProcessHandle targetProcess(OpenProcess(PROCESS_DUP_HANDLE,
                                                 FALSE,
                                                 aTargetProcessId));
   if (!targetProcess) {
     CrashReporter::AnnotateCrashReport(
-      CrashReporter::Annotation::IPCTransportFailureReason,
+      NS_LITERAL_CSTRING("IPCTransportFailureReason"),
       NS_LITERAL_CSTRING("Failed to open target process."));
     return false;
   }
 
   return !!::DuplicateHandle(::GetCurrentProcess(), aSourceHandle,
                               targetProcess, aTargetHandle,
                               aDesiredAccess, FALSE, aOptions);
 }
@@ -228,28 +228,30 @@ AnnotateSystemError()
   int64_t error = 0;
 #if defined(XP_WIN)
   error = ::GetLastError();
 #elif defined(OS_POSIX)
   error = errno;
 #endif
   if (error) {
     CrashReporter::AnnotateCrashReport(
-      CrashReporter::Annotation::IPCSystemError,
+      NS_LITERAL_CSTRING("IPCSystemError"),
       nsPrintfCString("%" PRId64, error));
   }
 }
 
 #if defined(XP_MACOSX)
 void
-AnnotateCrashReportWithErrno(CrashReporter::Annotation tag, int error)
+AnnotateCrashReportWithErrno(const char* tag, int error)
 {
-  CrashReporter::AnnotateCrashReport(tag, error);
+  CrashReporter::AnnotateCrashReport(
+    nsCString(tag),
+    nsPrintfCString("%d", error));
 }
-#endif // defined(XP_MACOSX)
+#endif
 
 void
 LogMessageForProtocol(const char* aTopLevelProtocol, base::ProcessId aOtherPid,
                       const char* aContextDescription,
                       uint32_t aMessageId,
                       MessageDirection aDirection)
 {
   nsPrintfCString logMessage("[time: %" PRId64 "][%d%s%d] [%s] %s %s\n",
@@ -283,19 +285,18 @@ FatalError(const char* aMsg, bool aIsPar
   nsAutoCString formattedMessage("IPDL error: \"");
   formattedMessage.AppendASCII(aMsg);
   if (aIsParent) {
     // We're going to crash the parent process because at this time
     // there's no other really nice way of getting a minidump out of
     // this process if we're off the main thread.
     formattedMessage.AppendLiteral("\". Intentionally crashing.");
     NS_ERROR(formattedMessage.get());
-    CrashReporter::AnnotateCrashReport(
-      CrashReporter::Annotation::IPCFatalErrorMsg,
-      nsDependentCString(aMsg));
+    CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("IPCFatalErrorMsg"),
+                                       nsDependentCString(aMsg));
     AnnotateSystemError();
 #ifndef FUZZING
     MOZ_CRASH("IPC FatalError in the parent process!");
 #endif
   } else {
     formattedMessage.AppendLiteral("\". abort()ing as a result.");
 #ifndef FUZZING
     MOZ_CRASH_UNSAFE_OOL(formattedMessage.get());
--- a/ipc/glue/ProtocolUtils.h
+++ b/ipc/glue/ProtocolUtils.h
@@ -28,17 +28,16 @@
 #include "mozilla/LinkedList.h"
 #include "mozilla/Maybe.h"
 #include "mozilla/MozPromise.h"
 #include "mozilla/Mutex.h"
 #include "mozilla/NotNull.h"
 #include "mozilla/Scoped.h"
 #include "mozilla/UniquePtr.h"
 #include "MainThreadUtils.h"
-#include "nsICrashReporter.h"
 #include "nsILabelableRunnable.h"
 
 #if defined(ANDROID) && defined(DEBUG)
 #include <android/log.h>
 #endif
 
 template<typename T> class nsTHashtable;
 template<typename T> class nsPtrHashKey;
@@ -910,19 +909,19 @@ private:
 
     bool mValid;
     mozilla::ipc::Transport::Mode mMode;
     TransportDescriptor mTransport;
     ProcessId mMyPid, mOtherPid;
 };
 
 #if defined(XP_MACOSX)
-void AnnotateCrashReportWithErrno(CrashReporter::Annotation tag, int error);
+void AnnotateCrashReportWithErrno(const char* tag, int error);
 #else
-static inline void AnnotateCrashReportWithErrno(CrashReporter::Annotation tag, int error)
+static inline void AnnotateCrashReportWithErrno(const char* tag, int error)
 {}
 #endif
 
 // This function is used internally to create a pair of Endpoints. See the
 // comment above Endpoint for a description of how it might be used.
 template<class PFooParent, class PFooChild>
 nsresult
 CreateEndpoints(const PrivateIPDLInterface& aPrivate,
@@ -932,18 +931,17 @@ CreateEndpoints(const PrivateIPDLInterfa
                 Endpoint<PFooChild>* aChildEndpoint)
 {
   MOZ_RELEASE_ASSERT(aParentDestPid);
   MOZ_RELEASE_ASSERT(aChildDestPid);
 
   TransportDescriptor parentTransport, childTransport;
   nsresult rv;
   if (NS_FAILED(rv = CreateTransport(aParentDestPid, &parentTransport, &childTransport))) {
-    AnnotateCrashReportWithErrno(
-      CrashReporter::Annotation::IpcCreateEndpointsNsresult, int(rv));
+    AnnotateCrashReportWithErrno("IpcCreateEndpointsNsresult", int(rv));
     return rv;
   }
 
   *aParentEndpoint = Endpoint<PFooParent>(aPrivate, mozilla::ipc::Transport::MODE_SERVER,
                                           parentTransport, aParentDestPid, aChildDestPid);
 
   *aChildEndpoint = Endpoint<PFooChild>(aPrivate, mozilla::ipc::Transport::MODE_CLIENT,
                                         childTransport, aChildDestPid, aParentDestPid);
--- a/ipc/glue/Transport_posix.cpp
+++ b/ipc/glue/Transport_posix.cpp
@@ -35,23 +35,21 @@ CreateTransport(base::ProcessId aProcIdO
   if (fd1 < 0 || fd2 < 0) {
     return NS_ERROR_TRANSPORT_INIT;
   }
 
   // The Transport closes these fds when it goes out of scope, so we
   // dup them here
   fd1 = dup(fd1);
   if (fd1 < 0) {
-    AnnotateCrashReportWithErrno(
-      CrashReporter::Annotation::IpcCreateTransportDupErrno, errno);
+    AnnotateCrashReportWithErrno("IpcCreateTransportDupErrno", errno);
   }
   fd2 = dup(fd2);
   if (fd2 < 0) {
-    AnnotateCrashReportWithErrno(
-      CrashReporter::Annotation::IpcCreateTransportDupErrno, errno);
+    AnnotateCrashReportWithErrno("IpcCreateTransportDupErrno", errno);
   }
 
   if (fd1 < 0 || fd2 < 0) {
     IGNORE_EINTR(close(fd1));
     IGNORE_EINTR(close(fd2));
     return NS_ERROR_DUPLICATE_HANDLE;
   }
 
--- a/ipc/mscom/COMPtrHolder.h
+++ b/ipc/mscom/COMPtrHolder.h
@@ -205,19 +205,18 @@ struct ParamTraits<mozilla::mscom::COMPt
         return false;
       }
     }
 
     typename paramType::EnvType env;
 
     mozilla::mscom::ProxyStream proxyStream(_IID, buf.get(), length, &env);
     if (!proxyStream.IsValid()) {
-      CrashReporter::AnnotateCrashReport(
-        CrashReporter::Annotation::ProxyStreamValid,
-        NS_LITERAL_CSTRING("false"));
+      CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("ProxyStreamValid"),
+                                         NS_LITERAL_CSTRING("false"));
       return false;
     }
 
     typename paramType::COMPtrType ptr;
     if (!proxyStream.GetInterface(mozilla::mscom::getter_AddRefs(ptr))) {
       return false;
     }
 
--- a/ipc/mscom/ProxyStream.cpp
+++ b/ipc/mscom/ProxyStream.cpp
@@ -39,18 +39,17 @@ ProxyStream::ProxyStream()
 // reconstructing the stream from a buffer anyway.
 ProxyStream::ProxyStream(REFIID aIID, const BYTE* aInitBuf,
                          const int aInitBufSize, Environment* aEnv)
   : mGlobalLockedBuf(nullptr)
   , mHGlobal(nullptr)
   , mBufSize(aInitBufSize)
   , mPreserveStream(false)
 {
-  CrashReporter::Annotation kCrashReportKey =
-    CrashReporter::Annotation::ProxyStreamUnmarshalStatus;
+  NS_NAMED_LITERAL_CSTRING(kCrashReportKey, "ProxyStreamUnmarshalStatus");
 
   if (!aInitBufSize) {
     CrashReporter::AnnotateCrashReport(kCrashReportKey,
                                        NS_LITERAL_CSTRING("!aInitBufSize"));
     // We marshaled a nullptr. Nothing else to do here.
     return;
   }
 
@@ -132,40 +131,43 @@ ProxyStream::ProxyStream(REFIID aIID, co
     EnsureMTA mta(marshalFn);
   }
 
   mStream = nullptr;
 
   if (FAILED(unmarshalResult) || !mUnmarshaledProxy) {
     nsPrintfCString hrAsStr("0x%08X", unmarshalResult);
     CrashReporter::AnnotateCrashReport(
-        CrashReporter::Annotation::CoUnmarshalInterfaceResult, hrAsStr);
+        NS_LITERAL_CSTRING("CoUnmarshalInterfaceResult"), hrAsStr);
     AnnotateInterfaceRegistration(aIID);
     if (!mUnmarshaledProxy) {
       CrashReporter::AnnotateCrashReport(kCrashReportKey,
                                          NS_LITERAL_CSTRING("!mUnmarshaledProxy"));
     }
 
 #if defined(ACCESSIBILITY)
     AnnotateClassRegistration(CLSID_AccessibleHandler);
-    CrashReporter::AnnotateCrashReport(
-      CrashReporter::Annotation::UnmarshalActCtx, strActCtx);
-    CrashReporter::AnnotateCrashReport(
-      CrashReporter::Annotation::UnmarshalActCtxManifestPath,
-      NS_ConvertUTF16toUTF8(manifestPath));
-    CrashReporter::AnnotateCrashReport(
-      CrashReporter::Annotation::A11yHandlerRegistered,
-      a11y::IsHandlerRegistered() ? NS_LITERAL_CSTRING("true")
-                                  : NS_LITERAL_CSTRING("false"));
+    CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("UnmarshalActCtx"),
+                                       strActCtx);
+    CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("UnmarshalActCtxManifestPath"),
+                                       NS_ConvertUTF16toUTF8(manifestPath));
+    CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("A11yHandlerRegistered"),
+                                       a11y::IsHandlerRegistered() ?
+                                       NS_LITERAL_CSTRING("true") :
+                                       NS_LITERAL_CSTRING("false"));
 
-    CrashReporter::AnnotateCrashReport(
-      CrashReporter::Annotation::ExpectedStreamLen, expectedStreamLen);
+    nsAutoCString strExpectedStreamLen;
+    strExpectedStreamLen.AppendInt(expectedStreamLen);
+    CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("ExpectedStreamLen"),
+                                       strExpectedStreamLen);
 
-    CrashReporter::AnnotateCrashReport(
-      CrashReporter::Annotation::ActualStreamLen, aInitBufSize);
+    nsAutoCString actualStreamLen;
+    actualStreamLen.AppendInt(aInitBufSize);
+    CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("ActualStreamLen"),
+                                       actualStreamLen);
 #endif // defined(ACCESSIBILITY)
   }
 }
 
 ProxyStream::ProxyStream(ProxyStream&& aOther)
   : mGlobalLockedBuf(nullptr)
   , mHGlobal(nullptr)
   , mBufSize(0)
@@ -353,66 +355,69 @@ ProxyStream::ProxyStream(REFIID aIID, IU
   } else {
     // When marshaling in child processes, we want to force the MTA.
     EnsureMTA mta(marshalFn);
   }
 
   if (FAILED(createStreamResult)) {
     nsPrintfCString hrAsStr("0x%08X", createStreamResult);
     CrashReporter::AnnotateCrashReport(
-      CrashReporter::Annotation::CreateStreamOnHGlobalFailure, hrAsStr);
+        NS_LITERAL_CSTRING("CreateStreamOnHGlobalFailure"),
+        hrAsStr);
   }
 
   if (FAILED(marshalResult)) {
     AnnotateInterfaceRegistration(aIID);
     nsPrintfCString hrAsStr("0x%08X", marshalResult);
     CrashReporter::AnnotateCrashReport(
-      CrashReporter::Annotation::CoMarshalInterfaceFailure, hrAsStr);
-    CrashReporter::AnnotateCrashReport(
-      CrashReporter::Annotation::MarshalActCtxManifestPath,
-      NS_ConvertUTF16toUTF8(manifestPath));
+        NS_LITERAL_CSTRING("CoMarshalInterfaceFailure"), hrAsStr);
+    CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("MarshalActCtxManifestPath"),
+                                       NS_ConvertUTF16toUTF8(manifestPath));
   }
 
   if (FAILED(statResult)) {
     nsPrintfCString hrAsStr("0x%08X", statResult);
-    CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::StatFailure,
-                                       hrAsStr);
+    CrashReporter::AnnotateCrashReport(
+        NS_LITERAL_CSTRING("StatFailure"),
+        hrAsStr);
   }
 
   if (FAILED(getHGlobalResult)) {
     nsPrintfCString hrAsStr("0x%08X", getHGlobalResult);
     CrashReporter::AnnotateCrashReport(
-      CrashReporter::Annotation::GetHGlobalFromStreamFailure, hrAsStr);
+        NS_LITERAL_CSTRING("GetHGlobalFromStreamFailure"),
+        hrAsStr);
   }
 
   mStream = std::move(stream);
 
   if (streamSize) {
-    CrashReporter::AnnotateCrashReport(
-      CrashReporter::Annotation::ProxyStreamSizeFrom,
-      NS_LITERAL_CSTRING("IStream::Stat"));
+    CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("ProxyStreamSizeFrom"),
+                                       NS_LITERAL_CSTRING("IStream::Stat"));
     mBufSize = streamSize;
   }
 
   if (!hglobal) {
     return;
   }
 
   mGlobalLockedBuf = reinterpret_cast<BYTE*>(::GlobalLock(hglobal));
   mHGlobal = hglobal;
 
   // If we couldn't get the stream size directly from mStream, we may use
   // the size of the memory block allocated by the HGLOBAL, though it might
   // be larger than the actual stream size.
   if (!streamSize) {
-    CrashReporter::AnnotateCrashReport(
-      CrashReporter::Annotation::ProxyStreamSizeFrom,
-      NS_LITERAL_CSTRING("GlobalSize"));
+    CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("ProxyStreamSizeFrom"),
+                                       NS_LITERAL_CSTRING("GlobalSize"));
     mBufSize = static_cast<int>(::GlobalSize(hglobal));
   }
 
-  CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::ProxyStreamSize,
-                                     mBufSize);
+  nsAutoCString strBufSize;
+  strBufSize.AppendInt(mBufSize);
+
+  CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("ProxyStreamSize"),
+                                     strBufSize);
 }
 
 } // namespace mscom
 } // namespace mozilla
 
--- a/ipc/mscom/RegistrationAnnotator.cpp
+++ b/ipc/mscom/RegistrationAnnotator.cpp
@@ -371,25 +371,26 @@ AnnotateInterfaceRegistration(REFIID aIi
   json.EndObject();
 
   json.StartObjectProperty("HKCU", style);
   AnnotateInterfaceRegistrationForHive(json, HKEY_CURRENT_USER, aIid, style);
   json.EndObject();
 
   json.End();
 
-  CrashReporter::Annotation annotationKey;
+  nsAutoCString annotationKey;
+  annotationKey.AppendLiteral("InterfaceRegistrationInfo");
   if (XRE_IsParentProcess()) {
-    annotationKey = CrashReporter::Annotation::InterfaceRegistrationInfoParent;
+    annotationKey.AppendLiteral("Parent");
   } else {
-    annotationKey = CrashReporter::Annotation::InterfaceRegistrationInfoChild;
+    annotationKey.AppendLiteral("Child");
   }
-  CrashReporter::AnnotateCrashReport(
-    annotationKey,
-    static_cast<CStringWriter*>(json.WriteFunc())->Get());
+
+  CrashReporter::AnnotateCrashReport(annotationKey,
+                                     static_cast<CStringWriter*>(json.WriteFunc())->Get());
 }
 
 void
 AnnotateClassRegistration(REFCLSID aClsid)
 {
 #if defined(DEBUG)
   const JSONWriter::CollectionStyle style = JSONWriter::MultiLineStyle;
 #else
@@ -408,21 +409,22 @@ AnnotateClassRegistration(REFCLSID aClsi
   json.EndObject();
 
   json.StartObjectProperty("HKCU", style);
   AnnotateClsidRegistrationForHive(json, HKEY_CURRENT_USER, strClsid, style);
   json.EndObject();
 
   json.End();
 
-  CrashReporter::Annotation annotationKey;
+  nsAutoCString annotationKey;
+  annotationKey.AppendLiteral("ClassRegistrationInfo");
   if (XRE_IsParentProcess()) {
-    annotationKey = CrashReporter::Annotation::ClassRegistrationInfoParent;
+    annotationKey.AppendLiteral("Parent");
   } else {
-    annotationKey = CrashReporter::Annotation::ClassRegistrationInfoChild;
+    annotationKey.AppendLiteral("Child");
   }
 
   CrashReporter::AnnotateCrashReport(annotationKey,
                                      static_cast<CStringWriter*>(json.WriteFunc())->Get());
 }
 
 } // namespace mscom
 } // namespace mozilla
--- a/js/xpconnect/loader/mozJSComponentLoader.cpp
+++ b/js/xpconnect/loader/mozJSComponentLoader.cpp
@@ -15,17 +15,16 @@
 #ifdef XP_WIN
 #include <windows.h>
 #endif
 
 #include "jsapi.h"
 #include "js/Printf.h"
 #include "nsCOMPtr.h"
 #include "nsAutoPtr.h"
-#include "nsExceptionHandler.h"
 #include "nsIComponentManager.h"
 #include "mozilla/Module.h"
 #include "nsIFile.h"
 #include "mozJSComponentLoader.h"
 #include "mozJSLoaderUtils.h"
 #include "nsIXPConnect.h"
 #include "nsIObserverService.h"
 #include "nsIScriptSecurityManager.h"
@@ -52,16 +51,20 @@
 #include "mozilla/ResultExtensions.h"
 #include "mozilla/ScriptPreloader.h"
 #include "mozilla/dom/DOMPrefs.h"
 #include "mozilla/dom/ScriptSettings.h"
 #include "mozilla/ResultExtensions.h"
 #include "mozilla/UniquePtrExtensions.h"
 #include "mozilla/Unused.h"
 
+#ifdef MOZ_CRASHREPORTER
+#include "mozilla/ipc/CrashReporterClient.h"
+#endif
+
 using namespace mozilla;
 using namespace mozilla::scache;
 using namespace mozilla::loader;
 using namespace xpc;
 using namespace JS;
 
 static const char kObserverServiceContractID[] = "@mozilla.org/observer-service;1";
 
@@ -355,47 +358,51 @@ ResolveModuleObjectProperty(JSContext* a
         }
         if (found) {
             return lexical;
         }
     }
     return aModObj;
 }
 
+#ifdef MOZ_CRASHREPORTER
 static mozilla::Result<nsCString, nsresult> ReadScript(ComponentLoaderInfo& aInfo);
 
 static nsresult
-AnnotateScriptContents(CrashReporter::Annotation aName, const nsACString& aURI)
+AnnotateScriptContents(const nsACString& aName, const nsACString& aURI)
 {
     ComponentLoaderInfo info(aURI);
 
     nsCString str;
     MOZ_TRY_VAR(str, ReadScript(info));
 
     // The crash reporter won't accept any strings with embedded nuls. We
     // shouldn't have any here, but if we do because of data corruption, we
     // still want the annotation. So replace any embedded nuls before
     // annotating.
     str.ReplaceSubstring(NS_LITERAL_CSTRING("\0"), NS_LITERAL_CSTRING("\\0"));
 
     CrashReporter::AnnotateCrashReport(aName, str);
 
     return NS_OK;
 }
+#endif // defined MOZ_CRASHREPORTER
 
 nsresult
 mozJSComponentLoader::AnnotateCrashReport()
 {
+#ifdef MOZ_CRASHREPORTER
     Unused << AnnotateScriptContents(
-        CrashReporter::Annotation::nsAsyncShutdownComponent,
+        NS_LITERAL_CSTRING("nsAsyncShutdownComponent"),
         NS_LITERAL_CSTRING("resource://gre/components/nsAsyncShutdown.js"));
 
     Unused << AnnotateScriptContents(
-        CrashReporter::Annotation::AsyncShutdownModule,
+        NS_LITERAL_CSTRING("AsyncShutdownModule"),
         NS_LITERAL_CSTRING("resource://gre/modules/AsyncShutdown.jsm"));
+#endif // defined MOZ_CRASHREPORTER
 
     return NS_OK;
 }
 
 const mozilla::Module*
 mozJSComponentLoader::LoadModule(FileLocation& aFile)
 {
     if (!NS_IsMainThread()) {
--- a/layout/style/ServoBindings.cpp
+++ b/layout/style/ServoBindings.cpp
@@ -2882,19 +2882,20 @@ Gecko_AddBufferToCrashReport(const void*
 {
   MOZ_ASSERT(NS_IsMainThread());
   nsCOMPtr<nsICrashReporter> cr = do_GetService("@mozilla.org/toolkit/crash-reporter;1");
   NS_ENSURE_TRUE_VOID(cr);
   cr->RegisterAppMemory((uint64_t) addr, len);
 }
 
 void
-Gecko_AnnotateCrashReport(uint32_t key, const char* value_str)
+Gecko_AnnotateCrashReport(const char* key_str, const char* value_str)
 {
   MOZ_ASSERT(NS_IsMainThread());
+  nsDependentCString key(key_str);
   nsDependentCString value(value_str);
   nsCOMPtr<nsICrashReporter> cr = do_GetService("@mozilla.org/toolkit/crash-reporter;1");
   NS_ENSURE_TRUE_VOID(cr);
   cr->AnnotateCrashReport(key, value);
 }
 
 void
 Gecko_ContentList_AppendAll(
--- a/layout/style/ServoBindings.h
+++ b/layout/style/ServoBindings.h
@@ -678,17 +678,17 @@ void Gecko_UnregisterProfilerThread();
 bool Gecko_DocumentRule_UseForPresentation(RawGeckoPresContextBorrowed,
                                            const nsACString* aPattern,
                                            mozilla::css::DocumentMatchingFunction);
 
 // Allocator hinting.
 void Gecko_SetJemallocThreadLocalArena(bool enabled);
 
 void Gecko_AddBufferToCrashReport(const void* addr, size_t len);
-void Gecko_AnnotateCrashReport(uint32_t key, const char* value_str);
+void Gecko_AnnotateCrashReport(const char* key_str, const char* value_str);
 
 // Pseudo-element flags.
 #define CSS_PSEUDO_ELEMENT(name_, value_, flags_) \
   const uint32_t SERVO_CSS_PSEUDO_ELEMENT_FLAGS_##name_ = flags_;
 #include "nsCSSPseudoElementList.h"
 #undef CSS_PSEUDO_ELEMENT
 
 #define SERVO_BINDING_FUNC(name_, return_, ...) return_ name_(__VA_ARGS__);
--- a/layout/style/nsLayoutStylesheetCache.cpp
+++ b/layout/style/nsLayoutStylesheetCache.cpp
@@ -707,19 +707,18 @@ AnnotateCrashReport(nsIURI* aURI)
         }
       }
       delete find;
     }
   } else {
     annotation.AppendLiteral("No GRE omnijar\n");
   }
 
-  CrashReporter::AnnotateCrashReport(
-    CrashReporter::Annotation::SheetLoadFailure,
-    NS_ConvertUTF16toUTF8(annotation));
+  CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("SheetLoadFailure"),
+                                     NS_ConvertUTF16toUTF8(annotation));
 }
 
 static void
 ErrorLoadingSheet(nsIURI* aURI, const char* aMsg, FailureAction aFailureAction)
 {
   nsPrintfCString errorMessage("%s loading built-in stylesheet '%s'",
                                aMsg,
                                aURI ? aURI->GetSpecOrDefault().get() : "");
--- a/mobile/android/base/java/org/mozilla/gecko/telemetry/pingbuilders/TelemetryCrashPingBuilder.java
+++ b/mobile/android/base/java/org/mozilla/gecko/telemetry/pingbuilders/TelemetryCrashPingBuilder.java
@@ -3,17 +3,16 @@
  * 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/.
  */
 
 package org.mozilla.gecko.telemetry.pingbuilders;
 
 import android.util.Log;
 
-import org.mozilla.gecko.CrashReporterConstants;
 import org.mozilla.gecko.sync.ExtendedJSONObject;
 import org.mozilla.gecko.sync.NonObjectJSONException;
 import org.mozilla.gecko.util.StringUtils;
 
 import java.io.IOException;
 import java.text.DateFormat;
 import java.text.SimpleDateFormat;
 import java.util.Arrays;
@@ -31,16 +30,50 @@ import java.util.TimeZone;
 public class TelemetryCrashPingBuilder extends TelemetryPingBuilder {
     private static final String LOGTAG = "GeckoTelemetryCrashPingBuilder";
 
     private static final int PING_VERSION = 1;
 
     private static final String ISO8601_DATE = "yyyy-MM-dd";
     private static final String ISO8601_DATE_HOURS = "yyyy-MM-dd'T'HH':00:00.000Z'";
 
+    // The following list should be kept in sync with the one in CrashManager.jsm
+    private static final String[] ANNOTATION_WHITELIST = {
+        "AsyncShutdownTimeout",
+        "AvailablePageFile",
+        "AvailablePhysicalMemory",
+        "AvailableVirtualMemory",
+        "BlockedDllList",
+        "BlocklistInitFailed",
+        "BuildID",
+        "ContainsMemoryReport",
+        "CrashTime",
+        "EventLoopNestingLevel",
+        "ipc_channel_error",
+        "IsGarbageCollecting",
+        "LowCommitSpaceEvents",
+        "MozCrashReason",
+        "OOMAllocationSize",
+        "ProductID",
+        "ProductName",
+        "ReleaseChannel",
+        "RemoteType",
+        "SecondsSinceLastCrash",
+        "ShutdownProgress",
+        "StartupCrash",
+        "SystemMemoryUsePercentage",
+        "TextureUsage",
+        "TotalPageFile",
+        "TotalPhysicalMemory",
+        "TotalVirtualMemory",
+        "UptimeTS",
+        "User32BeforeBlocklist",
+        "Version",
+    };
+
     public TelemetryCrashPingBuilder(String crashId, String clientId, HashMap<String, String> annotations) {
         super(TelemetryPingBuilder.UNIFIED_TELEMETRY_VERSION);
 
         payload.put("type", "crash");
         payload.put("id", docID);
         payload.put("version", TelemetryPingBuilder.UNIFIED_TELEMETRY_VERSION);
         payload.put("creationDate", currentDate(ISO8601_DATE_HOURS));
         payload.put("clientId", clientId);
@@ -140,17 +173,17 @@ public class TelemetryCrashPingBuilder e
      *
      * @param annotations A map holding the crash annotations
      * @returns A JSON object representing the ping's metadata node
      */
     private static ExtendedJSONObject createMetadataNode(HashMap<String, String> annotations) {
         ExtendedJSONObject node = new ExtendedJSONObject();
 
         for (Entry<String, String> pair : annotations.entrySet()) {
-            if (Arrays.binarySearch(CrashReporterConstants.ANNOTATION_WHITELIST, pair.getKey()) >= 0) {
+            if (Arrays.binarySearch(ANNOTATION_WHITELIST, pair.getKey()) >= 0) {
                 node.put(pair.getKey(), pair.getValue());
             }
         }
 
         return node;
     }
 
     /**
--- a/mobile/android/base/moz.build
+++ b/mobile/android/base/moz.build
@@ -111,37 +111,31 @@ with Files('../app/src/*/res/menu/browse
 
 DEFINES['ANDROID_PACKAGE_NAME'] = CONFIG['ANDROID_PACKAGE_NAME']
 FINAL_TARGET_PP_FILES += ['package-name.txt.in']
 
 GENERATED_FILES += [
     'AndroidManifest.xml',
     'generated/preprocessed/org/mozilla/gecko/AdjustConstants.java',
     'generated/preprocessed/org/mozilla/gecko/AppConstants.java',
-    'generated/preprocessed/org/mozilla/gecko/CrashReporterConstants.java',
     'generated/preprocessed/org/mozilla/gecko/MmaConstants.java',
 ]
 x = GENERATED_FILES['generated/preprocessed/org/mozilla/gecko/AdjustConstants.java']
 x.script = 'generate_build_config.py:generate_java'
 x.inputs += ['AdjustConstants.java.in']
 y = GENERATED_FILES['generated/preprocessed/org/mozilla/gecko/AppConstants.java']
 y.script = 'generate_build_config.py:generate_java'
 y.inputs += ['AppConstants.java.in']
 y = GENERATED_FILES['generated/preprocessed/org/mozilla/gecko/MmaConstants.java']
 y.script = 'generate_build_config.py:generate_java'
 y.inputs += ['MmaConstants.java.in']
 z = GENERATED_FILES['AndroidManifest.xml']
 z.script = 'generate_build_config.py:generate_android_manifest'
 z.inputs += ['AndroidManifest.xml.in']
 
-# Generate CrashReporterConstants.java
-crash_reporter_constants = GENERATED_FILES['generated/preprocessed/org/mozilla/gecko/CrashReporterConstants.java']
-crash_reporter_constants.script = '/toolkit/crashreporter/generate_crash_reporter_sources.py:emit_class'
-crash_reporter_constants.inputs += ['/toolkit/crashreporter/CrashAnnotations.yaml']
-
 # Regular builds invoke `libs` targets that localize files with no AB_CD set
 # into the default resources (res/{values,raw}).
 #
 # Multi-locale builds invoke `chrome-%` targets that localize files into
 # locale-specific resources (res/{values,raw}-AB-rCD).  Single-locale repacks
 # invoke `libs AB_CD=$*` targets that localize files into the default resources
 # (res/{values,raw}).
 #
@@ -193,16 +187,15 @@ t = ('android_apks',
 
 GENERATED_FILES += [t]
 GENERATED_FILES[t].force = True
 GENERATED_FILES[t].script = '/mobile/android/gradle.py:assemble_app'
 GENERATED_FILES[t].inputs += [
     '!AndroidManifest.xml',
     '!generated/preprocessed/org/mozilla/gecko/AdjustConstants.java',
     '!generated/preprocessed/org/mozilla/gecko/AppConstants.java',
-    '!generated/preprocessed/org/mozilla/gecko/CrashReporterConstants.java',
     '!generated/preprocessed/org/mozilla/gecko/MmaConstants.java',
     # These all depend on AB_CD, which isn't captured in this definition.  Due
     # to subtle RecursiveMake details, everything works out.  In the future we
     # can try to express the APKs themselves as LOCALIZED_GENERATED_FILES.
     '!res/raw/suggestedsites.json',
     '!res/values/strings.xml',
 ]
--- a/mobile/android/components/SessionStore.js
+++ b/mobile/android/components/SessionStore.js
@@ -1278,18 +1278,17 @@ SessionStore.prototype = {
       let currentURI = aWindow.BrowserApp.selectedBrowser.currentURI;
       // if the current URI contains a username/password, remove it
       try {
         currentURI = currentURI.mutate()
                                .setUserPass("")
                                .finalize();
       } catch (ex) { } // ignore failures on about: URIs
 
-      Services.appinfo.annotateCrashReport(Services.appinfo.URL,
-                                           currentURI.spec);
+      Services.appinfo.annotateCrashReport("URL", currentURI.spec);
     } catch (ex) {
       // don't make noise when crashreporter is built but not enabled
       if (ex.result != Cr.NS_ERROR_NOT_INITIALIZED) {
         Cu.reportError("SessionStore:" + ex);
       }
     }
   },
 
--- a/mozglue/build/WindowsDllBlocklist.cpp
+++ b/mozglue/build/WindowsDllBlocklist.cpp
@@ -19,42 +19,50 @@
 #include <io.h>
 
 #pragma warning( push )
 #pragma warning( disable : 4275 4530 ) // See msvc-stl-wrapper.template.h
 #include <map>
 #pragma warning( pop )
 
 #include "Authenticode.h"
-#include "CrashAnnotations.h"
 #include "nsAutoPtr.h"
 #include "nsWindowsDllInterceptor.h"
 #include "mozilla/Sprintf.h"
 #include "mozilla/StackWalk_windows.h"
 #include "mozilla/UniquePtr.h"
 #include "mozilla/Vector.h"
 #include "mozilla/WindowsVersion.h"
 #include "nsWindowsHelpers.h"
 #include "WindowsDllBlocklist.h"
 #include "mozilla/AutoProfilerLabel.h"
 #include "mozilla/glue/WindowsDllServices.h"
 
 using namespace mozilla;
 
-using CrashReporter::Annotation;
-using CrashReporter::AnnotationToString;
-
 #define DLL_BLOCKLIST_ENTRY(name, ...) \
   { name, __VA_ARGS__ },
 #define DLL_BLOCKLIST_STRING_TYPE const char*
 #include "mozilla/WindowsDllBlocklistDefs.h"
 
 // define this for very verbose dll load debug spew
 #undef DEBUG_very_verbose
 
+static const char kBlockedDllsParameter[] = "BlockedDllList=";
+static const int kBlockedDllsParameterLen =
+  sizeof(kBlockedDllsParameter) - 1;
+
+static const char kBlocklistInitFailedParameter[] = "BlocklistInitFailed=1\n";
+static const int kBlocklistInitFailedParameterLen =
+  sizeof(kBlocklistInitFailedParameter) - 1;
+
+static const char kUser32BeforeBlocklistParameter[] = "User32BeforeBlocklist=1\n";
+static const int kUser32BeforeBlocklistParameterLen =
+  sizeof(kUser32BeforeBlocklistParameter) - 1;
+
 static uint32_t sInitFlags;
 static bool sBlocklistInitAttempted;
 static bool sBlocklistInitFailed;
 static bool sUser32BeforeBlocklist;
 
 // Duplicated from xpcom glue. Ideally this should be shared.
 void
 printf_stderr(const char *fmt, ...)
@@ -767,40 +775,32 @@ DllBlocklist_Initialize(uint32_t aInitFl
     if (pProc) {
       gStartAddressesToBlock->append(pProc);
     }
   }
 #endif
 }
 
 static void
-WriteAnnotation(HANDLE aFile, Annotation aAnnotation, const char* aValue,
-                DWORD* aNumBytes)
-{
-  const char* str = AnnotationToString(aAnnotation);
-  WriteFile(aFile, str, strlen(str), aNumBytes, nullptr);
-  WriteFile(aFile, "=", 1, aNumBytes, nullptr);
-  WriteFile(aFile, aValue, strlen(aValue), aNumBytes, nullptr);
-}
-
-static void
 InternalWriteNotes(HANDLE file)
 {
   DWORD nBytes;
 
-  WriteAnnotation(file, Annotation::BlockedDllList, "", &nBytes);
+  WriteFile(file, kBlockedDllsParameter, kBlockedDllsParameterLen, &nBytes, nullptr);
   DllBlockSet::Write(file);
   WriteFile(file, "\n", 1, &nBytes, nullptr);
 
   if (sBlocklistInitFailed) {
-    WriteAnnotation(file, Annotation::BlocklistInitFailed, "1\n", &nBytes);
+    WriteFile(file, kBlocklistInitFailedParameter,
+              kBlocklistInitFailedParameterLen, &nBytes, nullptr);
   }
 
   if (sUser32BeforeBlocklist) {
-    WriteAnnotation(file, Annotation::User32BeforeBlocklist, "1\n", &nBytes);
+    WriteFile(file, kUser32BeforeBlocklistParameter,
+              kUser32BeforeBlocklistParameterLen, &nBytes, nullptr);
   }
 }
 
 using WriterFn = void (*)(HANDLE);
 static WriterFn gWriterFn = &InternalWriteNotes;
 
 static void
 GetNativeNtBlockSetWriter()
--- a/netwerk/ipc/NeckoMessageUtils.h
+++ b/netwerk/ipc/NeckoMessageUtils.h
@@ -102,18 +102,17 @@ struct ParamTraits<mozilla::net::NetAddr
       // Train's already off the rails:  let's get a stack trace at least...
       MOZ_CRASH("Error: please post stack trace to "
                       "https://bugzilla.mozilla.org/show_bug.cgi?id=661158");
       aMsg->WriteBytes(aParam.local.path, sizeof(aParam.local.path));
 #endif
     } else {
       if (XRE_IsParentProcess()) {
         nsPrintfCString msg("%d", aParam.raw.family);
-        CrashReporter::AnnotateCrashReport(
-          CrashReporter::Annotation::UnknownNetAddrSocketFamily, msg);
+        CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("Unknown NetAddr socket family"), msg);
       }
 
       MOZ_CRASH("Unknown socket family");
     }
   }
 
   static bool Read(const Message* aMsg, PickleIterator* aIter, mozilla::net::NetAddr* aResult)
   {
--- a/storage/mozStorageService.cpp
+++ b/storage/mozStorageService.cpp
@@ -791,17 +791,17 @@ Service::Observe(nsISupports *, const ch
     if (gShutdownChecks == SCM_CRASH) {
       nsTArray<RefPtr<Connection> > connections;
       getConnections(connections);
       for (uint32_t i = 0, n = connections.Length(); i < n; i++) {
         if (!connections[i]->isClosed()) {
           // getFilename is only the leaf name for the database file,
           // so it shouldn't contain privacy-sensitive information.
           CrashReporter::AnnotateCrashReport(
-            CrashReporter::Annotation::StorageConnectionNotClosed,
+            NS_LITERAL_CSTRING("StorageConnectionNotClosed"),
             connections[i]->getFilename());
 #ifdef DEBUG
           printf_stderr("Storage connection not closed: %s",
                         connections[i]->getFilename().get());
 #endif
           MOZ_CRASH();
         }
       }
--- a/toolkit/components/asyncshutdown/AsyncShutdown.jsm
+++ b/toolkit/components/asyncshutdown/AsyncShutdown.jsm
@@ -40,21 +40,31 @@
 
 ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm", this);
 ChromeUtils.import("resource://gre/modules/Services.jsm", this);
 
 ChromeUtils.defineModuleGetter(this, "PromiseUtils",
   "resource://gre/modules/PromiseUtils.jsm");
 ChromeUtils.defineModuleGetter(this, "Task",
   "resource://gre/modules/Task.jsm");
-XPCOMUtils.defineLazyModuleGetters(this, {
-  CrashReporter: "resource://gre/modules/CrashReporter.jsm",
-});
 XPCOMUtils.defineLazyServiceGetter(this, "gDebug",
   "@mozilla.org/xpcom/debug;1", "nsIDebug2");
+Object.defineProperty(this, "gCrashReporter", {
+  get() {
+    delete this.gCrashReporter;
+    try {
+      let reporter = Cc["@mozilla.org/xre/app-info;1"].
+            getService(Ci.nsICrashReporter);
+      return this.gCrashReporter = reporter;
+    } catch (ex) {
+      return this.gCrashReporter = null;
+    }
+  },
+  configurable: true
+});
 
 // `true` if this is a content process, `false` otherwise.
 // It would be nicer to go through `Services.appinfo`, but some tests need to be
 // able to replace that field with a custom implementation before it is first
 // called.
 // eslint-disable-next-line mozilla/use-services
 const isContent = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime).processType == Ci.nsIXULRuntime.PROCESS_TYPE_CONTENT;
 
@@ -929,23 +939,22 @@ Barrier.prototype = Object.freeze({
           // helps automatically sort oranges.
           let msg = "AsyncShutdown timeout in " + topic +
             " Conditions: " + JSON.stringify(state) +
             " At least one completion condition failed to complete" +
             " within a reasonable amount of time. Causing a crash to" +
             " ensure that we do not leave the user with an unresponsive" +
             " process draining resources.";
           fatalerr(msg);
-          if (CrashReporter.enabled) {
+          if (gCrashReporter && gCrashReporter.enabled) {
             let data = {
               phase: topic,
               conditions: state
             };
-            CrashReporter.addAnnotation(
-              CrashReporter.annotations.AsyncShutdownTimeout,
+            gCrashReporter.annotateCrashReport("AsyncShutdownTimeout",
               JSON.stringify(data));
           } else {
             warn("No crash reporter available");
           }
 
           // To help sorting out bugs, we want to make sure that the
           // call to nsIDebug2.abort points to a guilty client, rather
           // than to AsyncShutdown itself. We pick a client that is
--- a/toolkit/components/crashes/CrashManager.jsm
+++ b/toolkit/components/crashes/CrashManager.jsm
@@ -216,16 +216,54 @@ this.CrashManager.prototype = Object.fre
   // The following are return codes for individual event file processing.
   // File processed OK.
   EVENT_FILE_SUCCESS: "ok",
   // The event appears to be malformed.
   EVENT_FILE_ERROR_MALFORMED: "malformed",
   // The type of event is unknown.
   EVENT_FILE_ERROR_UNKNOWN_EVENT: "unknown-event",
 
+  // A whitelist of crash annotations which do not contain sensitive data
+  // and are saved in the crash record and sent with Firefox Health Report.
+  ANNOTATION_WHITELIST: [
+    "AsyncShutdownTimeout",
+    "BuildID",
+    "ipc_channel_error",
+    "LowCommitSpaceEvents",
+    "ProductID",
+    "ProductName",
+    "ReleaseChannel",
+    "RemoteType",
+    "SecondsSinceLastCrash",
+    "ShutdownProgress",
+    "StartupCrash",
+    "TelemetryEnvironment",
+    "Version",
+    // The following entries are not normal annotations that can be found in
+    // the .extra file but are included in the crash record/FHR:
+    "AvailablePageFile",
+    "AvailablePhysicalMemory",
+    "AvailableVirtualMemory",
+    "BlockedDllList",
+    "BlocklistInitFailed",
+    "ContainsMemoryReport",
+    "CrashTime",
+    "EventLoopNestingLevel",
+    "IsGarbageCollecting",
+    "MozCrashReason",
+    "OOMAllocationSize",
+    "SystemMemoryUsePercentage",
+    "TextureUsage",
+    "TotalPageFile",
+    "TotalPhysicalMemory",
+    "TotalVirtualMemory",
+    "UptimeTS",
+    "User32BeforeBlocklist",
+  ],
+
   /**
    * Obtain a list of all dumps pending upload.
    *
    * The returned value is a promise that resolves to an array of objects
    * on success. Each element in the array has the following properties:
    *
    *   id (string)
    *      The ID of the crash (a UUID).
@@ -594,26 +632,20 @@ this.CrashManager.prototype = Object.fre
       let payload = data.substring(start);
 
       return this._handleEventFilePayload(store, entry, type, date, payload);
     })();
   },
 
   _filterAnnotations(annotations) {
     let filteredAnnotations = {};
-    let crashReporter = Cc["@mozilla.org/toolkit/crash-reporter;1"]
-                          .getService(Ci.nsICrashReporter);
 
     for (let line in annotations) {
-      try {
-        if (crashReporter.isAnnotationWhitelistedForPing(line)) {
-          filteredAnnotations[line] = annotations[line];
-        }
-      } catch (e) {
-        // Silently drop unknown annotations
+      if (this.ANNOTATION_WHITELIST.includes(line)) {
+        filteredAnnotations[line] = annotations[line];
       }
     }
 
     return filteredAnnotations;
   },
 
   _sendCrashPing(crashId, type, date, metadata = {}) {
     // If we have a saved environment, use it. Otherwise report
--- a/toolkit/components/crashes/tests/xpcshell/crash.extra
+++ b/toolkit/components/crashes/tests/xpcshell/crash.extra
@@ -3,16 +3,17 @@ TelemetryEnvironment={"EscapedField":"Es
 EMCheckCompatibility=true
 ProductName=Firefox
 ContentSandboxCapabilities=119
 TelemetryClientId=
 Vendor=Mozilla
 InstallTime=1000000000
 Theme=classic/1.0
 ReleaseChannel=default
+AddonsShouldHaveBlockedE10s=1
 ServerURL=https://crash-reports.mozilla.com
 SafeMode=0
 ContentSandboxCapable=1
 useragent_locale=en-US
 Version=55.0a1
 BuildID=20170512114708
 ProductID={ec8030f7-c20a-464f-9b0e-13a3a9e97384}
 TelemetryServerURL=
--- a/toolkit/components/gfx/SanityTest.js
+++ b/toolkit/components/gfx/SanityTest.js
@@ -1,15 +1,14 @@
 /* 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/. */
 
 "use strict";
 
-ChromeUtils.import("resource://gre/modules/CrashReporter.jsm");
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 
 const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
 const FRAME_SCRIPT_URL = "chrome://gfxsanity/content/gfxFrameScript.js";
 
 const PAGE_WIDTH = 160;
 const PAGE_HEIGHT = 234;
@@ -68,16 +67,26 @@ function reportResult(val) {
   Services.prefs.savePrefFile(null);
 }
 
 function reportTestReason(val) {
   let histogram = Services.telemetry.getHistogramById("GRAPHICS_SANITY_TEST_REASON");
   histogram.add(val);
 }
 
+function annotateCrashReport(value) {
+  try {
+    // "1" if we're annotating the crash report, "" to remove the annotation.
+    var crashReporter = Cc["@mozilla.org/toolkit/crash-reporter;1"].
+                          getService(Ci.nsICrashReporter);
+    crashReporter.annotateCrashReport("GraphicsSanityTest", value ? "1" : "");
+  } catch (e) {
+  }
+}
+
 function setTimeout(aMs, aCallback) {
   var timer = Cc["@mozilla.org/timer;1"].
                 createInstance(Ci.nsITimer);
   timer.initWithCallback(aCallback, aMs, Ci.nsITimer.TYPE_ONE_SHOT);
 }
 
 function takeWindowSnapshot(win, ctx) {
   // TODO: drawWindow reads back from the gpu's backbuffer, which won't catch issues with presenting
@@ -226,18 +235,19 @@ var listener = {
       // We don't have a MessageManager if onWindowLoaded never fired.
       this.messages.forEach((msgName) => {
         this.mm.removeMessageListener(msgName, this);
       });
 
       this.mm = null;
     }
 
-    CrashReporter.removeAnnotation(
-      CrashReporter.annotations.GraphicsSanityTest);
+    // Remove the annotation after we've cleaned everything up, to catch any
+    // incidental crashes from having performed the sanity test.
+    annotateCrashReport(false);
   }
 };
 
 function SanityTest() {}
 SanityTest.prototype = {
   classID: Components.ID("{f3a8ca4d-4c83-456b-aee2-6a2cbf11e9bd}"),
   QueryInterface: ChromeUtils.generateQI([Ci.nsIObserver,
                                           Ci.nsISupportsWeakReference]),
@@ -315,18 +325,17 @@ SanityTest.prototype = {
 
     // profile-after-change fires only at startup, so we won't need
     // to use the listener again.
     let tester = listener;
     listener = null;
 
     if (!this.shouldRunTest()) return;
 
-    CrashReporter.addAnnotation(
-      CrashReporter.annotations.GraphicsSanityTest, "1");
+    annotateCrashReport(true);
 
     // Open a tiny window to render our test page, and notify us when it's loaded
     var sanityTest = Services.ww.openWindow(null,
         "chrome://gfxsanity/content/sanityparent.html",
         "Test Page",
         "width=" + PAGE_WIDTH + ",height=" + PAGE_HEIGHT + ",chrome,titlebar=0,scrollbars=0,popup=1",
         null);
 
--- a/toolkit/components/telemetry/TelemetrySend.jsm
+++ b/toolkit/components/telemetry/TelemetrySend.jsm
@@ -13,17 +13,16 @@
 
 var EXPORTED_SYMBOLS = [
   "TelemetrySend",
 ];
 
 ChromeUtils.import("resource://gre/modules/AppConstants.jsm", this);
 ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm", this);
 ChromeUtils.import("resource://gre/modules/ClientID.jsm");
-ChromeUtils.import("resource://gre/modules/CrashReporter.jsm", this);
 ChromeUtils.import("resource://gre/modules/Log.jsm", this);
 ChromeUtils.import("resource://gre/modules/PromiseUtils.jsm");
 ChromeUtils.import("resource://gre/modules/ServiceRequest.jsm", this);
 ChromeUtils.import("resource://gre/modules/Services.jsm", this);
 ChromeUtils.import("resource://gre/modules/TelemetryUtils.jsm", this);
 ChromeUtils.import("resource://gre/modules/Timer.jsm", this);
 
 ChromeUtils.defineModuleGetter(this, "TelemetryStorage",
@@ -677,30 +676,31 @@ var TelemetrySendImpl = {
   /**
    * Triggers the crash report annotations depending on the current
    * configuration. This communicates to the crash reporter if it can send a
    * crash ping or not. This method can be called safely before setup() has
    * been called.
    */
   _annotateCrashReport() {
     try {
-      let clientId = ClientID.getCachedClientID();
-      let server = this._server || Services.prefs.getStringPref(TelemetryUtils.Preferences.Server, undefined);
+      const cr = Cc["@mozilla.org/toolkit/crash-reporter;1"];
+      if (cr) {
+        const crs = cr.getService(Ci.nsICrashReporter);
+
+        let clientId = ClientID.getCachedClientID();
+        let server = this._server || Services.prefs.getStringPref(TelemetryUtils.Preferences.Server, undefined);
 
-      if (!this.sendingEnabled() || !TelemetryReportingPolicy.canUpload()) {
-        // If we cannot send pings then clear the crash annotations
-        CrashReporter.removeAnnotation(
-          CrashReporter.annotations.TelemetryClientId);
-        CrashReporter.removeAnnotation(
-          CrashReporter.annotations.TelemetryServerURL);
-      } else {
-        CrashReporter.addAnnotation(
-          CrashReporter.annotations.TelemetryClientId, clientId);
-        CrashReporter.addAnnotation(
-          CrashReporter.annotations.TelemetryServerURL, server);
+        if (!this.sendingEnabled() || !TelemetryReportingPolicy.canUpload()) {
+          // If we cannot send pings then clear the crash annotations
+          crs.annotateCrashReport("TelemetryClientId", "");
+          crs.annotateCrashReport("TelemetryServerURL", "");
+        } else {
+          crs.annotateCrashReport("TelemetryClientId", clientId);
+          crs.annotateCrashReport("TelemetryServerURL", server);
+        }
       }
     } catch (e) {
       // Ignore errors when crash reporting is disabled
     }
   },
 
   /**
    * Discard old pings from the pending pings and detect overdue ones.
--- a/toolkit/components/telemetry/TelemetryStartup.js
+++ b/toolkit/components/telemetry/TelemetryStartup.js
@@ -1,16 +1,15 @@
 /* -*- js-indent-level: 2; indent-tabs-mode: nil -*- */
 /* 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/. */
 
 "use strict";
 
-ChromeUtils.import("resource://gre/modules/CrashReporter.jsm", this);
 ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm", this);
 
 ChromeUtils.defineModuleGetter(this, "TelemetryController",
                                "resource://gre/modules/TelemetryController.jsm");
 ChromeUtils.defineModuleGetter(this, "TelemetryEnvironment",
                                "resource://gre/modules/TelemetryEnvironment.jsm");
 
 /**
@@ -31,17 +30,19 @@ TelemetryStartup.prototype.observe = fun
     annotateEnvironment();
     TelemetryEnvironment.registerChangeListener("CrashAnnotator", annotateEnvironment);
     TelemetryEnvironment.onInitialized().then(() => annotateEnvironment());
   }
 };
 
 function annotateEnvironment() {
   try {
-    let env = JSON.stringify(TelemetryEnvironment.currentEnvironment);
-    CrashReporter.addAnnotation(CrashReporter.annotations.TelemetryEnvironment,
-                                env);
+    let cr = Cc["@mozilla.org/toolkit/crash-reporter;1"];
+    if (cr) {
+      let env = JSON.stringify(TelemetryEnvironment.currentEnvironment);
+      cr.getService(Ci.nsICrashReporter).annotateCrashReport("TelemetryEnvironment", env);
+    }
   } catch (e) {
     // crash reporting not built or disabled? Ignore errors
   }
 }
 
 this.NSGetFactory = XPCOMUtils.generateNSGetFactory([TelemetryStartup]);
--- a/toolkit/components/telemetry/tests/unit/test_TelemetrySend.js
+++ b/toolkit/components/telemetry/tests/unit/test_TelemetrySend.js
@@ -4,28 +4,26 @@
 
 // This tests the public Telemetry API for submitting pings.
 
 "use strict";
 
 ChromeUtils.import("resource://gre/modules/TelemetryController.jsm", this);
 ChromeUtils.import("resource://testing-common/ContentTaskUtils.jsm", this);
 ChromeUtils.import("resource://testing-common/MockRegistrar.jsm", this);
-ChromeUtils.import("resource://gre/modules/CrashReporter.jsm", this);
 ChromeUtils.import("resource://gre/modules/TelemetrySession.jsm", this);
+ChromeUtils.import("resource://gre/modules/TelemetrySend.jsm", this);
 ChromeUtils.import("resource://gre/modules/TelemetryStorage.jsm", this);
 ChromeUtils.import("resource://gre/modules/TelemetryUtils.jsm", this);
 ChromeUtils.import("resource://gre/modules/Services.jsm", this);
 ChromeUtils.import("resource://gre/modules/osfile.jsm", this);
 ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm", this);
 
 ChromeUtils.import("resource://gre/modules/TelemetryStopwatch.jsm", this);
 
-ChromeUtils.defineModuleGetter(this, "TelemetrySend",
-  "resource://gre/modules/TelemetrySend.jsm");
 ChromeUtils.defineModuleGetter(this, "TelemetryHealthPing",
   "resource://gre/modules/TelemetryHealthPing.jsm");
 
 XPCOMUtils.defineLazyServiceGetter(Services, "cookies", "@mozilla.org/cookieService;1", "nsICookieService");
 
 const MS_IN_A_MINUTE = 60 * 1000;
 
 function countPingTypes(pings) {
@@ -602,101 +600,73 @@ add_task(async function test_measurePing
   Assert.equal(histogramValueCount(histSuccessPingSize.snapshot()), 2,
     "Should have recorded 2 successful ping into histogram.");
   Assert.equal(histogramValueCount(histFailedPingSize.snapshot()), 1,
     "Should have recorded 1 failed ping into histogram.");
 });
 
 add_task(async function test_pref_observer() {
   // This test requires the presence of the crash reporter component.
-  if (!AppConstants.MOZ_CRASHREPORTER) {
+  let registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
+  if (!registrar.isContractIDRegistered("@mozilla.org/toolkit/crash-reporter;1")) {
     return;
   }
 
-  // Mock the crash reporter wrapper so that we can inspect the annotations
-  var MockCrashReporter = {
-    addAnnotation(annotation, value) {
-      if (!this.keys.delete(annotation)) {
-        let string = Object.keys(CrashReporter.annotations)
-                           .find(key => key === annotation);
-        if (this.reject) {
-          this.reject(
-            Error(`Crash report annotation with unexpected key: "${string}".`));
-        }
-      }
-
-      if (this.expectedValue && value == "") {
-        if (this.reject) {
-          this.reject(Error("Crash report annotation without expected value."));
-        }
-      }
-
-      if (this.keys.size == 0) {
-        if (this.resolve) {
-          this.resolve();
-        }
-      }
-    },
-    removeAnnotation(annotation) {
-      if (!this.keys.delete(annotation)) {
-        let string = Object.keys(CrashReporter.annotations)
-                           .find(key => key === annotation);
-        if (this.reject) {
-          this.reject(
-            Error(`Crash report annotation with unexpected key: "${string}".`));
-        }
-      }
-
-      if (this.keys.size == 0) {
-        if (this.resolve) {
-          this.resolve();
-        }
-      }
-    },
-    annotations: Object.assign({}, CrashReporter.annotations),
-    keys: null,
-    expectedValue: false,
-    resolve: null,
-    reject: null,
-  };
-
-  let ts_scope = ChromeUtils.import("resource://gre/modules/TelemetrySend.jsm",
-                                    {});
-
-  ts_scope.CrashReporter = MockCrashReporter;
-  registerCleanupFunction(function() {
-    ts_scope.CrashReporter = CrashReporter;
-  });
-
-  function waitAnnotateCrashReport(expectedValue, trigger) {
-    MockCrashReporter.expectedValue = expectedValue;
-    MockCrashReporter.keys = new Set([
-      CrashReporter.annotations.TelemetryClientId,
-      CrashReporter.annotations.TelemetryServerURL
-    ]);
-
-    return new Promise(function(resolve, reject) {
-      MockCrashReporter.resolve = resolve;
-      MockCrashReporter.reject = reject;
-      trigger();
-    });
-  }
-
   await TelemetrySend.setup(true);
 
   const IS_UNIFIED_TELEMETRY = Services.prefs.getBoolPref(TelemetryUtils.Preferences.Unified, false);
 
   let origTelemetryEnabled = Services.prefs.getBoolPref(TelemetryUtils.Preferences.TelemetryEnabled);
   let origFhrUploadEnabled = Services.prefs.getBoolPref(TelemetryUtils.Preferences.FhrUploadEnabled);
 
   if (!IS_UNIFIED_TELEMETRY) {
     Services.prefs.setBoolPref(TelemetryUtils.Preferences.TelemetryEnabled, true);
   }
   Services.prefs.setBoolPref(TelemetryUtils.Preferences.FhrUploadEnabled, true);
 
+  function waitAnnotateCrashReport(expectedValue, trigger) {
+    return new Promise(function(resolve, reject) {
+      let keys = new Set(["TelemetryClientId", "TelemetryServerURL"]);
+
+      let crs = {
+        QueryInterface: ChromeUtils.generateQI([Ci.nsICrashReporter]),
+        annotateCrashReport(key, value) {
+          if (!keys.delete(key)) {
+            MockRegistrar.unregister(gMockCrs);
+            reject(Error(`Crash report annotation with unexpected key: "${key}".`));
+          }
+
+          if (expectedValue && value == "") {
+            MockRegistrar.unregister(gMockCrs);
+            reject(Error("Crash report annotation without expected value."));
+          }
+
+          if (!expectedValue && value != "") {
+            MockRegistrar.unregister(gMockCrs);
+            reject(Error(`Crash report annotation ("${key}") with unexpected value: "${value}".`));
+          }
+
+          if (keys.size == 0) {
+            MockRegistrar.unregister(gMockCrs);
+            resolve();
+          }
+        },
+        UpdateCrashEventsDir() {
+        },
+      };
+
+      let gMockCrs = MockRegistrar.register("@mozilla.org/toolkit/crash-reporter;1", crs);
+      registerCleanupFunction(function() {
+        MockRegistrar.unregister(gMockCrs);
+      });
+
+      trigger();
+    });
+  }
+
   await waitAnnotateCrashReport(!IS_UNIFIED_TELEMETRY, () => Services.prefs.setBoolPref(TelemetryUtils.Preferences.FhrUploadEnabled, false));
 
   await waitAnnotateCrashReport(true, () => Services.prefs.setBoolPref(TelemetryUtils.Preferences.FhrUploadEnabled, true));
 
   if (!IS_UNIFIED_TELEMETRY) {
     Services.prefs.setBoolPref(TelemetryUtils.Preferences.TelemetryEnabled, origTelemetryEnabled);
   }
   Services.prefs.setBoolPref(TelemetryUtils.Preferences.FhrUploadEnabled, origFhrUploadEnabled);
--- a/toolkit/components/terminator/nsTerminator.cpp
+++ b/toolkit/components/terminator/nsTerminator.cpp
@@ -598,18 +598,18 @@ nsTerminator::UpdateTelemetry()
 }
 
 void
 nsTerminator::UpdateCrashReport(const char* aTopic)
 {
   // In case of crash, we wish to know where in shutdown we are
   nsAutoCString report(aTopic);
 
-  Unused << CrashReporter::AnnotateCrashReport(
-    CrashReporter::Annotation::ShutdownProgress, report);
+  Unused << CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("ShutdownProgress"),
+                                               report);
 }
 
 void
 XPCOMShutdownNotified()
 {
   MOZ_DIAGNOSTIC_ASSERT(sShutdownNotified == false);
   sShutdownNotified = true;
 }
deleted file mode 100644
--- a/toolkit/crashreporter/CrashAnnotations.cpp
+++ /dev/null
@@ -1,63 +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/. */
-
-#include "CrashAnnotations.h"
-
-#include <algorithm>
-#include <cstring>
-#include <iterator>
-
-using std::begin;
-using std::end;
-using std::find_if;
-
-namespace CrashReporter {
-
-bool
-AnnotationFromString(Annotation& aResult, const char* aValue)
-{
-  auto elem = find_if(
-    begin(kAnnotationStrings),
-    end(kAnnotationStrings),
-    [&aValue](const char* aString) {
-      return strcmp(aString, aValue) == 0;
-    }
-  );
-
-  if (elem == end(kAnnotationStrings)) {
-    return false;
-  }
-
-  aResult = static_cast<Annotation>(elem - begin(kAnnotationStrings));
-  return true;
-}
-
-bool
-IsAnnotationWhitelistedForPing(Annotation aAnnotation) {
-  auto elem = find_if(
-    begin(kCrashPingWhitelist),
-    end(kCrashPingWhitelist),
-    [&aAnnotation](Annotation aElement) {
-      return aElement == aAnnotation;
-    }
-  );
-
-  return elem != end(kCrashPingWhitelist);
-}
-
-bool
-IsAnnotationBlacklistedForContent(Annotation aAnnotation)
-{
-  auto elem = find_if(
-    begin(kContentProcessBlacklist),
-    end(kContentProcessBlacklist),
-    [&aAnnotation](Annotation aElement) {
-      return aElement == aAnnotation;
-    }
-  );
-
-  return elem != end(kContentProcessBlacklist);
-}
-
-} // namespace CrashReporter
deleted file mode 100644
--- a/toolkit/crashreporter/CrashAnnotations.h.in
+++ /dev/null
@@ -1,76 +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/. */
-
-#ifndef CrashAnnotations_h
-#define CrashAnnotations_h
-
-#include <cstdint>
-
-namespace CrashReporter {
-
-// Typed enum representing all crash annotations
-enum class Annotation : uint32_t {
-${enum}
-};
-
-// Stringified crash annotation names
-const char* const kAnnotationStrings[] = {
-${strings}
-};
-
-// Whitelist of crash annotations that can be included in a crash ping
-const Annotation kCrashPingWhitelist[] = {
-${whitelist}
-};
-
-// Blacklist of crash annotations that shouldn't be read from a content process
-const Annotation kContentProcessBlacklist[] = {
-${blacklist}
-};
-
-/**
- * Return the string representation of a crash annotation.
- *
- * @param aAnnotation a crash annotation
- * @returns A constant string holding the annotation name
- */
-static inline const char*
-AnnotationToString(Annotation aAnnotation) {
-  return kAnnotationStrings[static_cast<uint32_t>(aAnnotation)];
-}
-
-/**
- * Converts a string to its corresponding crash annotation.
- *
- * @param aResult a reference where the annotation will be stored
- * @param aValue the string to be converted
- * @return true if the string was successfully converted, false if it did not
- *         correspond to any known annotation
- */
-bool AnnotationFromString(Annotation& aResult, const char* aValue);
-
-/**
- * Checks if the given crash annotation is whitelisted for inclusion in the
- * crash ping.
- *
- * @param aAnnotation the crash annotation to be checked
- * @return true if the annotation can be included in the crash ping, false
- *         otherwise
- */
-bool IsAnnotationWhitelistedForPing(Annotation aAnnotation);
-
-/**
- * Checks if the given crash annotation needs to be filtered out when reading
- * a content process crash annotations. Blacklisted annotations will be
- * replaced with ones provided by the parent process.
- *
- * @param aAnnotation the crash annotation to be checked
- * @return true if the annotation needs to be filtered out when reading
- *         annotations provided by a content process, false otherwise
- */
-bool IsAnnotationBlacklistedForContent(Annotation aAnnotation);
-
-} // namespace CrashReporter
-
-#endif // CrashAnnotations_h
deleted file mode 100644
--- a/toolkit/crashreporter/CrashAnnotations.yaml
+++ /dev/null
@@ -1,776 +0,0 @@
-# This lists all the available crash annotations.
-#
-# Mandatory fields for each entry are:
-# - description: A string describing the annotation
-# - type: the annotation type, currently `string`, `integer` or `boolean`.
-#   The latter are stringified to `1` for true and `0` for false.
-#
-# Additionally a field can have the following optional fields:
-# - altname: A string that will be used when writing out the annotation to the
-#   .extra file instead of the annotation name
-# - ping: A boolean that indicates whether the annotation is whitelisted for
-#   going into the crash ping, if not specified this defaults to false
-# - content: A boolean that indicates whether the field will be included in
-#   subprocess reports, if not specified this defaults to true
-
-A11yHandlerRegistered:
-  description: >
-    Set to "true" if the accessibility handler is registered, "false" otherwise.
-  type: string
-
-AbortMessage:
-  description: >
-    Message passed to NS_DebugBreak().
-  type: string
-
-Accessibility:
-  description: >
-    Set to "Active" by the accessibility service when it is active.
-  type: string
-
-AccessibilityClient:
-  description: >
-    Accessibility client ID.
-  type: string
-
-AccessibilityInProcClient:
-  description: >
-    Hexadecimal mask of in-process accessibility consumers, see
-    accessible/windows/msaa/Compatibility.h for the mappings.
-  type: string
-
-ActualStreamLen:
-  description: >
-    Actual length of an IPC proxy stream.
-  type: integer
-
-AdapterDeviceID:
-  description: >
-    Graphics adapter name.
-  type: string
-
-AdapterDriverVersion:
-  description: >
-    Graphics adapter driver version.
-  type: string
-
-AdapterSubsysID:
-  description: >
-    Graphics adapter subsystem ID.
-  type: string
-
-AdapterVendorID:
-  description: >
-    Graphics adapter vendor name.
-  type: string
-
-additional_minidumps:
-  description: >
-    Comma separated list of additional minidumps for this crash, each element
-    in the list represent the suffix used in the dump filename. E.g. the
-    "browser" entry for crash fa909194-737b-4b93-b8da-da110ac785e0 implies the
-    existence of the fa909194-737b-4b93-b8da-da110ac785e0-browser.dmp file.
-  type: string
-
-Addons:
-  description: >
-    List of currently enabled add-ons.
-  type: string
-  altname: Add-ons
-
-AppInitDLLs:
-  description: >
-    List of DLLs loaded when launching any application on Windows, this
-    reflects the contents of the AppInit_DLLs registry key.
-  type: string
-
-AsyncShutdownModule:
-  description: >
-    Holds the contents of the AsyncShutdown.js script
-  type: string
-
-AsyncShutdownTimeout:
-  description: >
-    This annotation is present if a shutdown blocker was not released in time
-    and the browser was crashed instead of waiting for shutdown to finish. The
-    condition that caused the hang is contained in the annotation.
-  type: string
-  ping: true
-
-AvailablePageFile:
-  description: >
-    Windows-only, maximum amount of memory that can be committed.  This
-    annotation is populated with the contents of the MEMORYSTATUSEX's structure
-    ullAvailPageFile field.
-  type: string
-  ping: true
-
-AvailablePhysicalMemory:
-  description: >
-    Windows-only, amount of free physical memory in bytes. This annotation
-    is populated with the contents of the MEMORYSTATUSEX's structure
-    ullAvailPhys field.
-  type: string
-  ping: true
-
-AvailableVirtualMemory:
-  description: >
-    Windows-only, amount of free virtual memory in bytes. This annotation is
-    populated with the contents of the MEMORYSTATUSEX's structure
-    ullAvailVirtual field.
-  type: string
-  ping: true
-
-BIOS_Manufacturer:
-  description: >
-    Name of the BIOS manufacturer.
-  type: string
-
-BlockedDllList:
-  description: >
-    Comma-separated list of blocked DLLS, Windows-only
-  type: string
-  ping: true
-
-BlocklistInitFailed:
-  description: >
-    Set to 1 if the DLL blocklist could not be initialized.
-  type: boolean
-  ping: true
-
-BreakpadReserveAddress:
-  description: >
-    Address of the buffer reserved by Breakpad.
-  type: string
-
-BreakpadReserveSize:
-  description: >
-    Size of the buffer reserved by Breakpad.
-  type: string
-
-BuildID:
-  description: >
-    Application build ID, the format is YYYYMMDDHHMMSS.
-  type: string
-  ping: true
-
-ClassRegistrationInfoChild:
-  description: >
-    Microsoft COM class registration annotation for the child process.
-  type: string
-
-ClassRegistrationInfoParent:
-  description: >
-    Microsoft COM class registration annotation for the parent process.
-  type: string
-
-CoMarshalInterfaceFailure:
-  description: >
-    Annotation describing the error returned by trying to marshal an object
-    via CoMarshalInterface during the creation of an IPC proxy stream.
-  type: string
-
-ContainsMemoryReport:
-  description: >
-    Indicates that the crash dump contains a memory report.
-  type: boolean
-  ping: true
-
-ContentSandboxCapabilities:
-  description: >
-    List of capabilities of the content process sandbox.
-  type: string
-
-ContentSandboxEnabled:
-  description: >
-    Set to 1 when content process sandboxing is enabled.
-  type: boolean
-
-ContentSandboxCapable:
-  description: >
-    Set to 1 if the client is capable of content sandboxing.
-  type: boolean
-
-ContentSandboxLevel:
-  description: >
-    Content sandbox level.
-  type: integer
-
-CoUnmarshalInterfaceResult:
-  description: >
-    Annotation describing the error returned by trying to unmarshal an object
-    via CoUnmarshalInterface during the creation of an IPC proxy stream.
-  type: integer
-
-CPUMicrocodeVersion:
-  description: >
-    Version of the CPU microcode.
-  type: string
-
-CpuUsageFlashProcess1:
-  description: >
-    CPU usage of the first Adobe Flash plugin process.
-  type: string
-
-CpuUsageFlashProcess2:
-  description: >
-    CPU usage of the second Adobe Flash plugin process.
-  type: string
-
-CrashAddressLikelyWrong:
-  description: >
-    Set to 1 if signal handling is broken, in which case the crash address is
-    likely to be wrong.
-  type: boolean
-
-CrashTime:
-  description: >
-    Crash time in seconds since the Epoch.
-  type: string
-  ping: true
-
-CreateStreamOnHGlobalFailure:
-  description: >
-    Set when failing to obtain a global memory handle during the creation of an
-    IPC proxy stream.
-  type: string
-
-CycleCollector:
-  description: >
-    Reason why the cycle collector crashed.
-  type: string
-
-DeviceResetReason:
-  description: >
-    Reason why a DirectX device has been reset, Windows only.
-  type: string
-
-DOMIPCEnabled:
-  description: >
-    Set to 1 when a tab is running in a content process
-  type: boolean
-
-EMCheckCompatibility:
-  description: >
-    Set to 1 if add-on compatibility checking is enabled.
-  type: boolean
-
-EventLoopNestingLevel:
-  description: >
-    Present only if higher than 0, indicates that we're running in a nested
-    event loop and indicates the nesting level.
-  type: integer
-  ping: true
-
-ExpectedStreamLen:
-  description: >
-    Expected length of an IPC proxy stream.
-  type: integer
-
-FlashProcessDump:
-  description: >
-    Type of process the flash plugin is running in, can be either "Broker" or
-    "Sandbox".
-  type: string
-
-FramePoisonBase:
-  description: >
-    Base pointer of the memory area used for the poison value we place in freed
-    memory.
-  type: string
-  content: false
-
-FramePoisonSize:
-  description: >
-    Size of the memory area used for the poison value we place in freed
-    memory.
-  type: integer
-  content: false
-
-GetHGlobalFromStreamFailure:
-  description: >
-    Error returned when invoking GetHGlobalFromStreamFailure() during the
-    creation of an IPC stream proxy.
-  type: string
-
-GMPLibraryPath:
-  description: >
-    Holds the path to the GMP plugin library.
-  type: string
-
-GMPPlugin:
-  description: >
-    Set to 1 if the GMP plugin is enabled.
-  type: boolean
-
-GPUProcessLaunchCount:
-  description: >
-    Number of times the GPU process was launched.
-  type: integer
-
-GPUProcessStatus:
-  description: >
-    Status of the GPU process, can be set to "Running" or "Destroyed"
-  type: string
-
-GraphicsCriticalError:
-  description: >
-    Information of a critical error that occurred within the graphics code.
-  type: string
-
-GraphicsSanityTest:
-  description: >
-    Annotation used in tests.
-  type: string
-
-GraphicsStartupTest:
-  description: >
-    Set to 1 by the graphics driver crash guard when it's activated.
-  type: boolean
-
-HangMonitorDescription:
-  description: >
-    Name of the hang monitor that generated the crash.
-  type: string
-
-HasDeviceTouchScreen:
-  description: >
-    Set to 1 if the device had a touch-screen, this only applies to Firefox
-    desktop as on mobile devices we assume a touch-screen is always present.
-  type: boolean
-
-IAccessibleConfig:
-  description: >
-    Set when something is seriously wrong with the IAccessible configuration in
-    the computer's registry. The value is always set to "NoSystemTypeLibOrPS"
-  type: string
-
-InstallTime:
-  description: >
-    The time when Firefox was installed expressed as seconds since the Epoch
-  type: integer
-
-InterfaceRegistrationInfoChild:
-  description: >
-    Microsoft COM interface registration annotation for the child process.
-  type: string
-
-InterfaceRegistrationInfoParent:
-  description: >
-    Microsoft COM interface registration annotation for the parent process.
-  type: string
-
-ipc_channel_error:
-  description: >
-    Set before a content process crashes because of an IPC channel error, holds
-    a description of the error.
-  type: string
-  ping: true
-
-IpcCreateEndpointsNsresult:
-  description: >
-    errno value retrieved after failing to create an IPC transport object.
-  type: integer
-
-IpcCreatePipeCloExecErrno:
-  description: >
-    errno value retrieved after failing to set the O_CLOEXEC flag on a pipe
-    used for IPC.
-  type: integer
-
-IpcCreatePipeFcntlErrno:
-  description: >
-    errno value retrieved after a call to fcntl() on a pipe used for IPC failed.
-  type: integer
-
-IpcCreatePipeSocketPairErrno:
-  description: >
-    errno value retrieved after a socketpair() call failed while creating an IPC
-    transport object.
-  type: integer
-
-IpcCreateTransportDupErrno:
-  description: >
-    errno value retrieved after a dup() call failed while creating an IPC
-    transport object.
-  type: integer
-
-IPCFatalErrorMsg:
-  description: >
-    Describes a fatal error that occurred during IPC operation.
-  type: string
-
-IPCFatalErrorProtocol:
-  description: >
-    Name of the protocol used by IPC when a fatal error occurred.
-  type: string
-
-IPCMessageName:
-  description: >
-    Name of the IPC message that caused a crash because it was too large.
-  type: string
-
-IPCMessageSize:
-  description: >
-    Size of the IPC message that caused a crash because it was too large.
-  type: integer
-
-IPCReadErrorReason:
-  description: >
-    Reason why reading an object via IPC failed.
-  type: string
-
-IPCShutdownState:
-  description: >
-    IPC shutdown state, can be set to either "RecvShutdown" or
-    "SendFinishShutdown" by a content process while it's shutting down.
-  type: string
-
-IPCSystemError:
-  description: >
-    Description of the last system error that occurred during IPC operation.
-  type: string
-
-IPCTransportFailureReason:
-  description: >
-    Reason why creating an IPC channel failed.
-  type: string
-
-IsGarbageCollecting:
-  description: >
-    If true then the JavaScript garbage collector was running when the crash
-    occurred.
-  type: boolean
-  ping: true
-
-JavaStackTrace:
-  description: >
-    Java stack trace, only present on Firefox for Android if we encounter an
-    uncaught Java exception.
-  type: string
-
-JSLargeAllocationFailure:
-  description: >
-    A large allocation couldn't be satisfied, check the JSOutOfMemory
-    description for the possible values of this annotation.
-  type: string
-
-JSOutOfMemory:
-  description: >
-    A small allocation couldn't be satisfied, the annotation may contain the
-    "Reporting", "Reported" or "Recovered" value. The first one means that
-    we crashed while responding to the OOM condition (possibly while running a
-    memory-pressure observers), the second that we crashed after having tried to
-    free some memory, and the last that the GC had managed to free enough memory
-    to satisfy the allocation.
-  type: string
-
-LowCommitSpaceEvents:
-  description: >
-    Number of times the available memory tracker has detected a that
-    commit-space was running low. This is a Windows-specific annotation.
-  type: integer
-  ping: true
-
-MarshalActCtxManifestPath:
-  description: >
-    Proxy stream marshalling current activation context manifest path.
-  type: string
-
-MozCrashReason:
-  description: >
-    Plaintext description of why Firefox crashed, this is usually set by
-    assertions and the like.
-  type: string
-  ping: true
-
-Notes:
-  description: >
-    Miscellaneous notes that can be appended to a crash.
-  type: string
-
-nsAsyncShutdownComponent:
-  description: >
-    Holds the contents of the nsAsyncShutdown.js script
-  type: string
-
-NumberOfProcessors:
-  description: >
-    Number of logical processors in the system.
-  type: integer
-
-OOMAllocationSize:
-  description: >
-    Size of the allocation that caused an out-of-memory condition.
-  type: string
-  ping: true
-
-PluginCpuUsage:
-  description: >
-    CPU usage of the plugin process.
-  type: string
-
-PluginFilename:
-  description: >
-    Plugin filename, only the process holding the plugin has this annotation.
-  type: string
-
-PluginHang:
-  description: >
-    The presence of this annotation indicates that this crash was generated in
-    response to a plugin hanging.
-  type: boolean
-
-PluginHangUIDuration:
-  description: >
-    Duration in milliseconds of the plugin hang that caused this crash.
-  type: integer
-
-PluginName:
-  description: >
-    Display name of a plugin, only the process holding the plugin has this
-    annotation.
-  type: string
-
-PluginVersion:
-  description: >
-    Version of a plugin, only the process holding the plugin has this
-    annotation.
-  type: string
-
-ProcessType:
-  description: >
-    Type of the process that crashed, can hold the values "content", "plugin" or
-    "gpu" currently.
-  type: string
-
-ProductName:
-  description: >
-    Application name (e.g. Firefox).
-  type: string
-  ping: true
-
-ProductID:
-  description: >
-    Application UUID (e.g. ec8030f7-c20a-464f-9b0e-13a3a9e97384).
-  type: string
-  ping: true
-
-ProxyStreamSize:
-  description: >
-    Size of an IPC proxy stream.
-  type: integer
-
-ProxyStreamSizeFrom:
-  description: >
-    Describes how the size of a proxy stream was obtained. It can be set to
-    either Stream::Stat or GlobalSize.
-  type: string
-
-ProxyStreamUnmarshalStatus:
-  description: >
-    Status of the proxy stream unmarshalling, see ipc/mscom/ProxyStream.cpp for
-    the various value this annotation can take.
-  type: string
-
-ProxyStreamValid:
-  description: >
-    Set to "false" when encountering an invalid IPC proxy stream.
-  type: string
-
-ReleaseChannel:
-  description: >
-    Application release channel (e.g. default, beta, ...)
-  type: string
-  ping: true
-
-RemoteType:
-  description: >
-    Type of the content process, can be set to "web", "file" or "extension".
-  type: string
-  ping: true
-
-SafeMode:
-  description: >
-    Set to 1 if the browser was started in safe mode.
-  type: boolean
-
-SecondsSinceLastCrash:
-  description: >
-    Time in seconds since the last crash occurred.
-  type: string
-  ping: true
-
-ServerURL:
-  description: >
-    URL used to post the crash report.
-  type: string
-
-SheetLoadFailure:
-  description: >
-    Set when failing to load a built-in style sheet. This can contain a
-    potentially very large amount of diagnostic information.
-  type: string
-
-ShutdownProgress:
-  description: >
-   Shutdown step at which the browser crashed, can be set to "quit-application",
-   "profile-change-teardown", "profile-before-change", "xpcom-will-shutdown" or
-   "xpcom-shutdown".
-  type: string
-  ping: true
-
-StartupCrash:
-  description: >
-    If set to 1 then this crash occurred during startup.
-  type: boolean
-  content: false
-  ping: true
-
-StartupTime:
-  description: >
-    The time when Firefox was launched expressed in seconds since the Epoch.
-  type: integer
-  content: false
-
-StatFailure:
-  description: >
-    Error returned when invoking IStream's Stat function during the creation
-    of an IPC proxy stream.
-  type: string
-
-StorageConnectionNotClosed:
-  description: >
-    This annotation is added when a mozStorage connection has not been properly
-    closed during shutdown. The annotation holds the filename of the database
-    associated with the connection.
-  type: string
-
-SystemMemoryUsePercentage:
-  description: >
-    Windows-only, percentage of physical memory in use. This annotation is
-    populated with the contents of the MEMORYSTATUSEX's structure dwMemoryLoad
-    field.
-  type: integer
-  ping: true
-
-TelemetryClientId:
-  description: >
-    Telemetry client ID.
-  type: string
-
-TelemetryEnvironment:
-  description: >
-    The telemetry environment in JSON format.
-  type: string
-
-TelemetryServerURL:
-  description: >
-    Telemetry server URL. Used to send main process crash pings directly from
-    the crashreporter client.
-  type: string
-
-TelemetrySessionId:
-  description: >
-    Telemetry session ID.
-  type: string
-
-TestKey:
-  description: >
-    Annotation used in tests.
-  type: string
-
-TestUnicode:
-  description: >
-    Annotation used in tests.
-  type: string
-
-TextureUsage:
-  description: >
-    Amount of memory in bytes consumed by textures.
-  type: string
-  ping: true
-
-ThreadIdNameMapping:
-  description: >
-    List of thread names with their corresponding thread IDs.
-  type: string
-
-TotalPageFile:
-  description: >
-    Windows-only, current committed memory limit. This annotation is
-    populated with the contents of the MEMORYSTATUSEX's structure
-    ullTotalPageFile field.
-  type: string
-  ping: true
-
-TotalPhysicalMemory:
-  description: >
-    Windows-only, amount of physical memory in bytes. This annotation is
-    populated with the contents of the MEMORYSTATUSEX's structure
-    ullTotalPhys field.
-  type: string
-  ping: true
-
-TotalVirtualMemory:
-  description: >
-    Windows-only, size of the virtual address space. This annotation is
-    populated with the contents of the MEMORYSTATUSEX's structure
-    ullTotalVirtual field.
-  type: string
-  ping: true
-
-UnknownNetAddrSocketFamily:
-  description: >
-    An unknown network address family was requested to Necko. The value is the
-    requested family number.
-  type: integer
-
-UnmarshalActCtx:
-  description: >
-    Proxy stream unmarshalling current activation context.
-  type: string
-
-UnmarshalActCtxManifestPath:
-  description: >
-    Proxy stream unmarshalling current activation context manifest path.
-  type: string
-
-UptimeTS:
-  description: >
-    Uptime in seconds. This annotation uses a string instead of an integer
-    because it has a fractional component.
-  type: string
-  ping: true
-
-URL:
-  description: >
-    URL being loaded.
-  type: string
-  content: false
-
-User32BeforeBlocklist:
-  description: >
-    Set to 1 if user32.dll was loaded before we could install the DLL blocklist.
-  type: boolean
-  ping: true
-
-useragent_locale:
-  description: >
-    User-agent locale.
-  type: string
-
-Vendor:
-  description: >
-    Application vendor (e.g. Mozilla).
-  type: string
-
-Version:
-  description: >
-    Product version.
-  type: string
-
-Winsock_LSP:
-  description: >
-    Information on winsock LSPs injected in our networking stack.
-  type: string
deleted file mode 100644
--- a/toolkit/crashreporter/CrashReporter.jsm.in
+++ /dev/null
@@ -1,45 +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/. */
-
-ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
-ChromeUtils.import("resource://gre/modules/Services.jsm");
-
-var EXPORTED_SYMBOLS = [
-  "CrashReporter"
-];
-
-var gCrashReporter = null;
-
-function getCrashReporter() {
-  if (!gCrashReporter) {
-    gCrashReporter = Cc["@mozilla.org/toolkit/crash-reporter;1"]
-                       .getService(Ci.nsICrashReporter);
-  }
-
-  if (AppConstants.MOZ_CRASHREPORTER && !gCrashReporter) {
-    throw new Error("The crash reporter is enabled but unavailable");
-  }
-
-  return gCrashReporter;
-}
-
-// ===================================
-// External API goes here
-var CrashReporter = {
-  addAnnotation(annotation, value) {
-    getCrashReporter().annotateCrashReport(annotation, value);
-  },
-
-  removeAnnotation(annotation) {
-    getCrashReporter().removeCrashReportAnnotation(annotation);
-  },
-
-  get enabled() {
-    return getCrashReporter().enabled;
-  },
-
-  annotations: {
-${annotations}
-  }
-};
--- a/toolkit/crashreporter/client/moz.build
+++ b/toolkit/crashreporter/client/moz.build
@@ -3,17 +3,16 @@
 # 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/.
 
 if CONFIG['OS_TARGET'] != 'Android':
     Program('crashreporter')
 
     UNIFIED_SOURCES += [
-        '../CrashAnnotations.cpp',
         'crashreporter.cpp',
         'ping.cpp',
     ]
 
     LOCAL_INCLUDES += [
         '/toolkit/components/jsoncpp/include',
     ]
 
--- a/toolkit/crashreporter/client/ping.cpp
+++ b/toolkit/crashreporter/client/ping.cpp
@@ -15,18 +15,16 @@
 #elif defined(XP_MACOSX)
 #include <CoreFoundation/CoreFoundation.h>
 #elif defined(XP_WIN)
 #include <objbase.h>
 #endif
 
 #include "json/json.h"
 
-#include "CrashAnnotations.h"
-
 using std::string;
 
 namespace CrashReporter {
 
 struct UUID {
     uint32_t m0;
     uint16_t m1;
     uint16_t m2;
@@ -117,25 +115,55 @@ const char kTelemetryUrl[]       = "Tele
 const char kTelemetrySessionId[] = "TelemetrySessionId";
 const int  kTelemetryVersion     = 4;
 
 // Create the payload.metadata node of the crash ping using fields extracted
 // from the .extra file
 static Json::Value
 CreateMetadataNode(StringTable& strings)
 {
+  // The following list should be kept in sync with the one in CrashManager.jsm
+  const char *entries[] = {
+    "AsyncShutdownTimeout",
+    "AvailablePageFile",
+    "AvailablePhysicalMemory",
+    "AvailableVirtualMemory",
+    "BlockedDllList",
+    "BlocklistInitFailed",
+    "BuildID",
+    "ContainsMemoryReport",
+    "CrashTime",
+    "EventLoopNestingLevel",
+    "ipc_channel_error",
+    "IsGarbageCollecting",
+    "LowCommitSpaceEvents",
+    "MozCrashReason",
+    "OOMAllocationSize",
+    "ProductID",
+    "ProductName",
+    "ReleaseChannel",
+    "RemoteType",
+    "SecondsSinceLastCrash",
+    "ShutdownProgress",
+    "StartupCrash",
+    "SystemMemoryUsePercentage",
+    "TextureUsage",
+    "TotalPageFile",
+    "TotalPhysicalMemory",
+    "TotalVirtualMemory",
+    "UptimeTS",
+    "User32BeforeBlocklist",
+    "Version",
+  };
+
   Json::Value node;
 
-  for (auto line : strings) {
-    Annotation annotation;
-
-    if (AnnotationFromString(annotation, line.first.c_str())) {
-      if (IsAnnotationWhitelistedForPing(annotation)) {
-        node[line.first] = line.second;
-      }
+  for (auto entry : entries) {
+    if ((strings.find(entry) != strings.end()) && !strings[entry].empty()) {
+      node[entry] = strings[entry];
     }
   }
 
   return node;
 }
 
 // Create the payload node of the crash ping
 static Json::Value
deleted file mode 100644
--- a/toolkit/crashreporter/generate_crash_reporter_sources.py
+++ /dev/null
@@ -1,241 +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 string
-import sys
-import textwrap
-import yaml
-
-###############################################################################
-# Language-agnostic functionality                                             #
-###############################################################################
-
-template_header = "/* This file was autogenerated by " \
-  "toolkit/crashreporter/generate_crash_reporter_sources.py. DO NOT EDIT */\n\n"
-
-
-def validate_annotations(annotations):
-    """ Ensure that the annotations have all the required fields """
-
-    for (name, data) in sorted(annotations.items()):
-        if "description" not in data:
-            print("Annotation " + name + " does not have a description\n")
-            sys.exit(1)
-        if "type" not in data:
-            print("Annotation " + name + " does not have a type\n")
-            sys.exit(1)
-        else:
-            annotation_type = data.get("type")
-            valid_types = ["boolean", "integer", "string"]
-            if not any(annotation_type == t for t in valid_types):
-                print("Annotation " + name + " has an unknown type: " + annotation_type + "\n")
-                sys.exit(1)
-
-
-def read_annotations(annotations_filename):
-    """Read the annotations from a YAML file.
-    If an error is encountered quit the program."""
-
-    try:
-        with open(annotations_filename, "r") as annotations_file:
-            annotations = yaml.safe_load(annotations_file)
-    except (IOError, ValueError) as e:
-        print("Error parsing " + annotations_filename + ":\n" + str(e) + "\n")
-        sys.exit(1)
-
-    validate_annotations(annotations)
-
-    return annotations
-
-
-def read_template(template_filename):
-    """Read the contents of the template.
-    If an error is encountered quit the program."""
-
-    try:
-        with open(template_filename, "r") as template_file:
-            template = template_file.read()
-    except IOError as ex:
-        print("Error when reading " + template_filename + ":\n" + str(ex) + "\n")
-        sys.exit(1)
-
-    return template
-
-
-def extract_crash_ping_whitelist(annotations):
-    """Extract an array holding the names of the annotations whitelisted for
-    inclusion in the crash ping."""
-
-    return [name
-            for (name, data)
-            in sorted(annotations.items())
-            if data.get("ping", False)]
-
-
-def extract_content_process_blacklist(annotations):
-    """Extract an array holding the names of the annotations blacklisted when
-    read from a content process."""
-
-    return [name
-            for (name, data)
-            in sorted(annotations.items())
-            if not data.get("content", True)]
-
-###############################################################################
-# C++ code generation                                                         #
-###############################################################################
-
-
-def generate_strings(annotations):
-    """Generate strings corresponding to every annotation."""
-
-    names = ["  \"" + data.get("altname", name) + "\""
-             for (name, data)
-             in sorted(annotations.items())]
-
-    return ",\n".join(names)
-
-
-def generate_enum(annotations):
-    """Generate the C++ typed enum holding all the annotations and return it
-    as a string."""
-
-    enum = ""
-
-    for i, (name, _) in enumerate(sorted(annotations.items())):
-        enum += "  " + name + " = " + str(i) + ",\n"
-
-    enum += "  Count = " + str(len(annotations))
-
-    return enum
-
-
-def generate_array_initializer(contents):
-    """Generates the initializer for a C++ array of annotations."""
-
-    initializer = ["  Annotation::" + name for name in contents]
-
-    return ",\n".join(initializer)
-
-
-def generate_header(template, annotations):
-    """Generate a header by filling the template with the the list of
-    annotations and return it as a string."""
-
-    whitelist = extract_crash_ping_whitelist(annotations)
-    blacklist = extract_content_process_blacklist(annotations)
-
-    return template_header + string.Template(template).substitute({
-               "enum": generate_enum(annotations),
-               "strings": generate_strings(annotations),
-               "whitelist": generate_array_initializer(whitelist),
-               "blacklist": generate_array_initializer(blacklist),
-           })
-
-
-def emit_header(output, template_filename, annotations_filename):
-    """Generate the C++ header from the template and write it out."""
-
-    annotations = read_annotations(annotations_filename)
-    template = read_template(template_filename)
-    generated_header = generate_header(template, annotations)
-
-    try:
-        output.write(generated_header)
-    except IOError as ex:
-        print("Error while writing out the generated file:\n" + str(ex) + "\n")
-        sys.exit(1)
-
-###############################################################################
-# JavaScript code generation                                                  #
-###############################################################################
-
-
-def generate_annotations_fields(annotations):
-    """Generate the list of JS fields corresponding to the annotations and
-    return it as a string."""
-
-    constants = []
-
-    for i, (name, _) in enumerate(sorted(annotations.items())):
-        constants.append("    " + name + ": " + str(i + 1) + ",")
-
-    return "\n".join(constants)
-
-
-def generate_jsm(template, annotations):
-    """Generate the CrashReporter.jsm module by filling the template with the
-    the list of annotations and return it as a string."""
-
-    annotations_list = generate_annotations_fields(annotations)
-
-    return template_header + string.Template(template).substitute({
-               "annotations": annotations_list,
-           })
-
-
-def emit_jsm(output, template_filename, annotations_filename):
-    """Generate the CrashReporter.jsm module."""
-
-    annotations = read_annotations(annotations_filename)
-    template = read_template(template_filename)
-    generated_jsm = generate_jsm(template, annotations)
-
-    try:
-        output.write(generated_jsm)
-    except IOError as ex:
-        print("Error while writing out the generated file:\n" + str(ex) + "\n")
-        sys.exit(1)
-
-###############################################################################
-# Java code generation                                                        #
-###############################################################################
-
-
-def generate_java_array_initializer(contents):
-    """Generates the initializer for an array of strings.
-    Effectively turns `["a", "b"]` into '   \"a\",\n   \"b\"\n'."""
-
-    initializer = ""
-
-    for name in contents:
-        initializer += "        \"" + name + "\",\n"
-
-    return initializer.strip(",\n")
-
-
-def generate_class(template, annotations):
-    """Fill the class template from the list of annotations."""
-
-    whitelist = extract_crash_ping_whitelist(annotations)
-
-    return template_header + string.Template(template).substitute({
-               "whitelist": generate_java_array_initializer(whitelist),
-           })
-
-
-def emit_class(output, annotations_filename):
-    """Generate the CrashReporterConstants.java file."""
-
-    template = textwrap.dedent("""\
-    package org.mozilla.gecko;
-
-    /**
-     * Constants used by the crash reporter. These are generated so that they
-     * are kept in sync with the other C++ and JS users.
-     */
-    public class CrashReporterConstants {
-        public static final String[] ANNOTATION_WHITELIST = {
-    ${whitelist}
-        };
-    }""")
-
-    annotations = read_annotations(annotations_filename)
-    generated_class = generate_class(template, annotations)
-
-    try:
-        output.write(generated_class)
-    except IOError as ex:
-        print("Error while writing out the generated file:\n" + str(ex) + "\n")
-        sys.exit(1)
--- a/toolkit/crashreporter/moz.build
+++ b/toolkit/crashreporter/moz.build
@@ -4,34 +4,23 @@
 # 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/.
 
 SPHINX_TREES['crashreporter'] = 'docs'
 
 with Files('docs/**'):
     SCHEDULES.exclusive = ['docs']
 
-GENERATED_FILES += [
-    'CrashAnnotations.h',
-    'CrashReporter.jsm',
-]
-
 EXPORTS += [
-    '!CrashAnnotations.h',
     'nsExceptionHandler.h',
 ]
 
-EXTRA_JS_MODULES += [
-    '!CrashReporter.jsm',
-]
-
 JAR_MANIFESTS += ['jar.mn']
 
 UNIFIED_SOURCES = [
-    'CrashAnnotations.cpp',
     'nsExceptionHandlerUtils.cpp',
 ]
 
 FINAL_LIBRARY = 'xul'
 
 if CONFIG['MOZ_CRASHREPORTER']:
     if CONFIG['OS_ARCH'] == 'WINNT':
         DIRS += [
@@ -131,26 +120,11 @@ if CONFIG['MOZ_CRASHREPORTER']:
 
     if CONFIG['CC_TYPE'] in ('clang', 'gcc'):
         CXXFLAGS += ['-Wno-shadow']
 else:
     UNIFIED_SOURCES += [
         'nsDummyExceptionHandler.cpp',
     ]
 
-# Generate CrashAnnotations.h
-crash_annotations = GENERATED_FILES['CrashAnnotations.h']
-crash_annotations.script = 'generate_crash_reporter_sources.py:emit_header'
-crash_annotations.inputs = [
-    'CrashAnnotations.h.in',
-    'CrashAnnotations.yaml',
-]
-
-# Generate CrashReporter.jsm
-crash_reporter_jsm = GENERATED_FILES['CrashReporter.jsm']
-crash_reporter_jsm.script = 'generate_crash_reporter_sources.py:emit_jsm'
-crash_reporter_jsm.inputs = [
-    'CrashReporter.jsm.in',
-    'CrashAnnotations.yaml',
-]
 
 with Files('**'):
     BUG_COMPONENT = ('Toolkit', 'Crash Reporting')
--- a/toolkit/crashreporter/nsDummyExceptionHandler.cpp
+++ b/toolkit/crashreporter/nsDummyExceptionHandler.cpp
@@ -61,41 +61,24 @@ SetupExtraData(nsIFile* aAppDataDirector
 
 nsresult
 UnsetExceptionHandler()
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 nsresult
-AnnotateCrashReport(Annotation key, bool data)
-{
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-nsresult
-AnnotateCrashReport(Annotation key, int data)
+AnnotateCrashReport(const nsACString& key,
+                    const nsACString& data)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 nsresult
-AnnotateCrashReport(Annotation key, unsigned int data)
-{
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-nsresult
-AnnotateCrashReport(Annotation key, const nsACString& data)
-{
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-nsresult
-RemoveCrashReportAnnotation(Annotation key)
+RemoveCrashReportAnnotation(const nsACString& key)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 nsresult
 SetGarbageCollecting(bool collecting)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
--- a/toolkit/crashreporter/nsExceptionHandler.cpp
+++ b/toolkit/crashreporter/nsExceptionHandler.cpp
@@ -7,17 +7,16 @@
 #include "nsExceptionHandler.h"
 #include "nsExceptionHandlerUtils.h"
 
 #include "nsAppDirectoryServiceDefs.h"
 #include "nsDirectoryServiceDefs.h"
 #include "nsDirectoryService.h"
 #include "nsDataHashtable.h"
 #include "mozilla/ArrayUtils.h"
-#include "mozilla/EnumeratedRange.h"
 #include "mozilla/Services.h"
 #include "nsIObserverService.h"
 #include "mozilla/Unused.h"
 #include "mozilla/Printf.h"
 #include "mozilla/Sprintf.h"
 #include "mozilla/SyncRunnable.h"
 #include "mozilla/TimeStamp.h"
 #include "mozilla/ipc/CrashReporterClient.h"
@@ -229,17 +228,17 @@ static const char* androidStartServiceCo
 // After targeting API 26 (Oreo) we ned to use a JobIntentService for the background
 // work regarding crash reporting. That Service needs a unique Job Id.
 static const char* androidCrashReporterJobId = nullptr;
 #endif
 
 // this holds additional data sent via the API
 static Mutex* crashReporterAPILock;
 static Mutex* notesFieldLock;
-static AnnotationTable crashReporterAPIData_Table;
+static AnnotationTable* crashReporterAPIData_Hash;
 static nsCString* crashReporterAPIData = nullptr;
 static nsCString* crashEventAPIData = nullptr;
 static nsCString* notesField = nullptr;
 static bool isGarbageCollecting;
 static uint32_t eventloopNestingLevel = 0;
 
 // Avoid a race during application termination.
 static Mutex* dumpSafetyLock;
@@ -320,16 +319,25 @@ public:
 
   NS_IMETHOD Run() override;
 
 private:
   uint32_t mPID;
 };
 #endif // MOZ_CRASHREPORTER_INJECTOR
 
+// Crashreporter annotations that we don't send along in subprocess reports.
+static const char* kSubprocessBlacklist[] = {
+  "FramePoisonBase",
+  "FramePoisonSize",
+  "StartupCrash",
+  "StartupTime",
+  "URL"
+};
+
 // If annotations are attempted before the crash reporter is enabled,
 // they queue up here.
 class DelayedNote;
 nsTArray<nsAutoPtr<DelayedNote> >* gDelayedAnnotations;
 
 #if defined(XP_WIN)
 // the following are used to prevent other DLLs reverting the last chance
 // exception handler to the windows default. Any attempt to change the
@@ -666,26 +674,23 @@ WriteString(PlatformWriter& pw, const ch
   size_t len = my_strlen(str);
 #else
   size_t len = strlen(str);
 #endif
 
   pw.WriteBuffer(str, len);
 }
 
+template<int N>
 static void
-WriteAnnotation(PlatformWriter& pw, const Annotation name,
-                const char* value, size_t len = 0) {
-  WriteString(pw, AnnotationToString(name));
+WriteAnnotation(PlatformWriter& pw, const char (&name)[N],
+                const char* value) {
+  WriteLiteral(pw, name);
   WriteLiteral(pw, "=");
-  if (len == 0) {
-    WriteString(pw, value);
-  } else {
-    pw.WriteBuffer(value, len);
-  }
+  WriteString(pw, value);
   WriteLiteral(pw, "\n");
 };
 
 /**
  * If minidump_id is null, we assume that dump_path contains the full
  * dump file path.
  */
 static void
@@ -727,28 +732,23 @@ WriteGlobalMemoryStatus(PlatformWriter* 
     conversionFunc(statex.field, buffer, 10);                  \
     if (apiData) {                                             \
       WriteAnnotation(*apiData, name, buffer);                  \
     }                                                          \
     if (eventFile) {                                           \
       WriteAnnotation(*eventFile, name, buffer);                \
     }
 
-    WRITE_STATEX_FIELD(dwMemoryLoad, Annotation::SystemMemoryUsePercentage,
-                       ltoa);
-    WRITE_STATEX_FIELD(ullTotalVirtual, Annotation::TotalVirtualMemory,
-                       _ui64toa);
-    WRITE_STATEX_FIELD(ullAvailVirtual, Annotation::AvailableVirtualMemory,
-                       _ui64toa);
-    WRITE_STATEX_FIELD(ullTotalPageFile, Annotation::TotalPageFile, _ui64toa);
-    WRITE_STATEX_FIELD(ullAvailPageFile, Annotation::AvailablePageFile,
-                       _ui64toa);
-    WRITE_STATEX_FIELD(ullTotalPhys, Annotation::TotalPhysicalMemory, _ui64toa);
-    WRITE_STATEX_FIELD(ullAvailPhys, Annotation::AvailablePhysicalMemory,
-                       _ui64toa);
+    WRITE_STATEX_FIELD(dwMemoryLoad, "SystemMemoryUsePercentage", ltoa);
+    WRITE_STATEX_FIELD(ullTotalVirtual, "TotalVirtualMemory", _ui64toa);
+    WRITE_STATEX_FIELD(ullAvailVirtual, "AvailableVirtualMemory", _ui64toa);
+    WRITE_STATEX_FIELD(ullTotalPageFile, "TotalPageFile", _ui64toa);
+    WRITE_STATEX_FIELD(ullAvailPageFile, "AvailablePageFile", _ui64toa);
+    WRITE_STATEX_FIELD(ullTotalPhys, "TotalPhysicalMemory", _ui64toa);
+    WRITE_STATEX_FIELD(ullAvailPhys, "AvailablePhysicalMemory", _ui64toa);
 
 #undef WRITE_STATEX_FIELD
   }
 }
 #endif
 
 #if !defined(MOZ_WIDGET_ANDROID)
 
@@ -1030,99 +1030,101 @@ MinidumpCallback(
       OpenAPIData(apiData, descriptor.path());
 #else
       OpenAPIData(apiData, dump_path, minidump_id);
 #endif
       apiData.WriteBuffer(crashReporterAPIData->get(), crashReporterAPIData->Length());
     }
 
     if (currentSessionId) {
-      WriteAnnotation(apiData, Annotation::TelemetrySessionId,
-                      currentSessionId);
-      WriteAnnotation(eventFile, Annotation::TelemetrySessionId,
-                      currentSessionId);
+      WriteAnnotation(apiData, "TelemetrySessionId", currentSessionId);
+      WriteAnnotation(eventFile, "TelemetrySessionId", currentSessionId);
     }
 
-    WriteAnnotation(apiData, Annotation::CrashTime, crashTimeString);
-    WriteAnnotation(eventFile, Annotation::CrashTime, crashTimeString);
-
-    WriteAnnotation(apiData, Annotation::UptimeTS, uptimeTSString);
-    WriteAnnotation(eventFile, Annotation::UptimeTS, uptimeTSString);
+    WriteAnnotation(apiData, "CrashTime", crashTimeString);
+    WriteAnnotation(eventFile, "CrashTime", crashTimeString);
+
+    WriteAnnotation(apiData, "UptimeTS", uptimeTSString);
+    WriteAnnotation(eventFile, "UptimeTS", uptimeTSString);
 
     if (timeSinceLastCrash != 0) {
-      WriteAnnotation(apiData, Annotation::SecondsSinceLastCrash,
+      WriteAnnotation(apiData, "SecondsSinceLastCrash",
                       timeSinceLastCrashString);
-      WriteAnnotation(eventFile, Annotation::SecondsSinceLastCrash,
+      WriteAnnotation(eventFile, "SecondsSinceLastCrash",
                       timeSinceLastCrashString);
     }
     if (isGarbageCollecting) {
-      WriteAnnotation(apiData, Annotation::IsGarbageCollecting, "1");
-      WriteAnnotation(eventFile, Annotation::IsGarbageCollecting, "1");
+      WriteAnnotation(apiData, "IsGarbageCollecting", "1");
+      WriteAnnotation(eventFile, "IsGarbageCollecting", "1");
     }
 
     char buffer[128];
 
     if (eventloopNestingLevel > 0) {
       XP_STOA(eventloopNestingLevel, buffer, 10);
-      WriteAnnotation(apiData, Annotation::EventLoopNestingLevel, buffer);
-      WriteAnnotation(eventFile, Annotation::EventLoopNestingLevel, buffer);
+      WriteAnnotation(apiData, "EventLoopNestingLevel", buffer);
+      WriteAnnotation(eventFile, "EventLoopNestingLevel", buffer);
     }
 
 #ifdef XP_WIN
     if (gBreakpadReservedVM) {
       _ui64toa(uintptr_t(gBreakpadReservedVM), buffer, 10);
-      WriteAnnotation(apiData, Annotation::BreakpadReserveAddress, buffer);
+      WriteAnnotation(apiData, "BreakpadReserveAddress", buffer);
       _ui64toa(kReserveSize, buffer, 10);
-      WriteAnnotation(apiData, Annotation::BreakpadReserveSize, buffer);
+      WriteAnnotation(apiData, "BreakpadReserveSize", buffer);
     }
 
 #ifdef HAS_DLL_BLOCKLIST
     if (apiData.Valid()) {
       DllBlocklist_WriteNotes(apiData.Handle());
       DllBlocklist_WriteNotes(eventFile.Handle());
     }
 #endif
     WriteGlobalMemoryStatus(&apiData, &eventFile);
 #endif // XP_WIN
 
     char* rust_panic_reason;
     size_t rust_panic_len;
     if (get_rust_panic_reason(&rust_panic_reason, &rust_panic_len)) {
       // rust_panic_reason is not null-terminated.
-      WriteAnnotation(apiData, Annotation::MozCrashReason, rust_panic_reason,
-                      rust_panic_len);
-      WriteAnnotation(eventFile, Annotation::MozCrashReason, rust_panic_reason,
-                      rust_panic_len);
+      WriteLiteral(apiData, "MozCrashReason=");
+      apiData.WriteBuffer(rust_panic_reason, rust_panic_len);
+      WriteLiteral(apiData, "\n");
+      WriteLiteral(eventFile, "MozCrashReason=");
+      eventFile.WriteBuffer(rust_panic_reason, rust_panic_len);
+      WriteLiteral(eventFile, "\n");
     } else if (gMozCrashReason) {
-      WriteAnnotation(apiData, Annotation::MozCrashReason, gMozCrashReason);
-      WriteAnnotation(eventFile, Annotation::MozCrashReason, gMozCrashReason);
+      WriteAnnotation(apiData, "MozCrashReason", gMozCrashReason);
+      WriteAnnotation(eventFile, "MozCrashReason", gMozCrashReason);
     }
 
     if (oomAllocationSizeBuffer[0]) {
-      WriteAnnotation(apiData, Annotation::OOMAllocationSize,
-                      oomAllocationSizeBuffer);
-      WriteAnnotation(eventFile, Annotation::OOMAllocationSize,
-                      oomAllocationSizeBuffer);
+      WriteAnnotation(apiData, "OOMAllocationSize", oomAllocationSizeBuffer);
+      WriteAnnotation(eventFile, "OOMAllocationSize", oomAllocationSizeBuffer);
     }
 
     if (texturesSizeBuffer[0]) {
-      WriteAnnotation(apiData, Annotation::TextureUsage, texturesSizeBuffer);
-      WriteAnnotation(eventFile, Annotation::TextureUsage, texturesSizeBuffer);
+      WriteAnnotation(apiData, "TextureUsage", texturesSizeBuffer);
+      WriteAnnotation(eventFile, "TextureUsage", texturesSizeBuffer);
     }
 
     if (memoryReportPath) {
-      WriteAnnotation(apiData, Annotation::ContainsMemoryReport, "1");
-      WriteAnnotation(eventFile, Annotation::ContainsMemoryReport, "1");
+      WriteLiteral(apiData, "ContainsMemoryReport=1\n");
+      WriteLiteral(eventFile, "ContainsMemoryReport=1\n");
     }
 
     std::function<void(const char*)> getThreadAnnotationCB =
-      [&] (const char* aValue) -> void {
-      if (aValue) {
-        WriteAnnotation(apiData, Annotation::ThreadIdNameMapping, aValue);
-        WriteAnnotation(eventFile, Annotation::ThreadIdNameMapping, aValue);
+      [&] (const char * aAnnotation) -> void {
+      if (aAnnotation) {
+        WriteLiteral(apiData, "ThreadIdNameMapping=");
+        WriteLiteral(eventFile, "ThreadIdNameMapping=");
+        WriteString(apiData, aAnnotation);
+        WriteString(eventFile, aAnnotation);
+        WriteLiteral(apiData, "\n");
+        WriteLiteral(eventFile, "\n");
       }
     };
     GetFlatThreadAnnotation(getThreadAnnotationCB, false);
   }
 
   if (!doReport) {
 #ifdef XP_WIN
     TerminateProcess(GetCurrentProcess(), 1);
@@ -1279,34 +1281,36 @@ PrepareChildExceptionTimeAnnotations(voi
 #endif
 
   char oomAllocationSizeBuffer[32] = "";
   if (gOOMAllocationSize) {
     XP_STOA(gOOMAllocationSize, oomAllocationSizeBuffer, 10);
   }
 
   if (oomAllocationSizeBuffer[0]) {
-    WriteAnnotation(apiData, Annotation::OOMAllocationSize,
-                    oomAllocationSizeBuffer);
+    WriteAnnotation(apiData, "OOMAllocationSize", oomAllocationSizeBuffer);
   }
 
   char* rust_panic_reason;
   size_t rust_panic_len;
   if (get_rust_panic_reason(&rust_panic_reason, &rust_panic_len)) {
     // rust_panic_reason is not null-terminated.
-    WriteAnnotation(apiData, Annotation::MozCrashReason, rust_panic_reason,
-                    rust_panic_len);
+    WriteLiteral(apiData, "MozCrashReason=");
+    apiData.WriteBuffer(rust_panic_reason, rust_panic_len);
+    WriteLiteral(apiData, "\n");
   } else if (gMozCrashReason) {
-    WriteAnnotation(apiData, Annotation::MozCrashReason, gMozCrashReason);
+    WriteAnnotation(apiData, "MozCrashReason", gMozCrashReason);
   }
 
   std::function<void(const char*)> getThreadAnnotationCB =
-    [&] (const char * aValue) -> void {
-    if (aValue) {
-      WriteAnnotation(apiData, Annotation::ThreadIdNameMapping, aValue);
+    [&] (const char * aAnnotation) -> void {
+    if (aAnnotation) {
+      WriteLiteral(apiData, "ThreadIdNameMapping=");
+      WriteString(apiData, aAnnotation);
+      WriteLiteral(apiData, "\n");
     }
   };
   GetFlatThreadAnnotation(getThreadAnnotationCB, true);
 }
 
 #ifdef XP_WIN
 static void
 ReserveBreakpadVM()
@@ -1499,16 +1503,20 @@ nsresult SetExceptionHandler(nsIFile* aX
   crashReporterAPIData = new nsCString();
   crashEventAPIData = new nsCString();
 
   NS_ASSERTION(!crashReporterAPILock, "Shouldn't have a lock yet");
   crashReporterAPILock = new Mutex("crashReporterAPILock");
   NS_ASSERTION(!notesFieldLock, "Shouldn't have a lock yet");
   notesFieldLock = new Mutex("notesFieldLock");
 
+  crashReporterAPIData_Hash =
+    new nsDataHashtable<nsCStringHashKey,nsCString>();
+  NS_ENSURE_TRUE(crashReporterAPIData_Hash, NS_ERROR_OUT_OF_MEMORY);
+
   notesField = new nsCString();
   NS_ENSURE_TRUE(notesField, NS_ERROR_OUT_OF_MEMORY);
 
 #if !defined(MOZ_WIDGET_ANDROID)
   // Locate the crash reporter executable
   nsAutoString crashReporterPath_temp;
   nsresult rv = LocateExecutable(aXREDirectory,
                                  NS_LITERAL_CSTRING(CRASH_REPORTER_FILENAME),
@@ -1665,17 +1673,18 @@ nsresult SetExceptionHandler(nsIFile* aX
     printf_stderr ("SetUnhandledExceptionFilter hook failed; crash reporter is vulnerable.\n");
 #endif
 #endif
 
   // store application start time
   char timeString[32];
   time_t startupTime = time(nullptr);
   XP_TTOA(startupTime, timeString, 10);
-  AnnotateCrashReport(Annotation::StartupTime, nsDependentCString(timeString));
+  AnnotateCrashReport(NS_LITERAL_CSTRING("StartupTime"),
+                      nsDependentCString(timeString));
 
 #if defined(XP_MACOSX)
   // On OS X, many testers like to see the OS crash reporting dialog
   // since it offers immediate stack traces.  We allow them to set
   // a default to pass exceptions to the OS handler.
   Boolean keyExistsAndHasValidFormat = false;
   Boolean prefValue = ::CFPreferencesGetAppBooleanValue(CFSTR("OSCrashReporter"),
                                                         kCFPreferencesCurrentApplication,
@@ -1919,17 +1928,17 @@ nsresult SetupExtraData(nsIFile* aAppDat
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   nsAutoCString data;
   if(NS_SUCCEEDED(GetOrInit(dataDirectory,
                             NS_LITERAL_CSTRING("InstallTime") + aBuildID,
                             data, InitInstallTime)))
-    AnnotateCrashReport(Annotation::InstallTime, data);
+    AnnotateCrashReport(NS_LITERAL_CSTRING("InstallTime"), data);
 
   // this is a little different, since we can't init it with anything,
   // since it's stored at crash time, and we can't annotate the
   // crash report with the stored value, since we really want
   // (now - LastCrash), so we just get a value if it exists,
   // and store it in a time_t value.
   if(NS_SUCCEEDED(GetOrInit(dataDirectory, NS_LITERAL_CSTRING("LastCrash"),
                             data, nullptr))) {
@@ -1977,19 +1986,18 @@ nsresult UnsetExceptionHandler()
   // allow SetUnhandledExceptionFilter
   gBlockUnhandledExceptionFilter = false;
 #endif
 
   delete gExceptionHandler;
 
   // do this here in the unlikely case that we succeeded in allocating
   // our strings but failed to allocate gExceptionHandler.
-  std::fill(crashReporterAPIData_Table.begin(),
-            crashReporterAPIData_Table.end(),
-            EmptyCString());
+  delete crashReporterAPIData_Hash;
+  crashReporterAPIData_Hash = nullptr;
 
   delete crashReporterAPILock;
   crashReporterAPILock = nullptr;
 
   delete notesFieldLock;
   notesFieldLock = nullptr;
 
   delete crashReporterAPIData;
@@ -2066,18 +2074,22 @@ static void ReplaceChar(nsCString& str, 
 
     str.BeginReading(iter);
     iter.advance(pos + replacement.Length() - 1);
     str.EndReading(end);
   }
 }
 
 static nsresult
-EscapeAnnotation(const nsACString& data, nsCString& escapedData)
+EscapeAnnotation(const nsACString& key, const nsACString& data, nsCString& escapedData)
 {
+  if (FindInReadable(NS_LITERAL_CSTRING("="), key) ||
+      FindInReadable(NS_LITERAL_CSTRING("\n"), key))
+    return NS_ERROR_INVALID_ARG;
+
   if (FindInReadable(NS_LITERAL_CSTRING("\0"), data))
     return NS_ERROR_INVALID_ARG;
 
   escapedData = data;
 
   // escape backslashes
   ReplaceChar(escapedData, NS_LITERAL_CSTRING("\\"),
               NS_LITERAL_CSTRING("\\\\"));
@@ -2085,35 +2097,35 @@ EscapeAnnotation(const nsACString& data,
   ReplaceChar(escapedData, NS_LITERAL_CSTRING("\n"),
               NS_LITERAL_CSTRING("\\n"));
   return NS_OK;
 }
 
 class DelayedNote
 {
  public:
-  DelayedNote(Annotation aKey, const nsACString& aData)
-  : mKey(aKey), mData(aData), mType(CrashAnnotation) {}
+  DelayedNote(const nsACString& aKey, const nsACString& aData)
+  : mKey(aKey), mData(aData), mType(Annotation) {}
 
   explicit DelayedNote(const nsACString& aData)
   : mData(aData), mType(AppNote) {}
 
   void Run()
   {
-    if (mType == CrashAnnotation) {
+    if (mType == Annotation) {
       AnnotateCrashReport(mKey, mData);
     } else {
       AppendAppNotesToCrashReport(mData);
     }
   }
 
  private:
-  Annotation mKey;
+  nsCString mKey;
   nsCString mData;
-  enum AnnotationType { CrashAnnotation, AppNote } mType;
+  enum AnnotationType { Annotation, AppNote } mType;
 };
 
 static void
 EnqueueDelayedNote(DelayedNote* aNote)
 {
   if (!gDelayedAnnotations) {
     gDelayedAnnotations = new nsTArray<nsAutoPtr<DelayedNote> >();
   }
@@ -2127,88 +2139,66 @@ RunAndCleanUpDelayedNotes()
     for (nsAutoPtr<DelayedNote>& note : *gDelayedAnnotations) {
       note->Run();
     }
     delete gDelayedAnnotations;
     gDelayedAnnotations = nullptr;
   }
 }
 
-nsresult AnnotateCrashReport(Annotation key, bool data)
-{
-  return AnnotateCrashReport(key, data ? NS_LITERAL_CSTRING("1")
-                                       : NS_LITERAL_CSTRING("0"));
-}
-
-nsresult AnnotateCrashReport(Annotation key, int data)
-{
-  nsAutoCString dataString;
-  dataString.AppendInt(data);
-
-  return AnnotateCrashReport(key, dataString);
-}
-
-nsresult AnnotateCrashReport(Annotation key, unsigned int data)
-{
-  nsAutoCString dataString;
-  dataString.AppendInt(data);
-
-  return AnnotateCrashReport(key, dataString);
-}
-
-nsresult AnnotateCrashReport(Annotation key, const nsACString& data)
+nsresult AnnotateCrashReport(const nsACString& key, const nsACString& data)
 {
   if (!GetEnabled())
     return NS_ERROR_NOT_INITIALIZED;
 
   nsCString escapedData;
-  nsresult rv = EscapeAnnotation(data, escapedData);
+  nsresult rv = EscapeAnnotation(key, data, escapedData);
   if (NS_FAILED(rv))
     return rv;
 
   if (!XRE_IsParentProcess()) {
     // The newer CrashReporterClient can be used from any thread.
     if (RefPtr<CrashReporterClient> client = CrashReporterClient::GetSingleton()) {
-      client->AnnotateCrashReport(key, escapedData);
+      client->AnnotateCrashReport(nsCString(key), escapedData);
       return NS_OK;
     }
 
     // EnqueueDelayedNote() can only be called on the main thread.
     MOZ_RELEASE_ASSERT(NS_IsMainThread());
 
     EnqueueDelayedNote(new DelayedNote(key, data));
     return NS_OK;
   }
 
   MutexAutoLock lock(*crashReporterAPILock);
 
-  crashReporterAPIData_Table[key] = escapedData;
+  crashReporterAPIData_Hash->Put(key, escapedData);
 
   // now rebuild the file contents
   crashReporterAPIData->Truncate(0);
   crashEventAPIData->Truncate(0);
-  for (auto key : MakeEnumeratedRange(Annotation::Count)) {
-    nsDependentCString str(AnnotationToString(key));
-    nsCString entry = crashReporterAPIData_Table[key];
+  for (auto it = crashReporterAPIData_Hash->Iter(); !it.Done(); it.Next()) {
+    const nsACString& key = it.Key();
+    nsCString entry = it.Data();
     if (!entry.IsEmpty()) {
       NS_NAMED_LITERAL_CSTRING(kEquals, "=");
       NS_NAMED_LITERAL_CSTRING(kNewline, "\n");
-      nsAutoCString line = str + kEquals + entry + kNewline;
+      nsAutoCString line = key + kEquals + entry + kNewline;
 
       crashReporterAPIData->Append(line);
       crashEventAPIData->Append(line);
     }
   }
 
   return NS_OK;
 }
 
-nsresult RemoveCrashReportAnnotation(Annotation key)
+nsresult RemoveCrashReportAnnotation(const nsACString& key)
 {
-  return AnnotateCrashReport(key, EmptyCString());
+  return AnnotateCrashReport(key, NS_LITERAL_CSTRING(""));
 }
 
 nsresult SetGarbageCollecting(bool collecting)
 {
   if (!GetEnabled())
     return NS_ERROR_NOT_INITIALIZED;
 
   isGarbageCollecting = collecting;
@@ -2235,17 +2225,17 @@ nsresult AppendAppNotesToCrashReport(con
   if (FindInReadable(NS_LITERAL_CSTRING("\0"), data))
     return NS_ERROR_INVALID_ARG;
 
   if (!XRE_IsParentProcess()) {
     // Since we don't go through AnnotateCrashReport in the parent process,
     // we must ensure that the data is escaped and valid before the parent
     // sees it.
     nsCString escapedData;
-    nsresult rv = EscapeAnnotation(data, escapedData);
+    nsresult rv = EscapeAnnotation(NS_LITERAL_CSTRING("Notes"), data, escapedData);
     if (NS_FAILED(rv))
       return rv;
 
     if (RefPtr<CrashReporterClient> client = CrashReporterClient::GetSingleton()) {
       client->AppendAppNotes(escapedData);
       return NS_OK;
     }
 
@@ -2254,31 +2244,30 @@ nsresult AppendAppNotesToCrashReport(con
 
     EnqueueDelayedNote(new DelayedNote(data));
     return NS_OK;
   }
 
   MutexAutoLock lock(*notesFieldLock);
 
   notesField->Append(data);
-  return AnnotateCrashReport(Annotation::Notes, *notesField);
+  return AnnotateCrashReport(NS_LITERAL_CSTRING("Notes"), *notesField);
 }
 
 // Returns true if found, false if not found.
 static bool
-GetAnnotation(CrashReporter::Annotation key, nsACString& data)
+GetAnnotation(const nsACString& key, nsACString& data)
 {
   if (!gExceptionHandler)
     return false;
 
   MutexAutoLock lock(*crashReporterAPILock);
-  nsCString entry = crashReporterAPIData_Table[key];
-  if (entry.IsEmpty()) {
+  nsAutoCString entry;
+  if (!crashReporterAPIData_Hash->Get(key, &entry))
     return false;
-  }
 
   data = entry;
   return true;
 }
 
 nsresult RegisterAppMemory(void* ptr, size_t length)
 {
   if (!GetEnabled())
@@ -2316,24 +2305,25 @@ void SetIncludeContextHeap(bool aValue)
 #endif
 }
 
 bool GetServerURL(nsACString& aServerURL)
 {
   if (!gExceptionHandler)
     return false;
 
-  return GetAnnotation(CrashReporter::Annotation::ServerURL, aServerURL);
+  return GetAnnotation(NS_LITERAL_CSTRING("ServerURL"), aServerURL);
 }
 
 nsresult SetServerURL(const nsACString& aServerURL)
 {
   // store server URL with the API data
   // the client knows to handle this specially
-  return AnnotateCrashReport(Annotation::ServerURL, aServerURL);
+  return AnnotateCrashReport(NS_LITERAL_CSTRING("ServerURL"),
+                             aServerURL);
 }
 
 nsresult
 SetRestartArgs(int argc, char** argv)
 {
   if (!gExceptionHandler)
     return NS_OK;
 
@@ -2946,21 +2936,35 @@ AppendExtraData(const nsAString& id, con
   if (!GetExtraFileForID(id, getter_AddRefs(extraFile)))
     return false;
   return AppendExtraData(extraFile, data);
 }
 
 //-----------------------------------------------------------------------------
 // Helpers for AppendExtraData()
 //
+struct Blacklist {
+  Blacklist() : mItems(nullptr), mLen(0) { }
+  Blacklist(const char** items, int len) : mItems(items), mLen(len) { }
+
+  bool Contains(const nsACString& key) const {
+    for (int i = 0; i < mLen; ++i)
+      if (key.EqualsASCII(mItems[i]))
+        return true;
+    return false;
+  }
+
+  const char** mItems;
+  const int mLen;
+};
+
 static void
-WriteAnnotation(PRFileDesc* fd, const Annotation key, const nsACString& value)
+WriteAnnotation(PRFileDesc* fd, const nsACString& key, const nsACString& value)
 {
-  const char* annotation = AnnotationToString(key);
-  PR_Write(fd, annotation, strlen(annotation));
+  PR_Write(fd, key.BeginReading(), key.Length());
   PR_Write(fd, "=", 1);
   PR_Write(fd, value.BeginReading(), value.Length());
   PR_Write(fd, "\n", 1);
 }
 
 template<int N>
 static void
 WriteLiteral(PRFileDesc* fd, const char (&str)[N])
@@ -2970,70 +2974,68 @@ WriteLiteral(PRFileDesc* fd, const char 
 
 /*
  * If accessing the AnnotationTable |data| argument requires locks, the
  * caller should ensure the required locks are already held.
  */
 static bool
 WriteExtraData(nsIFile* extraFile,
                const AnnotationTable& data,
+               const Blacklist& blacklist,
                bool writeCrashTime=false,
-               bool truncate=false,
-               bool content=false)
+               bool truncate=false)
 {
   PRFileDesc* fd;
   int truncOrAppend = truncate ? PR_TRUNCATE : PR_APPEND;
   nsresult rv =
     extraFile->OpenNSPRFileDesc(PR_WRONLY | PR_CREATE_FILE | truncOrAppend,
                                 0600, &fd);
   if (NS_FAILED(rv))
     return false;
 
-  for (auto key : MakeEnumeratedRange(Annotation::Count)) {
-    nsCString value = data[key];
-    // Skip entries in the blacklist and empty entries.
-    if ((content && IsAnnotationBlacklistedForContent(key)) ||
-         value.IsEmpty()) {
-      continue;
+  for (auto iter = data.ConstIter(); !iter.Done(); iter.Next()) {
+    // Skip entries in the blacklist.
+    const nsACString& key = iter.Key();
+    if (blacklist.Contains(key)) {
+        continue;
     }
-    WriteAnnotation(fd, key, value);
+    WriteAnnotation(fd, key, iter.Data());
   }
 
   if (writeCrashTime) {
     time_t crashTime = time(nullptr);
     char crashTimeString[32];
     XP_TTOA(crashTime, crashTimeString, 10);
 
     WriteAnnotation(fd,
-                    Annotation::CrashTime,
+                    nsDependentCString("CrashTime"),
                     nsDependentCString(crashTimeString));
 
     double uptimeTS = (TimeStamp::NowLoRes() -
                        TimeStamp::ProcessCreation()).ToSecondsSigDigits();
     char uptimeTSString[64];
     SimpleNoCLibDtoA(uptimeTS, uptimeTSString, sizeof(uptimeTSString));
 
     WriteAnnotation(fd,
-                    Annotation::UptimeTS,
+                    nsDependentCString("UptimeTS"),
                     nsDependentCString(uptimeTSString));
   }
 
   if (memoryReportPath) {
-    WriteAnnotation(fd, Annotation::ContainsMemoryReport,
-                    NS_LITERAL_CSTRING("1"));
+    WriteLiteral(fd, "ContainsMemoryReport=1\n");
   }
 
   PR_Close(fd);
   return true;
 }
 
 bool
 AppendExtraData(nsIFile* extraFile, const AnnotationTable& data)
 {
-  return WriteExtraData(extraFile, data);
+  return WriteExtraData(extraFile, data, Blacklist());
 }
 
 static bool
 IsDataEscaped(char* aData)
 {
   if (strchr(aData, '\n')) {
     // There should not be any newlines
     return false;
@@ -3068,55 +3070,47 @@ ReadAndValidateExceptionTimeAnnotations(
     if (dataLen > 0 && data[dataLen - 1] == '\n') {
       data[dataLen - 1] = 0;
       --dataLen;
     }
     // There should not be any newlines in the key
     if (strchr(line, '\n')) {
       break;
     }
-    // The annotation sould be known
-    Annotation annotation;
-    if (!AnnotationFromString(annotation, line)) {
-      break;
-    }
     // Data should have been escaped by the child
     if (!IsDataEscaped(data)) {
       break;
     }
     // Looks good, save the (line,data) pair
-    aAnnotations[annotation] = nsDependentCString(data, dataLen);
+    aAnnotations.Put(nsDependentCString(line),
+                     nsDependentCString(data, dataLen));
   }
 }
 
 /**
- * Writes extra data in the .extra file corresponding to the specified
- * minidump. If `content` is set to true then this assumes that of a child
- * process.
- *
  * NOTE: One side effect of this function is that it deletes the
  * GeckoChildCrash<pid>.extra file if it exists, once processed.
  */
 static bool
 WriteExtraForMinidump(nsIFile* minidump,
                       uint32_t pid,
-                      bool content,
+                      const Blacklist& blacklist,
                       nsIFile** extraFile)
 {
   nsCOMPtr<nsIFile> extra;
   if (!GetExtraFileForMinidump(minidump, getter_AddRefs(extra))) {
     return false;
   }
 
   {
     MutexAutoLock lock(*crashReporterAPILock);
-    if (!WriteExtraData(extra, crashReporterAPIData_Table,
+    if (!WriteExtraData(extra, *crashReporterAPIData_Hash,
+                        blacklist,
                         true /*write crash time*/,
-                        true /*truncate*/,
-                        content)) {
+                        true /*truncate*/)) {
       return false;
     }
   }
 
   if (pid && processToCrashFd.count(pid)) {
     PRFileDesc* prFd = processToCrashFd[pid];
     processToCrashFd.erase(pid);
     FILE* fd;
@@ -3211,20 +3205,21 @@ OnChildProcessDumpRequested(void* aConte
 
   uint32_t pid =
 #ifdef XP_MACOSX
     aClientInfo.pid();
 #else
     aClientInfo->pid();
 #endif
 
-  if (!WriteExtraForMinidump(minidump, pid, /* content */ true,
-                             getter_AddRefs(extraFile))) {
+  if (!WriteExtraForMinidump(minidump, pid,
+                             Blacklist(kSubprocessBlacklist,
+                                       ArrayLength(kSubprocessBlacklist)),
+                             getter_AddRefs(extraFile)))
     return;
-  }
 
   if (ShouldReport()) {
     nsCOMPtr<nsIFile> memoryReport;
     if (memoryReportPath) {
       CreateFileFromPath(memoryReportPath, getter_AddRefs(memoryReport));
       MOZ_ASSERT(memoryReport);
     }
     MoveToPending(minidump, extraFile, memoryReport);
@@ -3737,18 +3732,17 @@ PairedDumpCallbackExtra(
 #ifdef XP_WIN32
                      nullptr, nullptr,
 #endif
                      succeeded);
 
   nsCOMPtr<nsIFile>& minidump = *static_cast< nsCOMPtr<nsIFile>* >(context);
 
   nsCOMPtr<nsIFile> extra;
-  return WriteExtraForMinidump(minidump, 0, /* content */ false,
-                               getter_AddRefs(extra));
+  return WriteExtraForMinidump(minidump, 0, Blacklist(), getter_AddRefs(extra));
 }
 
 ThreadId
 CurrentThreadId()
 {
 #if defined(XP_WIN)
   return ::GetCurrentThreadId();
 #elif defined(XP_LINUX)
--- a/toolkit/crashreporter/nsExceptionHandler.h
+++ b/toolkit/crashreporter/nsExceptionHandler.h
@@ -8,19 +8,16 @@
 // configured with --disable-crashreporter. If you add or remove a function
 // from this header you must update both implementations otherwise you'll break
 // builds that disable the crash reporter.
 
 #ifndef nsExceptionHandler_h__
 #define nsExceptionHandler_h__
 
 #include "mozilla/Assertions.h"
-#include "mozilla/EnumeratedArray.h"
-
-#include "CrashAnnotations.h"
 
 #include <functional>
 #include <stddef.h>
 #include <stdint.h>
 #include "nsError.h"
 #include "nsString.h"
 #include "prio.h"
 
@@ -35,16 +32,18 @@
 #include <mach/mach.h>
 #endif
 
 #if defined(XP_LINUX)
 #include <signal.h>
 #endif
 
 class nsIFile;
+template<class KeyClass, class DataType> class nsDataHashtable;
+class nsCStringHashKey;
 
 namespace CrashReporter {
 
 /**
  * Returns true if the crash reporter is using the dummy implementation.
  */
 static inline bool
 IsDummy() {
@@ -88,21 +87,18 @@ bool     GetServerURL(nsACString& aServe
 nsresult SetServerURL(const nsACString& aServerURL);
 bool     GetMinidumpPath(nsAString& aPath);
 nsresult SetMinidumpPath(const nsAString& aPath);
 
 
 // AnnotateCrashReport, RemoveCrashReportAnnotation and
 // AppendAppNotesToCrashReport may be called from any thread in a chrome
 // process, but may only be called from the main thread in a content process.
-nsresult AnnotateCrashReport(Annotation key, bool data);
-nsresult AnnotateCrashReport(Annotation key, int data);
-nsresult AnnotateCrashReport(Annotation key, unsigned int data);
-nsresult AnnotateCrashReport(Annotation key, const nsACString& data);
-nsresult RemoveCrashReportAnnotation(Annotation key);
+nsresult AnnotateCrashReport(const nsACString& key, const nsACString& data);
+nsresult RemoveCrashReportAnnotation(const nsACString& key);
 nsresult AppendAppNotesToCrashReport(const nsACString& data);
 
 void AnnotateOOMAllocationSize(size_t size);
 void AnnotateTexturesSize(size_t size);
 nsresult SetGarbageCollecting(bool collecting);
 void SetEventloopNestingLevel(uint32_t level);
 void SetMinidumpAnalysisAllThreads();
 
@@ -112,18 +108,17 @@ nsresult SetupExtraData(nsIFile* aAppDat
 // Registers an additional memory region to be included in the minidump
 nsresult RegisterAppMemory(void* ptr, size_t length);
 nsresult UnregisterAppMemory(void* ptr);
 
 // Include heap regions of the crash context.
 void SetIncludeContextHeap(bool aValue);
 
 // Functions for working with minidumps and .extras
-typedef mozilla::EnumeratedArray<Annotation, Annotation::Count, nsCString>
-        AnnotationTable;
+typedef nsDataHashtable<nsCStringHashKey, nsCString> AnnotationTable;
 
 void DeleteMinidumpFilesForID(const nsAString& id);
 bool GetMinidumpForID(const nsAString& id, nsIFile** minidump);
 bool GetIDFromMinidump(nsIFile* minidump, nsAString& id);
 bool GetExtraFileForID(const nsAString& id, nsIFile** extraFile);
 bool GetExtraFileForMinidump(nsIFile* minidump, nsIFile** extraFile);
 bool AppendExtraData(const nsAString& id, const AnnotationTable& data);
 bool AppendExtraData(nsIFile* extraFile, const AnnotationTable& data);
--- a/toolkit/crashreporter/test/unit/crasher_subprocess_head.js
+++ b/toolkit/crashreporter/test/unit/crasher_subprocess_head.js
@@ -1,9 +1,8 @@
-ChromeUtils.import("resource://gre/modules/CrashReporter.jsm");
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 
 // enable crash reporting first
 var cwd = Services.dirsvc.get("CurWorkD", Ci.nsIFile);
 
 // get the temp dir
 var env = Cc["@mozilla.org/process/environment;1"].getService(Ci.nsIEnvironment);
 var _tmpd = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
--- a/toolkit/crashreporter/test/unit/head_crashreporter.js
+++ b/toolkit/crashreporter/test/unit/head_crashreporter.js
@@ -1,9 +1,8 @@
-ChromeUtils.import("resource://gre/modules/CrashReporter.jsm");
 ChromeUtils.import("resource://gre/modules/osfile.jsm");
 ChromeUtils.import("resource://gre/modules/Services.jsm", this);
 ChromeUtils.import("resource://testing-common/AppData.jsm", this);
 ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
 
 function getEventDir() {
   return OS.Path.join(do_get_tempdir().path, "crash-events");
 }
--- a/toolkit/crashreporter/test/unit/test_crash_abort.js
+++ b/toolkit/crashreporter/test/unit/test_crash_abort.js
@@ -1,16 +1,15 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 function run_test() {
   // Try crashing with an abort().
   do_crash(function() {
              crashType = CrashTestUtils.CRASH_ABORT;
-             crashReporter.annotateCrashReport(
-              CrashReporter.annotations.TestKey, "TestValue");
+             crashReporter.annotateCrashReport("TestKey", "TestValue");
            },
            function(mdump, extra) {
              Assert.equal(extra.TestKey, "TestValue");
            },
           // process will exit with a zero exit status
           true);
 }
--- a/toolkit/crashreporter/test/unit/test_crash_after_js_large_allocation_failure.js
+++ b/toolkit/crashreporter/test/unit/test_crash_after_js_large_allocation_failure.js
@@ -2,20 +2,19 @@ function run_test() {
   if (!("@mozilla.org/toolkit/crash-reporter;1" in Cc)) {
     dump("INFO | test_crash_after_js_large_allocation_failure.js | Can't test crashreporter in a non-libxul build.\n");
     return;
   }
 
   do_crash(
     function() {
       crashType = CrashTestUtils.CRASH_MOZ_CRASH;
-      crashReporter.annotateCrashReport(
-        CrashReporter.annotations.TestKey, "Yes");
+      crashReporter.annotateCrashReport("TestingOOMCrash", "Yes");
       Cu.getJSTestingFunctions().reportLargeAllocationFailure();
       Cu.forceGC();
     },
     function(mdump, extra) {
-      Assert.equal(extra.TestKey, "Yes");
+      Assert.equal(extra.TestingOOMCrash, "Yes");
       Assert.equal(false, "JSOutOfMemory" in extra);
       Assert.equal(extra.JSLargeAllocationFailure, "Recovered");
     },
     true);
 }
--- a/toolkit/crashreporter/test/unit/test_crash_after_js_large_allocation_failure_reporting.js
+++ b/toolkit/crashreporter/test/unit/test_crash_after_js_large_allocation_failure_reporting.js
@@ -2,24 +2,23 @@ function run_test() {
   if (!("@mozilla.org/toolkit/crash-reporter;1" in Cc)) {
     dump("INFO | test_crash_after_js_oom_reporting.js | Can't test crashreporter in a non-libxul build.\n");
     return;
   }
 
   do_crash(
     function() {
       crashType = CrashTestUtils.CRASH_MOZ_CRASH;
-      crashReporter.annotateCrashReport(
-        CrashReporter.annotations.TestKey, "Yes");
+      crashReporter.annotateCrashReport("TestingOOMCrash", "Yes");
 
       function crashWhileReporting() {
         CrashTestUtils.crash(crashType);
       }
 
       Services.obs.addObserver(crashWhileReporting, "memory-pressure");
       Cu.getJSTestingFunctions().reportLargeAllocationFailure();
     },
     function(mdump, extra) {
-      Assert.equal(extra.TestKey, "Yes");
+      Assert.equal(extra.TestingOOMCrash, "Yes");
       Assert.equal(extra.JSLargeAllocationFailure, "Reporting");
     },
     true);
 }
--- a/toolkit/crashreporter/test/unit/test_crash_after_js_oom_recovered.js
+++ b/toolkit/crashreporter/test/unit/test_crash_after_js_oom_recovered.js
@@ -2,19 +2,18 @@ function run_test() {
   if (!("@mozilla.org/toolkit/crash-reporter;1" in Cc)) {
     dump("INFO | test_crash_after_js_oom_recovered.js | Can't test crashreporter in a non-libxul build.\n");
     return;
   }
 
   do_crash(
     function() {
       crashType = CrashTestUtils.CRASH_MOZ_CRASH;
-      crashReporter.annotateCrashReport(
-        CrashReporter.annotations.TestKey, "Yes");
+      crashReporter.annotateCrashReport("TestingOOMCrash", "Yes");
       Cu.getJSTestingFunctions().reportOutOfMemory();
       Cu.forceGC();
     },
     function(mdump, extra) {
-      Assert.equal(extra.TestKey, "Yes");
+      Assert.equal(extra.TestingOOMCrash, "Yes");
       Assert.equal(extra.JSOutOfMemory, "Recovered");
     },
     true);
 }
--- a/toolkit/crashreporter/test/unit/test_crash_after_js_oom_reported.js
+++ b/toolkit/crashreporter/test/unit/test_crash_after_js_oom_reported.js
@@ -2,27 +2,26 @@ function run_test() {
   if (!("@mozilla.org/toolkit/crash-reporter;1" in Cc)) {
     dump("INFO | test_crash_after_js_oom_reported.js | Can't test crashreporter in a non-libxul build.\n");
     return;
   }
 
   do_crash(
     function() {
       crashType = CrashTestUtils.CRASH_MOZ_CRASH;
-      crashReporter.annotateCrashReport(
-        CrashReporter.annotations.TestKey, "Yes");
+      crashReporter.annotateCrashReport("TestingOOMCrash", "Yes");
 
       // GC now to avoid having it happen randomly later, which would make the
       // test bogusly fail. See comment below.
       Cu.forceGC();
 
       Cu.getJSTestingFunctions().reportOutOfMemory();
     },
     function(mdump, extra) {
-      Assert.equal(extra.TestKey, "Yes");
+      Assert.equal(extra.TestingOOMCrash, "Yes");
 
       // The JSOutOfMemory field is absent if the JS engine never reported OOM,
       // "Reported" if it did, and "Recovered" if it reported OOM but
       // subsequently completed a full GC cycle. Since this test calls
       // reportOutOfMemory() and then crashes, we expect "Reported".
       //
       // Theoretically, GC can happen any time, so it is just possible that
       // this property could be "Recovered" even if the implementation is
--- a/toolkit/crashreporter/test/unit/test_crash_after_js_oom_reported_2.js
+++ b/toolkit/crashreporter/test/unit/test_crash_after_js_oom_reported_2.js
@@ -2,24 +2,23 @@ function run_test() {
   if (!("@mozilla.org/toolkit/crash-reporter;1" in Cc)) {
     dump("INFO | test_crash_after_js_oom_reported_2.js | Can't test crashreporter in a non-libxul build.\n");
     return;
   }
 
   do_crash(
     function() {
       crashType = CrashTestUtils.CRASH_MOZ_CRASH;
-      crashReporter.annotateCrashReport(
-        CrashReporter.annotations.TestKey, "Yes");
+      crashReporter.annotateCrashReport("TestingOOMCrash", "Yes");
       Cu.getJSTestingFunctions().reportOutOfMemory();
       Cu.forceGC(); // recover from first OOM
       Cu.getJSTestingFunctions().reportOutOfMemory();
     },
     function(mdump, extra) {
-      Assert.equal(extra.TestKey, "Yes");
+      Assert.equal(extra.TestingOOMCrash, "Yes");
 
       // Technically, GC can happen at any time, but it would be really
       // peculiar for it to happen again heuristically right after a GC was
       // forced. If extra.JSOutOfMemory is "Recovered" here, that's most
       // likely a bug in the error reporting machinery.
       Assert.equal(extra.JSOutOfMemory, "Reported");
     },
     true);
--- a/toolkit/crashreporter/test/unit/test_crash_moz_crash.js
+++ b/toolkit/crashreporter/test/unit/test_crash_moz_crash.js
@@ -1,14 +1,13 @@
 function run_test() {
   // Try crashing with a runtime abort
   do_crash(function() {
              crashType = CrashTestUtils.CRASH_MOZ_CRASH;
-             crashReporter.annotateCrashReport(
-              CrashReporter.annotations.TestKey, "TestValue");
+             crashReporter.annotateCrashReport("TestKey", "TestValue");
            },
            function(mdump, extra) {
              Assert.equal(extra.TestKey, "TestValue");
              Assert.equal(false, "OOMAllocationSize" in extra);
              Assert.equal(false, "JSOutOfMemory" in extra);
              Assert.equal(false, "JSLargeAllocationFailure" in extra);
            },
           // process will exit with a zero exit status
--- a/toolkit/crashreporter/test/unit/test_crash_oom.js
+++ b/toolkit/crashreporter/test/unit/test_crash_oom.js
@@ -2,18 +2,17 @@ function run_test() {
   if (!("@mozilla.org/toolkit/crash-reporter;1" in Cc)) {
     dump("INFO | test_crash_oom.js | Can't test crashreporter in a non-libxul build.\n");
     return;
   }
 
   do_crash(
     function() {
       crashType = CrashTestUtils.CRASH_OOM;
-      crashReporter.annotateCrashReport(
-        CrashReporter.annotations.TestKey, "Yes");
+      crashReporter.annotateCrashReport("TestingOOMCrash", "Yes");
     },
     function(mdump, extra) {
-      Assert.equal(extra.TestKey, "Yes");
+      Assert.equal(extra.TestingOOMCrash, "Yes");
       Assert.ok("OOMAllocationSize" in extra);
       Assert.ok(Number(extra.OOMAllocationSize) > 0);
     },
     true);
 }
--- a/toolkit/crashreporter/test/unit/test_crash_purevirtual.js
+++ b/toolkit/crashreporter/test/unit/test_crash_purevirtual.js
@@ -8,17 +8,16 @@ function run_test() {
   if (isOSX) {
      dump("INFO | test_crash_purevirtual.js | TODO: purecalls not caught on OS X\n");
     return;
   }
 
   // Try crashing with a pure virtual call
   do_crash(function() {
              crashType = CrashTestUtils.CRASH_PURE_VIRTUAL_CALL;
-             crashReporter.annotateCrashReport(
-              CrashReporter.annotations.TestKey, "TestValue");
+             crashReporter.annotateCrashReport("TestKey", "TestValue");
            },
            function(mdump, extra) {
              Assert.equal(extra.TestKey, "TestValue");
            },
           // process will exit with a zero exit status
           true);
 }
--- a/toolkit/crashreporter/test/unit/test_crash_uncaught_exception.js
+++ b/toolkit/crashreporter/test/unit/test_crash_uncaught_exception.js
@@ -1,17 +1,16 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 function run_test() {
   // Try crashing with an uncaught exception.
   do_crash(function() {
              crashType = CrashTestUtils.CRASH_UNCAUGHT_EXCEPTION;
-             crashReporter.annotateCrashReport(
-              CrashReporter.annotations.TestKey, "TestValue");
+             crashReporter.annotateCrashReport("TestKey", "TestValue");
            },
            function(mdump, extra) {
              Assert.equal(extra.TestKey, "TestValue");
            },
           // process will exit with a zero exit status
           true);
 }
 
--- a/toolkit/crashreporter/test/unit/test_crashreporter.js
+++ b/toolkit/crashreporter/test/unit/test_crashreporter.js
@@ -34,60 +34,43 @@ function run_test() {
   // check getting/setting minidumpPath
   // it should be $TEMP by default, but I'm not sure if we can exactly test that
   // this will at least test that it doesn't throw
   Assert.notEqual(cr.minidumpPath.path, "");
   var cwd = do_get_cwd();
   cr.minidumpPath = cwd;
   Assert.equal(cr.minidumpPath.path, cwd.path);
 
-  // Test annotateCrashReport()
   try {
-    cr.annotateCrashReport(undefined, "");
-    do_throw("Calling annotateCrashReport() with an undefined key should have thrown!");
+    cr.annotateCrashReport("equal=equal", "");
+    do_throw("Calling annotateCrashReport() with an '=' in key should have thrown!");
   } catch (ex) {
     Assert.equal(ex.result, Cr.NS_ERROR_INVALID_ARG);
   }
   try {
-    cr.annotateCrashReport(1000000, "");
-    do_throw("Calling annotateCrashReport() with a bogus key should have thrown!");
+    cr.annotateCrashReport("new\nline", "");
+    do_throw("Calling annotateCrashReport() with a '\\n' in key should have thrown!");
   } catch (ex) {
     Assert.equal(ex.result, Cr.NS_ERROR_INVALID_ARG);
   }
   try {
-    cr.annotateCrashReport(CrashReporter.annotations.TestKey, "da\0ta");
+    cr.annotateCrashReport("", "da\0ta");
     do_throw("Calling annotateCrashReport() with a '\\0' in data should have thrown!");
   } catch (ex) {
     Assert.equal(ex.result, Cr.NS_ERROR_INVALID_ARG);
   }
-  cr.annotateCrashReport(CrashReporter.annotations.TestKey, "testData1");
+  cr.annotateCrashReport("testKey", "testData1");
   // Replace previous data.
-  cr.annotateCrashReport(CrashReporter.annotations.TestKey, "testData2");
+  cr.annotateCrashReport("testKey", "testData2");
 
   try {
     cr.appendAppNotesToCrashReport("da\0ta");
     do_throw("Calling appendAppNotesToCrashReport() with a '\\0' in data should have thrown!");
   } catch (ex) {
     Assert.equal(ex.result, Cr.NS_ERROR_INVALID_ARG);
   }
   cr.appendAppNotesToCrashReport("additional testData3");
   // Add more data.
   cr.appendAppNotesToCrashReport("additional testData4");
 
-  // Test removeCrashReportAnnotation()
-  try {
-    cr.removeCrashReportAnnotation(undefined);
-    do_throw("Calling removeCrashReportAnnotation() with an undefined key should have thrown!");
-  } catch (ex) {
-    Assert.equal(ex.result, Cr.NS_ERROR_INVALID_ARG);
-  }
-  try {
-    cr.removeCrashReportAnnotation(1000000);
-    do_throw("Calling removeCrashReportAnnotation() with a bogus key should have thrown!");
-  } catch (ex) {
-    Assert.equal(ex.result, Cr.NS_ERROR_INVALID_ARG);
-  }
-  cr.removeCrashReportAnnotation(CrashReporter.annotations.TestKey);
-
-  // Testing setting the minidumpPath field
   cr.minidumpPath = cwd;
   Assert.equal(cr.minidumpPath.path, cwd.path);
 }
--- a/toolkit/crashreporter/test/unit/test_crashreporter_crash.js
+++ b/toolkit/crashreporter/test/unit/test_crashreporter_crash.js
@@ -28,37 +28,30 @@ function run_test() {
              }
              if (is_win7_or_newer)
                Assert.ok(CrashTestUtils.dumpHasStream(mdump.path, CrashTestUtils.MD_MEMORY_INFO_LIST_STREAM));
            });
 
   // check setting some basic data
   do_crash(function() {
              // Add various annotations
-             crashReporter.annotateCrashReport(
-              CrashReporter.annotations.TestKey, "TestValue");
-             crashReporter.annotateCrashReport(
-              CrashReporter.annotations.TestUnicode, "\u{1F4A9}");
-             // Some annotations have an alternate form when written out, Addons
-             // for example will be written out as Add-ons
-             crashReporter.annotateCrashReport(CrashReporter.annotations.Addons,
-                                               "test%40mozilla.org:0.1");
+             crashReporter.annotateCrashReport("TestKey", "TestValue");
+             crashReporter.annotateCrashReport("\u2665", "\u{1F4A9}");
              crashReporter.appendAppNotesToCrashReport("Junk");
              crashReporter.appendAppNotesToCrashReport("MoreJunk");
 
              // TelemetrySession setup will trigger the session annotation
              let scope = {};
              ChromeUtils.import("resource://gre/modules/TelemetryController.jsm", scope);
              scope.TelemetryController.testSetup();
            },
            function(mdump, extra) {
              Assert.equal(extra.TestKey, "TestValue");
-             Assert.equal(extra.TestUnicode, "\u{1F4A9}");
+             Assert.equal(extra["\u2665"], "\u{1F4A9}");
              Assert.equal(extra.Notes, "JunkMoreJunk");
-             Assert.equal(extra["Add-ons"], "test%40mozilla.org:0.1");
              const UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
              Assert.ok("TelemetrySessionId" in extra,
                        "The TelemetrySessionId field is present in the extra file");
              Assert.ok(UUID_REGEX.test(extra.TelemetrySessionId),
                        "The TelemetrySessionId is a UUID");
              Assert.ok(!("TelemetryClientId" in extra),
                        "The TelemetryClientId field is omitted by default");
              Assert.ok(!("TelemetryServerURL" in extra),
--- a/toolkit/crashreporter/test/unit/test_event_files.js
+++ b/toolkit/crashreporter/test/unit/test_event_files.js
@@ -19,18 +19,17 @@ add_task(async function test_main_proces
   let count = await new Promise((resolve, reject) => {
     do_crash(
       function() {
         // TelemetrySession setup will trigger the session annotation
         let scope = {};
         ChromeUtils.import("resource://gre/modules/TelemetryController.jsm", scope);
         scope.TelemetryController.testSetup();
         crashType = CrashTestUtils.CRASH_MOZ_CRASH;
-        crashReporter.annotateCrashReport(
-          CrashReporter.annotations.ShutdownProgress, "event-test");
+        crashReporter.annotateCrashReport("ShutdownProgress", "event-test");
       },
       (minidump, extra) => {
         basename = minidump.leafName;
         cm._eventsDirs = [getEventDir()];
         cm.aggregateEventsFiles().then(resolve, reject);
       },
       true);
 
--- a/toolkit/crashreporter/test/unit/test_oom_annotation_windows.js
+++ b/toolkit/crashreporter/test/unit/test_oom_annotation_windows.js
@@ -2,21 +2,20 @@ function run_test() {
   if (!("@mozilla.org/toolkit/crash-reporter;1" in Cc)) {
     dump("INFO | test_crash_oom.js | Can't test crashreporter in a non-libxul build.\n");
     return;
   }
 
   do_crash(
     function() {
       crashType = CrashTestUtils.CRASH_OOM;
-      crashReporter.annotateCrashReport(
-        CrashReporter.annotations.TestKey, "Yes");
+      crashReporter.annotateCrashReport("TestingOOMCrash", "Yes");
     },
     function(mdump, extra) {
-      Assert.equal(extra.TestKey, "Yes");
+      Assert.equal(extra.TestingOOMCrash, "Yes");
       Assert.ok("OOMAllocationSize" in extra);
       Assert.ok(Number(extra.OOMAllocationSize) > 0);
       Assert.ok("SystemMemoryUsePercentage" in extra);
       Assert.ok("TotalVirtualMemory" in extra);
       Assert.ok("AvailableVirtualMemory" in extra);
       Assert.ok("TotalPageFile" in extra);
       Assert.ok("AvailablePageFile" in extra);
       Assert.ok("TotalPhysicalMemory" in extra);
--- a/toolkit/crashreporter/test/unit_ipc/test_content_annotation.js
+++ b/toolkit/crashreporter/test/unit_ipc/test_content_annotation.js
@@ -5,18 +5,17 @@ function run_test() {
   if (!("@mozilla.org/toolkit/crash-reporter;1" in Cc)) {
     dump("INFO | test_content_annotation.js | Can't test crashreporter in a non-libxul build.\n");
     return;
   }
 
   // Try crashing with a runtime abort
   do_content_crash(function() {
                      crashType = CrashTestUtils.CRASH_MOZ_CRASH;
-                     crashReporter.annotateCrashReport(
-                      CrashReporter.annotations.TestKey, "TestValue");
+                     crashReporter.annotateCrashReport("TestKey", "TestValue");
                      crashReporter.appendAppNotesToCrashReport("!!!foo!!!");
                    },
                    function(mdump, extra) {
                      Assert.equal(extra.TestKey, "TestValue");
                      Assert.ok("StartupTime" in extra);
                      Assert.ok("ProcessType" in extra);
                      Assert.notEqual(extra.Notes.indexOf("!!!foo!!!"), -1);
                    });
--- a/toolkit/modules/WebNavigationChild.jsm
+++ b/toolkit/modules/WebNavigationChild.jsm
@@ -1,24 +1,28 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* 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/. */
 "use strict";
 
 var EXPORTED_SYMBOLS = ["WebNavigationChild"];
 
-ChromeUtils.import("resource://gre/modules/CrashReporter.jsm");
 ChromeUtils.import("resource://gre/modules/Services.jsm");
+ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 
 ChromeUtils.defineModuleGetter(this, "AppConstants",
                                "resource://gre/modules/AppConstants.jsm");
 ChromeUtils.defineModuleGetter(this, "Utils",
                                "resource://gre/modules/sessionstore/Utils.jsm");
 
+XPCOMUtils.defineLazyServiceGetter(this, "CrashReporter",
+                                   "@mozilla.org/xre/app-info;1",
+                                   "nsICrashReporter");
+
 class WebNavigationChild {
   constructor(mm) {
     this.mm = mm;
 
     this.mm.addMessageListener("WebNavigation:GoBack", this);
     this.mm.addMessageListener("WebNavigation:GoForward", this);
     this.mm.addMessageListener("WebNavigation:GotoIndex", this);
     this.mm.addMessageListener("WebNavigation:LoadURI", this);
@@ -101,17 +105,17 @@ class WebNavigationChild {
         let url = Services.io.newURI(uri);
         // If the current URI contains a username/password, remove it.
         url = url.mutate()
                  .setUserPass("")
                  .finalize();
         annotation = url.spec;
       } catch (ex) { /* Ignore failures to parse and failures
                       on about: URIs. */ }
-      CrashReporter.addAnnotation(CrashReporter.annotations.URL, annotation);
+      CrashReporter.annotateCrashReport("URL", annotation);
     }
     if (referrer)
       referrer = Services.io.newURI(referrer);
     if (postData)
       postData = Utils.makeInputStream(postData);
     if (headers)
       headers = Utils.makeInputStream(headers);
     if (baseURI)
--- a/toolkit/modules/WebProgressChild.jsm
+++ b/toolkit/modules/WebProgressChild.jsm
@@ -1,22 +1,24 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* 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/. */
 "use strict";
 
 var EXPORTED_SYMBOLS = ["WebProgressChild"];
 
-ChromeUtils.import("resource://gre/modules/CrashReporter.jsm");
 ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 
 ChromeUtils.defineModuleGetter(this, "AppConstants",
                                "resource://gre/modules/AppConstants.jsm");
 
+XPCOMUtils.defineLazyServiceGetter(this, "CrashReporter",
+                                   "@mozilla.org/xre/app-info;1",
+                                   "nsICrashReporter");
 XPCOMUtils.defineLazyServiceGetter(this, "serializationHelper",
                                    "@mozilla.org/network/serialization-helper;1",
                                    "nsISerializationHelper");
 
 class WebProgressChild {
   constructor(mm) {
     this.mm = mm;
 
@@ -171,17 +173,17 @@ class WebProgressChild {
       if (AppConstants.MOZ_CRASHREPORTER && CrashReporter.enabled) {
         let uri = aLocationURI;
         try {
           // If the current URI contains a username/password, remove it.
           uri = uri.mutate()
                    .setUserPass("")
                    .finalize();
         } catch (ex) { /* Ignore failures on about: URIs. */ }
-        CrashReporter.addAnnotation(CrashReporter.annotations.URL, uri.spec);
+        CrashReporter.annotateCrashReport("URL", uri.spec);
       }
     }
 
     this._send("Content:LocationChange", json, objects);
   }
 
   // Note: Because the nsBrowserStatusFilter timeout runnable is
   // SystemGroup-labeled, this method should not modify this.mm.content DOM or
--- a/toolkit/mozapps/extensions/internal/AddonTestUtils.jsm
+++ b/toolkit/mozapps/extensions/internal/AddonTestUtils.jsm
@@ -2,21 +2,17 @@
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 /* eslint "mozilla/no-aArgs": 1 */
 /* eslint "no-unused-vars": [2, {"args": "none", "varsIgnorePattern": "^(Cc|Ci|Cr|Cu|EXPORTED_SYMBOLS)$"}] */
 /* eslint "semi": [2, "always"] */
 /* eslint "valid-jsdoc": [2, {requireReturn: false}] */
 
-var EXPORTED_SYMBOLS = [
-  "AddonTestUtils",
-  "MockAsyncShutdown",
-  "MockCrashReporter",
-];
+var EXPORTED_SYMBOLS = ["AddonTestUtils", "MockAsyncShutdown"];
 
 const CERTDB_CONTRACTID = "@mozilla.org/security/x509certdb;1";
 
 Cu.importGlobalProperties(["fetch", "TextEncoder"]);
 
 ChromeUtils.import("resource://gre/modules/AsyncShutdown.jsm");
 ChromeUtils.import("resource://gre/modules/FileUtils.jsm");
 ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
@@ -24,19 +20,16 @@ ChromeUtils.import("resource://gre/modul
 ChromeUtils.import("resource://gre/modules/Timer.jsm");
 ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 
 const {EventEmitter} = ChromeUtils.import("resource://gre/modules/EventEmitter.jsm", {});
 const {OS} = ChromeUtils.import("resource://gre/modules/osfile.jsm", {});
 
 ChromeUtils.defineModuleGetter(this, "Extension",
                                "resource://gre/modules/Extension.jsm");
-ChromeUtils.defineModuleGetter(this, "CrashReporter",
-                               "resource://gre/modules/CrashReporter.jsm");
-
 XPCOMUtils.defineLazyGetter(this, "Management", () => {
   let {Management} = ChromeUtils.import("resource://gre/modules/Extension.jsm", {});
   return Management;
 });
 
 ChromeUtils.defineModuleGetter(this, "FileTestUtils",
                                "resource://testing-common/FileTestUtils.jsm");
 ChromeUtils.defineModuleGetter(this, "HttpServer",
@@ -183,38 +176,16 @@ class MockBlocklist {
   async getPluginBlocklistState(plugin, version, appVersion, toolkitVersion) {
     await new Promise(r => setTimeout(r, 150));
     return Ci.nsIBlocklistService.STATE_NOT_BLOCKED;
   }
 }
 
 MockBlocklist.prototype.QueryInterface = ChromeUtils.generateQI(["nsIBlocklistService"]);
 
-// Mock the crash reporter wrapper so that we can inspect the annotations
-var MockCrashReporter = {
-  addAnnotation(annotation, value) {
-    this.checkAnnotation(annotation);
-    this.currentAnnotations[annotation] = value;
-  },
-  removeAnnotation(annotation) {
-    this.checkAnnotation(annotation);
-    delete this.currentAnnotations[annotation];
-  },
-  checkAnnotation(annotation) {
-    for (let i in this.annotations) {
-      if (annotation == this.annotations[i]) {
-        return;
-      }
-    }
-
-    throw Cr.NS_ERROR_INVALID_ARG;
-  },
-  annotations: Object.assign({}, CrashReporter.annotations),
-  currentAnnotations: {},
-};
 
 /**
  * Escapes any occurrences of &, ", < or > with XML entities.
  *
  * @param {string} str
  *        The string to escape.
  * @return {string} The escaped string.
  */
@@ -610,16 +581,17 @@ var AddonTestUtils = {
     if (error !== undefined)
       throw error;
     return result;
   },
 
   createAppInfo(ID, name, version, platformVersion = "1.0") {
     AppInfo.updateAppInfo({
       ID, name, version, platformVersion,
+      crashReporter: true,
       extraProps: {
         browserTabsRemoteAutostart: false,
       },
     });
     this.appInfo = AppInfo.getAppInfo();
   },
 
   getManifestURI(file) {
@@ -776,17 +748,16 @@ var AddonTestUtils = {
       if (Cu.isModuleLoaded("resource://gre/modules/Blocklist.jsm")) {
         let bsPassBlocklist = ChromeUtils.import("resource://gre/modules/Blocklist.jsm", {});
         Object.defineProperty(bsPassBlocklist, "gAppVersion", {value: newVersion});
       }
     }
 
     let XPIScope = ChromeUtils.import("resource://gre/modules/addons/XPIProvider.jsm", null);
     XPIScope.AsyncShutdown = MockAsyncShutdown;
-    XPIScope.CrashReporter = MockCrashReporter;
 
     XPIScope.XPIInternal.BootstrapScope.prototype
       ._beforeCallBootstrapMethod = (method, params, reason) => {
         try {
           this.emit("bootstrap-method", {method, params, reason});
         } catch (e) {
           try {
             this.testScope.do_throw(e);
@@ -834,17 +805,17 @@ var AddonTestUtils = {
 
     // Flush the jar cache entries for each bootstrapped XPI so that
     // we don't run into file locking issues on Windows.
     for (let file of this.addonsList.xpis) {
       Services.obs.notifyObservers(file, "flush-cache-entry");
     }
 
     // Clear any crash report annotations
-    MockCrashReporter.currentAnnotations = {};
+    this.appInfo.annotations = {};
 
     // Force the XPIProvider provider to reload to better
     // simulate real-world usage.
     let XPIscope = ChromeUtils.import("resource://gre/modules/addons/XPIProvider.jsm", {});
     // This would be cleaner if I could get it as the rejection reason from
     // the AddonManagerInternal.shutdown() promise
     let shutdownError = XPIscope.XPIDatabase._saveError;
 
--- a/toolkit/mozapps/extensions/internal/XPIProvider.jsm
+++ b/toolkit/mozapps/extensions/internal/XPIProvider.jsm
@@ -23,17 +23,16 @@ var EXPORTED_SYMBOLS = ["XPIProvider", "
 
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 ChromeUtils.import("resource://gre/modules/AddonManager.jsm");
 
 XPCOMUtils.defineLazyModuleGetters(this, {
   AppConstants: "resource://gre/modules/AppConstants.jsm",
   AsyncShutdown: "resource://gre/modules/AsyncShutdown.jsm",
-  CrashReporter: "resource://gre/modules/CrashReporter.jsm",
   Dictionary: "resource://gre/modules/Extension.jsm",
   Extension: "resource://gre/modules/Extension.jsm",
   Langpack: "resource://gre/modules/Extension.jsm",
   FileUtils: "resource://gre/modules/FileUtils.jsm",
   OS: "resource://gre/modules/osfile.jsm",
   ConsoleAPI: "resource://gre/modules/Console.jsm",
   JSONFile: "resource://gre/modules/JSONFile.jsm",
   LegacyExtensionsUtils: "resource://gre/modules/LegacyExtensionsUtils.jsm",
@@ -2120,19 +2119,18 @@ var XPIProvider = {
         Services.obs.notifyObservers(null, "startupcache-invalidate");
       }
 
       AddonManagerPrivate.markProviderSafe(this);
 
       if (AppConstants.MOZ_CRASHREPORTER) {
         // Annotate the crash report with relevant add-on information.
         try {
-          CrashReporter.addAnnotation(
-            CrashReporter.annotations.EMCheckCompatibility,
-            AddonManager.checkCompatibility);
+          Services.appinfo.annotateCrashReport("EMCheckCompatibility",
+                                               AddonManager.checkCompatibility);
         } catch (e) { }
         this.addAddonsToCrashReporter();
       }
 
       try {
         AddonManagerPrivate.recordTimestamp("XPI_bootstrap_addons_begin");
 
         for (let addon of this.sortBootstrappedAddons()) {
@@ -2312,24 +2310,25 @@ var XPIProvider = {
     }
     return Promise.all(promises);
   },
 
   /**
    * Adds a list of currently active add-ons to the next crash report.
    */
   addAddonsToCrashReporter() {
-    if (Services.appinfo.inSafeMode) {
+    if (!(Services.appinfo instanceof Ci.nsICrashReporter) ||
+        Services.appinfo.inSafeMode) {
       return;
     }
 
     let data = Array.from(XPIStates.enabledAddons(), a => a.telemetryKey).join(",");
 
     try {
-      CrashReporter.addAnnotation(CrashReporter.annotations.Addons, data);
+      Services.appinfo.annotateCrashReport("Add-ons", data);
     } catch (e) { }
 
     TelemetrySession.setAddOns(data);
   },
 
   /**
    * Check the staging directories of install locations for any add-ons to be
    * installed or add-ons to be uninstalled.
--- a/toolkit/mozapps/extensions/test/xpcshell/head_addons.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/head_addons.js
@@ -51,18 +51,16 @@ ChromeUtils.defineModuleGetter(this, "Ex
 ChromeUtils.defineModuleGetter(this, "ExtensionTestUtils",
                                "resource://testing-common/ExtensionXPCShellUtils.jsm");
 ChromeUtils.defineModuleGetter(this, "ExtensionTestCommon",
                                "resource://testing-common/ExtensionTestCommon.jsm");
 ChromeUtils.defineModuleGetter(this, "HttpServer",
                                "resource://testing-common/httpd.js");
 ChromeUtils.defineModuleGetter(this, "MockAsyncShutdown",
                                "resource://testing-common/AddonTestUtils.jsm");
-ChromeUtils.defineModuleGetter(this, "MockCrashReporter",
-                               "resource://testing-common/AddonTestUtils.jsm");
 ChromeUtils.defineModuleGetter(this, "MockRegistrar",
                                "resource://testing-common/MockRegistrar.jsm");
 ChromeUtils.defineModuleGetter(this, "MockRegistry",
                                "resource://testing-common/MockRegistry.jsm");
 ChromeUtils.defineModuleGetter(this, "PromiseTestUtils",
                                "resource://testing-common/PromiseTestUtils.jsm");
 ChromeUtils.defineModuleGetter(this, "TestUtils",
                                "resource://testing-common/TestUtils.jsm");
@@ -574,24 +572,22 @@ function checkAddon(id, addon, expected)
  * @param  aVersion
  *         The version of the add-on
  */
 function do_check_in_crash_annotation(aId, aVersion) {
   if (!AppConstants.MOZ_CRASHREPORTER) {
     return;
   }
 
-  const annotation = MockCrashReporter.annotations.Addons;
-
-  if (!(annotation in MockCrashReporter.currentAnnotations)) {
+  if (!("Add-ons" in gAppInfo.annotations)) {
     Assert.equal(false, true);
     return;
   }
 
-  let addons = MockCrashReporter.currentAnnotations[annotation].split(",");
+  let addons = gAppInfo.annotations["Add-ons"].split(",");
   Assert.ok(addons.includes(`${encodeURIComponent(aId)}:${encodeURIComponent(aVersion)}`));
 }
 
 /**
  * Tests that an add-on does not appear in the crash report annotations, if
  * crash reporting is enabled. The test will fail if the add-on is in the
  * annotation.
  * @param  aId
@@ -599,24 +595,22 @@ function do_check_in_crash_annotation(aI
  * @param  aVersion
  *         The version of the add-on
  */
 function do_check_not_in_crash_annotation(aId, aVersion) {
   if (!AppConstants.MOZ_CRASHREPORTER) {
     return;
   }
 
-  const annotation = MockCrashReporter.annotations.Addons;
-
-  if (!(annotation in MockCrashReporter.currentAnnotations)) {
+  if (!("Add-ons" in gAppInfo.annotations)) {
     Assert.ok(true);
     return;
   }
 
-  let addons = MockCrashReporter.currentAnnotations[annotation].split(",");
+  let addons = gAppInfo.annotations["Add-ons"].split(",");
   Assert.ok(!addons.includes(`${encodeURIComponent(aId)}:${encodeURIComponent(aVersion)}`));
 }
 
 function do_get_file_hash(aFile, aAlgorithm) {
   if (!aAlgorithm)
     aAlgorithm = "sha1";
 
   let crypto = Cc["@mozilla.org/security/hash;1"].
--- a/toolkit/xre/nsAppRunner.cpp
+++ b/toolkit/xre/nsAppRunner.cpp
@@ -263,23 +263,16 @@ char **gRestartArgv;
 
 // If gRestartedByOS is set, we were automatically restarted by the OS.
 bool gRestartedByOS = false;
 
 bool gIsGtest = false;
 
 nsString gAbsoluteArgv0Path;
 
-// This should always be 0 and it's used to catch JavaScript invocations of
-// nsICrashReporter.annotateCrashReporter() that are passed an undefined value.
-// Since undefined values are translated into 0 we need to special-case it.
-static const uint32_t kInvalidAnnotation = 0;
-static const uint32_t kAnnotationCount =
-  static_cast<uint32_t>(CrashReporter::Annotation::Count);
-
 #if defined(MOZ_WIDGET_GTK)
 #include <glib.h>
 #if defined(DEBUG) || defined(NS_BUILD_REFCNT_LOGGING)
 #define CLEANUP_MEMORY 1
 #define PANGO_ENABLE_BACKEND
 #include <pango/pangofc-fontmap.h>
 #endif
 #include <gtk/gtk.h>
@@ -1234,53 +1227,20 @@ nsXULAppInfo::GetExtraFileForID(const ns
   if (!CrashReporter::GetExtraFileForID(aId, aExtraFile)) {
     return NS_ERROR_FILE_NOT_FOUND;
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXULAppInfo::AnnotateCrashReport(uint32_t key,
+nsXULAppInfo::AnnotateCrashReport(const nsACString& key,
                                   const nsACString& data)
 {
-  if (key == kInvalidAnnotation || (key > kAnnotationCount)) {
-    return NS_ERROR_INVALID_ARG;
-  }
-
-  return CrashReporter::AnnotateCrashReport(
-    static_cast<CrashReporter::Annotation>(key - 1), data);
-}
-
-NS_IMETHODIMP
-nsXULAppInfo::RemoveCrashReportAnnotation(uint32_t key)
-{
-  if (key == kInvalidAnnotation || (key > kAnnotationCount)) {
-    return NS_ERROR_INVALID_ARG;
-  }
-
-  return CrashReporter::RemoveCrashReportAnnotation(
-    static_cast<CrashReporter::Annotation>(key - 1));
-}
-
-NS_IMETHODIMP
-nsXULAppInfo::IsAnnotationWhitelistedForPing(const nsACString& aValue,
-                                             bool* aIsWhitelisted)
-{
-  nsAutoCString aValueStr(aValue);
-  CrashReporter::Annotation annotation;
-
-  if (CrashReporter::AnnotationFromString(annotation,
-                                          PromiseFlatCString(aValue).get())) {
-    *aIsWhitelisted = CrashReporter::IsAnnotationWhitelistedForPing(annotation);
-  } else {
-    return NS_ERROR_INVALID_ARG;
-  }
-
-  return NS_OK;
+  return CrashReporter::AnnotateCrashReport(key, data);
 }
 
 NS_IMETHODIMP
 nsXULAppInfo::AppendAppNotesToCrashReport(const nsACString& data)
 {
   return CrashReporter::AppendAppNotesToCrashReport(data);
 }
 
@@ -3425,49 +3385,49 @@ XREMain::XRE_mainInit(bool* aExitFlag)
     rv = nsXREDirProvider::GetUserAppDataDirectory(getter_AddRefs(file));
     if (NS_SUCCEEDED(rv)) {
       CrashReporter::SetUserAppDataDirectory(file);
     }
     if (mAppData->crashReporterURL)
       CrashReporter::SetServerURL(nsDependentCString(mAppData->crashReporterURL));
 
     // We overwrite this once we finish starting up.
-    CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::StartupCrash,
-                                       true);
+    CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("StartupCrash"),
+                                       NS_LITERAL_CSTRING("1"));
 
     // pass some basic info from the app data
     if (mAppData->vendor)
-      CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::Vendor,
+      CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("Vendor"),
                                          nsDependentCString(mAppData->vendor));
     if (mAppData->name)
-      CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::ProductName,
+      CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("ProductName"),
                                          nsDependentCString(mAppData->name));
     if (mAppData->ID)
-      CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::ProductID,
+      CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("ProductID"),
                                          nsDependentCString(mAppData->ID));
     if (mAppData->version)
-      CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::Version,
+      CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("Version"),
                                          nsDependentCString(mAppData->version));
     if (mAppData->buildID)
-      CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::BuildID,
+      CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("BuildID"),
                                          nsDependentCString(mAppData->buildID));
 
     nsDependentCString releaseChannel(NS_STRINGIFY(MOZ_UPDATE_CHANNEL));
-    CrashReporter::AnnotateCrashReport(
-      CrashReporter::Annotation::ReleaseChannel, releaseChannel);
+    CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("ReleaseChannel"),
+                                       releaseChannel);
 #ifdef MOZ_LINKER
-    CrashReporter::AnnotateCrashReport(
-      CrashReporter::Annotation::CrashAddressLikelyWrong,
-      IsSignalHandlingBroken());
+    CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("CrashAddressLikelyWrong"),
+                                       IsSignalHandlingBroken() ? NS_LITERAL_CSTRING("1")
+                                                                : NS_LITERAL_CSTRING("0"));
 #endif
 
 #ifdef XP_WIN
     nsAutoString appInitDLLs;
     if (widget::WinUtils::GetAppInitDLLs(appInitDLLs)) {
-      CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::AppInitDLLs,
+      CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AppInitDLLs"),
                                          NS_ConvertUTF16toUTF8(appInitDLLs));
     }
 #endif
 
     CrashReporter::SetRestartArgs(gArgc, gArgv);
 
     // annotate other data (user id etc)
     nsCOMPtr<nsIFile> userAppDataDir;
@@ -3618,25 +3578,26 @@ XREMain::XRE_mainInit(bool* aExitFlag)
             cpuUpdateRevision = static_cast<int>(updateRevision[0]);
             break;
           }
         }
       }
     }
 
     if (cpuUpdateRevision > 0) {
-      CrashReporter::AnnotateCrashReport(
-        CrashReporter::Annotation::CPUMicrocodeVersion,
-        nsPrintfCString("0x%x", cpuUpdateRevision));
+      CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("CPUMicrocodeVersion"),
+                                         nsPrintfCString("0x%x",
+                                                         cpuUpdateRevision));
     }
   }
 #endif
 
-    CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::SafeMode,
-                                       gSafeMode);
+    CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("SafeMode"),
+                                       gSafeMode ? NS_LITERAL_CSTRING("1") :
+                                                   NS_LITERAL_CSTRING("0"));
 
   // Handle --no-remote and --new-instance command line arguments. Setup
   // the environment to better accommodate other components and various
   // restart scenarios.
   ar = CheckArg("no-remote", nullptr, CheckArgFlag::CheckOSInt | CheckArgFlag::RemoveArg);
   if (ar == ARG_BAD) {
     PR_fprintf(PR_STDERR, "Error: argument --no-remote is invalid when argument --osint is specified\n");
     return 1;
@@ -3749,19 +3710,18 @@ static void AnnotateSystemManufacturer()
   }
 
   VARIANT value;
   VariantInit(&value);
 
   hr = classObject->Get(L"Manufacturer", 0, &value, 0, 0);
 
   if (SUCCEEDED(hr) && V_VT(&value) == VT_BSTR) {
-    CrashReporter::AnnotateCrashReport(
-      CrashReporter::Annotation::BIOS_Manufacturer,
-      NS_ConvertUTF16toUTF8(V_BSTR(&value)));
+    CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("BIOS_Manufacturer"),
+                                       NS_ConvertUTF16toUTF8(V_BSTR(&value)));
   }
 
   VariantClear(&value);
 }
 
 static void PR_CALLBACK AnnotateSystemManufacturer_ThreadStart(void*)
 {
   HRESULT hr = CoInitialize(nullptr);
@@ -4395,33 +4355,34 @@ void AddSandboxAnnotations()
 {
   // Include the sandbox content level, regardless of platform
   int level = GetEffectiveContentSandboxLevel();
 
   nsAutoCString levelString;
   levelString.AppendInt(level);
 
   CrashReporter::AnnotateCrashReport(
-    CrashReporter::Annotation::ContentSandboxLevel, levelString);
+    NS_LITERAL_CSTRING("ContentSandboxLevel"), levelString);
 
   // Include whether or not this instance is capable of content sandboxing
   bool sandboxCapable = false;
 
 #if defined(XP_WIN)
   // All supported Windows versions support some level of content sandboxing
   sandboxCapable = true;
 #elif defined(XP_MACOSX)
   // All supported OS X versions are capable
   sandboxCapable = true;
 #elif defined(XP_LINUX)
   sandboxCapable = SandboxInfo::Get().CanSandboxContent();
 #endif
 
   CrashReporter::AnnotateCrashReport(
-    CrashReporter::Annotation::ContentSandboxCapable, sandboxCapable);
+    NS_LITERAL_CSTRING("ContentSandboxCapable"),
+    sandboxCapable ? NS_LITERAL_CSTRING("1") : NS_LITERAL_CSTRING("0"));
 }
 #endif /* MOZ_CONTENT_SANDBOX */
 
 /*
  * XRE_mainRun - Command line startup, profile migration, and
  * the calling of appStartup->Run().
  */
 nsresult
@@ -4465,28 +4426,26 @@ XREMain::XRE_mainRun()
   if (NS_SUCCEEDED(rv)) {
     nsCOMPtr<nsIPrefBranch> defaultPrefBranch;
     rv = prefs->GetDefaultBranch(nullptr, getter_AddRefs(defaultPrefBranch));
 
     if (NS_SUCCEEDED(rv)) {
       nsAutoCString sval;
       rv = defaultPrefBranch->GetCharPref("app.update.channel", sval);
       if (NS_SUCCEEDED(rv)) {
-        CrashReporter::AnnotateCrashReport(
-          CrashReporter::Annotation::ReleaseChannel, sval);
+        CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("ReleaseChannel"),
+                                            sval);
       }
     }
   }
   // Needs to be set after xpcom initialization.
-  CrashReporter::AnnotateCrashReport(
-    CrashReporter::Annotation::FramePoisonBase,
-    nsPrintfCString("%.16" PRIu64, uint64_t(gMozillaPoisonBase)));
-  CrashReporter::AnnotateCrashReport(
-    CrashReporter::Annotation::FramePoisonSize,
-    uint32_t(gMozillaPoisonSize));
+  CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("FramePoisonBase"),
+                                     nsPrintfCString("%.16" PRIu64, uint64_t(gMozillaPoisonBase)));
+  CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("FramePoisonSize"),
+                                     nsPrintfCString("%" PRIu32, uint32_t(gMozillaPoisonSize)));
 
   bool includeContextHeap =
     Preferences::GetBool("toolkit.crashreporter.include_context_heap", false);
   CrashReporter::SetIncludeContextHeap(includeContextHeap);
 
 #ifdef XP_WIN
   PR_CreateThread(PR_USER_THREAD, AnnotateSystemManufacturer_ThreadStart, 0,
                   PR_PRIORITY_LOW, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD, 0);
@@ -4635,18 +4594,17 @@ XREMain::XRE_mainRun()
   // As FilePreferences need the profile directory, we must initialize right here.
   mozilla::FilePreferences::InitDirectoriesWhitelist();
   mozilla::FilePreferences::InitPrefs();
 
   OverrideDefaultLocaleIfNeeded();
 
   nsCString userAgentLocale;
   LocaleService::GetInstance()->GetAppLocaleAsLangTag(userAgentLocale);
-  CrashReporter::AnnotateCrashReport(
-    CrashReporter::Annotation::useragent_locale, userAgentLocale);
+  CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("useragent_locale"), userAgentLocale);
 
   appStartup->GetShuttingDown(&mShuttingDown);
 
   nsCOMPtr<nsICommandLineRunner> cmdLine;
 
   nsCOMPtr<nsIFile> workingDir;
   rv = NS_GetSpecialDirectory(NS_OS_CURRENT_WORKING_DIR, getter_AddRefs(workingDir));
   NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
@@ -4732,18 +4690,18 @@ XREMain::XRE_mainRun()
 
     nsCOMPtr<nsIObserverService> obsService =
       mozilla::services::GetObserverService();
     if (obsService)
       obsService->NotifyObservers(nullptr, "final-ui-startup", nullptr);
 
     (void)appStartup->DoneStartingUp();
 
-    CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::StartupCrash,
-                                       false);
+    CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("StartupCrash"),
+                                       NS_LITERAL_CSTRING("0"));
 
     appStartup->GetShuttingDown(&mShuttingDown);
   }
 
   if (!mShuttingDown) {
     rv = cmdLine->Run();
     NS_ENSURE_SUCCESS_LOG(rv, NS_ERROR_FAILURE);
 
@@ -4790,17 +4748,17 @@ XREMain::XRE_mainRun()
   Telemetry::Accumulate(Telemetry::SANDBOX_CONTENT_ENABLED,
                         sandboxInfo.Test(SandboxInfo::kEnabledForContent));
   Telemetry::Accumulate(Telemetry::SANDBOX_MEDIA_ENABLED,
                         sandboxInfo.Test(SandboxInfo::kEnabledForMedia));
   nsAutoCString flagsString;
   flagsString.AppendInt(sandboxInfo.AsInteger());
 
   CrashReporter::AnnotateCrashReport(
-    CrashReporter::Annotation::ContentSandboxCapabilities, flagsString);
+    NS_LITERAL_CSTRING("ContentSandboxCapabilities"), flagsString);
 #endif /* MOZ_SANDBOX && XP_LINUX */
 
 #if defined(MOZ_CONTENT_SANDBOX)
   AddSandboxAnnotations();
 #endif /* MOZ_CONTENT_SANDBOX */
 
   {
     rv = appStartup->Run();
--- a/toolkit/xre/nsEmbedFunctions.cpp
+++ b/toolkit/xre/nsEmbedFunctions.cpp
@@ -320,18 +320,20 @@ SetTaskbarGroupId(const nsString& aId)
 #endif
 
 #if defined(MOZ_CONTENT_SANDBOX)
 void
 AddContentSandboxLevelAnnotation()
 {
   if (XRE_GetProcessType() == GeckoProcessType_Content) {
     int level = GetEffectiveContentSandboxLevel();
+    nsAutoCString levelString;
+    levelString.AppendInt(level);
     CrashReporter::AnnotateCrashReport(
-      CrashReporter::Annotation::ContentSandboxLevel, level);
+      NS_LITERAL_CSTRING("ContentSandboxLevel"), levelString);
   }
 }
 #endif /* MOZ_CONTENT_SANDBOX */
 
 namespace {
 
 int GetDebugChildPauseTime() {
   auto pauseStr = PR_GetEnv("MOZ_DEBUG_CHILD_PAUSE");
--- a/widget/android/GfxInfo.cpp
+++ b/widget/android/GfxInfo.cpp
@@ -343,22 +343,29 @@ GfxInfo::GetIsGPU2Active(bool* aIsGPU2Ac
 {
   EnsureInitialized();
   return NS_ERROR_FAILURE;
 }
 
 void
 GfxInfo::AddCrashReportAnnotations()
 {
-  CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::AdapterVendorID,
+  CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AdapterVendorID"),
                                      mGLStrings->Vendor());
-  CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::AdapterDeviceID,
+  CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AdapterDeviceID"),
                                      mGLStrings->Renderer());
-  CrashReporter::AnnotateCrashReport(
-    CrashReporter::Annotation::AdapterDriverVersion, mGLStrings->Version());
+  CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AdapterDriverVersion"),
+                                     mGLStrings->Version());
+
+  /* Add an App Note for now so that we get the data immediately. These
+   * can go away after we store the above in the socorro db */
+  nsAutoCString note;
+  note.AppendPrintf("AdapterDescription: '%s'\n", mAdapterDescription.get());
+
+  CrashReporter::AppendAppNotesToCrashReport(note);
 }
 
 const nsTArray<GfxDriverInfo>&
 GfxInfo::GetGfxDriverInfo()
 {
   if (sDriverInfo->IsEmpty()) {
     APPEND_TO_DRIVER_BLOCKLIST2(OperatingSystem::Android,
       (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorAll), GfxDriverInfo::allDevices,
--- a/widget/android/jni/Utils.cpp
+++ b/widget/android/jni/Utils.cpp
@@ -199,18 +199,18 @@ bool HandleUncaughtException(JNIEnv* aEn
     return true;
 }
 
 bool ReportException(JNIEnv* aEnv, jthrowable aExc, jstring aStack)
 {
     bool result = true;
 
     result &= NS_SUCCEEDED(CrashReporter::AnnotateCrashReport(
-                           CrashReporter::Annotation::JavaStackTrace,
-                           String::Ref::From(aStack)->ToCString()));
+            NS_LITERAL_CSTRING("JavaStackTrace"),
+            String::Ref::From(aStack)->ToCString()));
 
     auto appNotes = java::GeckoAppShell::GetAppNotes();
     if (NS_WARN_IF(aEnv->ExceptionCheck())) {
         aEnv->ExceptionDescribe();
         aEnv->ExceptionClear();
     } else if (appNotes) {
         CrashReporter::AppendAppNotesToCrashReport(NS_LITERAL_CSTRING("\n") +
                                                    appNotes->ToCString());
--- a/widget/android/nsAppShell.cpp
+++ b/widget/android/nsAppShell.cpp
@@ -4,21 +4,23 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsAppShell.h"
 
 #include "base/basictypes.h"
 #include "base/message_loop.h"
 #include "base/task.h"
 #include "mozilla/Hal.h"
+#include "nsExceptionHandler.h"
 #include "nsIScreen.h"
 #include "nsIScreenManager.h"
 #include "nsWindow.h"
 #include "nsThreadUtils.h"
 #include "nsICommandLineRunner.h"
+#include "nsICrashReporter.h"
 #include "nsIObserverService.h"
 #include "nsIAppStartup.h"
 #include "nsIGeolocationProvider.h"
 #include "nsCacheService.h"
 #include "nsIDOMEventListener.h"
 #include "nsIDOMWakeLockListener.h"
 #include "nsIPowerManagerService.h"
 #include "nsISpeculativeConnect.h"
--- a/widget/cocoa/GfxInfo.mm
+++ b/widget/cocoa/GfxInfo.mm
@@ -278,22 +278,31 @@ GfxInfo::AddCrashReportAnnotations()
 
   GetAdapterDeviceID(deviceID);
   CopyUTF16toUTF8(deviceID, narrowDeviceID);
   GetAdapterVendorID(vendorID);
   CopyUTF16toUTF8(vendorID, narrowVendorID);
   GetAdapterDriverVersion(driverVersion);
   CopyUTF16toUTF8(driverVersion, narrowDriverVersion);
 
-  CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::AdapterVendorID,
+  CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AdapterVendorID"),
                                      narrowVendorID);
-  CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::AdapterDeviceID,
+  CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AdapterDeviceID"),
                                      narrowDeviceID);
-  CrashReporter::AnnotateCrashReport(
-    CrashReporter::Annotation::AdapterDriverVersion, narrowDriverVersion);
+  CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AdapterDriverVersion"),
+                                     narrowDriverVersion);
+  /* Add an App Note for now so that we get the data immediately. These
+   * can go away after we store the above in the socorro db */
+  nsAutoCString note;
+  /* AppendPrintf only supports 32 character strings, mrghh. */
+  note.AppendLiteral("AdapterVendorID: ");
+  note.Append(narrowVendorID);
+  note.AppendLiteral(", AdapterDeviceID: ");
+  note.Append(narrowDeviceID);
+  CrashReporter::AppendAppNotesToCrashReport(note);
 }
 
 // We don't support checking driver versions on Mac.
 #define IMPLEMENT_MAC_DRIVER_BLOCKLIST(os, vendor, device, features, blockOn, ruleId) \
   APPEND_TO_DRIVER_BLOCKLIST(os, vendor, device, features, blockOn,           \
                              DRIVER_COMPARISON_IGNORED, V(0,0,0,0), ruleId, "")
 
 
--- a/widget/windows/GfxInfo.cpp
+++ b/widget/windows/GfxInfo.cpp
@@ -888,34 +888,45 @@ GfxInfo::AddCrashReportAnnotations()
   CopyUTF16toUTF8(deviceID, narrowDeviceID);
   GetAdapterVendorID(vendorID);
   CopyUTF16toUTF8(vendorID, narrowVendorID);
   GetAdapterDriverVersion(driverVersion);
   CopyUTF16toUTF8(driverVersion, narrowDriverVersion);
   GetAdapterSubsysID(subsysID);
   CopyUTF16toUTF8(subsysID, narrowSubsysID);
 
-  CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::AdapterVendorID,
+  CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AdapterVendorID"),
                                      narrowVendorID);
-  CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::AdapterDeviceID,
+  CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AdapterDeviceID"),
                                      narrowDeviceID);
-  CrashReporter::AnnotateCrashReport(
-    CrashReporter::Annotation::AdapterDriverVersion, narrowDriverVersion);
-  CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::AdapterSubsysID,
+  CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AdapterDriverVersion"),
+                                     narrowDriverVersion);
+  CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AdapterSubsysID"),
                                      narrowSubsysID);
 
-  /* Add an App Note, this contains extra information. */
+  /* Add an App Note for now so that we get the data immediately. These
+   * can go away after we store the above in the socorro db */
   nsAutoCString note;
+  /* AppendPrintf only supports 32 character strings, mrghh. */
+  note.AppendLiteral("AdapterVendorID: ");
+  note.Append(narrowVendorID);
+  note.AppendLiteral(", AdapterDeviceID: ");
+  note.Append(narrowDeviceID);
+  note.AppendLiteral(", AdapterSubsysID: ");
+  note.Append(narrowSubsysID);
+  note.AppendLiteral(", AdapterDriverVersion: ");
+  note.Append(NS_LossyConvertUTF16toASCII(driverVersion));
 
-  // TODO: We should probably convert this into a proper annotation
   if (vendorID == GfxDriverInfo::GetDeviceVendor(VendorAll)) {
     /* if we didn't find a valid vendorID lets append the mDeviceID string to try to find out why */
+    note.AppendLiteral(", ");
     LossyAppendUTF16toASCII(mDeviceID[mActiveGPUIndex], note);
     note.AppendLiteral(", ");
     LossyAppendUTF16toASCII(mDeviceKeyDebug, note);
+    LossyAppendUTF16toASCII(mDeviceKeyDebug, note);
   }
   note.AppendLiteral("\n");
 
   if (mHasDualGPU) {
     nsString deviceID2, vendorID2, subsysID2;
     nsAutoString adapterDriverVersionString2;
     nsCString narrowDeviceID2, narrowVendorID2, narrowSubsysID2;
 
--- a/widget/windows/LSPAnnotator.cpp
+++ b/widget/windows/LSPAnnotator.cpp
@@ -39,18 +39,17 @@ public:
 
 void
 LSPAnnotationGatherer::Annotate()
 {
   nsCOMPtr<nsICrashReporter> cr =
     do_GetService("@mozilla.org/toolkit/crash-reporter;1");
   bool enabled;
   if (cr && NS_SUCCEEDED(cr->GetEnabled(&enabled)) && enabled) {
-    cr->AnnotateCrashReport(
-      static_cast<uint32_t>(CrashReporter::Annotation::Winsock_LSP), mString);
+    cr->AnnotateCrashReport(NS_LITERAL_CSTRING("Winsock_LSP"), mString);
   }
   mThread->AsyncShutdown();
 }
 
 NS_IMETHODIMP
 LSPAnnotationGatherer::Run()
 {
   NS_SetCurrentThreadName("LSP Annotator");
--- a/xpcom/base/AvailableMemoryTracker.cpp
+++ b/xpcom/base/AvailableMemoryTracker.cpp
@@ -5,16 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/AvailableMemoryTracker.h"
 
 #if defined(XP_WIN)
 #include "nsExceptionHandler.h"
 #include "nsIMemoryReporter.h"
 #include "nsMemoryPressure.h"
+#include "nsPrintfCString.h"
 #endif
 
 #include "nsIObserver.h"
 #include "nsIObserverService.h"
 #include "nsIRunnable.h"
 #include "nsISupports.h"
 #include "nsITimer.h"
 #include "nsThreadUtils.h"
@@ -145,18 +146,18 @@ nsAvailableMemoryWatcher::IsVirtualMemor
 
 /* static */ bool
 nsAvailableMemoryWatcher::IsCommitSpaceLow(const MEMORYSTATUSEX& aStat)
 {
   if ((kLowCommitSpaceThreshold != 0) &&
       (aStat.ullAvailPageFile < kLowCommitSpaceThreshold)) {
     sNumLowCommitSpaceEvents++;
     CrashReporter::AnnotateCrashReport(
-      CrashReporter::Annotation::LowCommitSpaceEvents,
-      uint32_t(sNumLowCommitSpaceEvents));
+      NS_LITERAL_CSTRING("LowCommitSpaceEvents"),
+      nsPrintfCString("%" PRIu32, uint32_t(sNumLowCommitSpaceEvents)));
     return true;
   }
 
   return false;
 }
 
 /* static */ bool
 nsAvailableMemoryWatcher::IsPhysicalMemoryLow(const MEMORYSTATUSEX& aStat)
--- a/xpcom/base/CycleCollectedJSRuntime.cpp
+++ b/xpcom/base/CycleCollectedJSRuntime.cpp
@@ -1468,45 +1468,29 @@ CycleCollectedJSRuntime::FinalizeDeferre
   if (aType == CycleCollectedJSContext::FinalizeIncrementally) {
     NS_IdleDispatchToCurrentThread(do_AddRef(mFinalizeRunnable), 2500);
   } else {
     mFinalizeRunnable->ReleaseNow(false);
     MOZ_ASSERT(!mFinalizeRunnable);
   }
 }
 
-const char*
-CycleCollectedJSRuntime::OOMStateToString(const OOMState aOomState) const
-{
-  switch (aOomState) {
-    case OOMState::OK:
-      return "OK";
-    case OOMState::Reporting:
-      return "Reporting";
-    case OOMState::Reported:
-      return "Reported";
-    case OOMState::Recovered:
-      return "Recovered";
-    default:
-      MOZ_ASSERT_UNREACHABLE("OOMState holds an invalid value");
-      return "Unknown";
-  }
-}
-
 void
 CycleCollectedJSRuntime::AnnotateAndSetOutOfMemory(OOMState* aStatePtr,
                                                    OOMState aNewState)
 {
   *aStatePtr = aNewState;
-  CrashReporter::Annotation annotation = (aStatePtr == &mOutOfMemoryState)
-    ? CrashReporter::Annotation::JSOutOfMemory
-    : CrashReporter::Annotation::JSLargeAllocationFailure;
-
-  CrashReporter::AnnotateCrashReport(
-    annotation, nsDependentCString(OOMStateToString(aNewState)));
+  CrashReporter::AnnotateCrashReport(aStatePtr == &mOutOfMemoryState
+                                     ? NS_LITERAL_CSTRING("JSOutOfMemory")
+                                     : NS_LITERAL_CSTRING("JSLargeAllocationFailure"),
+                                     aNewState == OOMState::Reporting
+                                     ? NS_LITERAL_CSTRING("Reporting")
+                                     : aNewState == OOMState::Reported
+                                     ? NS_LITERAL_CSTRING("Reported")
+                                     : NS_LITERAL_CSTRING("Recovered"));
 }
 
 void
 CycleCollectedJSRuntime::OnGC(JSContext* aContext,
                               JSGCStatus aStatus)
 {
   switch (aStatus) {
     case JSGC_BEGIN:
--- a/xpcom/base/CycleCollectedJSRuntime.h
+++ b/xpcom/base/CycleCollectedJSRuntime.h
@@ -232,18 +232,16 @@ public:
 
     // The condition has happened, but a GC cycle ended since then.
     //
     // GC is taken as a proxy for "we've been banging on the heap a good bit
     // now and haven't crashed; the OOM was probably handled correctly".
     Recovered
   };
 
-  const char* OOMStateToString(const OOMState aOomState) const;
-
   void SetLargeAllocationFailure(OOMState aNewState);
 
   void AnnotateAndSetOutOfMemory(OOMState* aStatePtr, OOMState aNewState);
   void OnGC(JSContext* aContext, JSGCStatus aStatus);
   void OnOutOfMemory();
   void OnLargeAllocationFailure();
 
   JSRuntime* Runtime() { return mJSRuntime; }
--- a/xpcom/base/nsCycleCollector.cpp
+++ b/xpcom/base/nsCycleCollector.cpp
@@ -670,18 +670,17 @@ PtrInfo::AnnotatedReleaseAssert(bool aCo
     return;
   }
 
   const char* piName = "Unknown";
   if (mParticipant) {
     piName = mParticipant->ClassName();
   }
   nsPrintfCString msg("%s, for class %s", aMessage, piName);
-  CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::CycleCollector,
-                                     msg);
+  CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("CycleCollector"), msg);
 
   MOZ_CRASH();
 }
 
 /**
  * A structure designed to be used like a linked list of PtrInfo, except
  * it allocates many PtrInfos at a time.
  */
--- a/xpcom/base/nsDebugImpl.cpp
+++ b/xpcom/base/nsDebugImpl.cpp
@@ -404,19 +404,18 @@ NS_DebugBreak(uint32_t aSeverity, const 
       // have to do without the annotations in that case.
       if (XRE_IsParentProcess()) {
         // Don't include the PID in the crash report annotation to
         // allow faceting on crash-stats.mozilla.org.
         nsCString note("xpcom_runtime_abort(");
         note += nonPIDBuf.buffer;
         note += ")";
         CrashReporter::AppendAppNotesToCrashReport(note);
-        CrashReporter::AnnotateCrashReport(
-          CrashReporter::Annotation::AbortMessage,
-          nsDependentCString(nonPIDBuf.buffer));
+        CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AbortMessage"),
+                                           nsDependentCString(nonPIDBuf.buffer));
       }
 
 #if defined(DEBUG) && defined(_WIN32)
       RealBreak();
 #endif
 #if defined(DEBUG)
       nsTraceRefcnt::WalkTheStack(stderr);
 #endif
--- a/xpcom/system/nsICrashReporter.idl
+++ b/xpcom/system/nsICrashReporter.idl
@@ -71,49 +71,26 @@ interface nsICrashReporter : nsISupports
    * @throw NS_ERROR_FILE_NOT_FOUND if the extra file could not be found
    */
   nsIFile getExtraFileForID(in AString id);
 
   /**
    * Add some extra data to be submitted with a crash report.
    *
    * @param key
-   *        One of the crash annotation constants.
+   *        Name of the data to be added.
    * @param data
    *        Data to be added.
    *
    * @throw NS_ERROR_NOT_INITIALIZED if crash reporting not initialized
-   * @throw NS_ERROR_INVALID_ARG if key contains an invalid value or data
-   *                             contains invalid characters.  Invalid
-   *                             character for data is '\0'.
+   * @throw NS_ERROR_INVALID_ARG if key or data contain invalid characters.
+   *                             Invalid characters for key are '=' and
+   *                             '\n'.  Invalid character for data is '\0'.
    */
-  void annotateCrashReport(in unsigned long key, in AUTF8String data);
-
-  /**
-   * Remove a crash report annotation.
-   *
-   * @param key
-   *        One of the crash annotation constants.
-   *
-   * @throw NS_ERROR_NOT_INITIALIZED if crash reporting not initialized
-   * @throw NS_ERROR_INVALID_ARG if key contains an invalid value.
-   */
-  void removeCrashReportAnnotation(in unsigned long key);
-
-  /**
-   * Checks if an annotation is whitelisted for inclusion in the crash ping.
-   *
-   * @param key
-   *        One of the crash annotation strings.
-   *
-   * @return True if the specified value is a valid annotation and can be
-             included in the crash ping, false otherwise.
-   * @throw NS_ERROR_INVALID_ARG if key contains an invalid value.
-   */
-  boolean isAnnotationWhitelistedForPing(in ACString value);
+  void annotateCrashReport(in AUTF8String key, in AUTF8String data);
 
   /**
    * Append some data to the "Notes" field, to be submitted with a crash report.
    * Unlike annotateCrashReport, this method will append to existing data.
    *
    * @param data
    *        Data to be added.
    *
@@ -139,17 +116,17 @@ interface nsICrashReporter : nsISupports
   /**
    * Write a minidump immediately, with the user-supplied exception
    * information. This is implemented on Windows only, because
    * SEH (structured exception handling) exists on Windows only.
    *
    * @param aExceptionInfo  EXCEPTION_INFO* provided by Window's SEH
    */
   [noscript] void writeMinidumpForException(in voidPtr aExceptionInfo);
-
+  
   /**
    * Append note containing an Obj-C exception's info.
    *
    * @param aException  NSException object to append note for
    */
   [noscript] void appendObjCExceptionInfoToAppNotes(in voidPtr aException);
 
   /**