Backed out 4 changesets (bug 1132888) for SM-tc(r) failures a=backout
authorWes Kocher <wkocher@mozilla.com>
Fri, 04 Nov 2016 11:38:09 -0700
changeset 347752 9c43bca082b79800fc7e9217f41b87dc7e356636
parent 347751 4da7d22ebcd2fdd3047487d7c2e483093324263c
child 347753 7c9296be2a4f11a1ae6e018d128a5f1ae18cadb3
push id10298
push userraliiev@mozilla.com
push dateMon, 14 Nov 2016 12:33:03 +0000
treeherdermozilla-aurora@7e29173b1641 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbackout
bugs1132888
milestone52.0a1
backs outcd3ff163021bc877464113a006f3c412d81b7366
f596578a143e02a187656ff938db143208d4ceb8
5e2739dedc3a6633468e68427aa2c3d750ce0f81
e4b1a95a7f3997e90a1e278b82b17140ec235af8
Backed out 4 changesets (bug 1132888) for SM-tc(r) failures a=backout Backed out changeset cd3ff163021b (bug 1132888) Backed out changeset f596578a143e (bug 1132888) Backed out changeset 5e2739dedc3a (bug 1132888) Backed out changeset e4b1a95a7f39 (bug 1132888)
js/src/jit-test/tests/ion/dce-with-rinstructions.js
js/src/jit-test/tests/ion/recover-objects.js
js/src/jit-test/tests/self-test/assertRecoveredOnBailout-0.js
js/src/jit-test/tests/self-test/assertRecoveredOnBailout-1.js
js/src/jit-test/tests/self-test/assertRecoveredOnBailout.js
js/src/jit/JitSpewer.cpp
js/src/jit/MCallOptimize.cpp
js/src/jit/MIR.h
js/src/jit/Recover.cpp
js/src/jit/Recover.h
js/src/jit/ValueNumbering.cpp
js/src/jsapi.cpp
js/src/jsapi.h
js/src/tests/lib/jittests.py
--- a/js/src/jit-test/tests/ion/dce-with-rinstructions.js
+++ b/js/src/jit-test/tests/ion/dce-with-rinstructions.js
@@ -1,14 +1,13 @@
 setJitCompilerOption("baseline.warmup.trigger", 10);
 setJitCompilerOption("ion.warmup.trigger", 20);
 var i;
 
 var config = getBuildConfiguration();
