Merge inbound to mozilla-central. a=merge
authorMargareta Eliza Balazs <ebalazs@mozilla.com>
Thu, 24 May 2018 12:37:58 +0300
changeset 419659 043e4ab6e72469ed8121f4da98dcdfef983a49d9
parent 419633 c411ccb6bb4a46265eaffc89f9bf897e469197d0 (current diff)
parent 419658 7b99c5f0b05eae19a93699766a957ee658fb6856 (diff)
child 419665 a214755e4e46f81a203eddc8fcf490177b831f9a
child 419679 10aff8fde3f2bc15cd7f6b1ae6c55e11081c4172
push id34041
push userebalazs@mozilla.com
push dateThu, 24 May 2018 09:38:21 +0000
treeherdermozilla-central@043e4ab6e724 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone62.0a1
first release with
nightly linux32
043e4ab6e724 / 62.0a1 / 20180524100118 / files
nightly linux64
043e4ab6e724 / 62.0a1 / 20180524100118 / files
nightly mac
043e4ab6e724 / 62.0a1 / 20180524100118 / files
nightly win32
043e4ab6e724 / 62.0a1 / 20180524100118 / files
nightly win64
043e4ab6e724 / 62.0a1 / 20180524100118 / 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
Merge inbound to mozilla-central. a=merge
testing/web-platform/meta/html/dom/dynamic-markup-insertion/document-write/contentType.window.js.ini
--- a/accessible/tests/mochitest/states/a11y.ini
+++ b/accessible/tests/mochitest/states/a11y.ini
@@ -14,17 +14,16 @@ support-files =
 [test_aria.xul]
 [test_aria_imgmap.html]
 [test_aria_widgetitems.html]
 [test_buttons.html]
 [test_controls.html]
 [test_controls.xul]
 [test_doc.html]
 [test_doc_busy.html]
-skip-if = os == 'mac' && os_version == '10.6'
 [test_docarticle.html]
 [test_editablebody.html]
 [test_expandable.xul]
 [test_frames.html]
 [test_inputs.html]
 [test_link.html]
 [test_popup.xul]
 [test_selects.html]
--- a/dom/canvas/test/webgl-conf/generated-mochitest.ini
+++ b/dom/canvas/test/webgl-conf/generated-mochitest.ini
@@ -10690,17 +10690,16 @@ skip-if = (os == 'android')
 [generated/test_conformance__canvas__render-after-resize-test.html]
 [generated/test_conformance__canvas__texture-bindings-unaffected-on-resize.html]
 [generated/test_conformance__canvas__to-data-url-test.html]
 [generated/test_conformance__canvas__viewport-unchanged-upon-resize.html]
 skip-if = (os == 'mac')
 [generated/test_conformance__context__constants-and-properties.html]
 [generated/test_conformance__context__context-attribute-preserve-drawing-buffer.html]
 [generated/test_conformance__context__context-attributes-alpha-depth-stencil-antialias.html]
-fail-if = (os == 'mac' && os_version == '10.6')
 skip-if = (os == 'linux') || (os == 'android')
 [generated/test_conformance__context__context-creation-and-destruction.html]
 [generated/test_conformance__context__context-creation.html]
 skip-if = (os == 'android')
 [generated/test_conformance__context__context-eviction-with-garbage-collection.html]
 skip-if = (os == 'android')
 [generated/test_conformance__context__context-hidden-alpha.html]
 [generated/test_conformance__context__context-lost-restored.html]
@@ -10854,22 +10853,19 @@ skip-if = (os == 'linux') || (os == 'mac
 skip-if = (os == 'linux') || (os == 'mac') || (os == 'android')
 [generated/test_conformance__glsl__constructors__glsl-construct-ivec2.html]
 skip-if = (os == 'linux')
 [generated/test_conformance__glsl__constructors__glsl-construct-ivec3.html]
 skip-if = (os == 'linux') || (os == 'mac') || (os == 'android')
 [generated/test_conformance__glsl__constructors__glsl-construct-ivec4.html]
 skip-if = (os == 'linux') || (os == 'mac')
 [generated/test_conformance__glsl__constructors__glsl-construct-mat2.html]
-fail-if = (os == 'mac' && os_version == '10.6')
 skip-if = ((os == 'linux') && asan)
 [generated/test_conformance__glsl__constructors__glsl-construct-mat3.html]
-fail-if = (os == 'mac' && os_version == '10.6')
 [generated/test_conformance__glsl__constructors__glsl-construct-mat4.html]
-fail-if = (os == 'mac' && os_version == '10.6')
 [generated/test_conformance__glsl__constructors__glsl-construct-vec-mat-corner-cases.html]
 skip-if = (os == 'linux')
 [generated/test_conformance__glsl__constructors__glsl-construct-vec-mat-index.html]
 skip-if = (os == 'mac') || (os == 'win') || (os == 'linux') || (os == 'android')
 [generated/test_conformance__glsl__constructors__glsl-construct-vec2.html]
 [generated/test_conformance__glsl__constructors__glsl-construct-vec3.html]
 skip-if = (os == 'linux')
 [generated/test_conformance__glsl__constructors__glsl-construct-vec4.html]
@@ -10900,17 +10896,16 @@ skip-if = (os == 'linux')
 [generated/test_conformance__glsl__functions__glsl-function-mod-float.html]
 [generated/test_conformance__glsl__functions__glsl-function-mod-gentype.html]
 [generated/test_conformance__glsl__functions__glsl-function-normalize.html]
 [generated/test_conformance__glsl__functions__glsl-function-reflect.html]
 [generated/test_conformance__glsl__functions__glsl-function-sign.html]
 [generated/test_conformance__glsl__functions__glsl-function-sin.html]
 [generated/test_conformance__glsl__functions__glsl-function-smoothstep-float.html]
 [generated/test_conformance__glsl__functions__glsl-function-smoothstep-gentype.html]
-fail-if = (os == 'mac' && os_version == '10.8')
 [generated/test_conformance__glsl__functions__glsl-function-step-float.html]
 [generated/test_conformance__glsl__functions__glsl-function-step-gentype.html]
 skip-if = (os == 'android')
 [generated/test_conformance__glsl__functions__glsl-function.html]
 [generated/test_conformance__glsl__implicit__add_int_float.vert.html]
 [generated/test_conformance__glsl__implicit__add_int_mat2.vert.html]
 [generated/test_conformance__glsl__implicit__add_int_mat3.vert.html]
 [generated/test_conformance__glsl__implicit__add_int_mat4.vert.html]
@@ -10975,29 +10970,27 @@ skip-if = (os == 'android')
 [generated/test_conformance__glsl__implicit__ternary_ivec2_vec2.vert.html]
 [generated/test_conformance__glsl__implicit__ternary_ivec3_vec3.vert.html]
 [generated/test_conformance__glsl__implicit__ternary_ivec4_vec4.vert.html]
 [generated/test_conformance__glsl__literals__float_literal.vert.html]
 [generated/test_conformance__glsl__literals__literal_precision.html]
 [generated/test_conformance__glsl__literals__overflow_leak.vert.html]
 [generated/test_conformance__glsl__matrices__glsl-mat3-construction.html]
 [generated/test_conformance__glsl__matrices__glsl-mat4-to-mat3.html]
-fail-if = (os == 'mac' && os_version == '10.6')
 [generated/test_conformance__glsl__matrices__matrix-compound-multiply.html]
 [generated/test_conformance__glsl__misc__attrib-location-length-limits.html]
 [generated/test_conformance__glsl__misc__boolean_precision.html]
 [generated/test_conformance__glsl__misc__const-variable-initialization.html]
 [generated/test_conformance__glsl__misc__embedded-struct-definitions-forbidden.html]
 [generated/test_conformance__glsl__misc__empty-declaration.html]
 [generated/test_conformance__glsl__misc__empty_main.vert.html]
 [generated/test_conformance__glsl__misc__expression-list-in-declarator-initializer.html]
 [generated/test_conformance__glsl__misc__gl_position_unset.vert.html]
 [generated/test_conformance__glsl__misc__global-variable-init.html]
 [generated/test_conformance__glsl__misc__glsl-function-nodes.html]
-fail-if = (os == 'mac' && os_version == '10.6')
 [generated/test_conformance__glsl__misc__glsl-long-variable-names.html]
 [generated/test_conformance__glsl__misc__glsl-vertex-branch.html]
 [generated/test_conformance__glsl__misc__large-loop-compile.html]
 [generated/test_conformance__glsl__misc__local-variable-shadowing-outer-function.html]
 [generated/test_conformance__glsl__misc__non-ascii-comments.vert.html]
 [generated/test_conformance__glsl__misc__non-ascii.vert.html]
 [generated/test_conformance__glsl__misc__re-compile-re-link.html]
 fail-if = (os == 'android' && android_version == '10')
@@ -11118,22 +11111,20 @@ skip-if = (os == 'android')
 [generated/test_conformance__glsl__samplers__glsl-function-texture2dprojlod.html]
 skip-if = (os == 'android')
 [generated/test_conformance__glsl__variables__gl-fragcoord-xy-values.html]
 [generated/test_conformance__glsl__variables__gl-fragcoord.html]
 skip-if = (os == 'android')
 [generated/test_conformance__glsl__variables__gl-fragdata-and-fragcolor.html]
 [generated/test_conformance__glsl__variables__gl-frontfacing.html]
 [generated/test_conformance__glsl__variables__gl-pointcoord.html]
-fail-if = (os == 'mac' && os_version == '10.8')
 [generated/test_conformance__glsl__variables__glsl-built-ins.html]
 skip-if = (os == 'android')
 [generated/test_conformance__limits__gl-line-width.html]
 [generated/test_conformance__limits__gl-max-texture-dimensions.html]
-fail-if = (os == 'mac' && os_version == '10.8')
 [generated/test_conformance__limits__gl-min-attribs.html]
 [generated/test_conformance__limits__gl-min-textures.html]
 skip-if = (os == 'linux')
 [generated/test_conformance__limits__gl-min-uniforms.html]
 [generated/test_conformance__misc__bad-arguments-test.html]
 skip-if = (os == 'mac') || (os == 'win') || (os == 'linux') || (os == 'android')
 [generated/test_conformance__misc__boolean-argument-conversion.html]
 skip-if = (os == 'android')
@@ -11359,21 +11350,18 @@ fail-if = (os == 'android')
 [generated/test_conformance__ogles__GL__smoothstep__smoothstep_001_to_006.html]
 [generated/test_conformance__ogles__GL__sqrt__sqrt_001_to_006.html]
 [generated/test_conformance__ogles__GL__step__step_001_to_006.html]
 [generated/test_conformance__ogles__GL__struct__struct_001_to_008.html]
 [generated/test_conformance__ogles__GL__struct__struct_009_to_016.html]
 [generated/test_conformance__ogles__GL__struct__struct_017_to_024.html]
 [generated/test_conformance__ogles__GL__struct__struct_025_to_032.html]
 [generated/test_conformance__ogles__GL__struct__struct_033_to_040.html]
-fail-if = (os == 'mac' && os_version == '10.6')
 [generated/test_conformance__ogles__GL__struct__struct_041_to_048.html]
-fail-if = (os == 'mac' && os_version == '10.6')
 [generated/test_conformance__ogles__GL__struct__struct_049_to_056.html]
-fail-if = (os == 'mac' && os_version == '10.6')
 [generated/test_conformance__ogles__GL__swizzlers__swizzlers_001_to_008.html]
 [generated/test_conformance__ogles__GL__swizzlers__swizzlers_009_to_016.html]
 [generated/test_conformance__ogles__GL__swizzlers__swizzlers_017_to_024.html]
 [generated/test_conformance__ogles__GL__swizzlers__swizzlers_025_to_032.html]
 [generated/test_conformance__ogles__GL__swizzlers__swizzlers_033_to_040.html]
 [generated/test_conformance__ogles__GL__swizzlers__swizzlers_041_to_048.html]
 [generated/test_conformance__ogles__GL__swizzlers__swizzlers_049_to_056.html]
 [generated/test_conformance__ogles__GL__swizzlers__swizzlers_057_to_064.html]
@@ -11692,17 +11680,17 @@ fail-if = (os == 'mac')
 [generated/test_conformance__uniforms__no-over-optimization-on-uniform-array-12.html]
 [generated/test_conformance__uniforms__no-over-optimization-on-uniform-array-13.html]
 [generated/test_conformance__uniforms__no-over-optimization-on-uniform-array-14.html]
 [generated/test_conformance__uniforms__no-over-optimization-on-uniform-array-15.html]
 [generated/test_conformance__uniforms__no-over-optimization-on-uniform-array-16.html]
 [generated/test_conformance__uniforms__no-over-optimization-on-uniform-array-17.html]
 [generated/test_conformance__uniforms__null-uniform-location.html]
 [generated/test_conformance__uniforms__out-of-bounds-uniform-array-access.html]
-skip-if = (os == 'android') || (os == 'mac' && os_version == '10.6')
+skip-if = (os == 'android')
 [generated/test_conformance__uniforms__uniform-default-values.html]
 skip-if = (os == 'android') || (os == 'linux') || (os == 'win')
 [generated/test_conformance__uniforms__uniform-location.html]
 [generated/test_conformance__uniforms__uniform-samplers-test.html]
 [generated/test_conformance__uniforms__uniform-values-per-program.html]
 skip-if = (os == 'win')
 [generated/test_deqp__data__gles2__shaders__conditionals.html]
 skip-if = 1
--- a/dom/canvas/test/webgl-conf/mochitest-errata.ini
+++ b/dom/canvas/test/webgl-conf/mochitest-errata.ini
@@ -159,17 +159,16 @@ fail-if = 1
 
 [generated/test_2_conformance2__textures__misc__tex-unpack-params-with-flip-y-and-premultiply-alpha.html]
 fail-if = 1
 
 ########################################################################
 # Complicated
 
 [generated/test_conformance__context__context-attributes-alpha-depth-stencil-antialias.html]
-fail-if = (os == 'mac' && os_version == '10.6')
 # Asserts on linux debug. Crashes on Android.
 skip-if = (os == 'linux') || (os == 'android')
 
 [generated/test_conformance__extensions__webgl-draw-buffers.html]
 # Crashes
 skip-if = (os == 'linux')
 
 [generated/test_conformance__glsl__constructors__glsl-construct-bvec3.html]
@@ -184,17 +183,16 @@ skip-if = (os == 'linux') || (os == 'mac
 # application crashed [@ ParseOperand::GetLogicalSize() const + 0x4]
 # application crashed [@ jemalloc_crash] on Android
 skip-if = (os == 'linux') || (os == 'mac') || (os == 'android')
 [generated/test_conformance__glsl__constructors__glsl-construct-ivec4.html]
 # Assume crashes like ivec3
 skip-if = (os == 'linux') || (os == 'mac')
 
 [generated/test_conformance__glsl__constructors__glsl-construct-mat2.html]
-fail-if = (os == 'mac' && os_version == '10.6')
 # Crashes on Linux ASAN
 skip-if = ((os == 'linux') && asan)
 
 [generated/test_conformance__glsl__bugs__sampler-array-using-loop-index.html]
 # Testfail on Linux after removing SH_UNROLL_FOR_LOOP_WITH_SAMPLER_ARRAY_INDEX.
 # Only happen on tryserver
 fail-if = (os == 'linux')
 
@@ -454,17 +452,17 @@ skip-if = (os == 'android')
 # Crashes on Android
 # Times-out on DEBUG builds
 skip-if = (os == 'android') || debug
 [generated/test_2_conformance__rendering__many-draw-calls.html]
 # Appears to just take too long on debug, most of the time.
 skip-if = debug
 [generated/test_conformance__uniforms__out-of-bounds-uniform-array-access.html]
 # Crashes
-skip-if = (os == 'android') || (os == 'mac' && os_version == '10.6')
+skip-if = (os == 'android')
 [generated/test_conformance__glsl__samplers__glsl-function-texture2dproj.html]
 # Crashes
 skip-if = (os == 'android')
 [generated/test_conformance__rendering__framebuffer-switch.html]
 # Crashes
 skip-if = (os == 'android')
 [generated/test_conformance__glsl__bugs__modulo-arithmetic-accuracy.html]
 # Crashes
@@ -661,42 +659,16 @@ skip-if = (os == 'mac')
 #19:23:02     INFO -     r15 = 0x0000000000000003   rip = 0x000000010b0b61ef
 #19:23:02     INFO -     Found by: call frame info
 skip-if = (os == 'mac')
 [generated/test_conformance__attribs__gl-vertex-attrib-unconsumed-out-of-bounds.html]
 skip-if = (os == 'mac')
 
 
 ####################
-# 10.6
-[generated/test_conformance__glsl__constructors__glsl-construct-mat3.html]
-fail-if = (os == 'mac' && os_version == '10.6')
-[generated/test_conformance__glsl__constructors__glsl-construct-mat4.html]
-fail-if = (os == 'mac' && os_version == '10.6')
-[generated/test_conformance__glsl__matrices__glsl-mat4-to-mat3.html]
-fail-if = (os == 'mac' && os_version == '10.6')
-[generated/test_conformance__glsl__misc__glsl-function-nodes.html]
-fail-if = (os == 'mac' && os_version == '10.6')
-[generated/test_conformance__ogles__GL__struct__struct_033_to_040.html]
-fail-if = (os == 'mac' && os_version == '10.6')
-[generated/test_conformance__ogles__GL__struct__struct_041_to_048.html]
-fail-if = (os == 'mac' && os_version == '10.6')
-[generated/test_conformance__ogles__GL__struct__struct_049_to_056.html]
-fail-if = (os == 'mac' && os_version == '10.6')
-
-####################
-# 10.8
-[generated/test_conformance__glsl__functions__glsl-function-smoothstep-gentype.html]
-fail-if = (os == 'mac' && os_version == '10.8')
-[generated/test_conformance__glsl__variables__gl-pointcoord.html]
-fail-if = (os == 'mac' && os_version == '10.8')
-[generated/test_conformance__limits__gl-max-texture-dimensions.html]
-fail-if = (os == 'mac' && os_version == '10.8')
-
-####################
 # failure on OSX
 [generated/test_2_conformance2__renderbuffers__multisampled-depth-renderbuffer-initialization.html]
 fail-if = (os == 'mac')
 [generated/test_2_conformance2__textures__misc__tex-unpack-params.html]
 skip-if = (os == 'mac' && debug)
 fail-if = (os == 'mac')
 [generated/test_2_conformance2__glsl3__valid-invariant.html]
 fail-if = (os == 'mac')
--- a/dom/console/tests/test_timer.html
+++ b/dom/console/tests/test_timer.html
@@ -6,16 +6,19 @@
   <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 </head>
 <body>
   <script type="application/javascript">
 
 SimpleTest.waitForExplicitFinish();
 
+var reduceTimePrecisionPrevPrefValue = SpecialPowers.getBoolPref("privacy.reduceTimerPrecision");
+SpecialPowers.setBoolPref("privacy.reduceTimerPrecision", false);
+
 function ConsoleListener() {
   SpecialPowers.addObserver(this, "console-api-log-event");
 }
 
 ConsoleListener.prototype = {
   observe(aSubject, aTopic, aData) {
     let obj = aSubject.wrappedJSObject;
     if (obj.arguments[0] != 'test') {
@@ -98,14 +101,16 @@ async function runTest() {
   });
   console.timeLog('test');
   await cl;
   ok(true, "Console.time with error received!");
 }
 
 runTest().then(() => {
   listener.shutdown();
+
+  SpecialPowers.setBoolPref("privacy.reduceTimerPrecision", reduceTimePrecisionPrevPrefValue);
   SimpleTest.finish();
 });
 
   </script>
 </body>
 </html>
--- a/dom/html/ImageDocument.cpp
+++ b/dom/html/ImageDocument.cpp
@@ -268,41 +268,42 @@ ImageDocument::SetScriptGlobalObject(nsI
                                 false);
   }
 
   // Set the script global object on the superclass before doing
   // anything that might require it....
   MediaDocument::SetScriptGlobalObject(aScriptGlobalObject);
 
   if (aScriptGlobalObject) {
-    if (!GetRootElement()) {
+    if (!InitialSetupHasBeenDone()) {
+      MOZ_ASSERT(!GetRootElement(), "Where did the root element come from?");
       // Create synthetic document
 #ifdef DEBUG
       nsresult rv =
 #endif
         CreateSyntheticDocument();
       NS_ASSERTION(NS_SUCCEEDED(rv), "failed to create synthetic document");
 
       target = do_QueryInterface(mImageContent);
       target->AddEventListener(NS_LITERAL_STRING("load"), this, false);
       target->AddEventListener(NS_LITERAL_STRING("click"), this, false);
     }
 
     target = do_QueryInterface(aScriptGlobalObject);
     target->AddEventListener(NS_LITERAL_STRING("resize"), this, false);
     target->AddEventListener(NS_LITERAL_STRING("keypress"), this, false);
 
-    if (GetReadyStateEnum() != nsIDocument::READYSTATE_COMPLETE) {
+    if (!InitialSetupHasBeenDone()) {
       LinkStylesheet(NS_LITERAL_STRING("resource://content-accessible/ImageDocument.css"));
       if (!nsContentUtils::IsChildOfSameType(this)) {
         LinkStylesheet(NS_LITERAL_STRING("resource://content-accessible/TopLevelImageDocument.css"));
         LinkStylesheet(NS_LITERAL_STRING("chrome://global/skin/media/TopLevelImageDocument.css"));
       }
+      InitialSetupDone();
     }
-    BecomeInteractive();
   }
 }
 
 void
 ImageDocument::OnPageShow(bool aPersisted,
                           EventTarget* aDispatchStartTarget)
 {
   if (aPersisted) {
--- a/dom/html/MediaDocument.cpp
+++ b/dom/html/MediaDocument.cpp
@@ -105,17 +105,17 @@ const char* const MediaDocument::sFormat
   "MediaTitleWithNoInfo",    // eWithNoInfo
   "MediaTitleWithFile",      // eWithFile
   "",                        // eWithDim
   ""                         // eWithDimAndFile
 };
 
 MediaDocument::MediaDocument()
     : nsHTMLDocument(),
-      mDocumentElementInserted(false)
+      mDidInitialDocumentSetup(false)
 {
 }
 MediaDocument::~MediaDocument()
 {
 }
 
 nsresult
 MediaDocument::Init()
@@ -182,31 +182,31 @@ MediaDocument::StartDocumentLoad(const c
     SetDocumentCharacterSetSource(source);
     SetDocumentCharacterSet(WrapNotNull(encoding));
   }
 
   return NS_OK;
 }
 
 void
-MediaDocument::BecomeInteractive()
+MediaDocument::InitialSetupDone()
 {
-  // Even though our readyState code isn't really reliable, here we pretend
-  // that it is and conclude that we are restoring from the b/f cache if
-  // GetReadyStateEnum() == nsIDocument::READYSTATE_COMPLETE.
-  if (GetReadyStateEnum() != nsIDocument::READYSTATE_COMPLETE) {
-    MOZ_ASSERT(GetReadyStateEnum() == nsIDocument::READYSTATE_LOADING,
-               "Bad readyState");
-    SetReadyStateInternal(nsIDocument::READYSTATE_INTERACTIVE);
-  }
+  MOZ_ASSERT(GetReadyStateEnum() == nsIDocument::READYSTATE_LOADING,
+             "Bad readyState: we should still be doing our initial load");
+  mDidInitialDocumentSetup = true;
+  nsContentUtils::AddScriptRunner(
+    new nsDocElementCreatedNotificationRunner(this));
+  SetReadyStateInternal(nsIDocument::READYSTATE_INTERACTIVE);
 }
 
 nsresult
 MediaDocument::CreateSyntheticDocument()
 {
+  MOZ_ASSERT(!InitialSetupHasBeenDone());
+
   // Synthesize an empty html document
   nsresult rv;
 
   RefPtr<mozilla::dom::NodeInfo> nodeInfo;
   nodeInfo = mNodeInfoManager->GetNodeInfo(nsGkAtoms::html, nullptr,
                                            kNameSpaceID_XHTML,
                                            nsINode::ELEMENT_NODE);
 
@@ -413,21 +413,10 @@ MediaDocument::UpdateTitleAndCharset(con
     const char16_t *formatStrings[2] = {title.get(), status.get()};
     mStringBundle->FormatStringFromName("TitleWithStatus", formatStrings,
                                         2, titleWithStatus);
     IgnoredErrorResult ignored;
     SetTitle(titleWithStatus, ignored);
   }
 }
 
-void
-MediaDocument::SetScriptGlobalObject(nsIScriptGlobalObject* aGlobalObject)
-{
-    nsHTMLDocument::SetScriptGlobalObject(aGlobalObject);
-    if (!mDocumentElementInserted && aGlobalObject) {
-        mDocumentElementInserted = true;
-        nsContentUtils::AddScriptRunner(
-            new nsDocElementCreatedNotificationRunner(this));
-    }
-}
-
 } // namespace dom
 } // namespace mozilla
--- a/dom/html/MediaDocument.h
+++ b/dom/html/MediaDocument.h
@@ -28,25 +28,33 @@ public:
   virtual nsresult StartDocumentLoad(const char*         aCommand,
                                      nsIChannel*         aChannel,
                                      nsILoadGroup*       aLoadGroup,
                                      nsISupports*        aContainer,
                                      nsIStreamListener** aDocListener,
                                      bool                aReset = true,
                                      nsIContentSink*     aSink = nullptr) override;
 
-  virtual void SetScriptGlobalObject(nsIScriptGlobalObject* aGlobalObject) override;
-
   virtual bool WillIgnoreCharsetOverride() override
   {
     return true;
   }
 
 protected:
-  void BecomeInteractive();
+  // Hook to be called once our initial document setup is done.  Subclasses
+  // should call this from SetScriptGlobalObject when setup hasn't been done
+  // yet, a non-null script global is being set, and they have finished whatever
+  // setup work they plan to do for an initial load.
+  void InitialSetupDone();
+
+  // Check whether initial setup has been done.
+  MOZ_MUST_USE bool InitialSetupHasBeenDone() const
+  {
+    return mDidInitialDocumentSetup;
+  }
 
   virtual nsresult CreateSyntheticDocument();
 
   friend class MediaDocumentStreamListener;
   nsresult StartLayout();
 
   void GetFileName(nsAString& aResult, nsIChannel* aChannel);
 
@@ -71,17 +79,21 @@ protected:
                              int32_t            aHeight = 0,
                              const nsAString&   aStatus = EmptyString());
 
   nsCOMPtr<nsIStringBundle>     mStringBundle;
   static const char* const      sFormatNames[4];
 
 private:
   enum                          {eWithNoInfo, eWithFile, eWithDim, eWithDimAndFile};