-var max = 200;
 
 // Check that we are able to remove the operation inside recover test functions (denoted by "rop..."),
 // when we inline the first version of uceFault, and ensure that the bailout is correct
 // when uceFault is replaced (which cause an invalidation bailout)
 
 var uceFault = function (i) {
     if (i > 98)
         uceFault = function (i) { return true; };
@@ -1287,22 +1286,33 @@ function rhypot_object_4args(i) {
         assertEq(x, Math.sqrt(i * i + (i + 1) * (i + 1) + (i + 2) * (i + 2) + (i + 3) * (i + 3)));
     assertRecoveredOnBailout(x, false);
     return i;
 }
 
 var uceFault_random = eval(uneval(uceFault).replace('uceFault', 'uceFault_random'));
 function rrandom(i) {
     // setRNGState() exists only in debug builds
-    if(config.debug) setRNGState(2, 1+i);
 
-    var x = Math.random();
-    if (uceFault_random(i) || uceFault_random(i))
-        assertEq(x, config.debug ? setRNGState(2, 1+i) || Math.random() : x);
-    assertRecoveredOnBailout(x, true);
+    if(config.debug) {
+        setRNGState(2, 0);
+        var x = Math.random();
+        if (uceFault_random(i) || uceFault_random(i)) {
+            setRNGState(2, 0);
+            assertEq(x, Math.random());
+        }
+        assertRecoveredOnBailout(x, true);
+    } else {
+        var x = Math.random();
+        if (uceFault_random(i) || uceFault_random(i)) {
+            Math.random();
+        }
+        assertRecoveredOnBailout(x, true);
+    }
+
     return i;
 }
 
 var uceFault_sin_number = eval(uneval(uceFault).replace('uceFault', 'uceFault_sin_number'));
 function rsin_number(i) {
     var x = Math.sin(i);
     if (uceFault_sin_number(i) || uceFault_sin_number(i))
         assertEq(x, Math.sin(i));
@@ -1338,18 +1348,17 @@ function rlog_object(i) {
     var x = Math.log(o); /* Evaluated with t == i, not t == 1000 */
     t = 1000;
     if (uceFault_log_object(i) || uceFault_log_object(i))
         assertEq(x, Math.log(99) /* log(99) */);
     assertRecoveredOnBailout(x, false);
     return i;
 }
 
-for (j = 100 - max; j < 100; j++) {
-    let i = j < 0 ? Math.abs(j) % 50 : j;
+for (i = 0; i < 100; i++) {
     rbitnot_number(i);
     rbitnot_object(i);
     rbitand_number(i);
     rbitand_object(i);
     rbitor_number(i);
     rbitor_object(i);
     rbitxor_number(i);
     rbitxor_object(i);
--- a/js/src/jit-test/tests/ion/recover-objects.js
+++ b/js/src/jit-test/tests/ion/recover-objects.js
@@ -1,35 +1,29 @@
 // |jit-test| test-join=--no-unboxed-objects; --ion-pgo=on
 //
 // Unboxed object optimization might not trigger in all cases, thus we ensure
 // that Scalar Replacement optimization is working well independently of the
 // object representation.
 
-var max = 200;
-
 // Ion eager fails the test below because we have not yet created any
 // template object in baseline before running the content of the top-level
 // function.
-if (getJitCompilerOptions()["ion.warmup.trigger"] <= max - 10)
-    setJitCompilerOption("ion.warmup.trigger", max - 10);
-
-// Force Inlining heuristics to always inline the functions which have the same
-// number of use count.
-setJitCompilerOption("ion.warmup.trigger", getJitCompilerOptions()["ion.warmup.trigger"]);
+if (getJitCompilerOptions()["ion.warmup.trigger"] <= 90)
+    setJitCompilerOption("ion.warmup.trigger", 90);
 
 // This test checks that we are able to remove the getprop & setprop with scalar
 // replacement, so we should not force inline caches, as this would skip the
 // generation of getprop & setprop instructions.
 if (getJitCompilerOptions()["ion.forceinlineCaches"])
     setJitCompilerOption("ion.forceinlineCaches", 0);
 
 function resumeHere() {}
 var uceFault = function (i) {
-    if (i > max - 2)
+    if (i > 98)
         uceFault = function (i) { return true; };
     return false;
 };
 
 
 // Without "use script" in the inner function, the arguments might be
 // observable.
 function inline_notSoEmpty1(a, b, c, d) {
@@ -85,17 +79,17 @@ function notSoEmpty2(i) {
     // This can only be recovered on bailout iff either we have type
     // information for the property access in the branch, or the branch is
     // removed before scalar replacement.
     assertRecoveredOnBailout(res, true);
 }
 
 // Check that we can recover objects with their content.
 var argFault_observeArg = function (i) {
-    if (i > max - 2)
+    if (i > 98)
         return inline_observeArg.arguments[0];
     return { test : i };
 };
 function inline_observeArg(obj, i) {
     return argFault_observeArg(i);
 }
 function observeArg(i) {
     var obj = { test: i };
@@ -136,36 +130,36 @@ function withinIf(i) {
         obj = undefined;
     }
     assertEq(x, i);
 }
 
 // Check case where one successor can have multiple times the same predecessor.
 function unknownLoad(i) {
     var obj = { foo: i };
-    // Unknown properties are inlined as undefined.
     assertEq(obj.bar, undefined);
-    assertRecoveredOnBailout(obj, true);
+    // Unknown properties are using GetPropertyCache.
+    assertRecoveredOnBailout(obj, false);
 }
 
 // Check with dynamic slots.
 function dynamicSlots(i) {
     var obj = {
         p0: i + 0, p1: i + 1, p2: i + 2, p3: i + 3, p4: i + 4, p5: i + 5, p6: i + 6, p7: i + 7, p8: i + 8, p9: i + 9, p10: i + 10,
         p11: i + 11, p12: i + 12, p13: i + 13, p14: i + 14, p15: i + 15, p16: i + 16, p17: i + 17, p18: i + 18, p19: i + 19, p20: i + 20,
         p21: i + 21, p22: i + 22, p23: i + 23, p24: i + 24, p25: i + 25, p26: i + 26, p27: i + 27, p28: i + 28, p29: i + 29, p30: i + 30,
         p31: i + 31, p32: i + 32, p33: i + 33, p34: i + 34, p35: i + 35, p36: i + 36, p37: i + 37, p38: i + 38, p39: i + 39, p40: i + 40,
         p41: i + 41, p42: i + 42, p43: i + 43, p44: i + 44, p45: i + 45, p46: i + 46, p47: i + 47, p48: i + 48, p49: i + 49, p50: i + 50
     };
     // Add a function call to capture a resumepoint at the end of the call or
     // inside the inlined block, such as the bailout does not rewind to the
     // beginning of the function.
     resumeHere(); bailout();
     assertEq(obj.p0 + obj.p10 + obj.p20 + obj.p30 + obj.p40, 5 * i + 100);
-    assertRecoveredOnBailout(obj, false);
+    assertRecoveredOnBailout(obj, true);
 }
 
 // Check that we can correctly recover allocations of new objects.
 function Point(x, y)
 {
     this.x = x;
     this.y = y;
 }
@@ -173,17 +167,17 @@ function Point(x, y)
 function createThisWithTemplate(i)
 {
     var p = new Point(i - 1, i + 1);
     bailout();
     assertEq(p.y - p.x, 2);
     assertRecoveredOnBailout(p, true);
 }
 
-for (var i = 0; i < max; i++) {
+for (var i = 0; i < 100; i++) {
     notSoEmpty1(i);
     notSoEmpty2(i);
     observeArg(i);
     complexPhi(i);
     withinIf(i);
     unknownLoad(i);
     dynamicSlots(i);
     createThisWithTemplate(i);
deleted file mode 100644
--- a/js/src/jit-test/tests/self-test/assertRecoveredOnBailout-1.js
+++ /dev/null
@@ -1,32 +0,0 @@
-// |jit-test| crash
-
-var opts = getJitCompilerOptions();
-if (!opts['ion.enable'] || !opts['baseline.enable'] ||
-    opts["ion.forceinlineCaches"] || opts["ion.check-range-analysis"])
-{
-    crash("Cannot test assertRecoveredOnBailout");
-}
-
-function g() {
-    return inIon();
-}
-
-// Wait until IonMonkey compilation finished.
-while(!(res = g()));
-
-// Check that we entered Ion succesfully.
-if (res !== true)
-    crash("Cannot enter IonMonkey");
-
-// Test that assertRecoveredOnBailout fails as expected.
-function f () {
-    var o = {};
-    assertRecoveredOnBailout(o, false);
-    return inIon();
-}
-
-// Wait until IonMonkey compilation finished.
-while(!(res = f()));
-
-// Ensure that we entered Ion.
-assertEq(res, true);
rename from js/src/jit-test/tests/self-test/assertRecoveredOnBailout-0.js
rename to js/src/jit-test/tests/self-test/assertRecoveredOnBailout.js
--- a/js/src/jit/JitSpewer.cpp
+++ b/js/src/jit/JitSpewer.cpp
@@ -16,17 +16,16 @@
 # include <unistd.h>
 #endif
 
 #include "jsprf.h"
 
 #include "jit/Ion.h"
 #include "jit/MIR.h"
 #include "jit/MIRGenerator.h"
-#include "jit/MIRGraph.h"
 
 #include "threading/LockGuard.h"
 
 #include "vm/HelperThreads.h"
 #include "vm/MutexIDs.h"
 
 #ifndef JIT_SPEW_DIR
 # if defined(_WIN32)
@@ -298,23 +297,16 @@ GraphSpewer::spewPass(const char* pass)
     c1Spewer_.spewPass(pass);
 
     jsonSpewer_.beginPass(pass);
     jsonSpewer_.spewMIR(graph_);
     jsonSpewer_.spewLIR(graph_);
     jsonSpewer_.endPass();
 
     ionspewer.spewPass(this);
-
-    // As this function is used for debugging, we ignore any of the previous
-    // failures and ensure there is enough ballast space, such that we do not
-    // exhaust the ballast space before running the next phase.
-    AutoEnterOOMUnsafeRegion oomUnsafe;
-    if (!graph_->alloc().ensureBallast())
-        oomUnsafe.crash("Could not ensure enough ballast space after spewing graph information.");
 }
 
 void
 GraphSpewer::spewPass(const char* pass, BacktrackingAllocator* ra)
 {
     if (!isSpewing())
         return;
 
--- a/js/src/jit/MCallOptimize.cpp
+++ b/js/src/jit/MCallOptimize.cpp
@@ -2367,19 +2367,17 @@ IonBuilder::inlineTypedArray(CallInfo& c
             return InliningStatus_NotInlined;
 
         uint32_t len = AssertedCast<uint32_t>(providedLen);
 
         if (obj->length() != len)
             return InliningStatus_NotInlined;
 
         callInfo.setImplicitlyUsedUnchecked();
-        MConstant* templateConst = MConstant::NewConstraintlessObject(alloc(), obj);
-        current->add(templateConst);
-        ins = MNewTypedArray::New(alloc(), constraints(), templateConst,
+        ins = MNewTypedArray::New(alloc(), constraints(), obj,
                                   obj->group()->initialHeap(constraints()));
     }
 
     current->add(ins);
     current->push(ins);
     if (!resumeAfter(ins))
         return InliningStatus_Error;
 
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -3360,51 +3360,56 @@ class MNewArrayDynamicLength
         return AliasSet::None();
     }
 
     bool appendRoots(MRootList& roots) const override {
         return roots.append(templateObject_);
     }
 };
 
-class MNewTypedArray
-  : public MUnaryInstruction,
-    public NoTypePolicy::Data
-{
+class MNewTypedArray : public MNullaryInstruction
+{
+    CompilerGCPointer<TypedArrayObject*> templateObject_;
     gc::InitialHeap initialHeap_;
 
-    MNewTypedArray(CompilerConstraintList* constraints, MConstant* templateConst,
+    MNewTypedArray(CompilerConstraintList* constraints, TypedArrayObject* templateObject,
                    gc::InitialHeap initialHeap)
-      : MUnaryInstruction(templateConst),
+      : templateObject_(templateObject),
         initialHeap_(initialHeap)
     {
-        MOZ_ASSERT(!templateObject()->isSingleton());
+        MOZ_ASSERT(!templateObject->isSingleton());
         setResultType(MIRType::Object);
-        setResultTypeSet(MakeSingletonTypeSet(constraints, templateObject()));
+        setResultTypeSet(MakeSingletonTypeSet(constraints, templateObject));
     }
 
   public:
     INSTRUCTION_HEADER(NewTypedArray)
-    TRIVIAL_NEW_WRAPPERS
+
+    static MNewTypedArray* New(TempAllocator& alloc,
+                               CompilerConstraintList* constraints,
+                               TypedArrayObject* templateObject,
+                               gc::InitialHeap initialHeap)
+    {
+        return new(alloc) MNewTypedArray(constraints, templateObject, initialHeap);
+    }
 
     TypedArrayObject* templateObject() const {
-        return &getOperand(0)->toConstant()->toObject().as<TypedArrayObject>();
+        return templateObject_;
     }
 
     gc::InitialHeap initialHeap() const {
         return initialHeap_;
     }
 
     virtual AliasSet getAliasSet() const override {
         return AliasSet::None();
     }
 
-    MOZ_MUST_USE bool writeRecoverData(CompactBufferWriter& writer) const override;
-    bool canRecoverOnBailout() const override {
-        return true;
+    bool appendRoots(MRootList& roots) const override {
+        return roots.append(templateObject_);
     }
 };
 
 class MNewTypedArrayDynamicLength
   : public MUnaryInstruction,
     public IntPolicy<0>::Data
 {
     CompilerObject templateObject_;
--- a/js/src/jit/Recover.cpp
+++ b/js/src/jit/Recover.cpp
@@ -1297,44 +1297,16 @@ RNewObject::recover(JSContext* cx, Snaps
         return false;
 
     result.setObject(*resultObject);
     iter.storeInstructionResult(result);
     return true;
 }
 
 bool
-MNewTypedArray::writeRecoverData(CompactBufferWriter& writer) const
-{
-    MOZ_ASSERT(canRecoverOnBailout());
-    writer.writeUnsigned(uint32_t(RInstruction::Recover_NewTypedArray));
-    return true;
-}
-
-RNewTypedArray::RNewTypedArray(CompactBufferReader& reader)
-{
-}
-
-bool
-RNewTypedArray::recover(JSContext* cx, SnapshotIterator& iter) const
-{
-    RootedObject templateObject(cx, &iter.read().toObject());
-    RootedValue result(cx);
-
-    uint32_t length = templateObject.as<TypedArrayObject>()->length();
-    JSObject* resultObject = TypedArrayCreateWithTemplate(cx, templateObject, length);
-    if (!resultObject)
-        return false;
-
-    result.setObject(*resultObject);
-    iter.storeInstructionResult(result);
-    return true;
-}
-
-bool
 MNewArray::writeRecoverData(CompactBufferWriter& writer) const
 {
     MOZ_ASSERT(canRecoverOnBailout());
     writer.writeUnsigned(uint32_t(RInstruction::Recover_NewArray));
     writer.writeUnsigned(length());
     return true;
 }
 
--- a/js/src/jit/Recover.h
+++ b/js/src/jit/Recover.h
@@ -95,17 +95,16 @@ namespace jit {
     _(RegExpSearcher)                           \
     _(RegExpTester)                             \
     _(StringReplace)                            \
     _(TypeOf)                                   \
     _(ToDouble)                                 \
     _(ToFloat32)                                \
     _(TruncateToInt32)                          \
     _(NewObject)                                \
-    _(NewTypedArray)                            \
     _(NewArray)                                 \
     _(NewDerivedTypedObject)                    \
     _(CreateThisWithTemplate)                   \
     _(Lambda)                                   \
     _(SimdBox)                                  \
     _(ObjectState)                              \
     _(ArrayState)                               \
     _(AtomicIsLockFree)                         \
@@ -561,24 +560,16 @@ class RNewObject final : public RInstruc
     MNewObject::Mode mode_;
 
   public:
     RINSTRUCTION_HEADER_NUM_OP_(NewObject, 1)
 
     MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const;
 };
 
-class RNewTypedArray final : public RInstruction
-{
-  public:
-    RINSTRUCTION_HEADER_NUM_OP_(NewTypedArray, 1)
-
-    MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const;
-};
-
 class RNewArray final : public RInstruction
 {
   private:
     uint32_t count_;
 
   public:
     RINSTRUCTION_HEADER_NUM_OP_(NewArray, 1)
 
--- a/js/src/jit/ValueNumbering.cpp
+++ b/js/src/jit/ValueNumbering.cpp
@@ -722,18 +722,17 @@ ValueNumberer::visitDefinition(MDefiniti
 
         // The Nop is introduced to capture the result and make sure the operands
         // are not live anymore when there are no further uses. Though when
         // all operands are still needed the Nop doesn't decrease the liveness
         // and can get removed.
         MResumePoint* rp = nop->resumePoint();
         if (rp && rp->numOperands() > 0 &&
             rp->getOperand(rp->numOperands() - 1) == prev &&
-            !nop->block()->lastIns()->isThrow() &&
-            !prev->isAssertRecoveredOnBailout())
+            !nop->block()->lastIns()->isThrow())
         {
             size_t numOperandsLive = 0;
             for (size_t j = 0; j < prev->numOperands(); j++) {
                 for (size_t i = 0; i < rp->numOperands(); i++) {
                     if (prev->getOperand(j) == rp->getOperand(i)) {
                         numOperandsLive++;
                         break;
                     }
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -6219,25 +6219,16 @@ JS_SetGlobalJitCompilerOption(JSContext*
         if (value == 0) {
             jit::JitOptions.forceInlineCaches = false;
             JitSpew(js::jit::JitSpew_IonScripts, "IonBuilder: Enable non-IC optimizations.");
         } else {
             jit::JitOptions.forceInlineCaches = true;
             JitSpew(js::jit::JitSpew_IonScripts, "IonBuilder: Disable non-IC optimizations.");
         }
         break;
-      case JSJITCOMPILER_ION_CHECK_RANGE_ANALYSIS:
-        if (value == 0) {
-            jit::JitOptions.checkRangeAnalysis = false;
-            JitSpew(js::jit::JitSpew_IonScripts, "IonBuilder: Enable range analysis checks.");
-        } else {
-            jit::JitOptions.checkRangeAnalysis = true;
-            JitSpew(js::jit::JitSpew_IonScripts, "IonBuilder: Disable range analysis checks.");
-        }
-        break;
       case JSJITCOMPILER_ION_ENABLE:
         if (value == 1) {
             JS::ContextOptionsRef(cx).setIon(true);
             JitSpew(js::jit::JitSpew_IonScripts, "Enable ion");
         } else if (value == 0) {
             JS::ContextOptionsRef(cx).setIon(false);
             JitSpew(js::jit::JitSpew_IonScripts, "Disable ion");
         }
@@ -6299,19 +6290,16 @@ JS_GetGlobalJitCompilerOption(JSContext*
       case JSJITCOMPILER_ION_WARMUP_TRIGGER:
         *valueOut = jit::JitOptions.forcedDefaultIonWarmUpThreshold.isSome()
                   ? jit::JitOptions.forcedDefaultIonWarmUpThreshold.ref()
                   : jit::OptimizationInfo::CompilerWarmupThreshold;
         break;
       case JSJITCOMPILER_ION_FORCE_IC:
         *valueOut = jit::JitOptions.forceInlineCaches;
         break;
-      case JSJITCOMPILER_ION_CHECK_RANGE_ANALYSIS:
-        *valueOut = jit::JitOptions.checkRangeAnalysis;
-        break;
       case JSJITCOMPILER_ION_ENABLE:
         *valueOut = JS::ContextOptionsRef(cx).ion();
         break;
       case JSJITCOMPILER_BASELINE_ENABLE:
         *valueOut = JS::ContextOptionsRef(cx).baseline();
         break;
       case JSJITCOMPILER_OFFTHREAD_COMPILATION_ENABLE:
         *valueOut = rt->canUseOffthreadIonCompilation();
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -5731,17 +5731,16 @@ JS_SetOffthreadIonCompilationEnabled(JSC
 
 #define JIT_COMPILER_OPTIONS(Register)                                     \
     Register(BASELINE_WARMUP_TRIGGER, "baseline.warmup.trigger")           \
     Register(ION_WARMUP_TRIGGER, "ion.warmup.trigger")                     \
     Register(ION_GVN_ENABLE, "ion.gvn.enable")                             \
     Register(ION_FORCE_IC, "ion.forceinlineCaches")                        \
     Register(ION_ENABLE, "ion.enable")                                     \
     Register(ION_INTERRUPT_WITHOUT_SIGNAL, "ion.interrupt-without-signals") \
-    Register(ION_CHECK_RANGE_ANALYSIS, "ion.check-range-analysis")         \
     Register(BASELINE_ENABLE, "baseline.enable")                           \
     Register(OFFTHREAD_COMPILATION_ENABLE, "offthread-compilation.enable") \
     Register(JUMP_THRESHOLD, "jump-threshold")                             \
     Register(ASMJS_ATOMICS_ENABLE, "asmjs.atomics.enable")                 \
     Register(WASM_TEST_MODE, "wasm.test-mode")                             \
     Register(WASM_FOLD_OFFSETS, "wasm.fold-offsets")
 
 typedef enum JSJitCompilerOption {
--- a/js/src/tests/lib/jittests.py
+++ b/js/src/tests/lib/jittests.py
@@ -115,17 +115,16 @@ class JitTest:
         self.test_also_noasmjs = False # True means run with and without asm.js
                                        # enabled.
         self.test_also_wasm_baseline = False # True means run with and and without
                                        # wasm baseline compiler enabled.
         self.test_also = [] # List of other configurations to test with.
         self.test_join = [] # List of other configurations to test with all existing variants.
         self.expect_error = '' # Errors to expect and consider passing
         self.expect_status = 0 # Exit status to expect from shell
-        self.expect_crash = False # Exit status or error output.
         self.is_module = False
         self.test_reflect_stringify = None  # Reflect.stringify implementation to test
 
         # Expected by the test runner. Always true for jit-tests.
         self.enable = True
 
     def copy(self):
         t = JitTest(self.path)
@@ -137,17 +136,16 @@ class JitTest:
         t.valgrind = self.valgrind
         t.tz_pacific = self.tz_pacific
         t.test_also_noasmjs = self.test_also_noasmjs
         t.test_also_wasm_baseline = self.test_also_noasmjs
         t.test_also = self.test_also
         t.test_join = self.test_join
         t.expect_error = self.expect_error
         t.expect_status = self.expect_status
-        t.expect_crash = self.expect_crash
         t.test_reflect_stringify = self.test_reflect_stringify
         t.enable = True
         t.is_module = self.is_module
         return t
 
     def copy_and_extend_jitflags(self, variant):
         t = self.copy()
         t.jitflags.extend(variant)
@@ -228,18 +226,16 @@ class JitTest:
                         if options.can_test_also_wasm_baseline:
                             test.test_also.append(['--wasm-always-baseline'])
                     elif name.startswith('test-also='):
                         test.test_also.append([name[len('test-also='):]])
                     elif name.startswith('test-join='):
                         test.test_join.append([name[len('test-join='):]])
                     elif name == 'module':
                         test.is_module = True
-                    elif name == 'crash':
-                        test.expect_crash = True
                     elif name.startswith('--'):
                         # // |jit-test| --ion-gvn=off; --no-sse4
                         test.jitflags.append(name)
                     else:
                         print('{}: warning: unrecognized |jit-test| attribute'
                               ' {}'.format(path, part))
 
         if options.valgrind_all:
@@ -369,29 +365,16 @@ def check_output(out, err, rc, timed_out
     for line in out.split('\n'):
         if line.startswith('Trace stats check failed'):
             return False
 
     for line in err.split('\n'):
         if 'Assertion failed:' in line:
             return False
 
-    if test.expect_crash:
-        if sys.platform == 'win32' and rc == 3 - 2 ** 31:
-            return True
-
-        if sys.platform != 'win32' and rc == -11:
-            return True
-
-        # When building with ASan enabled, ASan will convert the -11 returned
-        # value to 1. As a work-around we look for the error output which
-        # includes the crash reason.
-        if rc == 1 and ("Hit MOZ_CRASH" in err or "Assertion failure:" in err):
-            return True
-
     if rc != test.expect_status:
         # Tests which expect a timeout check for exit code 6.
         # Sometimes 0 is returned on Windows for unknown reasons.
         # See bug 899697.
         if sys.platform in ['win32', 'cygwin'] and rc == 0:
             return True
 
         # Allow a non-zero exit code if we want to allow OOM, but only if we