-  bool                          mDocumentElementInserted;
+
+  // A boolean that indicates whether we did our initial document setup.  This
+  // will be false initially, become true when we finish setting up the document
+  // during initial load and stay true thereafter.
+  bool                          mDidInitialDocumentSetup;
 };
 
 
 class MediaDocumentStreamListener: public nsIStreamListener
 {
 protected:
   virtual ~MediaDocumentStreamListener();
 
--- a/dom/html/PluginDocument.cpp
+++ b/dom/html/PluginDocument.cpp
@@ -125,25 +125,25 @@ NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHER
 void
 PluginDocument::SetScriptGlobalObject(nsIScriptGlobalObject* aScriptGlobalObject)
 {
   // Set the script global object on the superclass before doing
   // anything that might require it....
   MediaDocument::SetScriptGlobalObject(aScriptGlobalObject);
 
   if (aScriptGlobalObject) {
-    if (!mPluginContent) {
+    if (!InitialSetupHasBeenDone()) {
       // Create synthetic document
 #ifdef DEBUG
       nsresult rv =
 #endif
         CreateSyntheticPluginDocument();
       NS_ASSERTION(NS_SUCCEEDED(rv), "failed to create synthetic document");
+      InitialSetupDone();
     }
-    BecomeInteractive();
   } else {
     mStreamListener = nullptr;
   }
 }
 
 
 bool
 PluginDocument::CanSavePresentation(nsIRequest* aNewRequest)
--- a/dom/html/VideoDocument.cpp
+++ b/dom/html/VideoDocument.cpp
@@ -74,24 +74,23 @@ VideoDocument::StartDocumentLoad(const c
 
 void
 VideoDocument::SetScriptGlobalObject(nsIScriptGlobalObject* aScriptGlobalObject)
 {
   // Set the script global object on the superclass before doing
   // anything that might require it....
   MediaDocument::SetScriptGlobalObject(aScriptGlobalObject);
 
-  if (aScriptGlobalObject) {
-    if (!nsContentUtils::IsChildOfSameType(this) &&
-        GetReadyStateEnum() != nsIDocument::READYSTATE_COMPLETE) {
+  if (aScriptGlobalObject && !InitialSetupHasBeenDone()) {
+    if (!nsContentUtils::IsChildOfSameType(this)) {
       LinkStylesheet(NS_LITERAL_STRING("resource://content-accessible/TopLevelVideoDocument.css"));
       LinkStylesheet(NS_LITERAL_STRING("chrome://global/skin/media/TopLevelVideoDocument.css"));
       LinkScript(NS_LITERAL_STRING("chrome://global/content/TopLevelVideoDocument.js"));
     }
-    BecomeInteractive();
+    InitialSetupDone();
   }
 }
 
 nsresult
 VideoDocument::CreateSyntheticVideoDocument(nsIChannel* aChannel,
                                             nsIStreamListener** aListener)
 {
   // make our generic document
--- a/dom/media/test/mochitest.ini
+++ b/dom/media/test/mochitest.ini
@@ -709,17 +709,17 @@ skip-if = android_version == '23' # bug 
 skip-if = android_version == '23' # bug 1424903
 [test_buffered.html]
 skip-if = android_version == '15' || android_version == '22' # bug 1308388, android(bug 1232305)
 [test_bug448534.html]
 [test_bug463162.xhtml]
 [test_bug465498.html]
 skip-if = toolkit == 'android' # android(bug 1232305)
 [test_bug495145.html]
-skip-if = (os == 'mac' && os_version == '10.6') || (toolkit == 'android')  # bug 1311229, android(bug 1232305)
+skip-if = toolkit == 'android' # android(bug 1232305)
 [test_bug495300.html]
 skip-if = toolkit == 'android' # bug 1243801, android(bug 1232305)
 [test_bug654550.html]
 skip-if = toolkit == 'android' # android(bug 1232305)
 [test_bug686942.html]
 skip-if = toolkit == 'android' # bug 896723, android(bug 1232305)
 [test_bug726904.html]
 skip-if = android_version == '17' # android(bug 1232305)
--- a/js/src/builtin/TypedObject.cpp
+++ b/js/src/builtin/TypedObject.cpp
@@ -1344,17 +1344,17 @@ TypedObject::typedMemBase() const
         return owner.as<ArrayBufferObject>().dataPointer();
     return owner.as<InlineTypedObject>().inlineTypedMem();
 }
 
 bool
 TypedObject::isAttached() const
 {
     if (is<InlineTransparentTypedObject>()) {
-        ObjectWeakMap* table = compartment()->lazyArrayBuffers;
+        ObjectWeakMap* table = compartment()->lazyArrayBuffers.get();
         if (table) {
             JSObject* buffer = table->lookup(this);
             if (buffer)
                 return !buffer->as<ArrayBufferObject>().isDetached();
         }
         return true;
     }
     if (is<InlineOpaqueTypedObject>())
@@ -2138,23 +2138,26 @@ InlineTypedObject::obj_moved(JSObject* d
     }
 
     return 0;
 }
 
 ArrayBufferObject*
 InlineTransparentTypedObject::getOrCreateBuffer(JSContext* cx)
 {
-    ObjectWeakMap*& table = cx->compartment()->lazyArrayBuffers;
-    if (!table) {
-        table = cx->new_<ObjectWeakMap>(cx);
+    if (!cx->compartment()->lazyArrayBuffers) {
+        auto table = cx->make_unique<ObjectWeakMap>(cx);
         if (!table || !table->init())
             return nullptr;
+
+        cx->compartment()->lazyArrayBuffers = Move(table);
     }
 
+    ObjectWeakMap* table = cx->compartment()->lazyArrayBuffers.get();
+
     JSObject* obj = table->lookup(this);
     if (obj)
         return &obj->as<ArrayBufferObject>();
 
     ArrayBufferObject::BufferContents contents =
         ArrayBufferObject::BufferContents::createPlain(inlineTypedMem());
     size_t nbytes = typeDescr().size();
 
--- a/js/src/jit/BaselineCacheIRCompiler.cpp
+++ b/js/src/jit/BaselineCacheIRCompiler.cpp
@@ -4,16 +4,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "jit/BaselineCacheIRCompiler.h"
 
 #include "jit/CacheIR.h"
 #include "jit/Linker.h"
 #include "jit/SharedICHelpers.h"
+#include "proxy/DeadObjectProxy.h"
 #include "proxy/Proxy.h"
 
 #include "jit/MacroAssembler-inl.h"
 #include "jit/SharedICHelpers-inl.h"
 #include "vm/JSCompartment-inl.h"
 #include "vm/JSContext-inl.h"
 
 using namespace js;
@@ -281,23 +282,29 @@ BaselineCacheIRCompiler::emitGuardProto(
     masm.branchPtr(Assembler::NotEqual, addr, scratch, failure->label());
     return true;
 }
 
 bool
 BaselineCacheIRCompiler::emitGuardCompartment()
 {
     Register obj = allocator.useRegister(masm, reader.objOperandId());
-    reader.stubOffset(); // Read global wrapper.
     AutoScratchRegister scratch(allocator, masm);
 
     FailurePath* failure;
     if (!addFailurePath(&failure))
         return false;
 
+    // Verify that the global wrapper is still valid, as
+    // it is pre-requisite for doing the compartment check.
+    Address globalWrapper(stubAddress(reader.stubOffset()));
+    masm.loadPtr(globalWrapper, scratch);
+    Address handlerAddr(scratch, ProxyObject::offsetOfHandler());
+    masm.branchPtr(Assembler::Equal, handlerAddr, ImmPtr(&DeadObjectProxy::singleton), failure->label());
+
     Address addr(stubAddress(reader.stubOffset()));
     masm.branchTestObjCompartment(Assembler::NotEqual, obj, addr, scratch, failure->label());
     return true;
 }
 
 bool
 BaselineCacheIRCompiler::emitGuardAnyClass()
 {
--- a/js/src/jit/BaselineIC.cpp
+++ b/js/src/jit/BaselineIC.cpp
@@ -4041,21 +4041,21 @@ ICIteratorMore_Native::Compiler::generat
     AllocatableGeneralRegisterSet regs(availableGeneralRegs(1));
     Register nativeIterator = regs.takeAny();
     Register scratch = regs.takeAny();
 
     masm.branchTestObjClass(Assembler::NotEqual, obj, &PropertyIteratorObject::class_, scratch,
                             obj, &failure);
     masm.loadObjPrivate(obj, JSObject::ITER_CLASS_NFIXED_SLOTS, nativeIterator);
 
-    // If props_cursor < props_end, load the next string and advance the cursor.
-    // Else, return MagicValue(JS_NO_ITER_VALUE).
+    // If propertyCursor_ < propertiesEnd_, load the next string and advance
+    // the cursor.  Otherwise return MagicValue(JS_NO_ITER_VALUE).
     Label iterDone;
-    Address cursorAddr(nativeIterator, offsetof(NativeIterator, props_cursor));
-    Address cursorEndAddr(nativeIterator, offsetof(NativeIterator, props_end));
+    Address cursorAddr(nativeIterator, NativeIterator::offsetOfPropertyCursor());
+    Address cursorEndAddr(nativeIterator, NativeIterator::offsetOfPropertiesEnd());
     masm.loadPtr(cursorAddr, scratch);
     masm.branchPtr(Assembler::BelowOrEqual, cursorEndAddr, scratch, &iterDone);
 
     // Get next string.
     masm.loadPtr(Address(scratch, 0), scratch);
 
     // Increase the cursor.
     masm.addPtr(Imm32(sizeof(JSString*)), cursorAddr);
--- a/js/src/jit/CacheIR.cpp
+++ b/js/src/jit/CacheIR.cpp
@@ -11,31 +11,36 @@
 
 #include "jit/BaselineCacheIRCompiler.h"
 #include "jit/BaselineIC.h"
 #include "jit/CacheIRSpewer.h"
 #include "vm/SelfHosting.h"
 
 #include "jit/MacroAssembler-inl.h"
 #include "vm/EnvironmentObject-inl.h"
+#include "vm/JSContext-inl.h"
 #include "vm/JSObject-inl.h"
 #include "vm/UnboxedObject-inl.h"
 
 using namespace js;
 using namespace js::jit;
 
 using mozilla::DebugOnly;
 using mozilla::Maybe;
 
 const char* js::jit::CacheKindNames[] = {
 #define DEFINE_KIND(kind) #kind,
     CACHE_IR_KINDS(DEFINE_KIND)
 #undef DEFINE_KIND
 };
 
+void
+CacheIRWriter::assertSameCompartment(JSObject* obj) {
+    assertSameCompartmentDebugOnly(cx_, obj);
+}
 
 IRGenerator::IRGenerator(JSContext* cx, HandleScript script, jsbytecode* pc, CacheKind cacheKind,
                          ICState::Mode mode)
   : writer(cx),
     cx_(cx),
     script_(script),
     pc_(pc),
     cacheKind_(cacheKind),
@@ -727,16 +732,43 @@ GeneratePrototypeHoleGuards(CacheIRWrite
 
         // Also make sure there are no dense elements.
         writer.guardNoDenseElements(protoId);
 
         pobj = pobj->staticPrototype();
     }
 }
 
+// Similar to |TestMatchingReceiver|, but for the holder object (when it
+// differs from the receiver). The holder may also be the expando of the
+// receiver if it exists.
+static void
+TestMatchingHolder(CacheIRWriter& writer, JSObject* obj, ObjOperandId objId)
+{
+    // The GeneratePrototypeGuards + TestMatchingHolder checks only support
+    // prototype chains composed of NativeObject (excluding the receiver
+    // itself).
+    MOZ_ASSERT(obj->is<NativeObject>());
+
+    writer.guardShapeForOwnProperties(objId, obj->as<NativeObject>().lastProperty());
+}
+
+static bool
+UncacheableProtoOnChain(JSObject* obj)
+{
+    while (true) {
+        if (obj->hasUncacheableProto())
+            return true;
+
+        obj = obj->staticPrototype();
+        if (!obj)
+            return false;
+    }
+}
+
 static void
 ShapeGuardProtoChain(CacheIRWriter& writer, JSObject* obj, ObjOperandId objId)
 {
     while (true) {
         // Guard on the proto if the shape does not imply the proto.
         bool guardProto = obj->hasUncacheableProto();
 
         obj = obj->staticPrototype();
@@ -745,64 +777,91 @@ ShapeGuardProtoChain(CacheIRWriter& writ
 
         objId = writer.loadProto(objId);
         if (guardProto)
             writer.guardSpecificObject(objId, obj);
         writer.guardShape(objId, obj->as<NativeObject>().shape());
     }
 }
 
-// Similar to |TestMatchingReceiver|, but for the holder object (when it
-// differs from the receiver). The holder may also be the expando of the
-// receiver if it exists.
+// For cross compartment guards we shape-guard the prototype chain to avoid
+// referencing the holder object.
+//
+// This peels off the first layer because it's guarded against obj == holder.
 static void
-TestMatchingHolder(CacheIRWriter& writer, JSObject* obj, ObjOperandId objId)
+ShapeGuardProtoChainForCrossCompartmentHolder(CacheIRWriter& writer, JSObject* obj,
+                                              ObjOperandId objId, JSObject* holder,
+                                              Maybe<ObjOperandId>* holderId)
 {
-    // The GeneratePrototypeGuards + TestMatchingHolder checks only support
-    // prototype chains composed of NativeObject (excluding the receiver
-    // itself).
-    MOZ_ASSERT(obj->is<NativeObject>());
-
-    writer.guardShapeForOwnProperties(objId, obj->as<NativeObject>().lastProperty());
+    MOZ_ASSERT(obj != holder);
+    MOZ_ASSERT(holder);
+    while (true) {
+        obj = obj->staticPrototype();
+        MOZ_ASSERT(obj);
+
+        objId = writer.loadProto(objId);
+        if (obj == holder) {
+            TestMatchingHolder(writer, obj, objId);
+            holderId->emplace(objId);
+            return;
+        } else {
+            writer.guardShapeForOwnProperties(objId, obj->as<NativeObject>().shape());
+        }
+    }
 }
 
+enum class SlotReadType {
+    Normal,
+    CrossCompartment
+};
+
+template <SlotReadType MaybeCrossCompartment = SlotReadType::Normal>
 static void
 EmitReadSlotGuard(CacheIRWriter& writer, JSObject* obj, JSObject* holder,
                   ObjOperandId objId, Maybe<ObjOperandId>* holderId)
 {
     Maybe<ObjOperandId> expandoId;
     TestMatchingReceiver(writer, obj, objId, &expandoId);
 
     if (obj != holder) {
         if (holder) {
-            // Guard proto chain integrity.
-            GeneratePrototypeGuards(writer, obj, holder, objId);
-
-            // Guard on the holder's shape.
-            holderId->emplace(writer.loadObject(holder));
-            TestMatchingHolder(writer, holder, holderId->ref());
+            if (MaybeCrossCompartment == SlotReadType::CrossCompartment) {
+                // Guard proto chain integrity.
+                // We use a variant of guards that avoid baking in any cross-compartment
+                // object pointers.
+                ShapeGuardProtoChainForCrossCompartmentHolder(writer, obj, objId, holder,
+                                                              holderId);
+            } else {
+                // Guard proto chain integrity.
+                GeneratePrototypeGuards(writer, obj, holder, objId);
+
+                // Guard on the holder's shape.
+                holderId->emplace(writer.loadObject(holder));
+                TestMatchingHolder(writer, holder, holderId->ref());
+            }
         } else {
             // The property does not exist. Guard on everything in the prototype
             // chain. This is guaranteed to see only Native objects because of
             // CanAttachNativeGetProp().
             ShapeGuardProtoChain(writer, obj, objId);
         }
     } else if (obj->is<UnboxedPlainObject>()) {
         holderId->emplace(*expandoId);
     } else {
         holderId->emplace(objId);
     }
 }
 
+template <SlotReadType MaybeCrossCompartment = SlotReadType::Normal>
 static void
 EmitReadSlotResult(CacheIRWriter& writer, JSObject* obj, JSObject* holder,
                    Shape* shape, ObjOperandId objId)
 {
     Maybe<ObjOperandId> holderId;
-    EmitReadSlotGuard(writer, obj, holder, objId, &holderId);
+    EmitReadSlotGuard<MaybeCrossCompartment>(writer, obj, holder, objId, &holderId);
 
     if (obj == holder && obj->is<UnboxedPlainObject>())
         holder = obj->as<UnboxedPlainObject>().maybeExpando();
 
     // Slot access.
     if (holder) {
         MOZ_ASSERT(holderId->valid());
         EmitLoadSlotResult(writer, *holderId, &holder->as<NativeObject>(), shape);
@@ -1039,70 +1098,87 @@ GetPropIRGenerator::tryAttachCrossCompar
 
     RootedObject unwrapped(cx_, Wrapper::wrappedObject(obj));
     MOZ_ASSERT(unwrapped == UnwrapOneChecked(obj));
 
     // If we allowed different zones we would have to wrap strings.
     if (unwrapped->compartment()->zone() != cx_->compartment()->zone())
         return false;
 
-    RootedObject wrappedGlobal(cx_, &obj->global());
-    if (!cx_->compartment()->wrap(cx_, &wrappedGlobal))
-        return false;
-
-    AutoRealm ar(cx_, unwrapped);
-
-    // The first CCW for iframes is almost always wrapping another WindowProxy
-    // so we optimize for that case as well.
-    bool isWindowProxy = IsWindowProxy(unwrapped);
-    if (isWindowProxy) {
-        MOZ_ASSERT(ToWindowIfWindowProxy(unwrapped) == unwrapped->realm()->maybeGlobal());
-        unwrapped = cx_->global();
-        MOZ_ASSERT(unwrapped);
-    }
-
+    // Take the unwrapped object's global, and wrap in a
+    // this-compartment wrapper. This is what will be stored in the IC
+    // keep the compartment alive.
+    RootedObject wrappedTargetGlobal(cx_, &unwrapped->global());
+    if (!cx_->compartment()->wrap(cx_, &wrappedTargetGlobal))
+        return false;
+
+    bool isWindowProxy = false;
     RootedShape shape(cx_);
     RootedNativeObject holder(cx_);
-    NativeGetPropCacheability canCache =
-        CanAttachNativeGetProp(cx_, unwrapped, id, &holder, &shape, pc_,
-                               resultFlags_, isTemporarilyUnoptimizable_);
-    if (canCache != CanAttachReadSlot)
-        return false;
-
-    if (holder) {
-        EnsureTrackPropertyTypes(cx_, holder, id);
-        if (unwrapped == holder) {
-            // See the comment in StripPreliminaryObjectStubs.
-            if (IsPreliminaryObject(unwrapped))
-                preliminaryObjectAction_ = PreliminaryObjectAction::NotePreliminary;
-            else
-                preliminaryObjectAction_ = PreliminaryObjectAction::Unlink;
+
+    // Enter compartment of target since some checks have side-effects
+    // such as de-lazifying type info.
+    {
+        AutoRealm ar(cx_, unwrapped);
+
+        // The first CCW for iframes is almost always wrapping another WindowProxy
+        // so we optimize for that case as well.
+        isWindowProxy = IsWindowProxy(unwrapped);
+        if (isWindowProxy) {
+            MOZ_ASSERT(ToWindowIfWindowProxy(unwrapped) == unwrapped->realm()->maybeGlobal());
+            unwrapped = cx_->global();
+            MOZ_ASSERT(unwrapped);
+        }
+
+        NativeGetPropCacheability canCache =
+            CanAttachNativeGetProp(cx_, unwrapped, id, &holder, &shape, pc_,
+                                resultFlags_, isTemporarilyUnoptimizable_);
+        if (canCache != CanAttachReadSlot)
+            return false;
+
+        if (holder) {
+            // Need to be in the compartment of the holder to
+            // call EnsureTrackPropertyTypes
+            EnsureTrackPropertyTypes(cx_, holder, id);
+            if (unwrapped == holder) {
+                // See the comment in StripPreliminaryObjectStubs.
+                if (IsPreliminaryObject(unwrapped))
+                    preliminaryObjectAction_ = PreliminaryObjectAction::NotePreliminary;
+                else
+                    preliminaryObjectAction_ = PreliminaryObjectAction::Unlink;
+            }
+        } else {
+            // UNCACHEABLE_PROTO may result in guards against specific (cross-compartment)
+            // prototype objects, so don't try to attach IC if we see the flag at all.
+            if (UncacheableProtoOnChain(unwrapped)) {
+                return false;
+            }
         }
     }
 
     maybeEmitIdGuard(id);
     writer.guardIsProxy(objId);
     writer.guardHasProxyHandler(objId, Wrapper::wrapperHandler(obj));
 
     // Load the object wrapped by the CCW
     ObjOperandId wrapperTargetId = writer.loadWrapperTarget(objId);
 
     // If the compartment of the wrapped object is different we should fail.
-    writer.guardCompartment(wrapperTargetId, wrappedGlobal, unwrapped->compartment());
+    writer.guardCompartment(wrapperTargetId, wrappedTargetGlobal, unwrapped->compartment());
 
     ObjOperandId unwrappedId = wrapperTargetId;
     if (isWindowProxy) {
         // For the WindowProxy case also unwrap the inner window.
         // We avoid loadObject, because storing cross compartment objects in
         // stubs / JIT code is tricky.
         writer.guardClass(wrapperTargetId, GuardClassKind::WindowProxy);
         unwrappedId = writer.loadWrapperTarget(wrapperTargetId);
     }
 
-    EmitReadSlotResult(writer, unwrapped, holder, shape, unwrappedId);
+    EmitReadSlotResult<SlotReadType::CrossCompartment>(writer, unwrapped, holder, shape, unwrappedId);
     EmitReadSlotReturn(writer, unwrapped, holder, shape, /* wrapResult = */ true);
 
     trackAttached("CCWSlot");
     return true;
 }
 
 static bool
 GetXrayExpandoShapeWrapper(JSContext* cx, HandleObject xray, MutableHandleObject wrapper)
--- a/js/src/jit/CacheIR.h
+++ b/js/src/jit/CacheIR.h
@@ -390,16 +390,17 @@ enum class GuardClassKind : uint8_t
 // zone, which refer to the actual shape via a reserved slot.
 JSObject* NewWrapperWithObjectShape(JSContext* cx, HandleNativeObject obj);
 
 void LoadShapeWrapperContents(MacroAssembler& masm, Register obj, Register dst, Label* failure);
 
 // Class to record CacheIR + some additional metadata for code generation.
 class MOZ_RAII CacheIRWriter : public JS::CustomAutoRooter
 {
+    JSContext* cx_;
     CompactBufferWriter buffer_;
 
     uint32_t nextOperandId_;
     uint32_t nextInstructionId_;
     uint32_t numInputOperands_;
 
     // The data (shapes, slot offsets, etc.) that will be stored in the ICStub.
     Vector<StubField, 8, SystemAllocPolicy> stubFields_;
@@ -410,16 +411,18 @@ class MOZ_RAII CacheIRWriter : public JS
     Vector<uint32_t, 8, SystemAllocPolicy> operandLastUsed_;
 
     // OperandId and stub offsets are stored in a single byte, so make sure
     // this doesn't overflow. We use a very conservative limit for now.
     static const size_t MaxOperandIds = 20;
     static const size_t MaxStubDataSizeInBytes = 20 * sizeof(uintptr_t);
     bool tooLarge_;
 
+    void assertSameCompartment(JSObject*);
+
     void writeOp(CacheOp op) {
         MOZ_ASSERT(uint32_t(op) <= UINT8_MAX);
         buffer_.writeByte(uint32_t(op));
         nextInstructionId_++;
     }
 
     void writeOperandId(OperandId opId) {
         if (opId.id() < MaxOperandIds) {
@@ -466,16 +469,17 @@ class MOZ_RAII CacheIRWriter : public JS
     }
 
     CacheIRWriter(const CacheIRWriter&) = delete;
     CacheIRWriter& operator=(const CacheIRWriter&) = delete;
 
   public:
     explicit CacheIRWriter(JSContext* cx)
       : CustomAutoRooter(cx),
+        cx_(cx),
         nextOperandId_(0),
         nextInstructionId_(0),
         numInputOperands_(0),
         stubDataSize_(0),
         tooLarge_(false)
     {}
 
     bool failed() const { return buffer_.oom() || tooLarge_; }
@@ -580,18 +584,20 @@ class MOZ_RAII CacheIRWriter : public JS
     }
     void guardShapeForOwnProperties(ObjOperandId obj, Shape* shape) {
         // Guard shape to detect changes to (non-dense) own properties. This
         // also implies |guardShapeForClass|.
         MOZ_ASSERT(shape->getObjectClass()->isNative());
         guardShape(obj, shape);
     }
     void guardXrayExpandoShapeAndDefaultProto(ObjOperandId obj, JSObject* shapeWrapper) {
+        assertSameCompartment(shapeWrapper);
         writeOpWithOperandId(CacheOp::GuardXrayExpandoShapeAndDefaultProto, obj);
-        buffer_.writeByte(uint32_t(!!shapeWrapper));        addStubField(uintptr_t(shapeWrapper), StubField::Type::JSObject);
+        buffer_.writeByte(uint32_t(!!shapeWrapper));
+        addStubField(uintptr_t(shapeWrapper), StubField::Type::JSObject);
     }
     // Guard rhs[slot] == prototypeObject
     void guardFunctionPrototype(ObjOperandId rhs, uint32_t slot, ObjOperandId protoId) {
         writeOpWithOperandId(CacheOp::GuardFunctionPrototype, rhs);
         writeOperandId(protoId);
         addStubField(slot, StubField::Type::RawWord);
     }
   private:
@@ -616,16 +622,17 @@ class MOZ_RAII CacheIRWriter : public JS
     void guardGroupForLayout(ObjOperandId obj, ObjectGroup* group) {
         // NOTE: Comment in guardGroupForTypeBarrier also applies.
         MOZ_ASSERT(!group->hasUncacheableClass());
         MOZ_ASSERT(IsUnboxedObjectClass(group->clasp()) ||
                    IsTypedObjectClass(group->clasp()));
         guardGroup(obj, group);
     }
     void guardProto(ObjOperandId obj, JSObject* proto) {
+        assertSameCompartment(proto);
         writeOpWithOperandId(CacheOp::GuardProto, obj);
         addStubField(uintptr_t(proto), StubField::Type::JSObject);
     }
     void guardClass(ObjOperandId obj, GuardClassKind kind) {
         static_assert(sizeof(GuardClassKind) == sizeof(uint8_t),
                       "GuardClassKind must fit in a byte");
         writeOpWithOperandId(CacheOp::GuardClass, obj);
         buffer_.writeByte(uint32_t(kind));
@@ -647,16 +654,17 @@ class MOZ_RAII CacheIRWriter : public JS
     void guardHasProxyHandler(ObjOperandId obj, const void* handler) {
         writeOpWithOperandId(CacheOp::GuardHasProxyHandler, obj);
         addStubField(uintptr_t(handler), StubField::Type::RawWord);
     }
     void guardNotDOMProxy(ObjOperandId obj) {
         writeOpWithOperandId(CacheOp::GuardNotDOMProxy, obj);
     }
     void guardSpecificObject(ObjOperandId obj, JSObject* expected) {
+        assertSameCompartment(expected);
         writeOpWithOperandId(CacheOp::GuardSpecificObject, obj);
         addStubField(uintptr_t(expected), StubField::Type::JSObject);
     }
     void guardSpecificAtom(StringOperandId str, JSAtom* expected) {
         writeOpWithOperandId(CacheOp::GuardSpecificAtom, str);
         addStubField(uintptr_t(expected), StubField::Type::String);
     }
     void guardSpecificSymbol(SymbolOperandId sym, JS::Symbol* expected) {
@@ -671,16 +679,17 @@ class MOZ_RAII CacheIRWriter : public JS
         writeInt32Immediate(expected);
         buffer_.writeByte(uint32_t(cond));
     }
     void guardMagicValue(ValOperandId val, JSWhyMagic magic) {
         writeOpWithOperandId(CacheOp::GuardMagicValue, val);
         buffer_.writeByte(uint32_t(magic));
     }
     void guardCompartment(ObjOperandId obj, JSObject* global, JSCompartment* compartment) {
+        assertSameCompartment(global);
         writeOpWithOperandId(CacheOp::GuardCompartment, obj);
         // Add a reference to the compartment's global to keep it alive.
         addStubField(uintptr_t(global), StubField::Type::JSObject);
         // Use RawWord, because compartments never move and it can't be GCed.
         addStubField(uintptr_t(compartment), StubField::Type::RawWord);
     }
     void guardNoDetachedTypedObjects() {
         writeOp(CacheOp::GuardNoDetachedTypedObjects);
@@ -747,16 +756,17 @@ class MOZ_RAII CacheIRWriter : public JS
 
     ValOperandId loadStackValue(uint32_t idx) {
         ValOperandId res(nextOperandId_++);
         writeOpWithOperandId(CacheOp::LoadStackValue, res);
         writeUint32Immediate(idx);
         return res;
     }
     ObjOperandId loadObject(JSObject* obj) {
+        assertSameCompartment(obj);
         ObjOperandId res(nextOperandId_++);
         writeOpWithOperandId(CacheOp::LoadObject, res);
         addStubField(uintptr_t(obj), StubField::Type::JSObject);
         return res;
     }
     ObjOperandId loadProto(ObjOperandId obj) {
         ObjOperandId res(nextOperandId_++);
         writeOpWithOperandId(CacheOp::LoadProto, obj);
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -4031,26 +4031,30 @@ CodeGenerator::visitOutOfLineCallPostWri
     masm.jump(ool->rejoin());
 }
 
 void
 CodeGenerator::maybeEmitGlobalBarrierCheck(const LAllocation* maybeGlobal, OutOfLineCode* ool)
 {
     // Check whether an object is a global that we have already barriered before
     // calling into the VM.
+    //
+    // We only check for the script's global, not other globals within the same
+    // compartment, because we bake in a pointer to realm->globalWriteBarriered
+    // and doing that would be invalid for other realms because they could be
+    // collected before the Ion code is discarded.
 
     if (!maybeGlobal->isConstant())
         return;
 
     JSObject* obj = &maybeGlobal->toConstant()->toObject();
-    if (!isGlobalObject(obj))
+    if (gen->compartment->maybeGlobal() != obj)
         return;
 
-    JSCompartment* comp = obj->compartment();
-    auto addr = AbsoluteAddress(&comp->globalWriteBarriered);
+    auto addr = AbsoluteAddress(gen->compartment->addressOfGlobalWriteBarriered());
     masm.branch32(Assembler::NotEqual, addr, Imm32(0), ool->rejoin());
 }
 
 template <class LPostBarrierType, MIRType nurseryType>
 void
 CodeGenerator::visitPostWriteBarrierCommon(LPostBarrierType* lir, OutOfLineCode* ool)
 {
     addOutOfLineCode(ool, lir->mir());
@@ -9867,21 +9871,21 @@ CodeGenerator::visitIteratorMore(LIterat
     const ValueOperand output = ToOutValue(lir);
     const Register temp = ToRegister(lir->temp());
 
     OutOfLineCode* ool = oolCallVM(IteratorMoreInfo, lir, ArgList(obj), StoreValueTo(output));
 
     Register outputScratch = output.scratchReg();
     LoadNativeIterator(masm, obj, outputScratch, ool->entry());
 
-    // If props_cursor < props_end, load the next string and advance the cursor.
-    // Else, return MagicValue(JS_NO_ITER_VALUE).
+    // If propertyCursor_ < propertiesEnd_, load the next string and advance
+    // the cursor.  Otherwise return MagicValue(JS_NO_ITER_VALUE).
     Label iterDone;
-    Address cursorAddr(outputScratch, offsetof(NativeIterator, props_cursor));
-    Address cursorEndAddr(outputScratch, offsetof(NativeIterator, props_end));
+    Address cursorAddr(outputScratch, NativeIterator::offsetOfPropertyCursor());
+    Address cursorEndAddr(outputScratch, NativeIterator::offsetOfPropertiesEnd());
     masm.loadPtr(cursorAddr, temp);
     masm.branchPtr(Assembler::BelowOrEqual, cursorEndAddr, temp, &iterDone);
 
     // Get next string.
     masm.loadPtr(Address(temp, 0), temp);
 
     // Increase the cursor.
     masm.addPtr(Imm32(sizeof(GCPtrFlatString)), cursorAddr);
@@ -9923,19 +9927,18 @@ CodeGenerator::visitIteratorEnd(LIterato
     OutOfLineCode* ool = oolCallVM(CloseIteratorFromIonInfo, lir, ArgList(obj), StoreNothing());
 
     LoadNativeIterator(masm, obj, temp1, ool->entry());
 
     // Clear active bit.
     masm.and32(Imm32(~JSITER_ACTIVE), Address(temp1, offsetof(NativeIterator, flags)));
 
     // Reset property cursor.
-    Address propCursor(temp1, offsetof(NativeIterator, props_cursor));
-    masm.computeEffectiveAddress(Address(temp1, sizeof(NativeIterator)), temp2);
-    masm.storePtr(temp2, propCursor);
+    masm.loadPtr(Address(temp1, NativeIterator::offsetOfGuardsEnd()), temp2);
+    masm.storePtr(temp2, Address(temp1, NativeIterator::offsetOfPropertyCursor()));
 
     // Unlink from the iterator list.
     const Register next = temp2;
     const Register prev = temp3;
     masm.loadPtr(Address(temp1, NativeIterator::offsetOfNext()), next);
     masm.loadPtr(Address(temp1, NativeIterator::offsetOfPrev()), prev);
     masm.storePtr(prev, Address(next, NativeIterator::offsetOfPrev()));
     masm.storePtr(next, Address(prev, NativeIterator::offsetOfNext()));
--- a/js/src/jit/CompileWrappers.cpp
+++ b/js/src/jit/CompileWrappers.cpp
@@ -270,16 +270,22 @@ const GlobalObject*
 CompileCompartment::maybeGlobal()
 {
     // This uses unsafeUnbarrieredMaybeGlobal() so as not to trigger the read
     // barrier on the global from off thread.  This is safe because we
     // abort Ion compilation when we GC.
     return JS::GetRealmForCompartment(compartment())->unsafeUnbarrieredMaybeGlobal();
 }
 
+const uint32_t*
+CompileCompartment::addressOfGlobalWriteBarriered()
+{
+    return &JS::GetRealmForCompartment(compartment())->globalWriteBarriered;
+}
+
 bool
 CompileCompartment::hasAllocationMetadataBuilder()
 {
     return JS::GetRealmForCompartment(compartment())->hasAllocationMetadataBuilder();
 }
 
 // Note: This function is thread-safe because setSingletonAsValue sets a boolean
 // variable to false, and this boolean variable has no way to be resetted to
--- a/js/src/jit/CompileWrappers.h
+++ b/js/src/jit/CompileWrappers.h
@@ -99,16 +99,17 @@ class CompileCompartment
     CompileZone* zone();
     CompileRuntime* runtime();
 
     const void* addressOfRandomNumberGenerator();
 
     const JitCompartment* jitCompartment();
 
     const GlobalObject* maybeGlobal();
+    const uint32_t* addressOfGlobalWriteBarriered();
 
     bool hasAllocationMetadataBuilder();
 
     // Mirror RealmOptions.
     void setSingletonsAsValues();
 };
 
 class JitCompileOptions
--- a/js/src/jit/IonCacheIRCompiler.cpp
+++ b/js/src/jit/IonCacheIRCompiler.cpp
@@ -8,16 +8,17 @@
 #include "mozilla/Maybe.h"
 
 #include "jit/BaselineIC.h"
 #include "jit/CacheIRCompiler.h"
 #include "jit/IonIC.h"
 #include "jit/JSJitFrameIter.h"
 #include "jit/Linker.h"
 #include "jit/SharedICHelpers.h"
+#include "proxy/DeadObjectProxy.h"
 #include "proxy/Proxy.h"
 
 #include "jit/JSJitFrameIter-inl.h"
 #include "jit/MacroAssembler-inl.h"
 #include "vm/JSCompartment-inl.h"
 #include "vm/TypeInference-inl.h"
 
 using namespace js;
@@ -673,25 +674,30 @@ IonCacheIRCompiler::emitGuardProto()
     masm.branchPtr(Assembler::NotEqual, scratch, ImmGCPtr(proto), failure->label());
     return true;
 }
 
 bool
 IonCacheIRCompiler::emitGuardCompartment()
 {
     Register obj = allocator.useRegister(masm, reader.objOperandId());
-    objectStubField(reader.stubOffset()); // Read global wrapper.
+    JSObject* globalWrapper = objectStubField(reader.stubOffset());
     JSCompartment* compartment = compartmentStubField(reader.stubOffset());
-
     AutoScratchRegister scratch(allocator, masm);
 
     FailurePath* failure;
     if (!addFailurePath(&failure))
         return false;
 
+    // Verify that the global wrapper is still valid, as
+    // it is pre-requisite for doing the compartment check.
+    masm.movePtr(ImmGCPtr(globalWrapper), scratch);
+    Address handlerAddr(scratch, ProxyObject::offsetOfHandler());
+    masm.branchPtr(Assembler::Equal, handlerAddr, ImmPtr(&DeadObjectProxy::singleton), failure->label());
+
     masm.branchTestObjCompartment(Assembler::NotEqual, obj, compartment, scratch,
                                   failure->label());
     return true;
 }
 
 bool
 IonCacheIRCompiler::emitGuardAnyClass()
 {
--- a/js/src/jit/VMFunctions.cpp
+++ b/js/src/jit/VMFunctions.cpp
@@ -742,19 +742,19 @@ PostWriteElementBarrier<IndexInBounds::Y
 
 template void
 PostWriteElementBarrier<IndexInBounds::Maybe>(JSRuntime* rt, JSObject* obj, int32_t index);
 
 void
 PostGlobalWriteBarrier(JSRuntime* rt, JSObject* obj)
 {
     MOZ_ASSERT(obj->is<GlobalObject>());
-    if (!obj->compartment()->globalWriteBarriered) {
+    if (!obj->realm()->globalWriteBarriered) {
         PostWriteBarrier(rt, obj);
-        obj->compartment()->globalWriteBarriered = 1;
+        obj->realm()->globalWriteBarriered = 1;
     }
 }
 
 int32_t
 GetIndexFromString(JSString* str)
 {
     // We shouldn't GC here as this is called directly from IC code.
     AutoUnsafeCallWithABI unsafe;
--- a/js/src/jit/arm/MacroAssembler-arm.cpp
+++ b/js/src/jit/arm/MacroAssembler-arm.cpp
@@ -5936,35 +5936,24 @@ MacroAssembler::speculationBarrier()
 }
 
 //}}} check_macroassembler_style
 
 void
 MacroAssemblerARM::wasmTruncateToInt32(FloatRegister input, Register output, MIRType fromType,
                                        bool isUnsigned, bool isSaturating, Label* oolEntry)
 {
-    // vcvt* converts NaN into 0, so check for NaNs here.
-    if (!isSaturating) {
-        if (fromType == MIRType::Double)
-            asMasm().compareDouble(input, input);
-        else if (fromType == MIRType::Float32)
-            asMasm().compareFloat(input, input);
-        else
-            MOZ_CRASH("unexpected type in visitWasmTruncateToInt32");
-
-        ma_b(oolEntry, Assembler::VFP_Unordered);
-    }
-
     ScratchDoubleScope scratchScope(asMasm());
     ScratchRegisterScope scratchReg(asMasm());
     FloatRegister scratch = scratchScope.uintOverlay();
 
     // ARM conversion instructions clamp the value to ensure it fits within the
     // target's type bounds, so every time we see those, we need to check the
-    // input.
+    // input. A NaN check is not necessary because NaN is converted to zero and
+    // on a zero result we branch out of line to do further processing anyway.
     if (isUnsigned) {
         if (fromType == MIRType::Double)
             ma_vcvt_F64_U32(input, scratch);
         else if (fromType == MIRType::Float32)
             ma_vcvt_F32_U32(input, scratch);
         else
             MOZ_CRASH("unexpected type in visitWasmTruncateToInt32");
 
@@ -5975,16 +5964,28 @@ MacroAssemblerARM::wasmTruncateToInt32(F
             ma_cmp(output, Imm32(-1), scratchReg);
             as_cmp(output, Imm8(0), Assembler::NotEqual);
             ma_b(oolEntry, Assembler::Equal);
         }
 
         return;
     }
 
+    // vcvt* converts NaN into 0, so check for NaNs here.
+    if (!isSaturating) {
+        if (fromType == MIRType::Double)
+            asMasm().compareDouble(input, input);
+        else if (fromType == MIRType::Float32)
+            asMasm().compareFloat(input, input);
+        else
+            MOZ_CRASH("unexpected type in visitWasmTruncateToInt32");
+
+        ma_b(oolEntry, Assembler::VFP_Unordered);
+    }
+
     scratch = scratchScope.sintOverlay();
 
     if (fromType == MIRType::Double)
         ma_vcvt_F64_I32(input, scratch);
     else if (fromType == MIRType::Float32)
         ma_vcvt_F32_I32(input, scratch);
     else
         MOZ_CRASH("unexpected type in visitWasmTruncateToInt32");
--- a/js/src/jsapi-tests/testGCGrayMarking.cpp
+++ b/js/src/jsapi-tests/testGCGrayMarking.cpp
@@ -8,29 +8,40 @@
 #include "gc/Heap.h"
 #include "gc/WeakMap.h"
 #include "gc/Zone.h"
 #include "jsapi-tests/tests.h"
 
 using namespace js;
 using namespace js::gc;
 
+namespace js {
+
+struct GCManagedObjectWeakMap : public ObjectWeakMap
+{
+    using ObjectWeakMap::ObjectWeakMap;
+};
+
+} // namespace js
+
 namespace JS {
 
 template <>
-struct DeletePolicy<js::ObjectWeakMap> : public js::GCManagedDeletePolicy<js::ObjectWeakMap>
+struct DeletePolicy<js::GCManagedObjectWeakMap>
+  : public js::GCManagedDeletePolicy<js::GCManagedObjectWeakMap>
 {};
 
 template <>
-struct MapTypeToRootKind<js::ObjectWeakMap*> {
+struct MapTypeToRootKind<js::GCManagedObjectWeakMap*> {
     static const JS::RootKind kind = JS::RootKind::Traceable;
 };
 
 template <>
-struct GCPolicy<js::ObjectWeakMap*> : public NonGCPointerPolicy<js::ObjectWeakMap*>
+struct GCPolicy<js::GCManagedObjectWeakMap*>
+  : public NonGCPointerPolicy<js::GCManagedObjectWeakMap*>
 {};
 
 } // namespace JS
 
 class AutoNoAnalysisForTest
 {
   public:
     AutoNoAnalysisForTest() {}
@@ -326,22 +337,22 @@ TestWeakMaps()
 
     return true;
 }
 
 bool
 TestUnassociatedWeakMaps()
 {
     // Make a weakmap that's not associated with a JSObject.
-    auto weakMap = cx->make_unique<ObjectWeakMap>(cx);
+    auto weakMap = cx->make_unique<GCManagedObjectWeakMap>(cx);
     CHECK(weakMap);
     CHECK(weakMap->init());
 
     // Make sure this gets traced during GC.
-    Rooted<ObjectWeakMap*> rootMap(cx, weakMap.get());
+    Rooted<GCManagedObjectWeakMap*> rootMap(cx, weakMap.get());
 
     JSObject* key = AllocWeakmapKeyObject();
     CHECK(key);
 
     JSObject* value = AllocPlainObject();
     CHECK(value);
 
     CHECK(weakMap->add(cx, key, value));
--- a/js/src/jsfriendapi.cpp
+++ b/js/src/jsfriendapi.cpp
@@ -1420,17 +1420,17 @@ JS_FRIEND_API(void)
 js::SetAllocationMetadataBuilder(JSContext* cx, const AllocationMetadataBuilder* callback)
 {
     cx->realm()->setAllocationMetadataBuilder(callback);
 }
 
 JS_FRIEND_API(JSObject*)
 js::GetAllocationMetadata(JSObject* obj)
 {
-    ObjectWeakMap* map = obj->compartment()->objectMetadataTable;
+    ObjectWeakMap* map = obj->compartment()->objectMetadataTable.get();
     if (map)
         return map->lookup(obj);
     return nullptr;
 }
 
 JS_FRIEND_API(bool)
 js::ReportIsNotFunction(JSContext* cx, HandleValue v)
 {
@@ -1532,17 +1532,17 @@ JS_FRIEND_API(void)
 js::EnableAccessValidation(JSContext* cx, bool enabled)
 {
     cx->enableAccessValidation = enabled;
 }
 
 JS_FRIEND_API(void)
 js::SetCompartmentValidAccessPtr(JSContext* cx, JS::HandleObject global, bool* accessp)
 {
-    global->compartment()->setValidAccessPtr(accessp);
+    global->realm()->setValidAccessPtr(accessp);
 }
 
 JS_FRIEND_API(bool)
 js::SystemZoneAvailable(JSContext* cx)
 {
     return true;
 }
 
--- a/js/src/proxy/CrossCompartmentWrapper.cpp
+++ b/js/src/proxy/CrossCompartmentWrapper.cpp
@@ -299,17 +299,17 @@ Reify(JSContext* cx, JSCompartment* orig
         size_t length = ni->numKeys();
         AutoIdVector keys(cx);
         if (length > 0) {
             if (!keys.reserve(length))
                 return nullptr;
             RootedId id(cx);
             RootedValue v(cx);
             for (size_t i = 0; i < length; ++i) {
-                v.setString(ni->begin()[i]);
+                v.setString(ni->propertiesBegin()[i]);
                 if (!ValueToId<CanGC>(cx, v, &id))
                     return nullptr;
                 cx->markId(id);
                 keys.infallibleAppend(id);
             }
         }
 
         close.clear();
--- a/js/src/vm/BytecodeUtil.cpp
+++ b/js/src/vm/BytecodeUtil.cpp
@@ -2883,59 +2883,59 @@ js::GetPCCountScriptContents(JSContext* 
         if (!GetPCCountJSON(cx, sac, buf))
             return nullptr;
     }
 
     return buf.finishString();
 }
 
 static bool
-GenerateLcovInfo(JSContext* cx, JSCompartment* comp, GenericPrinter& out)
+GenerateLcovInfo(JSContext* cx, JS::Realm* realm, GenericPrinter& out)
 {
     JSRuntime* rt = cx->runtime();
 
-    // Collect the list of scripts which are part of the current compartment.
+    // Collect the list of scripts which are part of the current realm.
     {
         js::gc::AutoPrepareForTracing apft(cx);
     }
     Rooted<ScriptVector> topScripts(cx, ScriptVector(cx));
     for (ZonesIter zone(rt, SkipAtoms); !zone.done(); zone.next()) {
         for (auto script = zone->cellIter<JSScript>(); !script.done(); script.next()) {
-            if (script->compartment() != comp ||
+            if (script->realm() != realm ||
                 !script->isTopLevel() ||
                 !script->filename())
             {
                 continue;
             }
 
             if (!topScripts.append(script))
                 return false;
         }
     }
 
     if (topScripts.length() == 0)
         return true;
 
-    // Collect code coverage info for one compartment.
-    coverage::LCovCompartment compCover;
+    // Collect code coverage info for one realm.
+    coverage::LCovRealm realmCover;
     for (JSScript* topLevel: topScripts) {
         RootedScript topScript(cx, topLevel);
 
         // We found the top-level script, visit all the functions reachable
         // from the top-level function, and delazify them.
         Rooted<ScriptVector> queue(cx, ScriptVector(cx));
         if (!queue.append(topLevel))
             return false;
 
         RootedScript script(cx);
         RootedFunction fun(cx);
         do {
             script = queue.popCopy();
             if (script->filename())
-                compCover.collectCodeCoverageInfo(comp, script, script->filename());
+                realmCover.collectCodeCoverageInfo(realm, script, script->filename());
 
             // Iterate from the last to the first object in order to have
             // the functions them visited in the opposite order when popping
             // elements from the stack of remaining scripts, such that the
             // functions are more-less listed with increasing line numbers.
             if (!script->hasObjects())
                 continue;
             size_t idx = script->objects()->length;
@@ -2956,31 +2956,31 @@ GenerateLcovInfo(JSContext* cx, JSCompar
                 JSScript* childScript = JSFunction::getOrCreateScript(cx, fun);
                 if (!childScript || !queue.append(childScript))
                     return false;
             }
         } while (!queue.empty());
     }
 
     bool isEmpty = true;
-    compCover.exportInto(out, &isEmpty);
+    realmCover.exportInto(out, &isEmpty);
     if (out.hadOutOfMemory())
         return false;
     return true;
 }
 
 JS_FRIEND_API(char*)
 js::GetCodeCoverageSummary(JSContext* cx, size_t* length)
 {
     Sprinter out(cx);
 
     if (!out.init())
         return nullptr;
 
-    if (!GenerateLcovInfo(cx, cx->compartment(), out)) {
+    if (!GenerateLcovInfo(cx, cx->realm(), out)) {
         JS_ReportOutOfMemory(cx);
         return nullptr;
     }
 
     if (out.hadOutOfMemory()) {
         JS_ReportOutOfMemory(cx);
         return nullptr;
     }
--- a/js/src/vm/CodeCoverage.cpp
+++ b/js/src/vm/CodeCoverage.cpp
@@ -450,53 +450,53 @@ LCovSource::writeScript(JSScript* script
     // assume that the code coverage report is complete, as this script has
     // references on all inner scripts.
     if (script->isTopLevel())
         hasTopLevelScript_ = true;
 
     return true;
 }
 
-LCovCompartment::LCovCompartment()
+LCovRealm::LCovRealm()
   : alloc_(4096),
     outTN_(&alloc_),
     sources_(nullptr)
 {
     MOZ_ASSERT(alloc_.isEmpty());
 }
 
 void
-LCovCompartment::collectCodeCoverageInfo(JSCompartment* comp, JSScript* script, const char* name)
+LCovRealm::collectCodeCoverageInfo(JS::Realm* realm, JSScript* script, const char* name)
 {
     // Skip any operation if we already some out-of memory issues.
     if (outTN_.hadOutOfMemory())
         return;
 
     if (!script->code())
         return;
 
     // Get the existing source LCov summary, or create a new one.
-    LCovSource* source = lookupOrAdd(comp, name);
+    LCovSource* source = lookupOrAdd(realm, name);
     if (!source)
         return;
 
     // Write code coverage data into the LCovSource.
     if (!source->writeScript(script)) {
         outTN_.reportOutOfMemory();
         return;
     }
 }
 
 LCovSource*
-LCovCompartment::lookupOrAdd(JSCompartment* comp, const char* name)
+LCovRealm::lookupOrAdd(JS::Realm* realm, const char* name)
 {
-    // On the first call, write the compartment name, and allocate a LCovSource
+    // On the first call, write the realm name, and allocate a LCovSource
     // vector in the LifoAlloc.
     if (!sources_) {
-        if (!writeCompartmentName(comp))
+        if (!writeRealmName(realm))
             return nullptr;
 
         LCovSourceVector* raw = alloc_.pod_malloc<LCovSourceVector>();
         if (!raw) {
             outTN_.reportOutOfMemory();
             return nullptr;
         }
 
@@ -520,17 +520,17 @@ LCovCompartment::lookupOrAdd(JSCompartme
         outTN_.reportOutOfMemory();
         return nullptr;
     }
 
     return &sources_->back();
 }
 
 void
-LCovCompartment::exportInto(GenericPrinter& out, bool* isEmpty) const
+LCovRealm::exportInto(GenericPrinter& out, bool* isEmpty) const
 {
     if (!sources_ || outTN_.hadOutOfMemory())
         return;
 
     // If we only have cloned function, then do not serialize anything.
     bool someComplete = false;
     for (const LCovSource& sc : *sources_) {
         if (sc.isComplete()) {
@@ -546,47 +546,48 @@ LCovCompartment::exportInto(GenericPrint
     outTN_.exportInto(out);
     for (const LCovSource& sc : *sources_) {
         if (sc.isComplete())
             sc.exportInto(out);
     }
 }
 
 bool
-LCovCompartment::writeCompartmentName(JSCompartment* comp)
+LCovRealm::writeRealmName(JS::Realm* realm)
 {
     JSContext* cx = TlsContext.get();
 
     // lcov trace files are starting with an optional test case name, that we
-    // recycle to be a compartment name.
+    // recycle to be a realm name.
     //
     // Note: The test case name has some constraint in terms of valid character,
     // thus we escape invalid chracters with a "_" symbol in front of its
     // hexadecimal code.
     outTN_.put("TN:");
     if (cx->runtime()->compartmentNameCallback) {
         char name[1024];
         {
             // Hazard analysis cannot tell that the callback does not GC.
             JS::AutoSuppressGCAnalysis nogc;
+            JSCompartment* comp = JS::GetCompartmentForRealm(realm);
             (*cx->runtime()->compartmentNameCallback)(cx, comp, name, sizeof(name));
         }
         for (char *s = name; s < name + sizeof(name) && *s; s++) {
             if (('a' <= *s && *s <= 'z') ||
                 ('A' <= *s && *s <= 'Z') ||
                 ('0' <= *s && *s <= '9'))
             {
                 outTN_.put(s, 1);
                 continue;
             }
             outTN_.printf("_%p", (void*) size_t(*s));
         }
         outTN_.put("\n", 1);
     } else {
-        outTN_.printf("Compartment_%p%p\n", (void*) size_t('_'), comp);
+        outTN_.printf("Realm_%p%p\n", (void*) size_t('_'), realm);
     }
 
     return !outTN_.hadOutOfMemory();
 }
 
 LCovRuntime::LCovRuntime()
   : out_(),
     pid_(getpid()),
@@ -644,28 +645,28 @@ LCovRuntime::finishFile()
         char name[1024];
         if (!fillWithFilename(name, sizeof(name)))
             return;
         remove(name);
     }
 }
 
 void
-LCovRuntime::writeLCovResult(LCovCompartment& comp)
+LCovRuntime::writeLCovResult(LCovRealm& realm)
 {
     if (!out_.isInitialized())
         return;
 
     uint32_t p = getpid();
     if (pid_ != p) {
         pid_ = p;
         finishFile();
         init();
         if (!out_.isInitialized())
             return;
     }
 
-    comp.exportInto(out_, &isEmpty_);
+    realm.exportInto(out_, &isEmpty_);
     out_.flush();
 }
 
 } // namespace coverage
 } // namespace js
--- a/js/src/vm/CodeCoverage.h
+++ b/js/src/vm/CodeCoverage.h
@@ -17,18 +17,16 @@
 #include "vm/Printer.h"
 
 namespace js {
 
 class ScriptSourceObject;
 
 namespace coverage {
 
-class LCovCompartment;
-
 class LCovSource
 {
   public:
     LCovSource(LifoAlloc* alloc, const char* name);
     LCovSource(LCovSource&& src);
     ~LCovSource();
 
     // Whether the given script name matches this LCovSource.
@@ -77,46 +75,46 @@ class LCovSource
     size_t numLinesInstrumented_;
     size_t numLinesHit_;
     size_t maxLineHit_;
 
     // Status flags.
     bool hasTopLevelScript_ : 1;
 };
 
-class LCovCompartment
+class LCovRealm
 {
   public:
-    LCovCompartment();
+    LCovRealm();
 
     // Collect code coverage information for the given source.
-    void collectCodeCoverageInfo(JSCompartment* comp, JSScript* topLevel, const char* name);
+    void collectCodeCoverageInfo(JS::Realm* realm, JSScript* topLevel, const char* name);
 
     // Write the Lcov output in a buffer, such as the one associated with
     // the runtime code coverage trace file.
     void exportInto(GenericPrinter& out, bool* isEmpty) const;
 
   private:
     // Write the script name in out.
-    bool writeCompartmentName(JSCompartment* comp);
+    bool writeRealmName(JS::Realm* realm);
 
     // Return the LCovSource entry which matches the given ScriptSourceObject.
-    LCovSource* lookupOrAdd(JSCompartment* comp, const char* name);
+    LCovSource* lookupOrAdd(JS::Realm* realm, const char* name);
 
   private:
     typedef mozilla::Vector<LCovSource, 16, LifoAllocPolicy<Fallible>> LCovSourceVector;
 
     // LifoAlloc backend for all temporary allocations needed to stash the
     // strings to be written in the file.
     LifoAlloc alloc_;
 
-    // LifoAlloc string which hold the name of the compartment.
+    // LifoAlloc string which hold the name of the realm.
     LSprinter outTN_;
 
-    // Vector of all sources which are used in this compartment.
+    // Vector of all sources which are used in this realm.
     LCovSourceVector* sources_;
 };
 
 class LCovRuntime
 {
   public:
     LCovRuntime();
     ~LCovRuntime();
@@ -128,19 +126,19 @@ class LCovRuntime
     //
     // At the end of the execution, this file should contains the LCOV output of
     // all the scripts executed in the current JSRuntime.
     void init();
 
     // Check if we should collect code coverage information.
     bool isEnabled() const { return out_.isInitialized(); }
 
-    // Write the aggregated result of the code coverage of a compartment
+    // Write the aggregated result of the code coverage of a realm
     // into a file.
-    void writeLCovResult(LCovCompartment& comp);
+    void writeLCovResult(LCovRealm& realm);
 
   private:
     // When a process forks, the file will remain open, but 2 processes will
     // have the same file. To avoid conflicting writes, we open a new file for
     // the child process.
     void maybeReopenAfterFork();
 
     // Fill an array with the name of the file. Return false if we are unable to
--- a/js/src/vm/EnvironmentObject.cpp
+++ b/js/src/vm/EnvironmentObject.cpp
@@ -2513,32 +2513,32 @@ CanUseDebugEnvironmentMaps(JSContext* cx
     return cx->realm()->isDebuggee();
 }
 
 DebugEnvironments*
 DebugEnvironments::ensureCompartmentData(JSContext* cx)
 {
     JSCompartment* c = cx->compartment();
     if (c->debugEnvs)
-        return c->debugEnvs;
+        return c->debugEnvs.get();
 
     auto debugEnvs = cx->make_unique<DebugEnvironments>(cx, cx->zone());
     if (!debugEnvs || !debugEnvs->init()) {
         ReportOutOfMemory(cx);
         return nullptr;
     }
 
-    c->debugEnvs = debugEnvs.release();
-    return c->debugEnvs;
+    c->debugEnvs = Move(debugEnvs);
+    return c->debugEnvs.get();
 }
 
 /* static */ DebugEnvironmentProxy*
 DebugEnvironments::hasDebugEnvironment(JSContext* cx, EnvironmentObject& env)
 {
-    DebugEnvironments* envs = env.compartment()->debugEnvs;
+    DebugEnvironments* envs = env.compartment()->debugEnvs.get();
     if (!envs)
         return nullptr;
 
     if (JSObject* obj = envs->proxiedEnvs.lookup(&env)) {
         MOZ_ASSERT(CanUseDebugEnvironmentMaps(cx));
         return &obj->as<DebugEnvironmentProxy>();
     }
 
@@ -2562,17 +2562,17 @@ DebugEnvironments::addDebugEnvironment(J
     return envs->proxiedEnvs.add(cx, env, debugEnv);
 }
 
 /* static */ DebugEnvironmentProxy*
 DebugEnvironments::hasDebugEnvironment(JSContext* cx, const EnvironmentIter& ei)
 {
     MOZ_ASSERT(!ei.hasSyntacticEnvironment());
 
-    DebugEnvironments* envs = cx->compartment()->debugEnvs;
+    DebugEnvironments* envs = cx->compartment()->debugEnvs.get();
     if (!envs)
         return nullptr;
 
     if (MissingEnvironmentMap::Ptr p = envs->missingEnvs.lookup(MissingEnvironmentKey(ei))) {
         MOZ_ASSERT(CanUseDebugEnvironmentMaps(cx));
         return p->value();
     }
     return nullptr;
@@ -2712,17 +2712,17 @@ DebugEnvironments::takeFrameSnapshot(JSC
     debugEnv->initSnapshot(*snapshot);
 }
 
 /* static */ void
 DebugEnvironments::onPopCall(JSContext* cx, AbstractFramePtr frame)
 {
     assertSameCompartment(cx, frame);
 
-    DebugEnvironments* envs = cx->compartment()->debugEnvs;
+    DebugEnvironments* envs = cx->compartment()->debugEnvs.get();
     if (!envs)
         return;
 
     Rooted<DebugEnvironmentProxy*> debugEnv(cx, nullptr);
 
     FunctionScope* funScope = &frame.script()->bodyScope()->as<FunctionScope>();
     if (funScope->hasEnvironment()) {
         MOZ_ASSERT(frame.callee()->needsCallObject());
@@ -2754,29 +2754,29 @@ DebugEnvironments::onPopCall(JSContext* 
         DebugEnvironments::takeFrameSnapshot(cx, debugEnv, frame);
 }
 
 void
 DebugEnvironments::onPopLexical(JSContext* cx, AbstractFramePtr frame, jsbytecode* pc)
 {
     assertSameCompartment(cx, frame);
 
-    DebugEnvironments* envs = cx->compartment()->debugEnvs;
+    DebugEnvironments* envs = cx->compartment()->debugEnvs.get();
     if (!envs)
         return;
 
     EnvironmentIter ei(cx, frame, pc);
     onPopLexical(cx, ei);
 }
 
 template <typename Environment, typename Scope>
 void
 DebugEnvironments::onPopGeneric(JSContext* cx, const EnvironmentIter& ei)
 {
-    DebugEnvironments* envs = cx->compartment()->debugEnvs;
+    DebugEnvironments* envs = cx->compartment()->debugEnvs.get();
     if (!envs)
         return;
 
     MOZ_ASSERT(ei.withinInitialFrame());
     MOZ_ASSERT(ei.scope().is<Scope>());
 
     Rooted<Environment*> env(cx);
     if (MissingEnvironmentMap::Ptr p = envs->missingEnvs.lookup(MissingEnvironmentKey(ei))) {
@@ -2802,17 +2802,17 @@ DebugEnvironments::onPopLexical(JSContex
     onPopGeneric<LexicalEnvironmentObject, LexicalScope>(cx, ei);
 }
 
 void
 DebugEnvironments::onPopVar(JSContext* cx, AbstractFramePtr frame, jsbytecode* pc)
 {
     assertSameCompartment(cx, frame);
 
-    DebugEnvironments* envs = cx->compartment()->debugEnvs;
+    DebugEnvironments* envs = cx->compartment()->debugEnvs.get();
     if (!envs)
         return;
 
     EnvironmentIter ei(cx, frame, pc);
     onPopVar(cx, ei);
 }
 
 void
@@ -2822,24 +2822,24 @@ DebugEnvironments::onPopVar(JSContext* c
         onPopGeneric<VarEnvironmentObject, EvalScope>(cx, ei);
     else
         onPopGeneric<VarEnvironmentObject, VarScope>(cx, ei);
 }
 
 void
 DebugEnvironments::onPopWith(AbstractFramePtr frame)
 {
-    if (DebugEnvironments* envs = frame.compartment()->debugEnvs)
+    if (DebugEnvironments* envs = frame.compartment()->debugEnvs.get())
         envs->liveEnvs.remove(&frame.environmentChain()->as<WithEnvironmentObject>());
 }
 
 void
 DebugEnvironments::onCompartmentUnsetIsDebuggee(JSCompartment* c)
 {
-    if (DebugEnvironments* envs = c->debugEnvs) {
+    if (DebugEnvironments* envs = c->debugEnvs.get()) {
         envs->proxiedEnvs.clear();
         envs->missingEnvs.clear();
         envs->liveEnvs.clear();
     }
 }
 
 bool
 DebugEnvironments::updateLiveEnvironments(JSContext* cx)
@@ -2898,17 +2898,17 @@ DebugEnvironments::updateLiveEnvironment
     }
 
     return true;
 }
 
 LiveEnvironmentVal*
 DebugEnvironments::hasLiveEnvironment(EnvironmentObject& env)
 {
-    DebugEnvironments* envs = env.compartment()->debugEnvs;
+    DebugEnvironments* envs = env.compartment()->debugEnvs.get();
     if (!envs)
         return nullptr;
 
     if (LiveEnvironmentMap::Ptr p = envs->liveEnvs.lookup(&env))
         return &p->value();
 
     return nullptr;
 }
@@ -2937,17 +2937,17 @@ DebugEnvironments::unsetPrevUpToDateUnti
 
         frame.unsetPrevUpToDate();
     }
 }
 
 /* static */ void
 DebugEnvironments::forwardLiveFrame(JSContext* cx, AbstractFramePtr from, AbstractFramePtr to)
 {
-    DebugEnvironments* envs = cx->compartment()->debugEnvs;
+    DebugEnvironments* envs = cx->compartment()->debugEnvs.get();
     if (!envs)
         return;
 
     for (MissingEnvironmentMap::Enum e(envs->missingEnvs); !e.empty(); e.popFront()) {
         MissingEnvironmentKey key = e.front().key();
         if (key.frame() == from) {
             key.updateFrame(to);
             e.rekeyFront(key);
--- a/js/src/vm/EnvironmentObject.h
+++ b/js/src/vm/EnvironmentObject.h
@@ -1206,17 +1206,9 @@ GetFrameEnvironmentAndScope(JSContext* c
 
 #ifdef DEBUG
 bool
 AnalyzeEntrainedVariables(JSContext* cx, HandleScript script);
 #endif
 
 } // namespace js
 
-namespace JS {
-
-template <>
-struct DeletePolicy<js::DebugEnvironments> : public js::GCManagedDeletePolicy<js::DebugEnvironments>
-{};
-
-} // namespace JS
-
 #endif /* vm_EnvironmentObject_h */
--- a/js/src/vm/Interpreter.cpp
+++ b/js/src/vm/Interpreter.cpp
@@ -382,17 +382,17 @@ js::RunScript(JSContext* cx, RunState& s
 
     // Since any script can conceivably GC, make sure it's safe to do so.
     cx->verifyIsSafeToGC();
 
     MOZ_DIAGNOSTIC_ASSERT(cx->realm()->isSystem() ||
                           cx->runtime()->allowContentJS());
 
     MOZ_ASSERT(!cx->enableAccessValidation ||
-               cx->compartment()->isAccessValid());
+               cx->realm()->isAccessValid());
 
     if (!Debugger::checkNoExecute(cx, state.script()))
         return false;
 
 #if defined(MOZ_HAVE_RDTSC)
     js::AutoStopwatch stopwatch(cx);
 #endif // defined(MOZ_HAVE_RDTSC)
 
--- a/js/src/vm/Iteration.cpp
+++ b/js/src/vm/Iteration.cpp
@@ -9,16 +9,17 @@
 #include "vm/Iteration.h"
 
 #include "mozilla/DebugOnly.h"
 #include "mozilla/Maybe.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/PodOperations.h"
 #include "mozilla/Unused.h"
 
+#include <algorithm>
 #include <new>
 
 #include "jstypes.h"
 #include "jsutil.h"
 
 #include "builtin/Array.h"
 #include "ds/Sort.h"
 #include "gc/FreeOp.h"
@@ -51,28 +52,32 @@ using mozilla::PodEqual;
 
 typedef Rooted<PropertyIteratorObject*> RootedPropertyIteratorObject;
 
 static const gc::AllocKind ITERATOR_FINALIZE_KIND = gc::AllocKind::OBJECT2_BACKGROUND;
 
 void
 NativeIterator::trace(JSTracer* trc)
 {
-    for (GCPtrFlatString* str = begin(); str < end(); str++)
-        TraceNullableEdge(trc, str, "prop");
     TraceNullableEdge(trc, &obj, "obj");
 
-    HeapReceiverGuard* guards = guardArray();
-    for (size_t i = 0; i < guard_length; i++)
-        guards[i].trace(trc);
-
     // The SuppressDeletedPropertyHelper loop can GC, so make sure that if the
     // GC removes any elements from the list, it won't remove this one.
     if (iterObj_)
         TraceManuallyBarrieredEdge(trc, &iterObj_, "iterObj");
+
+    std::for_each(guardsBegin(), guardsEnd(),
+                  [trc](HeapReceiverGuard& guard) {
+                      guard.trace(trc);
+                  });
+
+    std::for_each(propertiesBegin(), propertiesEnd(),
+                  [trc](GCPtrFlatString& prop) {
+                      TraceNullableEdge(trc, &prop, "prop");
+                  });
 }
 
 typedef HashSet<jsid, DefaultHasher<jsid>> IdSet;
 
 template <bool CheckForDuplicates>
 static inline bool
 Enumerate(JSContext* cx, HandleObject pobj, jsid id,
           bool enumerable, unsigned flags, Maybe<IdSet>& ht, AutoIdVector* props)
@@ -647,21 +652,22 @@ NativeIterator::allocateSentinel(JSConte
  * as we initialize, we must carefully keep this in GC-safe state (see
  * NativeIterator::trace).
  */
 NativeIterator::NativeIterator(JSContext* cx, Handle<PropertyIteratorObject*> propIter,
                                Handle<JSObject*> objBeingIterated, const AutoIdVector& props,
                                uint32_t numGuards, uint32_t guardKey, bool* hadError)
   : obj(objBeingIterated),
     iterObj_(propIter),
-    // NativeIterator initially acts as if it contains no properties.
-    props_cursor(begin()),
-    props_end(props_cursor),
-    // ...and no HeapReceiverGuards.
-    guard_length(0),
+    // NativeIterator initially acts (before full initialization) as if it
+    // contains no guards...
+    guardsEnd_(guardsBegin()),
+    // ...and no properties.
+    propertyCursor_(reinterpret_cast<GCPtrFlatString*>(guardsBegin() + numGuards)),
+    propertiesEnd_(propertyCursor_),
     guard_key(guardKey),
     flags(0)
 {
     MOZ_ASSERT(!*hadError);
 
     // NOTE: This must be done first thing: PropertyIteratorObject::finalize
     //       can only free |this| (and not leak it) if this has happened.
     propIter->setNativeIterator(this);
@@ -670,60 +676,66 @@ NativeIterator::NativeIterator(JSContext
         JSFlatString* str = IdToString(cx, props[i]);
         if (!str) {
             *hadError = true;
             return;
         }
 
         // Placement-new the next property string at the end of the currently
         // computed property strings.
-        GCPtrFlatString* loc = props_end;
+        GCPtrFlatString* loc = propertiesEnd_;
 
         // Increase the overall property string count before initializing the
         // property string, so this construction isn't on a location not known
         // to the GC yet.
-        props_end++;
+        propertiesEnd_++;
 
         new (loc) GCPtrFlatString(str);
     }
 
     if (numGuards > 0) {
         // Construct guards into the guard array.  Also recompute the guard key,
         // which incorporates Shape* and ObjectGroup* addresses that could have
         // changed during a GC triggered in (among other places) |IdToString|
         //. above.
         JSObject* pobj = objBeingIterated;
+#ifdef DEBUG
+        uint32_t i = 0;
+#endif
         uint32_t key = 0;
-        HeapReceiverGuard* guards = guardArray();
         do {
             ReceiverGuard guard(pobj);
 
             // Placement-new the next HeapReceiverGuard at the end of the
             // currently initialized HeapReceiverGuards.
-            uint32_t index = guard_length;
+            HeapReceiverGuard* loc = guardsEnd_;
 
             // Increase the overall guard-count before initializing the
             // HeapReceiverGuard, so this construction isn't on a location not
             // known to the GC.
-            guard_length++;
+            guardsEnd_++;
+#ifdef DEBUG
+            i++;
+#endif
 
-            new (&guards[index]) HeapReceiverGuard(guard);
+            new (loc) HeapReceiverGuard(guard);
 
             key = mozilla::AddToHash(key, guard.hash());
 
             // The one caller of this method that passes |numGuards > 0|, does
             // so only if the entire chain consists of cacheable objects (that
             // necessarily have static prototypes).
             pobj = pobj->staticPrototype();
         } while (pobj);
 
         guard_key = key;
-        MOZ_ASSERT(guard_length == numGuards);
+        MOZ_ASSERT(i == numGuards);
     }
 
+    MOZ_ASSERT(static_cast<void*>(guardsEnd_) == propertyCursor_);
     MOZ_ASSERT(!*hadError);
 }
 
 static inline PropertyIteratorObject*
 VectorToKeyIterator(JSContext* cx, HandleObject obj, AutoIdVector& props, uint32_t numGuards)
 {
     if (obj->isSingleton() && !JSObject::setIteratedSingleton(cx, obj))
         return nullptr;
@@ -746,21 +758,21 @@ js::NewEmptyPropertyIterator(JSContext* 
     AutoIdVector props(cx); // Empty
     return CreatePropertyIterator(cx, nullptr, props, 0, 0);
 }
 
 /* static */ bool
 IteratorHashPolicy::match(PropertyIteratorObject* obj, const Lookup& lookup)
 {
     NativeIterator* ni = obj->getNativeIterator();
-    if (ni->guard_key != lookup.key || ni->guard_length != lookup.numGuards)
+    if (ni->guard_key != lookup.key || ni->guardCount() != lookup.numGuards)
         return false;
 
-    return PodEqual(reinterpret_cast<ReceiverGuard*>(ni->guardArray()), lookup.guards,
-                    ni->guard_length);
+    return PodEqual(reinterpret_cast<ReceiverGuard*>(ni->guardsBegin()), lookup.guards,
+                    ni->guardCount());
 }
 
 static inline void
 UpdateNativeIterator(NativeIterator* ni, JSObject* obj)
 {
     // Update the object for which the native iterator is associated, so
     // SuppressDeletedPropertyHelper will recognize the iterator as a match.
     ni->obj = obj;
@@ -847,20 +859,20 @@ CanStoreInIteratorCache(JSObject* obj)
 }
 
 static MOZ_MUST_USE bool
 StoreInIteratorCache(JSContext* cx, JSObject* obj, PropertyIteratorObject* iterobj)
 {
     MOZ_ASSERT(CanStoreInIteratorCache(obj));
 
     NativeIterator* ni = iterobj->getNativeIterator();
-    MOZ_ASSERT(ni->guard_length > 0);
+    MOZ_ASSERT(ni->guardCount() > 0);
 
-    IteratorHashPolicy::Lookup lookup(reinterpret_cast<ReceiverGuard*>(ni->guardArray()),
-                                      ni->guard_length,
+    IteratorHashPolicy::Lookup lookup(reinterpret_cast<ReceiverGuard*>(ni->guardsBegin()),
+                                      ni->guardCount(),
                                       ni->guard_key);
 
     JSCompartment::IteratorCache& cache = cx->compartment()->iteratorCache;
     bool ok;
     auto p = cache.lookupForAdd(lookup);
     if (MOZ_LIKELY(!p)) {
         ok = cache.add(p, iterobj);
     } else {
@@ -1007,20 +1019,21 @@ Realm::getOrCreateIterResultTemplateObje
     return iterResultTemplate_;
 }
 
 /*** Iterator objects ****************************************************************************/
 
 MOZ_ALWAYS_INLINE void
 NativeIteratorNext(NativeIterator* ni, MutableHandleValue rval)
 {
-    if (ni->props_cursor >= ni->props_end) {
+    if (ni->propertyCursor_ >= ni->propertiesEnd()) {
+        MOZ_ASSERT(ni->propertyCursor_ == ni->propertiesEnd());
         rval.setMagic(JS_NO_ITER_VALUE);
     } else {
-        rval.setString(*ni->current());
+        rval.setString(*ni->currentProperty());
         ni->incCursor();
     }
 }
 
 bool
 js::IsPropertyIterator(HandleValue v)
 {
     return v.isObject() && v.toObject().is<PropertyIteratorObject>();
@@ -1165,17 +1178,17 @@ js::CloseIterator(JSObject* obj)
 
         MOZ_ASSERT(ni->flags & JSITER_ACTIVE);
         ni->flags &= ~JSITER_ACTIVE;
 
         /*
          * Reset the enumerator; it may still be in the cached iterators
          * for this thread, and can be reused.
          */
-        ni->props_cursor = ni->begin();
+        ni->propertyCursor_ = ni->propertiesBegin();
     }
 }
 
 bool
 js::IteratorCloseForException(JSContext* cx, HandleObject obj)
 {
     MOZ_ASSERT(cx->isExceptionPending());
 
@@ -1243,26 +1256,26 @@ SuppressDeletedProperty(JSContext* cx, N
     // Optimization for the following common case:
     //
     //    for (var p in o) {
     //        delete o[p];
     //    }
     //
     // Note that usually both strings will be atoms so we only check for pointer
     // equality here.
-    if (ni->props_cursor > ni->begin() && ni->props_cursor[-1] == str)
+    if (ni->propertyCursor_ > ni->propertiesBegin() && ni->propertyCursor_[-1] == str)
         return true;
 
     while (true) {
         bool restart = false;
 
         // Check whether id is still to come.
-        GCPtrFlatString* const props_cursor = ni->props_cursor;
-        GCPtrFlatString* const props_end = ni->end();
-        for (GCPtrFlatString* idp = props_cursor; idp < props_end; ++idp) {
+        GCPtrFlatString* const cursor = ni->propertyCursor_;
+        GCPtrFlatString* const end = ni->propertiesEnd();
+        for (GCPtrFlatString* idp = cursor; idp < end; ++idp) {
             // Common case: both strings are atoms.
             if ((*idp)->isAtom() && str->isAtom()) {
                 if (*idp != str)
                     continue;
             } else {
                 if (!EqualStrings(*idp, str))
                     continue;
             }
@@ -1283,35 +1296,35 @@ SuppressDeletedProperty(JSContext* cx, N
                     return false;
 
                 if (desc.object() && desc.enumerable())
                     continue;
             }
 
             // If GetPropertyDescriptor above removed a property from ni, start
             // over.
-            if (props_end != ni->props_end || props_cursor != ni->props_cursor) {
+            if (end != ni->propertiesEnd() || cursor != ni->propertyCursor_) {
                 restart = true;
                 break;
             }
 
             // No property along the prototype chain stepped in to take the
             // property's place, so go ahead and delete id from the list.
             // If it is the next property to be enumerated, just skip it.
-            if (idp == props_cursor) {
+            if (idp == cursor) {
                 ni->incCursor();
             } else {
-                for (GCPtrFlatString* p = idp; p + 1 != props_end; p++)
+                for (GCPtrFlatString* p = idp; p + 1 != end; p++)
                     *p = *(p + 1);
-                ni->props_end = ni->end() - 1;
+                ni->propertiesEnd_--;
 
                 // This invokes the pre barrier on this element, since
                 // it's no longer going to be marked, and ensures that
                 // any existing remembered set entry will be dropped.
-                *ni->props_end = nullptr;
+                *ni->propertiesEnd_ = nullptr;
             }
 
             // Don't reuse modified native iterators.
             ni->flags |= JSITER_UNREUSABLE;
             return true;
         }
 
         if (!restart)
--- a/js/src/vm/Iteration.h
+++ b/js/src/vm/Iteration.h
@@ -6,16 +6,17 @@
 
 #ifndef vm_Iteration_h
 #define vm_Iteration_h
 
 /*
  * JavaScript iterators.
  */
 
+#include "mozilla/ArrayUtils.h"
 #include "mozilla/MemoryReporting.h"
 
 #include "gc/Barrier.h"
 #include "vm/JSContext.h"
 #include "vm/ReceiverGuard.h"
 #include "vm/Stack.h"
 
 /*
@@ -26,32 +27,43 @@
 #define JSITER_UNREUSABLE   0x2000
 
 namespace js {
 
 class PropertyIteratorObject;
 
 struct NativeIterator
 {
+  public:
     // Object being iterated.
     GCPtrObject obj = {};
 
+  private:
     // Internal iterator object.
     JSObject* iterObj_ = nullptr;
 
-    // The next property, pointing into an array of strings directly after this
-    // NativeIterator as part of the overall allocation containing |*this|.
-    GCPtrFlatString* props_cursor; // initialized by constructor
+    // The end of HeapReceiverGuards that appear directly after |this|, as part
+    // of an overall allocation that stores |*this|, receiver guards, and
+    // iterated strings.  Once this has been fully initialized, it also equals
+    // the start of iterated strings.
+    HeapReceiverGuard* guardsEnd_; // initialized by constructor
 
-    // The limit/end of properties to iterate.  (This is also, after casting,
-    // the start of an array of HeapReceiverGuards included in the overall
-    // allocation that stores |*this| and the iterated strings.)
-    GCPtrFlatString* props_end; // initialized by constructor
+  public:
+    // The next property, pointing into an array of strings directly after any
+    // HeapReceiverGuards that appear directly after |*this|, as part of an
+    // overall allocation that stores |*this|, receiver guards, and iterated
+    // strings.
+    GCPtrFlatString* propertyCursor_; // initialized by constructor
 
-    uint32_t guard_length = 0;
+    // The limit/end of properties to iterate (and, assuming no error occurred
+    // while constructing this NativeIterator, the end of the full allocation
+    // storing |*this|, receiver guards, and strings).  Beware!  This value may
+    // change as properties are deleted from the observed object.
+    GCPtrFlatString* propertiesEnd_; // initialized by constructor
+
     uint32_t guard_key = 0;
     uint32_t flags = 0;
 
   private:
     /* While in compartment->enumerators, these form a doubly linked list. */
     NativeIterator* next_ = nullptr;
     NativeIterator* prev_ = nullptr;
 
@@ -71,67 +83,80 @@ struct NativeIterator
      */
     NativeIterator(JSContext* cx, Handle<PropertyIteratorObject*> propIter,
                    Handle<JSObject*> objBeingIterated, const AutoIdVector& props,
                    uint32_t numGuards, uint32_t guardKey, bool* hadError);
 
     /** Initialize a |JSCompartment::enumerators| sentinel. */
     NativeIterator();
 
-    GCPtrFlatString* begin() const {
-        static_assert(alignof(NativeIterator) >= alignof(GCPtrFlatString),
-                      "GCPtrFlatStrings for properties must be able to appear "
-                      "directly after NativeIterator, with no padding space "
-                      "required for correct alignment");
-
-        // Note that JIT code inlines this computation to reset |props_cursor|
-        // when an iterator ends: see |CodeGenerator::visitIteratorEnd|.
+    HeapReceiverGuard* guardsBegin() const {
+        static_assert(alignof(HeapReceiverGuard) <= alignof(NativeIterator),
+                      "NativeIterator must be aligned to begin storing "
+                      "HeapReceiverGuards immediately after it with no "
+                      "required padding");
         const NativeIterator* immediatelyAfter = this + 1;
         auto* afterNonConst = const_cast<NativeIterator*>(immediatelyAfter);
-        return reinterpret_cast<GCPtrFlatString*>(afterNonConst);
+        return reinterpret_cast<HeapReceiverGuard*>(afterNonConst);
     }
 
-    GCPtrFlatString* end() const {
-        return props_end;
+    HeapReceiverGuard* guardsEnd() const {
+        return guardsEnd_;
+    }
+
+    uint32_t guardCount() const {
+        return mozilla::PointerRangeSize(guardsBegin(), guardsEnd());
     }
 
-    HeapReceiverGuard* guardArray() const {
-        static_assert(alignof(ReceiverGuard) == alignof(GCPtrFlatString),
-                      "the end of all properties must be exactly aligned "
-                      "adequate to begin storing ReceiverGuards, else the "
-                      "full tacked-on memory won't be enough to store all "
-                      "properties/guards");
-        return reinterpret_cast<HeapReceiverGuard*>(props_end);
+    GCPtrFlatString* propertiesBegin() const {
+        static_assert(alignof(HeapReceiverGuard) >= alignof(GCPtrFlatString),
+                      "GCPtrFlatStrings for properties must be able to appear "
+                      "directly after any HeapReceiverGuards after this "
+                      "NativeIterator, with no padding space required for "
+                      "correct alignment");
+        static_assert(alignof(NativeIterator) >= alignof(GCPtrFlatString),
+                      "GCPtrFlatStrings for properties must be able to appear "
+                      "directly after this NativeIterator when no "
+                      "HeapReceiverGuards are present, with no padding space "
+                      "required for correct alignment");
+
+        // Note: JIT code inlines this computation to reset |propertyCursor_|
+        //       when an iterator ends: see |CodeGenerator::visitIteratorEnd|.
+        return reinterpret_cast<GCPtrFlatString*>(guardsEnd_);
+    }
+
+    GCPtrFlatString* propertiesEnd() const {
+        return propertiesEnd_;
     }
 
     size_t numKeys() const {
-        return end() - begin();
+        return mozilla::PointerRangeSize(propertiesBegin(), propertiesEnd());
     }
 
     JSObject* iterObj() const {
         return iterObj_;
     }
-    GCPtrFlatString* current() const {
-        MOZ_ASSERT(props_cursor < props_end);
-        return props_cursor;
+    GCPtrFlatString* currentProperty() const {
+        MOZ_ASSERT(propertyCursor_ < propertiesEnd());
+        return propertyCursor_;
     }
 
     NativeIterator* next() {
         return next_;
     }
 
     static inline size_t offsetOfNext() {
         return offsetof(NativeIterator, next_);
     }
     static inline size_t offsetOfPrev() {
         return offsetof(NativeIterator, prev_);
     }
 
     void incCursor() {
-        props_cursor = props_cursor + 1;
+        propertyCursor_++;
     }
     void link(NativeIterator* other) {
         /* A NativeIterator cannot appear in the enumerator list twice. */
         MOZ_ASSERT(!next_ && !prev_);
 
         this->next_ = other;
         this->prev_ = other->prev_;
         other->prev_->next_ = this;
@@ -142,16 +167,28 @@ struct NativeIterator
         prev_->next_ = next_;
         next_ = nullptr;
         prev_ = nullptr;
     }
 
     static NativeIterator* allocateSentinel(JSContext* maybecx);
 
     void trace(JSTracer* trc);
+
+    static constexpr size_t offsetOfGuardsEnd() {
+        return offsetof(NativeIterator, guardsEnd_);
+    }
+
+    static constexpr size_t offsetOfPropertyCursor() {
+        return offsetof(NativeIterator, propertyCursor_);
+    }
+
+    static constexpr size_t offsetOfPropertiesEnd() {
+        return offsetof(NativeIterator, propertiesEnd_);
+    }
 };
 
 class PropertyIteratorObject : public NativeObject
 {
     static const ClassOps classOps_;
 
   public:
     static const Class class_;
--- a/js/src/vm/JSCompartment.cpp
+++ b/js/src/vm/JSCompartment.cpp
@@ -41,28 +41,20 @@ using namespace js::jit;
 
 using mozilla::PodArrayZero;
 
 JSCompartment::JSCompartment(Zone* zone)
   : zone_(zone),
     runtime_(zone->runtimeFromAnyThread()),
     data(nullptr),
     regExps(),
-    globalWriteBarriered(0),
     detachedTypedObjects(0),
-    objectMetadataTable(nullptr),
     innerViews(zone),
-    lazyArrayBuffers(nullptr),
-    nonSyntacticLexicalEnvironments_(nullptr),
     gcIncomingGrayPointers(nullptr),
-    validAccessPtr(nullptr),
-    debugEnvs(nullptr),
-    enumerators(nullptr),
-    jitCompartment_(nullptr),
-    lcovOutput()
+    enumerators(nullptr)
 {
     runtime_->numCompartments++;
 }
 
 Realm::Realm(JS::Zone* zone, const JS::RealmOptions& options)
   : JSCompartment(zone),
     creationOptions_(options.creationOptions()),
     behaviors_(options.behaviors()),
@@ -72,53 +64,52 @@ Realm::Realm(JS::Zone* zone, const JS::R
     performanceMonitoring(runtime_)
 {
     MOZ_ASSERT_IF(creationOptions_.mergeable(),
                   creationOptions_.invisibleToDebugger());
 }
 
 Realm::~Realm()
 {
-    // Empty destructor: using the default destructor requires adding various
-    // #includes to other files where we destruct Realms.
-}
-
-JSCompartment::~JSCompartment()
-{
     // Write the code coverage information in a file.
     JSRuntime* rt = runtimeFromMainThread();
     if (rt->lcovOutput().isEnabled())
         rt->lcovOutput().writeLCovResult(lcovOutput);
+}
 
-    js_delete(jitCompartment_);
-    js_delete(debugEnvs);
-    js_delete(objectMetadataTable);
-    js_delete(lazyArrayBuffers);
-    js_delete(nonSyntacticLexicalEnvironments_);
-    js_free(enumerators);
+JSCompartment::~JSCompartment()
+{
+    MOZ_ASSERT(enumerators == iteratorSentinel_.get());
 
 #ifdef DEBUG
     // Avoid assertion destroying the unboxed layouts list if the embedding
     // leaked GC things.
-    if (!rt->gc.shutdownCollectedEverything())
+    if (!runtime_->gc.shutdownCollectedEverything())
         unboxedLayouts.clear();
 #endif
 
     runtime_->numCompartments--;
 }
 
 bool
 JSCompartment::init(JSContext* maybecx)
 {
     if (!crossCompartmentWrappers.init(0)) {
         if (maybecx)
             ReportOutOfMemory(maybecx);
         return false;
     }
 
+    NativeIteratorSentinel sentinel(NativeIterator::allocateSentinel(maybecx));
+    if (!sentinel)
+        return false;
+
+    iteratorSentinel_ = Move(sentinel);
+    enumerators = iteratorSentinel_.get();
+
     return true;
 }
 
 bool
 Realm::init(JSContext* maybecx)
 {
     // Initialize JSCompartment. This is temporary until Realm and
     // JSCompartment are completely separated.
@@ -131,20 +122,16 @@ Realm::init(JSContext* maybecx)
      *
      * As a hack, we clear our timezone cache every time we create a new realm.
      * This ensures that the cache is always relatively fresh, but shouldn't
      * interfere with benchmarks that create tons of date objects (unless they
      * also create tons of iframes, which seems unlikely).
      */
     JS::ResetTimeZone();
 
-    enumerators = NativeIterator::allocateSentinel(maybecx);
-    if (!enumerators)
-        return false;
-
     if (!savedStacks_.init() ||
         !varNames_.init() ||
         !iteratorCache.init())
     {
         if (maybecx)
             ReportOutOfMemory(maybecx);
         return false;
     }
@@ -191,28 +178,24 @@ JSCompartment::ensureJitCompartmentExist
 {
     using namespace js::jit;
     if (jitCompartment_)
         return true;
 
     if (!zone()->getJitZone(cx))
         return false;
 
-    /* Set the compartment early, so linking works. */
-    jitCompartment_ = cx->new_<JitCompartment>();
-
-    if (!jitCompartment_)
+    UniquePtr<JitCompartment> jitComp = cx->make_unique<JitCompartment>();
+    if (!jitComp)
         return false;
 
-    if (!jitCompartment_->initialize(cx)) {
-        js_delete(jitCompartment_);
-        jitCompartment_ = nullptr;
+    if (!jitComp->initialize(cx))
         return false;
-    }
 
+    jitCompartment_ = Move(jitComp);
     return true;
 }
 
 #ifdef JSGC_HASH_TABLE_CHECKS
 
 void
 js::DtoaCache::checkCacheAfterMovingGC()
 {
@@ -532,19 +515,21 @@ JSCompartment::wrap(JSContext* cx, Mutab
     }
     return true;
 }
 
 LexicalEnvironmentObject*
 JSCompartment::getOrCreateNonSyntacticLexicalEnvironment(JSContext* cx, HandleObject enclosing)
 {
     if (!nonSyntacticLexicalEnvironments_) {
-        nonSyntacticLexicalEnvironments_ = cx->new_<ObjectWeakMap>(cx);
-        if (!nonSyntacticLexicalEnvironments_ || !nonSyntacticLexicalEnvironments_->init())
+        auto map = cx->make_unique<ObjectWeakMap>(cx);
+        if (!map || !map->init())
             return nullptr;
+
+        nonSyntacticLexicalEnvironments_ = Move(map);
     }
 
     // If a wrapped WithEnvironmentObject was passed in, unwrap it, as we may
     // be creating different WithEnvironmentObject wrappers each time.
     RootedObject key(cx, enclosing);
     if (enclosing->is<WithEnvironmentObject>()) {
         MOZ_ASSERT(!enclosing->as<WithEnvironmentObject>().isSyntactic());
         key = &enclosing->as<WithEnvironmentObject>().object();
@@ -728,25 +713,24 @@ Realm::finishRoots()
 
     if (nonSyntacticLexicalEnvironments_)
         nonSyntacticLexicalEnvironments_->clear();
 }
 
 void
 JSCompartment::sweepAfterMinorGC(JSTracer* trc)
 {
-    globalWriteBarriered = 0;
-
     InnerViewTable& table = innerViews.get();
     if (table.needsSweepAfterMinorGC())
         table.sweepAfterMinorGC();
 
     crossCompartmentWrappers.sweepAfterMinorGC(trc);
 
     Realm* realm = JS::GetRealmForCompartment(this);
+    realm->globalWriteBarriered = 0;
     realm->dtoaCache.purge();
 }
 
 void
 JSCompartment::sweepSavedStacks()
 {
     savedStacks_.sweep();
 }
@@ -1024,32 +1008,25 @@ Realm::forgetAllocationMetadataBuilder()
     // to cancel off-thread Ion compilations to avoid races when Ion calls
     // hasAllocationMetadataBuilder off-thread.
     CancelOffThreadIonCompile(this);
 
     allocationMetadataBuilder_ = nullptr;
 }
 
 void
-Realm::clearObjectMetadata()
-{
-    js_delete(objectMetadataTable);
-    objectMetadataTable = nullptr;
-}
-
-void
 Realm::setNewObjectMetadata(JSContext* cx, HandleObject obj)
 {
     assertSameCompartment(cx, this, obj);
 
     AutoEnterOOMUnsafeRegion oomUnsafe;
     if (JSObject* metadata = allocationMetadataBuilder_->build(cx, obj, oomUnsafe)) {
         assertSameCompartment(cx, metadata);
         if (!objectMetadataTable) {
-            objectMetadataTable = cx->new_<ObjectWeakMap>(cx);
+            objectMetadataTable = cx->make_unique<ObjectWeakMap>(cx);
             if (!objectMetadataTable || !objectMetadataTable->init())
                 oomUnsafe.crash("setNewObjectMetadata");
         }
         if (!objectMetadataTable->add(cx, obj, metadata))
             oomUnsafe.crash("setNewObjectMetadata");
     }
 }
 
--- a/js/src/vm/JSCompartment.h
+++ b/js/src/vm/JSCompartment.h
@@ -592,25 +592,16 @@ struct JSCompartment
   public:
     js::RegExpCompartment        regExps;
 
     using IteratorCache = js::HashSet<js::PropertyIteratorObject*,
                                       js::IteratorHashPolicy,
                                       js::SystemAllocPolicy>;
     IteratorCache iteratorCache;
 
-    /*
-     * For generational GC, record whether a write barrier has added this
-     * compartment's global to the store buffer since the last minor GC.
-     *
-     * This is used to avoid calling into the VM every time a nursery object is
-     * written to a property of the global.
-     */
-    uint32_t                     globalWriteBarriered;
-
     // Non-zero if the storage underlying any typed object in this compartment
     // might be detached.
     int32_t                      detachedTypedObjects;
 
     // Recompute the probability with which this compartment should record
     // profiling data (stack traces, allocations log, etc.) about each
     // allocation. We consult the probabilities requested by the Debugger
     // instances observing us, if any.
@@ -624,59 +615,49 @@ struct JSCompartment
     // Object group tables and other state in the compartment.
     js::ObjectGroupCompartment   objectGroups;
 
 #ifdef JSGC_HASH_TABLE_CHECKS
     void checkWrapperMapAfterMovingGC();
 #endif
     // Keep track of the metadata objects which can be associated with each JS
     // object. Both keys and values are in this compartment.
-    js::ObjectWeakMap* objectMetadataTable;
+    js::UniquePtr<js::ObjectWeakMap> objectMetadataTable;
 
     // Map from array buffers to views sharing that storage.
     JS::WeakCache<js::InnerViewTable> innerViews;
 
     // Inline transparent typed objects do not initially have an array buffer,
     // but can have that buffer created lazily if it is accessed later. This
     // table manages references from such typed objects to their buffers.
-    js::ObjectWeakMap* lazyArrayBuffers;
+    js::UniquePtr<js::ObjectWeakMap> lazyArrayBuffers;
 
     // All unboxed layouts in the compartment.
     mozilla::LinkedList<js::UnboxedLayout> unboxedLayouts;
 
   protected:
     // All non-syntactic lexical environments in the compartment. These are kept in
     // a map because when loading scripts into a non-syntactic environment, we need
     // to use the same lexical environment to persist lexical bindings.
-    js::ObjectWeakMap* nonSyntacticLexicalEnvironments_;
+    js::UniquePtr<js::ObjectWeakMap> nonSyntacticLexicalEnvironments_;
 
   public:
     /*
      * During GC, stores the head of a list of incoming pointers from gray cells.
      *
      * The objects in the list are either cross-compartment wrappers, or
      * debugger wrapper objects.  The list link is either in the second extra
      * slot for the former, or a special slot for the latter.
      */
     JSObject*                    gcIncomingGrayPointers;
 
   private:
     bool getNonWrapperObjectForCurrentCompartment(JSContext* cx, js::MutableHandleObject obj);
     bool getOrCreateWrapper(JSContext* cx, js::HandleObject existing, js::MutableHandleObject obj);
 
-  private:
-    // This pointer is controlled by the embedder. If it is non-null, and if
-    // cx->enableAccessValidation is true, then we assert that *validAccessPtr
-    // is true before running any code in this compartment.
-    bool* validAccessPtr;
-
-  public:
-    bool isAccessValid() const { return validAccessPtr ? *validAccessPtr : true; }
-    void setValidAccessPtr(bool* accessp) { validAccessPtr = accessp; }
-
   protected:
     explicit JSCompartment(JS::Zone* zone);
     ~JSCompartment();
 
     MOZ_MUST_USE bool init(JSContext* maybecx);
 
   public:
     MOZ_MUST_USE inline bool wrap(JSContext* cx, JS::MutableHandleValue vp);
@@ -749,45 +730,45 @@ struct JSCompartment
 
     void findOutgoingEdges(js::gc::ZoneComponentFinder& finder);
 
     static size_t offsetOfRegExps() {
         return offsetof(JSCompartment, regExps);
     }
 
     /* Bookkeeping information for debug scope objects. */
-    js::DebugEnvironments* debugEnvs;
+    js::UniquePtr<js::DebugEnvironments> debugEnvs;
 
     /*
      * List of potentially active iterators that may need deleted property
      * suppression.
      */
+  private:
+    using NativeIteratorSentinel = js::UniquePtr<js::NativeIterator, JS::FreePolicy>;
+    NativeIteratorSentinel iteratorSentinel_;
+  public:
     js::NativeIterator* enumerators;
 
     MOZ_ALWAYS_INLINE bool objectMaybeInIteration(JSObject* obj);
 
     // These flags help us to discover if a compartment that shouldn't be alive
     // manages to outlive a GC. Note that these flags have to be on the
     // compartment, not the realm, because same-compartment realms can have
     // cross-realm pointers without wrappers.
     bool scheduledForDestruction = false;
     bool maybeAlive = true;
 
   protected:
-    js::jit::JitCompartment* jitCompartment_;
+    js::UniquePtr<js::jit::JitCompartment> jitCompartment_;
 
   public:
     bool ensureJitCompartmentExists(JSContext* cx);
     js::jit::JitCompartment* jitCompartment() {
-        return jitCompartment_;
+        return jitCompartment_.get();
     }
-
-    // Aggregated output used to collect JSScript hit counts when code coverage
-    // is enabled.
-    js::coverage::LCovCompartment lcovOutput;
 };
 
 class JS::Realm : public JSCompartment
 {
     const JS::RealmCreationOptions creationOptions_;
     JS::RealmBehaviors behaviors_;
 
     friend struct ::JSContext;
@@ -815,16 +796,21 @@ class JS::Realm : public JSCompartment
     JSPrincipals* principals_ = nullptr;
 
     // Used by memory reporters and invalid otherwise.
     JS::RealmStats* realmStats_ = nullptr;
 
     const js::AllocationMetadataBuilder* allocationMetadataBuilder_ = nullptr;
     void* realmPrivate_ = nullptr;
 
+    // This pointer is controlled by the embedder. If it is non-null, and if
+    // cx->enableAccessValidation is true, then we assert that *validAccessPtr
+    // is true before running any code in this realm.
+    bool* validAccessPtr_ = nullptr;
+
     js::ReadBarriered<js::ArgumentsObject*> mappedArgumentsTemplate_ { nullptr };
     js::ReadBarriered<js::ArgumentsObject*> unmappedArgumentsTemplate_ { nullptr };
     js::ReadBarriered<js::NativeObject*> iterResultTemplate_ { nullptr };
 
     unsigned enterRealmDepth_ = 0;
 
     enum {
         IsDebuggee = 1 << 0,
@@ -846,16 +832,20 @@ class JS::Realm : public JSCompartment
     bool isSelfHostingRealm_ = false;
     bool marked_ = true;
     bool isSystem_ = false;
 
   public:
     // WebAssembly state for the realm.
     js::wasm::Realm wasm;
 
+    // Aggregated output used to collect JSScript hit counts when code coverage
+    // is enabled.
+    js::coverage::LCovRealm lcovOutput;
+
     js::DtoaCache dtoaCache;
     js::NewProxyCache newProxyCache;
     js::ArraySpeciesLookup arraySpeciesLookup;
 
     js::PerformanceGroupHolder performanceMonitoring;
 
     js::UniquePtr<js::ScriptCountsMap> scriptCountsMap;
     js::UniquePtr<js::ScriptNameMap> scriptNameMap;
@@ -865,16 +855,25 @@ class JS::Realm : public JSCompartment
      * Lazily initialized script source object to use for scripts cloned
      * from the self-hosting global.
      */
     js::ReadBarrieredScriptSourceObject selfHostingScriptSource { nullptr };
 
     // Last time at which an animation was played for this realm.
     int64_t lastAnimationTime = 0;
 
+    /*
+     * For generational GC, record whether a write barrier has added this
+     * realm's global to the store buffer since the last minor GC.
+     *
+     * This is used to avoid calling into the VM every time a nursery object is
+     * written to a property of the global.
+     */
+    uint32_t globalWriteBarriered = 0;
+
     uint32_t warnedAboutStringGenericsMethods = 0;
 #ifdef DEBUG
     bool firedOnNewGlobalObject = false;
 #endif
 
   private:
     void updateDebuggerObservesFlag(unsigned flag);
 
@@ -1009,17 +1008,16 @@ class JS::Realm : public JSCompartment
         return allocationMetadataBuilder_;
     }
     const void* addressOfMetadataBuilder() const {
         return &allocationMetadataBuilder_;
     }
     void setAllocationMetadataBuilder(const js::AllocationMetadataBuilder* builder);
     void forgetAllocationMetadataBuilder();
     void setNewObjectMetadata(JSContext* cx, JS::HandleObject obj);
-    void clearObjectMetadata();
 
     bool hasObjectPendingMetadata() const {
         return objectMetadataState_.is<js::PendingMetadata>();
     }
     void setObjectPendingMetadata(JSContext* cx, JSObject* obj) {
         if (!cx->helperThread()) {
             MOZ_ASSERT(objectMetadataState_.is<js::DelayMetadata>());
             objectMetadataState_ = js::NewObjectMetadataState(js::PendingMetadata(obj));
@@ -1222,16 +1220,23 @@ class JS::Realm : public JSCompartment
 
     const void* addressOfRandomNumberGenerator() const {
         return randomNumberGenerator_.ptr();
     }
 
     js::HashNumber randomHashCode();
 
     mozilla::HashCodeScrambler randomHashCodeScrambler();
+
+    bool isAccessValid() const {
+        return validAccessPtr_ ? *validAccessPtr_ : true;
+    }
+    void setValidAccessPtr(bool* accessp) {
+        validAccessPtr_ = accessp;
+    }
 };
 
 namespace js {
 
 // We only set the maybeAlive flag for objects and scripts. It's assumed that,
 // if a compartment is alive, then it will have at least some live object or
 // script it in. Even if we get this wrong, the worst that will happen is that
 // scheduledForDestruction will be set on the compartment, which will cause
--- a/js/src/vm/JSScript.cpp
+++ b/js/src/vm/JSScript.cpp
@@ -3103,20 +3103,20 @@ void
 JSScript::finalize(FreeOp* fop)
 {
     // NOTE: this JSScript may be partially initialized at this point.  E.g. we
     // may have created it and partially initialized it with
     // JSScript::Create(), but not yet finished initializing it with
     // fullyInitFromEmitter() or fullyInitTrivial().
 
     // Collect code coverage information for this script and all its inner
-    // scripts, and store the aggregated information on the compartment.
+    // scripts, and store the aggregated information on the realm.
     MOZ_ASSERT_IF(hasScriptName(), fop->runtime()->lcovOutput().isEnabled());
     if (fop->runtime()->lcovOutput().isEnabled() && hasScriptName()) {
-        compartment()->lcovOutput.collectCodeCoverageInfo(compartment(), this, getScriptName());
+        realm()->lcovOutput.collectCodeCoverageInfo(realm(), this, getScriptName());
         destroyScriptName();
     }
 
     fop->runtime()->geckoProfiler().onScriptFinalized(this);
 
     if (types_)
         types_->destroy();
 
--- a/layout/reftests/bidi/dirAuto/reftest.list
+++ b/layout/reftests/bidi/dirAuto/reftest.list
@@ -1,12 +1,12 @@
 == bdi-auto-dir-default.html bdi-auto-dir-default-ref.html
-== dir_auto-set-contained-dir-L.html dir_auto-contained-dir-L-ref.html
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == dir_auto-set-contained-dir-L.html dir_auto-contained-dir-L-ref.html
 == dir_auto-set-contained-dir-R.html dir_auto-contained-dir-R-ref.html
-== dir_auto-set-contained-invalid-dir-L.html dir_auto-contained-dir-L-ref.html
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == dir_auto-set-contained-invalid-dir-L.html dir_auto-contained-dir-L-ref.html
 == dir_auto-set-contained-invalid-dir-R.html dir_auto-contained-dir-R-ref.html
 == dir_auto-unset-contained-dir-L.html dir_auto-unset-contained-dir-L-ref.html
 == dir_auto-unset-contained-dir-R.html dir_auto-unset-contained-dir-R-ref.html
 == dynamicDirAuto-setLTR-Auto1.html dynamicDirAuto-refLTR-LTR.html
 == dynamicDirAuto-setLTR-Auto2.html dynamicDirAuto-refLTR-LTR.html
 == dynamicDirAuto-setLTR-Auto3.html dynamicDirAuto-refLTR-LTR.html
 == dynamicDirAuto-setLTR-Auto4.html dynamicDirAuto-refLTR-LTR.html
 == dynamicDirAuto-setLTR-Auto5.html dynamicDirAuto-refLTR-LTR.html
--- a/layout/reftests/bidi/reftest.list
+++ b/layout/reftests/bidi/reftest.list
@@ -1,11 +1,11 @@
 include dirAuto/reftest.list
 include numeral/reftest.list
-== bdi-element.html bdi-element-ref.html
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == bdi-element.html bdi-element-ref.html
 == bidi-000.html bidi-000-ref.html
 == bidi-001.html bidi-001-ref.html
 == bidi-001-j.html bidi-001-ref.html
 == bidi-001-v.html bidi-001-ref.html
 == bidi-002.html bidi-002-ref.html
 == bidi-003.html bidi-003-ref.html
 fuzzy-if(gtkWidget,255,17) == bidi-004.html bidi-004-ref.html # inconsistency in the Hebrew font that gets used
 fuzzy-if(gtkWidget,255,17) == bidi-004-j.html bidi-004-ref.html # inconsistency in the Hebrew font that gets used
--- a/layout/reftests/bugs/reftest.list
+++ b/layout/reftests/bugs/reftest.list
@@ -651,17 +651,17 @@ fails-if(Android&&!asyncPan) == 371561-1
 == 372062-1.html 372062-1-ref.html
 == 372063-1.html 372063-1-ref.html
 == 372323-1.xhtml 372323-1-ref.xhtml
 == 372553-1.html 372553-1-ref.html
 == 372632-1.html 372632-1-ref.html
 == 372768-1.html 372768-1-ref.html
 fuzzy-if(webrender&&winWidget,83-83,2-2) == 373295-1.html 373295-1-ref.html
 == 373298-1.html 373298-1-ref.html
-== 373381-1.html 373381-1-ref.html
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == 373381-1.html 373381-1-ref.html
 fuzzy-if(skiaContent&&!Android,2,40) == 373381-2.html 373381-2-ref.html
 random-if(d2d) == 373381-3.html 373381-3-ref.html
 == 373381-4.html 373381-4-ref.html
 == 373383-1.html 373383-1-ref.html
 == 373433-1.html 373433-1-ref.html
 == 373533-1.xhtml about:blank
 == 373533-2.xhtml about:blank
 == 373533-3.xhtml about:blank
@@ -1601,19 +1601,19 @@ fuzzy-if(skiaContent,1,80) fuzzy-if(webr
 random-if(winWidget) fuzzy-if(Android,38,539) fuzzy-if(skiaContent,1,480) needs-focus == 598726-1.html 598726-1-ref.html # Fails on Windows, bug 782196
 == 599113-1.html 599113-1-ref.html
 fails-if(!haveTestPlugin) HTTP == 599476.html 599476-ref.html
 == 599882-1a.html 599882-1-ref.html
 == 599882-1b.html 599882-1-ref.html
 == 599882-2.html 599882-2-ref.html
 == 600045-1.html 600045-1-ref.html
 == 600803-1.html 600803-1-ref.html
-== 600974-1.html 600974-1-ref.html
-== 600974-2.html 600974-1-ref.html
-== 600974-3.html 600974-1-ref.html
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == 600974-1.html 600974-1-ref.html
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == 600974-2.html 600974-1-ref.html
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == 600974-3.html 600974-1-ref.html
 == 602200-1.html 602200-1-ref.html
 == 602200-2.html 602200-2-ref.html
 fuzzy-if(Android,8,20) == 602200-3.html 602200-3-ref.html
 == 602200-4.html 602200-4-ref.html
 == 603423-1.html 603423-1-ref.html
 == 604737.html 604737-ref.html
 == 605138-1.html 605138-1-ref.html
 == 605157-1.xhtml 605157-1-ref.xhtml
--- a/layout/reftests/counters/reftest.list
+++ b/layout/reftests/counters/reftest.list
@@ -3,17 +3,17 @@
 == t1202-counter-01-b-test.html t1202-counter-01-b-reference.html
 == t1202-counter-02-b-test.html t1202-counter-02-b-reference.html
 == t1202-counter-03-b-test.html t1202-counter-03-b-reference.html
 == t1202-counter-04-b-test.html t1202-counter-04-b-reference.html
 == t1202-counter-05-b-test.html t1202-counter-05-b-reference.html
 == t1202-counter-06-b-test.html t1202-counter-06-b-reference.html
 == t1202-counter-07-b-test.html t1202-counter-07-b-reference.html
 == t1202-counter-08-b-test.html t1202-counter-08-b-reference.html
-== t1202-counter-09-b-test.html t1202-counter-09-b-reference.html
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == t1202-counter-09-b-test.html t1202-counter-09-b-reference.html
 == t1202-counter-10-b-test.html t1202-counter-10-b-reference.html
 == t1202-counter-11-b-test.html t1202-counter-11-b-reference.html
 == t1202-counter-12-b-test.html t1202-counter-12-b-reference.html
 == t1202-counter-13-b-test.html t1202-counter-13-b-reference.html
 == t1202-counter-14-b-test.html t1202-counter-14-b-reference.html
 == t1202-counter-15-b-test.html t1202-counter-15-b-reference.html
 == t1202-counter-16-f-test.html t1202-counter-16-f-reference.html
 == t1202-counters-00-b-test.html t1202-counters-00-b-reference.html
@@ -64,19 +64,19 @@
 == counter-ua-limits-00.html counter-ua-limits-00-ref.html
 == counter-ua-limits-01.html counter-ua-limits-01-ref.html
 == counter-ua-limits-02.html counter-ua-limits-02-ref.html
 == counter-ua-limits-03.html counter-ua-limits-03-ref.html
 == counter-ua-limits-list-00.html counter-ua-limits-list-00-ref.html
 == counter-ua-limits-list-01.html counter-ua-limits-list-01-ref.html
 == multiple-thai-counters.html multiple-thai-counters-ref.html
 fuzzy-if(webrender&&cocoaWidget,40-40,6-6) == counter-suffix.html counter-suffix-ref.html
-== counter-cjk-decimal.html counter-cjk-decimal-ref.html
-== counter-japanese-informal.html counter-japanese-informal-ref.html
-== counter-japanese-formal.html counter-japanese-formal-ref.html
-== counter-korean-hangul-formal.html counter-korean-hangul-formal-ref.html
-== counter-korean-hanja-informal.html counter-korean-hanja-informal-ref.html
-== counter-korean-hanja-formal.html counter-korean-hanja-formal-ref.html
-== counter-simp-chinese-informal.html counter-simp-chinese-informal-ref.html
-== counter-simp-chinese-formal.html counter-simp-chinese-formal-ref.html
-== counter-trad-chinese-informal.html counter-trad-chinese-informal-ref.html
-== counter-trad-chinese-formal.html counter-trad-chinese-formal-ref.html
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == counter-cjk-decimal.html counter-cjk-decimal-ref.html
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == counter-japanese-informal.html counter-japanese-informal-ref.html
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == counter-japanese-formal.html counter-japanese-formal-ref.html
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == counter-korean-hangul-formal.html counter-korean-hangul-formal-ref.html
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == counter-korean-hanja-informal.html counter-korean-hanja-informal-ref.html
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == counter-korean-hanja-formal.html counter-korean-hanja-formal-ref.html
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == counter-simp-chinese-informal.html counter-simp-chinese-informal-ref.html
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == counter-simp-chinese-formal.html counter-simp-chinese-formal-ref.html
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == counter-trad-chinese-informal.html counter-trad-chinese-informal-ref.html
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == counter-trad-chinese-formal.html counter-trad-chinese-formal-ref.html
 == counter-ethiopic-numeric.html counter-ethiopic-numeric-ref.html
--- a/layout/reftests/css-grid/reftest.list
+++ b/layout/reftests/css-grid/reftest.list
@@ -103,17 +103,17 @@ skip-if(Android) == grid-auto-min-sizing
 == grid-item-intrinsic-ratio-normal-001.html grid-item-intrinsic-ratio-normal-001-ref.html
 == grid-item-intrinsic-ratio-normal-002.html grid-item-intrinsic-ratio-normal-002-ref.html
 == grid-item-intrinsic-ratio-normal-003.html grid-item-intrinsic-ratio-normal-003-ref.html
 == grid-item-intrinsic-ratio-normal-004.html grid-item-intrinsic-ratio-normal-004-ref.html
 == grid-item-intrinsic-ratio-normal-005.html grid-item-intrinsic-ratio-normal-005-ref.html
 == grid-item-intrinsic-size-normal-001.html grid-item-intrinsic-size-normal-001-ref.html
 == grid-item-intrinsic-size-normal-002.html grid-item-intrinsic-size-normal-002-ref.html
 == grid-item-auto-min-size-clamp-001.html grid-item-auto-min-size-clamp-001-ref.html
-== grid-item-auto-min-size-clamp-002.html grid-item-auto-min-size-clamp-002-ref.html
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == grid-item-auto-min-size-clamp-002.html grid-item-auto-min-size-clamp-002-ref.html
 == grid-item-auto-min-size-clamp-003.html grid-item-auto-min-size-clamp-003-ref.html
 # == grid-item-auto-min-size-clamp-004.html grid-item-auto-min-size-clamp-004-ref.html # bug 1421976
 == grid-item-auto-min-size-clamp-005.html grid-item-auto-min-size-clamp-005-ref.html
 # == grid-item-auto-min-size-clamp-006.html grid-item-auto-min-size-clamp-006-ref.html # bug 1421976
 == grid-item-auto-min-size-clamp-007.html grid-item-auto-min-size-clamp-007-ref.html
 == grid-item-overflow-stretch-001.html grid-item-overflow-stretch-001-ref.html
 == grid-item-overflow-stretch-002.html grid-item-overflow-stretch-002-ref.html
 == grid-item-overflow-stretch-003.html grid-item-overflow-stretch-003-ref.html
--- a/layout/reftests/css-ruby/reftest.list
+++ b/layout/reftests/css-ruby/reftest.list
@@ -15,21 +15,21 @@
 == dynamic-removal-1.html dynamic-removal-1-ref.html
 == dynamic-removal-2.html dynamic-removal-2-ref.html
 == dynamic-removal-3.html dynamic-removal-3-ref.html
 == float-handling.html float-handling-ref.html
 test-pref(dom.meta-viewport.enabled,true) test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == inflated-ruby-1.html inflated-ruby-1-ref.html
 == intra-level-whitespace-1.html intra-level-whitespace-1-ref.html
 == intra-level-whitespace-2.html intra-level-whitespace-2-ref.html
 == intra-level-whitespace-3.html intra-level-whitespace-3-ref.html
-== intrinsic-isize-1.html intrinsic-isize-1-ref.html
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == intrinsic-isize-1.html intrinsic-isize-1-ref.html
 == intrinsic-isize-2.html intrinsic-isize-2-ref.html
 == justification-1.html justification-1-ref.html
 == justification-2.html justification-2-ref.html
-fuzzy-if(winWidget,255,792) == lang-specific-style-1.html lang-specific-style-1-ref.html # bug 1134947
+fuzzy-if(winWidget,255,792) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == lang-specific-style-1.html lang-specific-style-1-ref.html # bug 1134947
 == line-breaking-1.html line-breaking-1-ref.html
 == line-breaking-2.html line-breaking-2-ref.html
 == line-breaking-3.html line-breaking-3-ref.html
 fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu),3,2) == line-break-suppression-1.html line-break-suppression-1-ref.html
 fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu),3,2) == line-break-suppression-2.html line-break-suppression-2-ref.html
 == line-break-suppression-3.html line-break-suppression-3-ref.html
 == line-break-suppression-4.html line-break-suppression-4-ref.html
 == line-break-suppression-5.html line-break-suppression-5-ref.html
--- a/layout/reftests/font-features/reftest.list
+++ b/layout/reftests/font-features/reftest.list
@@ -86,17 +86,17 @@ skip-if(winWidget) == annotations.html a
 == spacelookups.html spacelookups-ref.html
 # tests whether word cache is in use by testing for ignored space kerns
 == spacelookups-wordcache.html spacelookups-wordcache-ref.html
 # requires Japanese font with feature support, WinXP lacks one
 random-if(!winWidget&&!cocoaWidget) == fwid-spaces.html fwid-spaces-ref.html
 # Arial/Times New Roman on Win7+/OSX 10.6+ have kerning pairs that include spaces
 random-if(!winWidget&&!cocoaWidget) fails-if(winWidget||cocoaWidget) != kerning-spaces-arial-nokern.html kerning-spaces-arial-default.html
 random-if(!winWidget&&!cocoaWidget) fails-if(winWidget||cocoaWidget) == kerning-spaces-arial-kern.html kerning-spaces-arial-default.html
-random-if(!winWidget&&!cocoaWidget) fails-if(winWidget||cocoaWidget) != kerning-spaces-tnr-nokern.html kerning-spaces-tnr-default.html
+random-if(!winWidget&&!cocoaWidget) fails-if(winWidget||cocoaWidget) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) != kerning-spaces-tnr-nokern.html kerning-spaces-tnr-default.html
 random-if(!winWidget&&!cocoaWidget) fails-if(winWidget||cocoaWidget) == kerning-spaces-tnr-kern.html kerning-spaces-tnr-default.html
 
 # font-variant-caps fallback
 # -- sanity check - none of these should look like the default rendering
 != caps-fallback-smallcaps1.html caps-fallback-default.html
 != caps-fallback-smallcaps2.html caps-fallback-default.html
 != caps-fallback-petitecaps.html caps-fallback-default.html
 != caps-fallback-allsmallcaps.html caps-fallback-default.html
--- a/layout/reftests/font-matching/reftest.list
+++ b/layout/reftests/font-matching/reftest.list
@@ -14,27 +14,27 @@ pref(font.default.zh-CN,"sans-serif") pr
 
 # tests for bug 1367860 (correct default generic font based on language)
 == 1367860-1.htm 1367860-ref.htm
 == 1367860-2.htm 1367860-ref.htm
 == 1367860-3.htm 1367860-ref.htm
 
 # Test for bug 1458158: Arabic text in Arial weight 900 should fall back to Bold rather than Regular.
 # Limited to Windows because this is specific to the fonts shipped on Windows by default.
-skip-if(!winWidget) == 1458158-1.html 1458158-1-ref.html
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) skip-if(!winWidget) == 1458158-1.html 1458158-1-ref.html
 
 # basic tests for bug 538730
 != synthetic-bold-1.html synthetic-bold-1-ref.html
 != synthetic-bold-2.html synthetic-bold-2-ref.html
 
 # synthetic bold/italic tests
 != defaultfont-bold.html defaultfont.html
-!= defaultfont-italic.html defaultfont.html 
-!= defaultfont-oblique.html defaultfont.html 
-!= defaultfont-bolditalic.html defaultfont.html 
+!= defaultfont-italic.html defaultfont.html
+!= defaultfont-oblique.html defaultfont.html
+!= defaultfont-bolditalic.html defaultfont.html
 != defaultfont-bolditalic.html defaultfont-bold.html
 
 != defaultjapanese-bold.html defaultjapanese.html
 != defaultjapanese-italic.html defaultjapanese.html
 != defaultjapanese-oblique.html defaultjapanese.html
 != defaultjapanese-bolditalic.html defaultjapanese.html
 != defaultjapanese-bolditalic.html defaultjapanese-bold.html
 
@@ -52,28 +52,28 @@ random-if(cocoaWidget) != impact-bold.ht
 
 != lucidaconsole-bold.html lucidaconsole.html
 != lucidaconsole-italic.html lucidaconsole.html
 != lucidaconsole-oblique.html lucidaconsole.html
 != lucidaconsole-bolditalic.html lucidaconsole.html
 != lucidaconsole-bolditalic.html lucidaconsole-bold.html
 
 # checking that we don't match fullnames, psnames (see bug 538103)
-== arial-variations-1.html arial-variations-1-ref.html
-== arial-variations-2.html arial-variations-2-ref.html
-== arial-variations-3.html arial-variations-3-ref.html
-== arial-variations-4.html arial-variations-4-ref.html
-== arial-variations-5.html arial-variations-5-ref.html
-== arial-variations-6.html arial-variations-6-ref.html
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == arial-variations-1.html arial-variations-1-ref.html
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == arial-variations-2.html arial-variations-2-ref.html
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == arial-variations-3.html arial-variations-3-ref.html
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == arial-variations-4.html arial-variations-4-ref.html
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == arial-variations-5.html arial-variations-5-ref.html
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == arial-variations-6.html arial-variations-6-ref.html
 
 # localized font family names should always match just as English names do
-== localized-family-names-001.html localized-family-names-001-ref.html
-== localized-family-names-002.html localized-family-names-002-ref.html
-== localized-family-names-003.html localized-family-names-003-ref.html
-== localized-family-names-004.html localized-family-names-004-ref.html
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == localized-family-names-001.html localized-family-names-001-ref.html
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == localized-family-names-002.html localized-family-names-002-ref.html
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == localized-family-names-003.html localized-family-names-003-ref.html
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == localized-family-names-004.html localized-family-names-004-ref.html
 
 # family names with escaped spaces shouldn't match the names without the spaces
 fails-if(gtkWidget) == familyname-escapedidents.html familyname-escapedidents-ref.html # bug 1309425, bug 1328771
 
 # weight mapping tests
 == normalmedium.html normalmedium-ref.html
 != normalmedium.html normalmedium-notref.html
 
@@ -81,17 +81,17 @@ fails-if(gtkWidget) == familyname-escape
 fuzzy-if(OSX==1010&&browserIsRemote,1,23) == weightmapping-12.html weightmapping-12-ref.html
 == weightmapping-25.html weightmapping-25-ref.html
 == weightmapping-45.html weightmapping-45-ref.html
 == weightmapping-458.html weightmapping-458-ref.html
 == weightmapping-478.html weightmapping-478-ref.html
 == weightmapping-7.html weightmapping-7-ref.html
 fuzzy-if(OSX==1010,1,30) == weightmapping-12579.html weightmapping-12579-ref.html
 
-== stretchmapping-all.html stretchmapping-all-ref.html
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == stretchmapping-all.html stretchmapping-all-ref.html
 == stretchmapping-reverse.html stretchmapping-reverse-ref.html
 fuzzy-if(OSX==1010&&browserIsRemote,1,17) fuzzy-if(Android,4,8) == stretchmapping-35.html stretchmapping-35-ref.html
 fuzzy-if(OSX==1010,3,5) == stretchmapping-137.html stretchmapping-137-ref.html
 
 # test for font-stretch using @font-face
 == font-stretch-1.html font-stretch-1-ref.html
 == font-shorthand-stretch-1.html font-stretch-1-ref.html
 
--- a/layout/reftests/mathml/reftest.list
+++ b/layout/reftests/mathml/reftest.list
@@ -32,17 +32,17 @@ random-if(smallScreen&&Android) fuzzy(25
 == mfenced-3c.xhtml mfenced-3-ref.xhtml
 == mfenced-3d.xhtml mfenced-3-ref.xhtml
 == mfenced-4a.xhtml mfenced-4-ref.xhtml
 == mfenced-4b.xhtml mfenced-4-ref.xhtml
 == mfenced-5a.xhtml mfenced-5-ref.xhtml
 == mfenced-5b.xhtml mfenced-5-ref.xhtml
 == mfenced-5c.xhtml mfenced-5-ref.xhtml
 == mfenced-5d.xhtml mfenced-5-ref.xhtml
-== mfenced-6.html mfenced-6-ref.html
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == mfenced-6.html mfenced-6-ref.html
 == mfenced-7.html mfenced-7-ref.html
 != mfenced-8.html mfenced-8-ref.html
 == mfenced-9.html mfenced-9-ref.html
 == mfenced-10.html mfenced-10-ref.html
 fails-if(gtkWidget) == mfenced-11.html mfenced-11-ref.html # bug 670592, bug 1328771
 fails-if(gtkWidget) == mfenced-12.html mfenced-12-ref.html # bug 670592, bug 1328771
 == mi-mathvariant-1.xhtml mi-mathvariant-1-ref.xhtml
 == mi-mathvariant-2.xhtml mi-mathvariant-2-ref.xhtml
--- a/layout/reftests/svg/reftest.list
+++ b/layout/reftests/svg/reftest.list
@@ -154,17 +154,17 @@ fuzzy-if(d2d&&layersGPUAccelerated,3,120
 == dynamic-rect-05.svg pass.svg
 == dynamic-reflow-01.svg dynamic-reflow-01-ref.svg
 == dynamic-small-object-scaled-up-01.svg pass.svg
 == dynamic-small-object-scaled-up-02.svg pass.svg
 == dynamic-stroke-01.svg pass.svg
 == dynamic-stroke-opacity-01.svg pass.svg
 == dynamic-stroke-width-01.svg pass.svg
 == dynamic-switch-01.svg pass.svg
-== dynamic-text-01.svg dynamic-text-01-ref.svg
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == dynamic-text-01.svg dynamic-text-01-ref.svg
 fuzzy-if(d2d&&layersGPUAccelerated,3,12739) == dynamic-text-02.svg dynamic-text-02-ref.svg # bug 776038 for Win7, Win8
 fuzzy-if(d2d&&layersGPUAccelerated,2,10539) == dynamic-text-03.svg dynamic-text-03-ref.svg # bug 776038 for Win7
 fuzzy-if(/^Windows\x20NT\x206\.1/.test(http.oscpu),47,89) == dynamic-text-04.svg dynamic-text-04-ref.svg # bug 776038 for Win7
 == dynamic-text-05.svg pass.svg
 == dynamic-text-06.svg pass.svg
 == dynamic-text-07.svg dynamic-text-07-ref.svg
 == dynamic-text-08.svg dynamic-text-08-ref.svg
 == dynamic-text-attr-01.svg dynamic-text-attr-01-ref.svg
@@ -490,24 +490,24 @@ fuzzy-if(skiaContent,1,610) == textPath-
 
 == tspan-dxdy-01.svg tspan-dxdy-ref.svg
 == tspan-dxdy-02.svg tspan-dxdy-ref.svg
 == tspan-dxdy-03.svg tspan-dxdy-ref.svg
 == tspan-dxdy-04.svg tspan-dxdy-ref.svg
 == tspan-dxdy-05.svg tspan-dxdy-ref.svg
 == tspan-dxdy-06.svg tspan-dxdy-ref.svg
 == tspan-dxdy-textPath-01.svg tspan-dxdy-textPath-01-ref.svg
-== tspan-rotate-01.svg tspan-rotate-ref.svg
-fuzzy-if(skiaContent,1,550) == tspan-rotate-02.svg tspan-rotate-02.svg
-fuzzy-if(skiaContent,1,550) == tspan-rotate-02.svg tspan-rotate-02-ref.svg
-fuzzy-if(skiaContent,1,550) == tspan-rotate-03.svg tspan-rotate-ref.svg
-fuzzy-if(skiaContent,1,550) == tspan-rotate-04.svg tspan-rotate-04.svg
-fuzzy-if(skiaContent,1,550) == tspan-rotate-04.svg tspan-rotate-04-ref.svg
-fuzzy-if(skiaContent,1,550) == tspan-rotate-05.svg tspan-rotate-ref.svg
-fuzzy-if(skiaContent,1,550) == tspan-rotate-06.svg tspan-rotate-ref.svg
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == tspan-rotate-01.svg tspan-rotate-ref.svg
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fuzzy-if(skiaContent,1,550) == tspan-rotate-02.svg tspan-rotate-02.svg
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fuzzy-if(skiaContent,1,550) == tspan-rotate-02.svg tspan-rotate-02-ref.svg
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fuzzy-if(skiaContent,1,550) == tspan-rotate-03.svg tspan-rotate-ref.svg
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fuzzy-if(skiaContent,1,550) == tspan-rotate-04.svg tspan-rotate-04.svg
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fuzzy-if(skiaContent,1,550) == tspan-rotate-04.svg tspan-rotate-04-ref.svg
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fuzzy-if(skiaContent,1,550) == tspan-rotate-05.svg tspan-rotate-ref.svg
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fuzzy-if(skiaContent,1,550) == tspan-rotate-06.svg tspan-rotate-ref.svg
 == tspan-rotate-07.svg tspan-rotate-07-ref.svg
 == tspan-rotate-textPath-01.svg tspan-rotate-textPath-01-ref.svg
 fuzzy-if(skiaContent,1,100) == tspan-xy-01.svg tspan-xy-ref.svg
 == tspan-xy-02.svg tspan-xy-ref.svg
 fuzzy-if(skiaContent,1,300) == tspan-xy-03.svg tspan-xy-ref.svg
 fuzzy-if(skiaContent,1,300) == tspan-xy-04.svg tspan-xy-ref.svg
 fuzzy-if(skiaContent,1,300) == tspan-xy-05.svg tspan-xy-ref.svg
 fuzzy-if(skiaContent,1,300) == tspan-xy-06.svg tspan-xy-ref.svg
--- a/layout/reftests/svg/smil/reftest.list
+++ b/layout/reftests/svg/smil/reftest.list
@@ -160,17 +160,17 @@ fuzzy-if(Android,4,1) == anim-svg-viewBo
 == anim-class-02.svg lime.svg
 == anim-class-03.svg lime.svg
 == anim-class-04.svg anim-class-04-ref.svg
 
 # animate with some paint server values
 == anim-paintserver-1.svg anim-paintserver-1-ref.svg
 
 # animate attributes on text content children
-== anim-text-attr-01.svg anim-text-attr-01-ref.svg
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == anim-text-attr-01.svg anim-text-attr-01-ref.svg
 
 # animate where the base value is non-interpolatable but will be replaced anyway
 == anim-fill-overpaintserver-1.svg lime.svg
 == anim-fill-overpaintserver-2.svg lime.svg
 
 # animate where we fallback from 'additive' animation to non-additive
 == anim-additive-fallback-1.svg anim-standard-ref.svg
 
@@ -202,17 +202,17 @@ fails == anim-strokecolor-1.svg anim-sta
 == anim-targethref-4.svg anim-standard-ref.svg
 == anim-targethref-5.svg anim-standard-ref.svg
 == anim-targethref-6.svg anim-standard-ref.svg
 == anim-targethref-7.svg anim-standard-ref.svg
 == anim-targethref-8.svg anim-standard-ref.svg
 == anim-targethref-9.svg anim-standard-ref.svg
 == anim-targethref-10.svg anim-standard-ref.svg
 
-== anim-text-rotate-01.svg anim-text-rotate-01-ref.svg
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == anim-text-rotate-01.svg anim-text-rotate-01-ref.svg
 == anim-feFuncR-tableValues-01.svg anim-feFuncR-tableValues-01-ref.svg
 
 skip == anim-text-x-y-dx-dy-01.svg anim-text-x-y-dx-dy-01-ref.svg # bug 579588
 
 == anim-width-done-1a.svg anim-standard-ref.svg
 == anim-width-done-1b.svg anim-standard-ref.svg
 
 == anim-x-done-1a.svg anim-standard-ref.svg
--- a/layout/reftests/svg/smil/set/reftest.list
+++ b/layout/reftests/svg/smil/set/reftest.list
@@ -1,2 +1,2 @@
-== set-css-fontsize-freeze-1.svg set-css-fontsize-freeze-1-ref.svg
-== set-css-fontsize-remove-1.svg set-css-fontsize-remove-1-ref.svg
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == set-css-fontsize-freeze-1.svg set-css-fontsize-freeze-1-ref.svg
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == set-css-fontsize-remove-1.svg set-css-fontsize-remove-1-ref.svg
--- a/layout/reftests/svg/smil/style/reftest.list
+++ b/layout/reftests/svg/smil/style/reftest.list
@@ -66,35 +66,35 @@ fuzzy-if(skiaContent,1,550) == anim-css-
 fails == anim-css-fillopacity-3-clamp-big.svg     anim-css-fillopacity-3-ref.svg # bug 501188
 fuzzy-if(skiaContent,1,365) == anim-css-fillopacity-3-clamp-small.svg   anim-css-fillopacity-3-ref.svg
 
 # 'font' shorthand property
 == anim-css-font-1.svg  anim-css-font-1-ref.svg
 
 # 'font-size' property, from/by/to with pixel values only
 == anim-css-fontsize-1-from-by-px-px.svg    anim-css-fontsize-1-ref.svg
-== anim-css-fontsize-1-from-to-px-px.svg    anim-css-fontsize-1-ref.svg
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == anim-css-fontsize-1-from-to-px-px.svg    anim-css-fontsize-1-ref.svg
 
 # 'font-size' property (accepts unitless values)
-== anim-css-fontsize-1-from-to-no-no.svg    anim-css-fontsize-1-ref.svg
-== anim-css-fontsize-1-from-to-no-px.svg    anim-css-fontsize-1-ref.svg
-== anim-css-fontsize-1-from-to-px-no.svg    anim-css-fontsize-1-ref.svg
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == anim-css-fontsize-1-from-to-no-no.svg    anim-css-fontsize-1-ref.svg
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == anim-css-fontsize-1-from-to-no-px.svg    anim-css-fontsize-1-ref.svg
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == anim-css-fontsize-1-from-to-px-no.svg    anim-css-fontsize-1-ref.svg
 
 # 'font-size' mapped attribute (accepts unitless values)
 == anim-mapped-fontsize-1-from-to-no-no.svg anim-css-fontsize-1-ref.svg
 == anim-mapped-fontsize-1-from-to-no-px.svg anim-css-fontsize-1-ref.svg
 == anim-mapped-fontsize-1-from-to-px-no.svg anim-css-fontsize-1-ref.svg
 
 # 'font-size' property, from/by/to with percent values
 == anim-css-fontsize-1-from-by-pct-pct.svg  anim-css-fontsize-1-ref.svg
 == anim-css-fontsize-1-from-by-pct-px.svg   anim-css-fontsize-1-ref.svg
 == anim-css-fontsize-1-from-by-px-pct.svg   anim-css-fontsize-1-ref.svg
-== anim-css-fontsize-1-from-to-pct-pct.svg  anim-css-fontsize-1-ref.svg
-== anim-css-fontsize-1-from-to-pct-px.svg   anim-css-fontsize-1-ref.svg
-== anim-css-fontsize-1-from-to-px-pct.svg   anim-css-fontsize-1-ref.svg
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == anim-css-fontsize-1-from-to-pct-pct.svg  anim-css-fontsize-1-ref.svg
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == anim-css-fontsize-1-from-to-pct-px.svg   anim-css-fontsize-1-ref.svg
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == anim-css-fontsize-1-from-to-px-pct.svg   anim-css-fontsize-1-ref.svg
 
 # 'font-size' property, with negative addition
 == anim-css-fontsize-2-from-by-px-px.svg    anim-css-fontsize-2-ref.svg
 == anim-css-fontsize-2-from-by-px-em.svg    anim-css-fontsize-2-ref.svg
 == anim-css-fontsize-2-from-by-em-em.svg    anim-css-fontsize-2-ref.svg
 
 # 'stroke-dasharray' property, from/to with pixel values only
 fails == anim-css-strokedasharray-1.svg anim-css-strokedasharray-1-ref.svg # bug 474049
--- a/layout/reftests/svg/text/reftest.list
+++ b/layout/reftests/svg/text/reftest.list
@@ -105,27 +105,27 @@ fuzzy-if(Android,242,81) == multiple-chu
 == display-none-3.svg simple.svg
 == display-none-4.svg simple.svg
 
 == simple-multiline.svg simple-multiline-ref.svg
 == simple-multiline-number.svg simple-multiline-number-ref.svg
 == simple-multiline-pc.svg simple-multiline-pc-ref.svg
 == simple-multiline-anchor-end.svg simple-multiline-anchor-end-ref.svg
 
-fuzzy-if(skiaContent,1,15) == textpath.svg textpath-ref.svg
-== textpath-a.svg textpath-a-ref.svg
-== textpath-anchor-middle.svg textpath-anchor-middle-ref.svg
-== textpath-anchor-end.svg textpath-anchor-end-ref.svg
-== textpath-invalid-parent.svg textpath-invalid-parent-ref.svg
-== textpath-multiline.svg textpath-multiline-ref.svg
-== textpath-multiline-2.svg textpath-multiline-2-ref.svg
-== textpath-after.svg textpath-after-ref.svg
-== textpath-after-anchor-end.svg textpath-after-anchor-end-ref.svg
-== textpath-reset-position.svg textpath-reset-position-ref.svg
-== textpath-inherit-position.svg textpath-inherit-position-ref.svg
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fuzzy-if(skiaContent,1,15) == textpath.svg textpath-ref.svg
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == textpath-a.svg textpath-a-ref.svg
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == textpath-anchor-middle.svg textpath-anchor-middle-ref.svg
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == textpath-anchor-end.svg textpath-anchor-end-ref.svg
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == textpath-invalid-parent.svg textpath-invalid-parent-ref.svg
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == textpath-multiline.svg textpath-multiline-ref.svg
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == textpath-multiline-2.svg textpath-multiline-2-ref.svg
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == textpath-after.svg textpath-after-ref.svg
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == textpath-after-anchor-end.svg textpath-after-anchor-end-ref.svg
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == textpath-reset-position.svg textpath-reset-position-ref.svg
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == textpath-inherit-position.svg textpath-inherit-position-ref.svg
 
 == textLength.svg textLength-ref.svg
 fuzzy-if(skiaContent,1,200) == textLength-2.svg textLength-2-ref.svg
 fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu)||/^Windows\x20NT\x206\.[12]/.test(http.oscpu),4,17) fuzzy-if(skiaContent,4,100) == textLength-3.svg textLength-3-ref.svg
 == textLength-4.svg textLength-4-ref.svg
 == textLength-5.svg textLength-5-ref.svg
 == textLength-6.svg textLength-6-ref.svg
 
--- a/layout/reftests/text/reftest.list
+++ b/layout/reftests/text/reftest.list
@@ -23,17 +23,17 @@ load ligature-with-space-1.html
 == line-editing-1b.html line-editing-1-ref.html
 == line-editing-1c.html line-editing-1-ref.html
 == line-editing-1d.html line-editing-1-ref.html
 == line-editing-1e.html line-editing-1-ref.html
 fails-if(cocoaWidget) == lineheight-metrics-1.html lineheight-metrics-1-ref.html # bug 657864
 == lineheight-metrics-2a.html lineheight-metrics-2-ref.html
 == lineheight-metrics-2b.html lineheight-metrics-2-ref.html
 == lineheight-percentage-1.html lineheight-percentage-1-ref.html
-== long-1.html long-ref.html
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == long-1.html long-ref.html
 fuzzy-if(Android,255,325) == pre-line-1.html pre-line-1-ref.html
 == pre-line-2.html pre-line-2-ref.html
 == pre-line-3.html pre-line-3-ref.html
 == pre-line-4.html pre-line-4-ref.html
 == pre-space-1.html pre-space-1-ref.html
 == pre-wrap-1.html pre-wrap-1-ref.html
 == soft-hyphens-1a.html soft-hyphens-1-ref.html
 == soft-hyphens-1b.html soft-hyphens-1-ref.html
--- a/layout/reftests/w3c-css/failures.list
+++ b/layout/reftests/w3c-css/failures.list
@@ -54,36 +54,36 @@ fails css-writing-modes/float-lft-orthog
 fails css-writing-modes/float-lft-orthog-vrl-in-htb-002.xht
 fails css-writing-modes/float-rgt-orthog-htb-in-vlr-003.xht
 fails css-writing-modes/float-rgt-orthog-htb-in-vrl-003.xht
 fails css-writing-modes/float-rgt-orthog-vlr-in-htb-003.xht
 fails css-writing-modes/float-rgt-orthog-vrl-in-htb-003.xht
 fails css-writing-modes/sizing-orthog-htb-in-vrl-001.xht
 fails css-writing-modes/sizing-orthog-htb-in-vrl-004.xht
 fails css-writing-modes/sizing-orthog-htb-in-vrl-013.xht
-fails-if(OSX||winWidget||Android) css-writing-modes/sizing-orthog-htb-in-vlr-008.xht
-fails-if(OSX||winWidget||Android) css-writing-modes/sizing-orthog-htb-in-vlr-020.xht
-fails-if(OSX||winWidget||Android) css-writing-modes/sizing-orthog-htb-in-vrl-008.xht
-fails-if(OSX||winWidget||Android) css-writing-modes/sizing-orthog-htb-in-vrl-020.xht
-fuzzy-if(winWidget,255,648-713) css-writing-modes/sizing-orthog-vlr-in-htb-008.xht
-fuzzy-if(winWidget,255,648-713) css-writing-modes/sizing-orthog-vlr-in-htb-020.xht
-fuzzy-if(winWidget,255,648-713) css-writing-modes/sizing-orthog-vrl-in-htb-008.xht
-fuzzy-if(winWidget,255,648-713) css-writing-modes/sizing-orthog-vrl-in-htb-020.xht
-fails-if(Android) css-writing-modes/sizing-orthog-htb-in-vlr-003.xht
-fails-if(Android) css-writing-modes/sizing-orthog-htb-in-vlr-009.xht
-fails-if(Android) css-writing-modes/sizing-orthog-htb-in-vlr-015.xht
-fails-if(Android) css-writing-modes/sizing-orthog-htb-in-vlr-021.xht
-fails-if(Android) css-writing-modes/sizing-orthog-vlr-in-htb-003.xht
-fails-if(Android) css-writing-modes/sizing-orthog-vlr-in-htb-009.xht
-fails-if(Android) css-writing-modes/sizing-orthog-vlr-in-htb-015.xht
-fails-if(Android) css-writing-modes/sizing-orthog-vlr-in-htb-021.xht
-fails-if(Android) css-writing-modes/sizing-orthog-vrl-in-htb-003.xht
-fails-if(Android) css-writing-modes/sizing-orthog-vrl-in-htb-009.xht
-fails-if(Android) css-writing-modes/sizing-orthog-vrl-in-htb-015.xht
-fails-if(Android) css-writing-modes/sizing-orthog-vrl-in-htb-021.xht
+fails-if(OSX||winWidget||Android) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) css-writing-modes/sizing-orthog-htb-in-vlr-008.xht
+fails-if(OSX||winWidget||Android) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) css-writing-modes/sizing-orthog-htb-in-vlr-020.xht
+fails-if(OSX||winWidget||Android) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) css-writing-modes/sizing-orthog-htb-in-vrl-008.xht
+fails-if(OSX||winWidget||Android) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) css-writing-modes/sizing-orthog-htb-in-vrl-020.xht
+fuzzy-if(winWidget,255,648-713) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) css-writing-modes/sizing-orthog-vlr-in-htb-008.xht
+fuzzy-if(winWidget,255,648-713) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) css-writing-modes/sizing-orthog-vlr-in-htb-020.xht
+fuzzy-if(winWidget,255,648-713) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) css-writing-modes/sizing-orthog-vrl-in-htb-008.xht
+fuzzy-if(winWidget,255,648-713) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) css-writing-modes/sizing-orthog-vrl-in-htb-020.xht
+fails-if(Android) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) css-writing-modes/sizing-orthog-htb-in-vlr-003.xht
+fails-if(Android) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) css-writing-modes/sizing-orthog-htb-in-vlr-009.xht
+fails-if(Android) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) css-writing-modes/sizing-orthog-htb-in-vlr-015.xht
+fails-if(Android) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) css-writing-modes/sizing-orthog-htb-in-vlr-021.xht
+fails-if(Android) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) css-writing-modes/sizing-orthog-vlr-in-htb-003.xht
+fails-if(Android) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) css-writing-modes/sizing-orthog-vlr-in-htb-009.xht
+fails-if(Android) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) css-writing-modes/sizing-orthog-vlr-in-htb-015.xht
+fails-if(Android) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) css-writing-modes/sizing-orthog-vlr-in-htb-021.xht
+fails-if(Android) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) css-writing-modes/sizing-orthog-vrl-in-htb-003.xht
+fails-if(Android) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) css-writing-modes/sizing-orthog-vrl-in-htb-009.xht
+fails-if(Android) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) css-writing-modes/sizing-orthog-vrl-in-htb-015.xht
+fails-if(Android) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) css-writing-modes/sizing-orthog-vrl-in-htb-021.xht
 
 # Fuzzy
 fuzzy-if(OSX||winWidget,255,480)  css-writing-modes/abs-pos-non-replaced-v??-???.xht
 fuzzy-if(OSX||winWidget,114,600) css-writing-modes/baseline-inline-non-replaced-00?.xht
 fuzzy-if(OSX||winWidget,213,1540) css-writing-modes/block-flow-direction-???-0??.xht
 fuzzy-if(OSX,255,200)  css-writing-modes/box-offsets-rel-pos-vlr-005.xht
 fuzzy-if(OSX,255,200)  css-writing-modes/box-offsets-rel-pos-vrl-004.xht
 fuzzy-if(OSX||winWidget,114,300)  css-writing-modes/caption-side-v??-00?.xht
@@ -107,16 +107,17 @@ fuzzy-if(OSX||winWidget,110,1200) css-wr
 fuzzy-if(OSX||winWidget,75,404) fuzzy-if(webrender&&!gtkWidget,92-108,300-302) css-writing-modes/text-align-v??-0??.xht
 fuzzy-if(OSX||winWidget,215,780)  css-writing-modes/text-baseline-???-00?.xht
 fuzzy-if(OSX,15,16) css-writing-modes/text-combine-upright-decorations-001.html
 fuzzy-if(OSX||winWidget,255,480)  css-writing-modes/text-indent-v??-0??.xht
 fuzzy-if(OSX||winWidget,226,960) fails-if(webrender&&cocoaWidget)  css-writing-modes/text-orientation-016.xht
 fuzzy-if(OSX||winWidget,223,720)  css-writing-modes/vertical-alignment-*.xht
 fuzzy-if(OSX||winWidget,153,612)  css-writing-modes/writing-mode-vertical-??-00?.*
 fuzzy(255,960) css-writing-modes/text-combine-upright-value-all-00?.html
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) css-writing-modes/text-combine-upright-compression-???.html
 
 # Bug 1167911
 skip css-writing-modes/abs-pos-non-replaced-icb-vlr-021.xht
 skip css-writing-modes/abs-pos-non-replaced-icb-vrl-020.xht
 
 # Bug 1244601
 fails css-writing-modes/block-flow-direction-slr-058.xht
 fails css-writing-modes/block-flow-direction-srl-057.xht
--- a/layout/reftests/w3c-css/received/reftest.list
+++ b/layout/reftests/w3c-css/received/reftest.list
@@ -912,51 +912,51 @@ fuzzy-if(OSX||winWidget,110,1200) == css
 fuzzy-if(OSX||winWidget,110,1200) == css-writing-modes/row-progression-vlr-005.xht css-writing-modes/block-flow-direction-001-ref.xht
 fuzzy-if(OSX||winWidget,110,1200) == css-writing-modes/row-progression-vlr-007.xht css-writing-modes/block-flow-direction-001-ref.xht
 fuzzy-if(OSX||winWidget,110,1200) == css-writing-modes/row-progression-vlr-009.xht css-writing-modes/block-flow-direction-001-ref.xht
 fuzzy-if(OSX||winWidget,110,1200) == css-writing-modes/row-progression-vrl-002.xht css-writing-modes/block-flow-direction-001-ref.xht
 fuzzy-if(OSX||winWidget,110,1200) == css-writing-modes/row-progression-vrl-004.xht css-writing-modes/block-flow-direction-001-ref.xht
 fuzzy-if(OSX||winWidget,110,1200) == css-writing-modes/row-progression-vrl-006.xht css-writing-modes/block-flow-direction-001-ref.xht
 fuzzy-if(OSX||winWidget,110,1200) == css-writing-modes/row-progression-vrl-008.xht css-writing-modes/block-flow-direction-001-ref.xht
 == css-writing-modes/sizing-orthog-htb-in-vlr-001.xht css-writing-modes/sizing-orthog-htb-in-vlr-001-ref.xht
-fails-if(Android) == css-writing-modes/sizing-orthog-htb-in-vlr-003.xht css-writing-modes/sizing-orthog-htb-in-vlr-003-ref.xht
+fails-if(Android) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == css-writing-modes/sizing-orthog-htb-in-vlr-003.xht css-writing-modes/sizing-orthog-htb-in-vlr-003-ref.xht
 == css-writing-modes/sizing-orthog-htb-in-vlr-004.xht css-writing-modes/sizing-orthog-htb-in-vlr-004-ref.xht
 == css-writing-modes/sizing-orthog-htb-in-vlr-006.xht css-writing-modes/sizing-orthog-htb-in-vlr-006-ref.xht
 == css-writing-modes/sizing-orthog-htb-in-vlr-007.xht css-writing-modes/sizing-orthog-htb-in-vlr-007-ref.xht
-fails-if(OSX||winWidget||Android) == css-writing-modes/sizing-orthog-htb-in-vlr-008.xht css-writing-modes/sizing-orthog-htb-in-vlr-008-ref.xht
-fails-if(Android) == css-writing-modes/sizing-orthog-htb-in-vlr-009.xht css-writing-modes/sizing-orthog-htb-in-vlr-003-ref.xht
+fails-if(OSX||winWidget||Android) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == css-writing-modes/sizing-orthog-htb-in-vlr-008.xht css-writing-modes/sizing-orthog-htb-in-vlr-008-ref.xht
+fails-if(Android) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == css-writing-modes/sizing-orthog-htb-in-vlr-009.xht css-writing-modes/sizing-orthog-htb-in-vlr-003-ref.xht
 == css-writing-modes/sizing-orthog-htb-in-vlr-010.xht css-writing-modes/sizing-orthog-htb-in-vlr-010-ref.xht
 == css-writing-modes/sizing-orthog-htb-in-vlr-011.xht css-writing-modes/sizing-orthog-htb-in-vlr-011-ref.xht
 == css-writing-modes/sizing-orthog-htb-in-vlr-012.xht css-writing-modes/sizing-orthog-htb-in-vlr-006-ref.xht
 == css-writing-modes/sizing-orthog-htb-in-vlr-013.xht css-writing-modes/sizing-orthog-htb-in-vlr-013-ref.xht
-fails-if(Android) == css-writing-modes/sizing-orthog-htb-in-vlr-015.xht css-writing-modes/sizing-orthog-htb-in-vlr-015-ref.xht
+fails-if(Android) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == css-writing-modes/sizing-orthog-htb-in-vlr-015.xht css-writing-modes/sizing-orthog-htb-in-vlr-015-ref.xht
 == css-writing-modes/sizing-orthog-htb-in-vlr-016.xht css-writing-modes/sizing-orthog-htb-in-vlr-016-ref.xht
 == css-writing-modes/sizing-orthog-htb-in-vlr-018.xht css-writing-modes/sizing-orthog-htb-in-vlr-018-ref.xht
 == css-writing-modes/sizing-orthog-htb-in-vlr-019.xht css-writing-modes/sizing-orthog-htb-in-vlr-019-ref.xht
-fails-if(OSX||winWidget||Android) == css-writing-modes/sizing-orthog-htb-in-vlr-020.xht css-writing-modes/sizing-orthog-htb-in-vlr-020-ref.xht
-fails-if(Android) == css-writing-modes/sizing-orthog-htb-in-vlr-021.xht css-writing-modes/sizing-orthog-htb-in-vlr-015-ref.xht
+fails-if(OSX||winWidget||Android) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == css-writing-modes/sizing-orthog-htb-in-vlr-020.xht css-writing-modes/sizing-orthog-htb-in-vlr-020-ref.xht
+fails-if(Android) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == css-writing-modes/sizing-orthog-htb-in-vlr-021.xht css-writing-modes/sizing-orthog-htb-in-vlr-015-ref.xht
 == css-writing-modes/sizing-orthog-htb-in-vlr-022.xht css-writing-modes/sizing-orthog-htb-in-vlr-022-ref.xht
 == css-writing-modes/sizing-orthog-htb-in-vlr-023.xht css-writing-modes/sizing-orthog-htb-in-vlr-023-ref.xht
 == css-writing-modes/sizing-orthog-htb-in-vlr-024.xht css-writing-modes/sizing-orthog-htb-in-vlr-018-ref.xht
 fails == css-writing-modes/sizing-orthog-htb-in-vrl-001.xht css-writing-modes/sizing-orthog-htb-in-vrl-001-ref.xht
 == css-writing-modes/sizing-orthog-htb-in-vrl-003.xht css-writing-modes/sizing-orthog-htb-in-vrl-003-ref.xht
 fails == css-writing-modes/sizing-orthog-htb-in-vrl-004.xht css-writing-modes/sizing-orthog-htb-in-vlr-004-ref.xht
 == css-writing-modes/sizing-orthog-htb-in-vrl-006.xht css-writing-modes/sizing-orthog-htb-in-vrl-006-ref.xht
 == css-writing-modes/sizing-orthog-htb-in-vrl-007.xht css-writing-modes/sizing-orthog-htb-in-vrl-007-ref.xht
-fails-if(OSX||winWidget||Android) == css-writing-modes/sizing-orthog-htb-in-vrl-008.xht css-writing-modes/sizing-orthog-htb-in-vrl-008-ref.xht
+fails-if(OSX||winWidget||Android) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == css-writing-modes/sizing-orthog-htb-in-vrl-008.xht css-writing-modes/sizing-orthog-htb-in-vrl-008-ref.xht
 == css-writing-modes/sizing-orthog-htb-in-vrl-009.xht css-writing-modes/sizing-orthog-htb-in-vrl-003-ref.xht
 == css-writing-modes/sizing-orthog-htb-in-vrl-010.xht css-writing-modes/sizing-orthog-htb-in-vrl-010-ref.xht
 == css-writing-modes/sizing-orthog-htb-in-vrl-011.xht css-writing-modes/sizing-orthog-htb-in-vrl-011-ref.xht
 == css-writing-modes/sizing-orthog-htb-in-vrl-012.xht css-writing-modes/sizing-orthog-htb-in-vrl-006-ref.xht
 fails == css-writing-modes/sizing-orthog-htb-in-vrl-013.xht css-writing-modes/sizing-orthog-htb-in-vrl-013-ref.xht
 == css-writing-modes/sizing-orthog-htb-in-vrl-015.xht css-writing-modes/sizing-orthog-htb-in-vrl-015-ref.xht
 == css-writing-modes/sizing-orthog-htb-in-vrl-016.xht css-writing-modes/sizing-orthog-htb-in-vlr-016-ref.xht
 == css-writing-modes/sizing-orthog-htb-in-vrl-018.xht css-writing-modes/sizing-orthog-htb-in-vrl-018-ref.xht
 == css-writing-modes/sizing-orthog-htb-in-vrl-019.xht css-writing-modes/sizing-orthog-htb-in-vrl-019-ref.xht
-fails-if(OSX||winWidget||Android) == css-writing-modes/sizing-orthog-htb-in-vrl-020.xht css-writing-modes/sizing-orthog-htb-in-vrl-020-ref.xht
+fails-if(OSX||winWidget||Android) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == css-writing-modes/sizing-orthog-htb-in-vrl-020.xht css-writing-modes/sizing-orthog-htb-in-vrl-020-ref.xht
 == css-writing-modes/sizing-orthog-htb-in-vrl-021.xht css-writing-modes/sizing-orthog-htb-in-vrl-015-ref.xht
 == css-writing-modes/sizing-orthog-htb-in-vrl-022.xht css-writing-modes/sizing-orthog-htb-in-vrl-022-ref.xht
 == css-writing-modes/sizing-orthog-htb-in-vrl-023.xht css-writing-modes/sizing-orthog-htb-in-vrl-023-ref.xht
 == css-writing-modes/sizing-orthog-htb-in-vrl-024.xht css-writing-modes/sizing-orthog-htb-in-vrl-018-ref.xht
 == css-writing-modes/sizing-orthog-prct-htb-in-vlr-001.xht css-writing-modes/sizing-orthog-prct-htb-in-vlr-001-ref.xht
 == css-writing-modes/sizing-orthog-prct-htb-in-vlr-002.xht css-writing-modes/sizing-orthog-prct-htb-in-vlr-002-ref.xht
 == css-writing-modes/sizing-orthog-prct-htb-in-vlr-003.xht css-writing-modes/sizing-orthog-prct-htb-in-vlr-003-ref.xht
 == css-writing-modes/sizing-orthog-prct-htb-in-vlr-004.xht css-writing-modes/sizing-orthog-prct-htb-in-vlr-004-ref.xht
@@ -984,52 +984,52 @@ fails-if(OSX||winWidget||Android) == css
 == css-writing-modes/sizing-orthog-prct-vrl-in-htb-002.xht css-writing-modes/sizing-orthog-prct-vrl-in-htb-002-ref.xht
 == css-writing-modes/sizing-orthog-prct-vrl-in-htb-003.xht css-writing-modes/sizing-orthog-prct-vrl-in-htb-003-ref.xht
 == css-writing-modes/sizing-orthog-prct-vrl-in-htb-004.xht css-writing-modes/sizing-orthog-prct-vrl-in-htb-004-ref.xht
 == css-writing-modes/sizing-orthog-prct-vrl-in-htb-005.xht css-writing-modes/sizing-orthog-prct-vrl-in-htb-005-ref.xht
 == css-writing-modes/sizing-orthog-prct-vrl-in-htb-006.xht css-writing-modes/sizing-orthog-prct-vrl-in-htb-006-ref.xht
 == css-writing-modes/sizing-orthog-prct-vrl-in-htb-007.xht css-writing-modes/sizing-orthog-prct-vrl-in-htb-007-ref.xht
 == css-writing-modes/sizing-orthog-prct-vrl-in-htb-008.xht css-writing-modes/sizing-orthog-prct-vrl-in-htb-008-ref.xht
 == css-writing-modes/sizing-orthog-vlr-in-htb-001.xht css-writing-modes/sizing-orthog-vlr-in-htb-001-ref.xht
-fails-if(Android) == css-writing-modes/sizing-orthog-vlr-in-htb-003.xht css-writing-modes/sizing-orthog-vlr-in-htb-003-ref.xht
+fails-if(Android) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == css-writing-modes/sizing-orthog-vlr-in-htb-003.xht css-writing-modes/sizing-orthog-vlr-in-htb-003-ref.xht
 == css-writing-modes/sizing-orthog-vlr-in-htb-004.xht css-writing-modes/sizing-orthog-vlr-in-htb-004-ref.xht
 == css-writing-modes/sizing-orthog-vlr-in-htb-006.xht css-writing-modes/sizing-orthog-vlr-in-htb-006-ref.xht
 == css-writing-modes/sizing-orthog-vlr-in-htb-007.xht css-writing-modes/sizing-orthog-vlr-in-htb-007-ref.xht
-fuzzy-if(winWidget,255,648-713) == css-writing-modes/sizing-orthog-vlr-in-htb-008.xht css-writing-modes/sizing-orthog-vlr-in-htb-008-ref.xht
-fails-if(Android) == css-writing-modes/sizing-orthog-vlr-in-htb-009.xht css-writing-modes/sizing-orthog-vlr-in-htb-009-ref.xht
+fuzzy-if(winWidget,255,648-713) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == css-writing-modes/sizing-orthog-vlr-in-htb-008.xht css-writing-modes/sizing-orthog-vlr-in-htb-008-ref.xht
+fails-if(Android) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == css-writing-modes/sizing-orthog-vlr-in-htb-009.xht css-writing-modes/sizing-orthog-vlr-in-htb-009-ref.xht
 == css-writing-modes/sizing-orthog-vlr-in-htb-010.xht css-writing-modes/sizing-orthog-vlr-in-htb-010-ref.xht
 == css-writing-modes/sizing-orthog-vlr-in-htb-011.xht css-writing-modes/sizing-orthog-vlr-in-htb-011-ref.xht
 == css-writing-modes/sizing-orthog-vlr-in-htb-012.xht css-writing-modes/sizing-orthog-vlr-in-htb-012-ref.xht
 == css-writing-modes/sizing-orthog-vlr-in-htb-013.xht css-writing-modes/sizing-orthog-vlr-in-htb-013-ref.xht
-fails-if(Android) == css-writing-modes/sizing-orthog-vlr-in-htb-015.xht css-writing-modes/sizing-orthog-vlr-in-htb-015-ref.xht
+fails-if(Android) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == css-writing-modes/sizing-orthog-vlr-in-htb-015.xht css-writing-modes/sizing-orthog-vlr-in-htb-015-ref.xht
 == css-writing-modes/sizing-orthog-vlr-in-htb-016.xht css-writing-modes/sizing-orthog-vlr-in-htb-016-ref.xht
 == css-writing-modes/sizing-orthog-vlr-in-htb-018.xht css-writing-modes/sizing-orthog-vlr-in-htb-018-ref.xht
 == css-writing-modes/sizing-orthog-vlr-in-htb-019.xht css-writing-modes/sizing-orthog-vlr-in-htb-019-ref.xht
-fuzzy-if(winWidget,255,648-713) == css-writing-modes/sizing-orthog-vlr-in-htb-020.xht css-writing-modes/sizing-orthog-vlr-in-htb-020-ref.xht
-fails-if(Android) == css-writing-modes/sizing-orthog-vlr-in-htb-021.xht css-writing-modes/sizing-orthog-vlr-in-htb-015-ref.xht
+fuzzy-if(winWidget,255,648-713) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == css-writing-modes/sizing-orthog-vlr-in-htb-020.xht css-writing-modes/sizing-orthog-vlr-in-htb-020-ref.xht
+fails-if(Android) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == css-writing-modes/sizing-orthog-vlr-in-htb-021.xht css-writing-modes/sizing-orthog-vlr-in-htb-015-ref.xht
 == css-writing-modes/sizing-orthog-vlr-in-htb-022.xht css-writing-modes/sizing-orthog-vlr-in-htb-022-ref.xht
 == css-writing-modes/sizing-orthog-vlr-in-htb-023.xht css-writing-modes/sizing-orthog-vlr-in-htb-023-ref.xht
 == css-writing-modes/sizing-orthog-vlr-in-htb-024.xht css-writing-modes/sizing-orthog-vlr-in-htb-018-ref.xht
 == css-writing-modes/sizing-orthog-vrl-in-htb-001.xht css-writing-modes/sizing-orthog-vrl-in-htb-001-ref.xht
-fails-if(Android) == css-writing-modes/sizing-orthog-vrl-in-htb-003.xht css-writing-modes/sizing-orthog-vrl-in-htb-003-ref.xht
+fails-if(Android) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == css-writing-modes/sizing-orthog-vrl-in-htb-003.xht css-writing-modes/sizing-orthog-vrl-in-htb-003-ref.xht
 == css-writing-modes/sizing-orthog-vrl-in-htb-004.xht css-writing-modes/sizing-orthog-vrl-in-htb-004-ref.xht
 == css-writing-modes/sizing-orthog-vrl-in-htb-006.xht css-writing-modes/sizing-orthog-vrl-in-htb-006-ref.xht
 == css-writing-modes/sizing-orthog-vrl-in-htb-007.xht css-writing-modes/sizing-orthog-vrl-in-htb-007-ref.xht
-fuzzy-if(winWidget,255,648-713) == css-writing-modes/sizing-orthog-vrl-in-htb-008.xht css-writing-modes/sizing-orthog-vrl-in-htb-008-ref.xht
-fails-if(Android) == css-writing-modes/sizing-orthog-vrl-in-htb-009.xht css-writing-modes/sizing-orthog-vrl-in-htb-009-ref.xht
+fuzzy-if(winWidget,255,648-713) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == css-writing-modes/sizing-orthog-vrl-in-htb-008.xht css-writing-modes/sizing-orthog-vrl-in-htb-008-ref.xht
+fails-if(Android) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == css-writing-modes/sizing-orthog-vrl-in-htb-009.xht css-writing-modes/sizing-orthog-vrl-in-htb-009-ref.xht
 == css-writing-modes/sizing-orthog-vrl-in-htb-010.xht css-writing-modes/sizing-orthog-vrl-in-htb-010-ref.xht
 == css-writing-modes/sizing-orthog-vrl-in-htb-011.xht css-writing-modes/sizing-orthog-vrl-in-htb-011-ref.xht
 == css-writing-modes/sizing-orthog-vrl-in-htb-012.xht css-writing-modes/sizing-orthog-vrl-in-htb-012-ref.xht
 == css-writing-modes/sizing-orthog-vrl-in-htb-013.xht css-writing-modes/sizing-orthog-vrl-in-htb-013-ref.xht
-fails-if(Android) == css-writing-modes/sizing-orthog-vrl-in-htb-015.xht css-writing-modes/sizing-orthog-vrl-in-htb-015-ref.xht
+fails-if(Android) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == css-writing-modes/sizing-orthog-vrl-in-htb-015.xht css-writing-modes/sizing-orthog-vrl-in-htb-015-ref.xht
 == css-writing-modes/sizing-orthog-vrl-in-htb-016.xht css-writing-modes/sizing-orthog-vrl-in-htb-016-ref.xht
 == css-writing-modes/sizing-orthog-vrl-in-htb-018.xht css-writing-modes/sizing-orthog-vrl-in-htb-018-ref.xht
 == css-writing-modes/sizing-orthog-vrl-in-htb-019.xht css-writing-modes/sizing-orthog-vrl-in-htb-019-ref.xht
-fuzzy-if(winWidget,255,648-713) == css-writing-modes/sizing-orthog-vrl-in-htb-020.xht css-writing-modes/sizing-orthog-vrl-in-htb-020-ref.xht
-fails-if(Android) == css-writing-modes/sizing-orthog-vrl-in-htb-021.xht css-writing-modes/sizing-orthog-vrl-in-htb-015-ref.xht
+fuzzy-if(winWidget,255,648-713) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == css-writing-modes/sizing-orthog-vrl-in-htb-020.xht css-writing-modes/sizing-orthog-vrl-in-htb-020-ref.xht
+fails-if(Android) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == css-writing-modes/sizing-orthog-vrl-in-htb-021.xht css-writing-modes/sizing-orthog-vrl-in-htb-015-ref.xht
 == css-writing-modes/sizing-orthog-vrl-in-htb-022.xht css-writing-modes/sizing-orthog-vrl-in-htb-022-ref.xht
 == css-writing-modes/sizing-orthog-vrl-in-htb-023.xht css-writing-modes/sizing-orthog-vrl-in-htb-023-ref.xht
 == css-writing-modes/sizing-orthog-vrl-in-htb-024.xht css-writing-modes/sizing-orthog-vrl-in-htb-018-ref.xht
 skip == css-writing-modes/table-cell-001.html css-writing-modes/reference/table-cell-001-ref.html
 skip == css-writing-modes/table-cell-002.html css-writing-modes/reference/table-cell-002-ref.html
 fuzzy-if(OSX||winWidget,110,1200) == css-writing-modes/table-column-order-002.xht css-writing-modes/block-flow-direction-001-ref.xht
 fuzzy-if(OSX||winWidget,110,1200) == css-writing-modes/table-column-order-003.xht css-writing-modes/block-flow-direction-001-ref.xht
 fuzzy-if(OSX||winWidget,110,1200) == css-writing-modes/table-column-order-004.xht css-writing-modes/block-flow-direction-001-ref.xht
--- a/layout/reftests/w3c-css/submitted/flexbox/reftest.list
+++ b/layout/reftests/w3c-css/submitted/flexbox/reftest.list
@@ -1,15 +1,15 @@
 # Tests for absolutely-positioned children of a flex container
 == flexbox-abspos-child-001a.html flexbox-abspos-child-001-ref.html
 == flexbox-abspos-child-001b.html flexbox-abspos-child-001-ref.html
 == flexbox-abspos-child-002.html flexbox-abspos-child-002-ref.html
 
 # Tests for handling anonymous flex items
-fuzzy-if(Android,225,116) == flexbox-anonymous-items-001.html flexbox-anonymous-items-001-ref.html
+== flexbox-anonymous-items-001.html flexbox-anonymous-items-001-ref.html
 
 # Tests for alignment of flex lines (align-content property)
 == flexbox-align-content-horiz-001a.xhtml flexbox-align-content-horiz-001-ref.xhtml
 == flexbox-align-content-horiz-001b.xhtml flexbox-align-content-horiz-001-ref.xhtml
 == flexbox-align-content-vert-001a.xhtml  flexbox-align-content-vert-001-ref.xhtml
 == flexbox-align-content-vert-001b.xhtml  flexbox-align-content-vert-001-ref.xhtml
 
 # Tests for cross-axis alignment (align-self / align-items properties)
--- a/layout/reftests/writing-mode/reftest.list
+++ b/layout/reftests/writing-mode/reftest.list
@@ -133,17 +133,17 @@ test-pref(dom.meta-viewport.enabled,true
 == 1147834-relative-overconstrained-vertical-lr-rtl.html 1147834-top-right-ref.html
 == 1147834-relative-overconstrained-vertical-rl-ltr.html 1147834-bottom-left-ref.html
 == 1147834-relative-overconstrained-vertical-rl-rtl.html 1147834-top-left-ref.html
 == 1151993-1-orthogonal-block-size.html 1151993-1-orthogonal-block-size-ref.html
 == 1152941-1-orthogonal-blocksize-overflow.html 1152941-1-orthogonal-blocksize-overflow-ref.html
 == 1156021-text-indent-percent.html 1156021-text-indent-percent-ref.html
 == 1157752-upright-bidi.html 1157752-upright-bidi-ref.html
 == 1157758-1-vertical-arabic.html 1157758-1-vertical-arabic-ref.html
-== 1158549-1-vertical-block-size-constraints.html 1158549-1-vertical-block-size-constraints-ref.html
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == 1158549-1-vertical-block-size-constraints.html 1158549-1-vertical-block-size-constraints-ref.html
 == 1163238-orthogonal-auto-margins.html 1163238-orthogonal-auto-margins-ref.html
 == 1174450-intrinsic-sizing.html 1174450-intrinsic-sizing-ref.html
 skip-if(winWidget&&/^Windows\x20NT\x206\.1/.test(http.oscpu)) == 1175789-underline-overline-1.html 1175789-underline-overline-1-ref.html # bug 1442637
 == 1188061-1-nsChangeHint_ClearAncestorIntrinsics.html 1188061-1-nsChangeHint_ClearAncestorIntrinsics-ref.html
 == 1188061-2-nsChangeHint_UpdateComputedBSize.html 1188061-2-nsChangeHint_UpdateComputedBSize-ref.html
 
 # tests involving sideways-lr mode
 == 1193519-sideways-lr-1.html 1193519-sideways-lr-1-ref.html
--- a/layout/reftests/xul/reftest.list
+++ b/layout/reftests/xul/reftest.list
@@ -6,17 +6,17 @@ random-if(Android) == menulist-shrinkwra
 random-if(Android) == menulist-shrinkwrap-2.xul menulist-shrinkwrap-2-ref.xul
 == textbox-overflow-1.xul textbox-overflow-1-ref.xul # for bug 749658
 # accesskeys are not normally displayed on Mac, so skip this test
 skip-if(cocoaWidget) == accesskey.xul accesskey-ref.xul
 fails-if(cocoaWidget) fuzzy-if(xulRuntime.widgetToolkit=="gtk3",1,11) == tree-row-outline-1.xul tree-row-outline-1-ref.xul # win8: bug 1254832
 skip-if(!cocoaWidget) fails-if(webrender&&cocoaWidget) == mac-tab-toolbar.xul mac-tab-toolbar-ref.xul
 != tree-row-outline-1.xul tree-row-outline-1-notref.xul
 == text-crop.xul text-crop-ref.xul
-== text-small-caps-1.xul text-small-caps-1-ref.xul
+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == text-small-caps-1.xul text-small-caps-1-ref.xul
 fuzzy-if(skiaContent,1,60) fuzzy-if(cocoaWidget&&browserIsRemote&&!skiaContent,1,31) fuzzy-if(winWidget&&browserIsRemote&&layersGPUAccelerated,1,50) == inactive-fixed-bg-bug1205630.xul inactive-fixed-bg-bug1205630-ref.html
 fuzzy-if(skiaContent,1,60) fuzzy-if(cocoaWidget&&browserIsRemote&&!skiaContent,1,31) fuzzy-if(winWidget&&browserIsRemote&&layersGPUAccelerated,1,50) == inactive-fixed-bg-bug1272525.xul inactive-fixed-bg-bug1272525-ref.html
 
 # Tests for XUL <image> with 'object-fit' & 'object-position':
 # These tests should be very similar to tests in our w3c-css/submitted/images3
 # reftest directory. They live here because they use XUL, and it
 # wouldn't be fair of us to make a W3C testsuite implicitly depend on XUL.
 == object-fit-contain-png-001.xul object-fit-contain-png-001-ref.html
--- a/memory/replace/dmd/test/xpcshell.ini
+++ b/memory/replace/dmd/test/xpcshell.ini
@@ -24,12 +24,11 @@ support-files =
   script-ignore-alloc-fns-expected.txt
   script-diff-live1.json
   script-diff-live2.json
   script-diff-live-expected.txt
   script-diff-dark-matter1.json
   script-diff-dark-matter2.json
   script-diff-dark-matter-expected.txt
 
-# Bug 1077230 explains why this test is disabled on Mac 10.6.
 [test_dmd.js]
 dmd = true
-skip-if = !(os=='linux' || os=='win' || (os=='mac' && os_version!='10.6'))
+skip-if = !(os=='linux' || os=='win' || os=='mac')
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -57,18 +57,18 @@ pref("browser.cache.memory.max_entry_siz
 // Memory limit (in kB) for new cache data not yet written to disk. Writes to
 // the cache are buffered and written to disk on background with low priority.
 // With a slow persistent storage these buffers may grow when data is coming
 // fast from the network. When the amount of unwritten data is exceeded, new
 // writes will simply fail. We have two buckets, one for important data
 // (priority) like html, css, fonts and js, and one for other data like images,
 // video, etc.
 // Note: 0 means no limit.
-pref("browser.cache.disk.max_chunks_memory_usage", 10240);
-pref("browser.cache.disk.max_priority_chunks_memory_usage", 10240);
+pref("browser.cache.disk.max_chunks_memory_usage", 40960);
+pref("browser.cache.disk.max_priority_chunks_memory_usage", 40960);
 
 pref("browser.cache.disk_cache_ssl",        true);
 // 0 = once-per-session, 1 = each-time, 2 = never, 3 = when-appropriate/automatically
 pref("browser.cache.check_doc_frequency",   3);
 // Limit of recent metadata we keep in memory for faster access, in Kb
 pref("browser.cache.disk.metadata_memory_limit", 250); // 0.25 MB
 // The number of chunks we preload ahead of read.  One chunk has currently 256kB.
 pref("browser.cache.disk.preload_chunk_count", 4); // 1 MB of read ahead
--- a/netwerk/cache2/CacheFileIOManager.cpp
+++ b/netwerk/cache2/CacheFileIOManager.cpp
@@ -47,20 +47,21 @@ namespace mozilla {
 namespace net {
 
 #define kOpenHandlesLimit        128
 #define kMetadataWriteDelay      5000
 #define kRemoveTrashStartDelay   60000 // in milliseconds
 #define kSmartSizeUpdateInterval 60000 // in milliseconds
 
 #ifdef ANDROID
-const uint32_t kMaxCacheSizeKB = 200*1024; // 200 MB
+const uint32_t kMaxCacheSizeKB = 512*1024; // 512 MB
 #else
-const uint32_t kMaxCacheSizeKB = 350*1024; // 350 MB
+const uint32_t kMaxCacheSizeKB = 1024*1024; // 1 GB
 #endif
+const uint32_t kMaxClearOnShutdownCacheSizeKB = 150*1024; // 150 MB
 
 bool
 CacheFileHandle::DispatchRelease()
 {
   if (CacheFileIOManager::IsOnIOThreadOrCeased()) {
     return false;
   }
 
@@ -4163,54 +4164,55 @@ CacheFileIOManager::SyncRemoveAllCacheFi
   }
 }
 
 // Returns default ("smart") size (in KB) of cache, given available disk space
 // (also in KB)
 static uint32_t
 SmartCacheSize(const uint32_t availKB)
 {
-  uint32_t maxSize = kMaxCacheSizeKB;
-
-  if (availKB > 100 * 1024 * 1024) {
-    return maxSize;  // skip computing if we're over 100 GB
+  uint32_t maxSize;
+
+  if (CacheObserver::ClearCacheOnShutdown()) {
+    maxSize = kMaxClearOnShutdownCacheSizeKB;
+  } else {
+    maxSize = kMaxCacheSizeKB;
+  }
+
+  if (availKB > 25 * 1024 * 1024) {
+    return maxSize;  // skip computing if we're over 25 GB
   }
 
   // Grow/shrink in 10 MB units, deliberately, so that in the common case we
   // don't shrink cache and evict items every time we startup (it's important
   // that we don't slow down startup benchmarks).
   uint32_t sz10MBs = 0;
   uint32_t avail10MBs = availKB / (1024*10);
 
-  // .5% of space above 25 GB
-  if (avail10MBs > 2500) {
-    sz10MBs += static_cast<uint32_t>((avail10MBs - 2500)*.005);
-    avail10MBs = 2500;
-  }
-  // 1% of space between 7GB -> 25 GB
+  // 2.5% of space above 7GB
   if (avail10MBs > 700) {
-    sz10MBs += static_cast<uint32_t>((avail10MBs - 700)*.01);
+    sz10MBs += static_cast<uint32_t>((avail10MBs - 700)*.025);
     avail10MBs = 700;
   }
-  // 5% of space between 500 MB -> 7 GB
+  // 7.5% of space between 500 MB -> 7 GB
   if (avail10MBs > 50) {
-    sz10MBs += static_cast<uint32_t>((avail10MBs - 50)*.05);
+    sz10MBs += static_cast<uint32_t>((avail10MBs - 50)*.075);
     avail10MBs = 50;
   }
 
 #ifdef ANDROID
   // On Android, smaller/older devices may have very little storage and
   // device owners may be sensitive to storage footprint: Use a smaller
   // percentage of available space and a smaller minimum.
 
-  // 20% of space up to 500 MB (10 MB min)
-  sz10MBs += std::max<uint32_t>(1, static_cast<uint32_t>(avail10MBs * .2));
+  // 16% of space up to 500 MB (10 MB min)
+  sz10MBs += std::max<uint32_t>(1, static_cast<uint32_t>(avail10MBs * .16));
 #else
-  // 40% of space up to 500 MB (50 MB min)
-  sz10MBs += std::max<uint32_t>(5, static_cast<uint32_t>(avail10MBs * .4));
+  // 30% of space up to 500 MB (50 MB min)
+  sz10MBs += std::max<uint32_t>(5, static_cast<uint32_t>(avail10MBs * .3));
 #endif
 
   return std::min<uint32_t>(maxSize, sz10MBs * 10 * 1024);
 }
 
 nsresult
 CacheFileIOManager::UpdateSmartCacheSize(int64_t aFreeSpace)
 {
--- a/netwerk/cache2/CacheObserver.cpp
+++ b/netwerk/cache2/CacheObserver.cpp
@@ -57,20 +57,20 @@ static uint32_t const kDefaultPreloadChu
 uint32_t CacheObserver::sPreloadChunkCount = kDefaultPreloadChunkCount;
 
 static int32_t const kDefaultMaxMemoryEntrySize = 4 * 1024; // 4 MB
 int32_t CacheObserver::sMaxMemoryEntrySize = kDefaultMaxMemoryEntrySize;
 
 static int32_t const kDefaultMaxDiskEntrySize = 50 * 1024; // 50 MB
 int32_t CacheObserver::sMaxDiskEntrySize = kDefaultMaxDiskEntrySize;
 
-static uint32_t const kDefaultMaxDiskChunksMemoryUsage = 10 * 1024; // 10MB
+static uint32_t const kDefaultMaxDiskChunksMemoryUsage = 40 * 1024; // 40MB
 uint32_t CacheObserver::sMaxDiskChunksMemoryUsage = kDefaultMaxDiskChunksMemoryUsage;
 
-static uint32_t const kDefaultMaxDiskPriorityChunksMemoryUsage = 10 * 1024; // 10MB
+static uint32_t const kDefaultMaxDiskPriorityChunksMemoryUsage = 40 * 1024; // 40MB
 uint32_t CacheObserver::sMaxDiskPriorityChunksMemoryUsage = kDefaultMaxDiskPriorityChunksMemoryUsage;
 
 static uint32_t const kDefaultCompressionLevel = 1;
 uint32_t CacheObserver::sCompressionLevel = kDefaultCompressionLevel;
 
 static bool kDefaultSanitizeOnShutdown = false;
 bool CacheObserver::sSanitizeOnShutdown = kDefaultSanitizeOnShutdown;
 
--- a/netwerk/protocol/websocket/WebSocketChannelParent.cpp
+++ b/netwerk/protocol/websocket/WebSocketChannelParent.cpp
@@ -278,16 +278,24 @@ WebSocketChannelParent::OnServerClose(ns
   }
   return NS_OK;
 }
 
 void
 WebSocketChannelParent::ActorDestroy(ActorDestroyReason why)
 {
   LOG(("WebSocketChannelParent::ActorDestroy() %p\n", this));
+
+  // Make sure we close the channel if the content process dies without going
+  // through a clean shutdown.
+  if (mChannel) {
+    Unused << mChannel->Close(nsIWebSocketChannel::CLOSE_GOING_AWAY,
+                              NS_LITERAL_CSTRING("Child was killed"));
+  }
+
   mIPCOpen = false;
 }
 
 //-----------------------------------------------------------------------------
 // WebSocketChannelParent::nsIInterfaceRequestor
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
--- a/taskcluster/taskgraph/util/perfile.py
+++ b/taskcluster/taskgraph/util/perfile.py
@@ -5,16 +5,17 @@
 from __future__ import absolute_import, print_function, unicode_literals
 
 import logging
 import math
 
 from mozbuild.util import memoize
 from mozpack.path import match as mozpackmatch
 from mozversioncontrol import get_repository_object, InvalidRepoPath
+from subprocess import CalledProcessError
 from taskgraph import files_changed
 from .. import GECKO
 
 logger = logging.getLogger(__name__)
 
 
 @memoize
 def perfile_number_of_chunks(try_task_config, head_repository, head_rev, type):
@@ -46,16 +47,18 @@ def perfile_number_of_chunks(try_task_co
     if try_task_config:
         specified_files = try_task_config.split(":")
 
     try:
         vcs = get_repository_object(GECKO)
         changed_files.update(vcs.get_outgoing_files('AM'))
     except InvalidRepoPath:
         vcs = None
+    except CalledProcessError:
+        return 0
 
     if not changed_files:
         changed_files.update(files_changed.get_changed_files(head_repository,
                                                              head_rev))
 
     changed_files.update(specified_files)
     test_count = 0
     for pattern in file_patterns:
deleted file mode 100644
--- a/testing/web-platform/meta/html/dom/dynamic-markup-insertion/document-write/contentType.window.js.ini
+++ /dev/null
@@ -1,8 +0,0 @@
-[contentType.window.html]
-  expected:
-    if debug and not webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): CRASH
-    if debug and not webrender and not e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): CRASH
-    if debug and not webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): CRASH
-    if debug and not webrender and e10s and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): CRASH
-    if debug and not webrender and e10s and (os == "win") and (version == "10.0.15063") and (processor == "x86_64") and (bits == 64): CRASH
-    if debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): CRASH