Back out 805ac89b5924 (Bug 1036781) for 52% regression on AWFY's asmjs-ubench-skinning.
authorChris Peterson <cpeterson@mozilla.com>
Fri, 11 Jul 2014 16:01:11 -0700
changeset 215622 67c13008762f79f95e6f8d51f5b74386e075822b
parent 215621 de4ce465c58c5b53030a33fe956851f2bb8d3503
child 215623 e437d7fa90a5dc06a399b432eadc79a02877b0ae
push id515
push userraliiev@mozilla.com
push dateMon, 06 Oct 2014 12:51:51 +0000
treeherdermozilla-release@267c7a481bef [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1036781
milestone33.0a1
backs out805ac89b59240d1cec3116591cba55d51f0aaa7e
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Back out 805ac89b5924 (Bug 1036781) for 52% regression on AWFY's asmjs-ubench-skinning.
js/src/assembler/jit/ExecutableAllocator.h
js/src/assembler/wtf/Assertions.h
js/src/jit/AsmJS.cpp
js/src/jit/AsmJSModule.cpp
js/src/jit/BacktrackingAllocator.cpp
js/src/jit/BaselineBailouts.cpp
js/src/jit/BaselineCompiler.cpp
js/src/jit/BaselineDebugModeOSR.cpp
js/src/jit/BaselineFrameInfo.cpp
js/src/jit/BaselineIC.cpp
js/src/jit/BaselineIC.h
js/src/jit/BaselineJIT.cpp
js/src/jit/CodeGenerator.cpp
js/src/jit/CompactBuffer.h
js/src/jit/ExecutionMode-inl.h
js/src/jit/Ion.cpp
js/src/jit/IonAnalysis.cpp
js/src/jit/IonBuilder.cpp
js/src/jit/IonCaches.cpp
js/src/jit/IonCaches.h
js/src/jit/IonFrames.cpp
js/src/jit/IonFrames.h
js/src/jit/IonMacroAssembler.cpp
js/src/jit/IonMacroAssembler.h
js/src/jit/IonOptimizationLevels.cpp
js/src/jit/IonOptimizationLevels.h
js/src/jit/IonTypes.h
js/src/jit/JitCompartment.h
js/src/jit/LIR-Common.h
js/src/jit/LIR.cpp
js/src/jit/LIR.h
js/src/jit/LiveRangeAllocator.cpp
js/src/jit/LiveRangeAllocator.h
js/src/jit/Lowering.cpp
js/src/jit/MCallOptimize.cpp
js/src/jit/MIR.cpp
js/src/jit/MIR.h
js/src/jit/MIRGraph.cpp
js/src/jit/MOpcodes.h
js/src/jit/RangeAnalysis.cpp
js/src/jit/Recover.cpp
js/src/jit/Snapshots.cpp
js/src/jit/StackSlotAllocator.h
js/src/jit/StupidAllocator.cpp
js/src/jit/TypePolicy.cpp
js/src/jit/TypedObjectPrediction.cpp
js/src/jit/VMFunctions.cpp
js/src/jit/arm/Architecture-arm.cpp
js/src/jit/arm/Assembler-arm.cpp
js/src/jit/arm/Assembler-arm.h
js/src/jit/arm/Bailouts-arm.cpp
js/src/jit/arm/BaselineIC-arm.cpp
js/src/jit/arm/CodeGenerator-arm.cpp
js/src/jit/arm/Lowering-arm.cpp
js/src/jit/arm/MacroAssembler-arm.cpp
js/src/jit/arm/MacroAssembler-arm.h
js/src/jit/arm/MoveEmitter-arm.cpp
js/src/jit/arm/Simulator-arm.cpp
js/src/jit/arm/Trampoline-arm.cpp
js/src/jit/mips/Assembler-mips.cpp
js/src/jit/mips/Bailouts-mips.cpp
js/src/jit/mips/BaselineIC-mips.cpp
js/src/jit/mips/CodeGenerator-mips.cpp
js/src/jit/mips/CodeGenerator-mips.h
js/src/jit/mips/Lowering-mips.cpp
js/src/jit/mips/MacroAssembler-mips.cpp
js/src/jit/mips/MacroAssembler-mips.h
js/src/jit/mips/MoveEmitter-mips.cpp
js/src/jit/mips/Simulator-mips.cpp
js/src/jit/mips/Trampoline-mips.cpp
js/src/jit/shared/Assembler-shared.h
js/src/jit/shared/Assembler-x86-shared.cpp
js/src/jit/shared/Assembler-x86-shared.h
js/src/jit/shared/CodeGenerator-shared-inl.h
js/src/jit/shared/CodeGenerator-shared.cpp
js/src/jit/shared/CodeGenerator-x86-shared.cpp
js/src/jit/shared/IonAssemblerBuffer.h
js/src/jit/shared/IonAssemblerBufferWithConstantPools.h
js/src/jit/shared/MacroAssembler-x86-shared.h
js/src/jit/shared/MoveEmitter-x86-shared.cpp
js/src/jit/x64/Assembler-x64.cpp
js/src/jit/x64/Assembler-x64.h
js/src/jit/x64/Bailouts-x64.cpp
js/src/jit/x64/BaselineIC-x64.cpp
js/src/jit/x64/CodeGenerator-x64.cpp
js/src/jit/x64/Lowering-x64.cpp
js/src/jit/x64/MacroAssembler-x64.cpp
js/src/jit/x64/MacroAssembler-x64.h
js/src/jit/x64/Trampoline-x64.cpp
js/src/jit/x86/Assembler-x86.cpp
js/src/jit/x86/Assembler-x86.h
js/src/jit/x86/Bailouts-x86.cpp
js/src/jit/x86/BaselineIC-x86.cpp
js/src/jit/x86/CodeGenerator-x86.cpp
js/src/jit/x86/Lowering-x86.cpp
js/src/jit/x86/MacroAssembler-x86.cpp
js/src/jit/x86/MacroAssembler-x86.h
js/src/jit/x86/Trampoline-x86.cpp
--- a/js/src/assembler/jit/ExecutableAllocator.h
+++ b/js/src/assembler/jit/ExecutableAllocator.h
@@ -140,17 +140,17 @@ public:
             m_regexpCodeBytes -= n;
             MOZ_ASSERT(m_regexpCodeBytes < m_allocation.size);
             break;
           case OTHER_CODE:
             m_otherCodeBytes -= n;
             MOZ_ASSERT(m_otherCodeBytes < m_allocation.size);
             break;
           default:
-            MOZ_CRASH("bad code kind");
+            MOZ_ASSUME_UNREACHABLE("bad code kind");
         }
 
         release();
     }
 
     ExecutablePool(ExecutableAllocator* allocator, Allocation a)
       : m_allocator(allocator), m_freePtr(a.pages), m_end(m_freePtr + a.size), m_allocation(a),
         m_refCount(1), m_ionCodeBytes(0), m_baselineCodeBytes(0), m_regexpCodeBytes(0),
@@ -175,17 +175,17 @@ private:
         void *result = m_freePtr;
         m_freePtr += n;
 
         switch (kind) {
           case ION_CODE:      m_ionCodeBytes      += n;        break;
           case BASELINE_CODE: m_baselineCodeBytes += n;        break;
           case REGEXP_CODE:   m_regexpCodeBytes   += n;        break;
           case OTHER_CODE:    m_otherCodeBytes    += n;        break;
-          default:            MOZ_CRASH("bad code kind");
+          default:            MOZ_ASSUME_UNREACHABLE("bad code kind");
         }
         return result;
     }
 
     size_t available() const {
         JS_ASSERT(m_end >= m_freePtr);
         return m_end - m_freePtr;
     }
--- a/js/src/assembler/wtf/Assertions.h
+++ b/js/src/assembler/wtf/Assertions.h
@@ -39,13 +39,13 @@
 
 #ifndef ASSERT
 #define ASSERT(assertion) MOZ_ASSERT(assertion)
 #endif
 #define ASSERT_UNUSED(variable, assertion) do { \
     (void)variable; \
     ASSERT(assertion); \
 } while (0)
-#define ASSERT_NOT_REACHED() MOZ_CRASH("WTF: ASSERT_NOT_REACHED")
-#define CRASH() MOZ_CRASH("WTF: CRASH")
+#define ASSERT_NOT_REACHED() MOZ_ASSUME_UNREACHABLE("wtf/Assertions.h")
+#define CRASH() MOZ_CRASH()
 #define COMPILE_ASSERT(exp, name) static_assert(exp, #name)
 
 #endif /* assembler_wtf_Assertions_h */
--- a/js/src/jit/AsmJS.cpp
+++ b/js/src/jit/AsmJS.cpp
@@ -452,34 +452,34 @@ class Type
           case Int:
           case Signed:
           case Unsigned:
           case Intish:
             return MIRType_Int32;
           case Void:
             return MIRType_None;
         }
-        MOZ_CRASH("Invalid Type");
+        MOZ_ASSUME_UNREACHABLE("Invalid Type");
     }
 
     const char *toChars() const {
         switch (which_) {
           case Double:      return "double";
           case MaybeDouble: return "double?";
           case Float:       return "float";
           case Floatish:    return "floatish";
           case MaybeFloat:  return "float?";
           case Fixnum:      return "fixnum";
           case Int:         return "int";
           case Signed:      return "signed";
           case Unsigned:    return "unsigned";
           case Intish:      return "intish";
           case Void:        return "void";
         }
-        MOZ_CRASH("Invalid Type");
+        MOZ_ASSUME_UNREACHABLE("Invalid Type");
     }
 };
 
 } /* anonymous namespace */
 
 // Represents the subset of Type that can be used as the return type of a
 // function.
 class RetType
@@ -513,26 +513,26 @@ class RetType
     }
     AsmJSModule::ReturnType toModuleReturnType() const {
         switch (which_) {
           case Void: return AsmJSModule::Return_Void;
           case Signed: return AsmJSModule::Return_Int32;
           case Float: // will be converted to a Double
           case Double: return AsmJSModule::Return_Double;
         }
-        MOZ_CRASH("Unexpected return type");
+        MOZ_ASSUME_UNREACHABLE("Unexpected return type");
     }
     MIRType toMIRType() const {
         switch (which_) {
           case Void: return MIRType_None;
           case Signed: return MIRType_Int32;
           case Double: return MIRType_Double;
           case Float: return MIRType_Float32;
         }
-        MOZ_CRASH("Unexpected return type");
+        MOZ_ASSUME_UNREACHABLE("Unexpected return type");
     }
     bool operator==(RetType rhs) const { return which_ == rhs.which_; }
     bool operator!=(RetType rhs) const { return which_ != rhs.which_; }
 };
 
 namespace {
 
 // Represents the subset of Type that can be used as a variable or
@@ -587,25 +587,25 @@ class VarType
         return Type::Which(which_);
     }
     MIRType toMIRType() const {
         switch(which_) {
           case Int:     return MIRType_Int32;
           case Double:  return MIRType_Double;
           case Float:   return MIRType_Float32;
         }
-        MOZ_CRASH("VarType can only be Int, Double or Float");
+        MOZ_ASSUME_UNREACHABLE("VarType can only be Int, Double or Float");
     }
     AsmJSCoercion toCoercion() const {
         switch(which_) {
           case Int:     return AsmJS_ToInt32;
           case Double:  return AsmJS_ToNumber;
           case Float:   return AsmJS_FRound;
         }
-        MOZ_CRASH("VarType can only be Int, Double or Float");
+        MOZ_ASSUME_UNREACHABLE("VarType can only be Int, Double or Float");
     }
     static VarType FromCheckedType(Type type) {
         JS_ASSERT(type.isInt() || type.isMaybeDouble() || type.isFloatish());
         if (type.isMaybeDouble())
             return Double;
         else if (type.isFloatish())
             return Float;
         else
@@ -621,17 +621,17 @@ class VarType
 static inline bool
 operator<=(Type lhs, VarType rhs)
 {
     switch (rhs.which()) {
       case VarType::Int:    return lhs.isInt();
       case VarType::Double: return lhs.isDouble();
       case VarType::Float:  return lhs.isFloat();
     }
-    MOZ_CRASH("Unexpected rhs type");
+    MOZ_ASSUME_UNREACHABLE("Unexpected rhs type");
 }
 
 /*****************************************************************************/
 
 static inline MIRType ToMIRType(MIRType t) { return t; }
 static inline MIRType ToMIRType(VarType t) { return t.toMIRType(); }
 
 namespace {
@@ -733,17 +733,17 @@ TypedArrayLoadType(Scalar::Type viewType
       case Scalar::Uint32:
         return Type::Intish;
       case Scalar::Float32:
         return Type::MaybeFloat;
       case Scalar::Float64:
         return Type::MaybeDouble;
       default:;
     }
-    MOZ_CRASH("Unexpected array type");
+    MOZ_ASSUME_UNREACHABLE("Unexpected array type");
 }
 
 enum NeedsBoundsCheck {
     NO_BOUNDS_CHECK,
     NEEDS_BOUNDS_CHECK
 };
 
 namespace {
@@ -1629,17 +1629,17 @@ class NumLit
           case NumLit::BigUnsigned:
             return VarType::Int;
           case NumLit::Double:
             return VarType::Double;
           case NumLit::Float:
             return VarType::Float;
           case NumLit::OutOfRangeInt:;
         }
-        MOZ_CRASH("Unexpected NumLit type");
+        MOZ_ASSUME_UNREACHABLE("Unexpected NumLit type");
     }
 };
 
 } /* anonymous namespace */
 
 static bool
 IsNumericNonFloatLiteral(ParseNode *pn)
 {
@@ -1768,17 +1768,17 @@ IsLiteralInt(ModuleCompiler &m, ParseNod
         *u32 = uint32_t(literal.toInt32());
         return true;
       case NumLit::Double:
       case NumLit::Float:
       case NumLit::OutOfRangeInt:
         return false;
     }
 
-    MOZ_CRASH("Bad literal type");
+    MOZ_ASSUME_UNREACHABLE("Bad literal type");
 }
 
 /*****************************************************************************/
 
 namespace {
 
 // Encapsulates the compilation of a single function in an asm.js module. The
 // function compiler handles the creation and final backend compilation of the
@@ -3036,17 +3036,17 @@ CheckGlobalDotImport(ModuleCompiler &m, 
         switch (mathBuiltin.kind) {
           case ModuleCompiler::MathBuiltin::Function:
             return m.addMathBuiltinFunction(varName, mathBuiltin.u.func, field);
           case ModuleCompiler::MathBuiltin::Constant:
             return m.addMathBuiltinConstant(varName, mathBuiltin.u.cst, field);
           default:
             break;
         }
-        MOZ_CRASH("unexpected or uninitialized math builtin type");
+        MOZ_ASSUME_UNREACHABLE("unexpected or uninitialized math builtin type");
     }
 
     if (IsUseOfName(base, m.module().globalArgumentName())) {
         if (field == m.cx()->names().NaN)
             return m.addGlobalConstant(varName, GenericNaN(), field);
         if (field == m.cx()->names().Infinity)
             return m.addGlobalConstant(varName, PositiveInfinity<double>(), field);
         return m.failName(initNode, "'%s' is not a standard global constant", field);
@@ -3504,17 +3504,17 @@ CheckStoreArray(FunctionCompiler &f, Par
         break;
       case Scalar::Float64:
         if (rhsType.isMaybeFloat())
             rhsDef = f.unary<MToDouble>(rhsDef);
         else if (!rhsType.isMaybeDouble())
             return f.failf(lhs, "%s is not a subtype of float? or double?", rhsType.toChars());
         break;
       default:
-        MOZ_CRASH("Unexpected view type");
+        MOZ_ASSUME_UNREACHABLE("Unexpected view type");
     }
 
     f.storeHeap(viewType, pointerDef, rhsDef, needsBoundsCheck);
 
     *def = rhsDef;
     *type = rhsType;
     return true;
 }
@@ -3974,17 +3974,17 @@ CheckMathFRound(FunctionCompiler &f, Par
         *def = operand;
         *type = Type::Float;
         return true;
       case RetType::Void:
         // definition and return types should be ignored by the caller
         return true;
     }
 
-    MOZ_CRASH("return value of fround is ignored");
+    MOZ_ASSUME_UNREACHABLE("return value of fround is ignored");
 }
 
 static bool
 CheckIsMaybeDouble(FunctionCompiler &f, ParseNode *argNode, Type type)
 {
     if (!type.isMaybeDouble())
         return f.failf(argNode, "%s is not a subtype of double?", type.toChars());
     return true;
@@ -4018,17 +4018,17 @@ CheckMathBuiltinCall(FunctionCompiler &f
       case AsmJSMathBuiltin_tan:    arity = 1; doubleCallee = AsmJSImm_TanD;   floatCallee = AsmJSImm_Invalid; break;
       case AsmJSMathBuiltin_asin:   arity = 1; doubleCallee = AsmJSImm_ASinD;  floatCallee = AsmJSImm_Invalid; break;
       case AsmJSMathBuiltin_acos:   arity = 1; doubleCallee = AsmJSImm_ACosD;  floatCallee = AsmJSImm_Invalid; break;
       case AsmJSMathBuiltin_atan:   arity = 1; doubleCallee = AsmJSImm_ATanD;  floatCallee = AsmJSImm_Invalid; break;
       case AsmJSMathBuiltin_exp:    arity = 1; doubleCallee = AsmJSImm_ExpD;   floatCallee = AsmJSImm_Invalid; break;
       case AsmJSMathBuiltin_log:    arity = 1; doubleCallee = AsmJSImm_LogD;   floatCallee = AsmJSImm_Invalid; break;
       case AsmJSMathBuiltin_pow:    arity = 2; doubleCallee = AsmJSImm_PowD;   floatCallee = AsmJSImm_Invalid; break;
       case AsmJSMathBuiltin_atan2:  arity = 2; doubleCallee = AsmJSImm_ATan2D; floatCallee = AsmJSImm_Invalid; break;
-      default: MOZ_CRASH("unexpected mathBuiltin function");
+      default: MOZ_ASSUME_UNREACHABLE("unexpected mathBuiltin function");
     }
 
     if (retType == RetType::Float && floatCallee == AsmJSImm_Invalid)
         return f.fail(callNode, "math builtin cannot be used as float");
     if (retType != RetType::Double && retType != RetType::Float)
         return f.failf(callNode, "return type of math function is double or float, used as %s", retType.toType().toChars());
 
     FunctionCompiler::Call call(f, callNode, retType);
@@ -4306,17 +4306,17 @@ IsValidIntMultiplyConstant(ModuleCompile
         return false;
       case NumLit::BigUnsigned:
       case NumLit::Double:
       case NumLit::Float:
       case NumLit::OutOfRangeInt:
         return false;
     }
 
-    MOZ_CRASH("Bad literal");
+    MOZ_ASSUME_UNREACHABLE("Bad literal");
 }
 
 static bool
 CheckMultiply(FunctionCompiler &f, ParseNode *star, MDefinition **def, Type *type)
 {
     JS_ASSERT(star->isKind(PNK_STAR));
     ParseNode *lhs = BinaryLeft(star);
     ParseNode *rhs = BinaryRight(star);
@@ -4522,17 +4522,17 @@ CheckBitwise(FunctionCompiler &f, ParseN
     bool onlyOnRight;
     switch (bitwise->getKind()) {
       case PNK_BITOR:  identityElement = 0;  onlyOnRight = false; *type = Type::Signed;   break;
       case PNK_BITAND: identityElement = -1; onlyOnRight = false; *type = Type::Signed;   break;
       case PNK_BITXOR: identityElement = 0;  onlyOnRight = false; *type = Type::Signed;   break;
       case PNK_LSH:    identityElement = 0;  onlyOnRight = true;  *type = Type::Signed;   break;
       case PNK_RSH:    identityElement = 0;  onlyOnRight = true;  *type = Type::Signed;   break;
       case PNK_URSH:   identityElement = 0;  onlyOnRight = true;  *type = Type::Unsigned; break;
-      default: MOZ_CRASH("not a bitwise op");
+      default: MOZ_ASSUME_UNREACHABLE("not a bitwise op");
     }
 
     uint32_t i;
     if (!onlyOnRight && IsLiteralInt(f.m(), lhs, &i) && i == uint32_t(identityElement)) {
         Type rhsType;
         if (!CheckExpr(f, rhs, def, &rhsType))
             return false;
         if (!rhsType.isIntish())
@@ -4569,17 +4569,17 @@ CheckBitwise(FunctionCompiler &f, ParseN
 
     switch (bitwise->getKind()) {
       case PNK_BITOR:  *def = f.bitwise<MBitOr>(lhsDef, rhsDef); break;
       case PNK_BITAND: *def = f.bitwise<MBitAnd>(lhsDef, rhsDef); break;
       case PNK_BITXOR: *def = f.bitwise<MBitXor>(lhsDef, rhsDef); break;
       case PNK_LSH:    *def = f.bitwise<MLsh>(lhsDef, rhsDef); break;
       case PNK_RSH:    *def = f.bitwise<MRsh>(lhsDef, rhsDef); break;
       case PNK_URSH:   *def = f.bitwise<MUrsh>(lhsDef, rhsDef); break;
-      default: MOZ_CRASH("not a bitwise op");
+      default: MOZ_ASSUME_UNREACHABLE("not a bitwise op");
     }
 
     return true;
 }
 
 static bool
 CheckUncoercedCall(FunctionCompiler &f, ParseNode *expr, MDefinition **def, Type *type)
 {
@@ -6177,16 +6177,17 @@ FillArgumentArray(ModuleCompiler &m, con
 #endif
             } else {
                 JS_ASSERT(i.mirType() == MIRType_Double);
                 Address src(StackPointer, offsetToCallerStackArgs + i->offsetFromArgBase());
                 masm.loadDouble(src, ScratchDoubleReg);
                 masm.canonicalizeDouble(ScratchDoubleReg);
                 masm.storeDouble(ScratchDoubleReg, dstAddr);
             }
+            break;
         }
     }
 }
 
 static void
 GenerateFFIInterpreterExit(ModuleCompiler &m, const ModuleCompiler::ExitDescriptor &exit,
                            unsigned exitIndex, Label *throwLabel)
 {
@@ -6279,17 +6280,18 @@ GenerateFFIInterpreterExit(ModuleCompile
         masm.unboxInt32(argv, ReturnReg);
         break;
       case RetType::Double:
         masm.call(AsmJSImmPtr(AsmJSImm_InvokeFromAsmJS_ToNumber));
         masm.branchTest32(Assembler::Zero, ReturnReg, ReturnReg, throwLabel);
         masm.loadDouble(argv, ReturnDoubleReg);
         break;
       case RetType::Float:
-        MOZ_CRASH("Float32 shouldn't be returned from a FFI");
+        MOZ_ASSUME_UNREACHABLE("Float32 shouldn't be returned from a FFI");
+        break;
     }
 
     // Note: the caller is IonMonkey code which means there are no non-volatile
     // registers to restore.
     masm.freeStack(stackDec);
 
     // Clear exitFP before the frame is destroyed.
     LoadAsmJSActivationIntoRegister(masm, activation);
@@ -6503,17 +6505,18 @@ GenerateFFIIonExit(ModuleCompiler &m, co
       case RetType::Signed:
         masm.convertValueToInt32(JSReturnOperand, ReturnDoubleReg, ReturnReg, &oolConvert,
                                  /* -0 check */ false);
         break;
       case RetType::Double:
         masm.convertValueToDouble(JSReturnOperand, ReturnDoubleReg, &oolConvert);
         break;
       case RetType::Float:
-        MOZ_CRASH("Float shouldn't be returned from a FFI");
+        MOZ_ASSUME_UNREACHABLE("Float shouldn't be returned from a FFI");
+        break;
     }
 
     Label done;
     masm.bind(&done);
 
     JS_ASSERT(masm.framePushed() == framePushed);
 #if defined(JS_CODEGEN_X64)
     masm.loadPtr(Address(StackPointer, savedHeapOffset), HeapReg);
@@ -6571,17 +6574,17 @@ GenerateFFIIonExit(ModuleCompiler &m, co
             masm.unboxInt32(Address(StackPointer, offsetToArgv), ReturnReg);
             break;
           case RetType::Double:
             masm.call(AsmJSImmPtr(AsmJSImm_CoerceInPlace_ToNumber));
             masm.branchTest32(Assembler::Zero, ReturnReg, ReturnReg, throwLabel);
             masm.loadDouble(Address(StackPointer, offsetToArgv), ReturnDoubleReg);
             break;
           default:
-            MOZ_CRASH("Unsupported convert type");
+            MOZ_ASSUME_UNREACHABLE("Unsupported convert type");
         }
 
         masm.jump(&done);
         masm.setFramePushed(0);
     }
 
     JS_ASSERT(masm.framePushed() == 0);
 }
--- a/js/src/jit/AsmJSModule.cpp
+++ b/js/src/jit/AsmJSModule.cpp
@@ -571,17 +571,18 @@ AddressOf(AsmJSImmKind kind, ExclusiveCo
       case AsmJSImm_PowD:
         return RedirectCall(FuncCast(ecmaPow), Args_Double_DoubleDouble);
       case AsmJSImm_ATan2D:
         return RedirectCall(FuncCast(ecmaAtan2), Args_Double_DoubleDouble);
       case AsmJSImm_Invalid:
         break;
     }
 
-    MOZ_CRASH("Bad AsmJSImmKind");
+    MOZ_ASSUME_UNREACHABLE("Bad AsmJSImmKind");
+    return nullptr;
 }
 
 void
 AsmJSModule::staticallyLink(ExclusiveContext *cx)
 {
     JS_ASSERT(isFinished());
     JS_ASSERT(!isStaticallyLinked());
 
@@ -1267,20 +1268,20 @@ AsmJSModule::protectCode(JSRuntime *rt) 
         return;
 
     // Technically, we should be able to only take away the execute permissions,
     // however this seems to break our emulators which don't always check
     // execute permissions while executing code.
 #if defined(XP_WIN)
     DWORD oldProtect;
     if (!VirtualProtect(codeBase(), functionBytes(), PAGE_NOACCESS, &oldProtect))
-        MOZ_CRASH("PAGE_NOACESS failed");
+        MOZ_CRASH();
 #else  // assume Unix
     if (mprotect(codeBase(), functionBytes(), PROT_NONE))
-        MOZ_CRASH("PROT_NONE");
+        MOZ_CRASH();
 #endif
 }
 
 void
 AsmJSModule::unprotectCode(JSRuntime *rt) const
 {
     JS_ASSERT(isDynamicallyLinked());
     JS_ASSERT(rt->currentThreadOwnsInterruptLock());
@@ -1288,20 +1289,20 @@ AsmJSModule::unprotectCode(JSRuntime *rt
     codeIsProtected_ = false;
 
     if (!pod.functionBytes_)
         return;
 
 #if defined(XP_WIN)
     DWORD oldProtect;
     if (!VirtualProtect(codeBase(), functionBytes(), PAGE_EXECUTE_READWRITE, &oldProtect))
-        MOZ_CRASH("PAGE_EXECUTE_READWRITE failed");
+        MOZ_CRASH();
 #else  // assume Unix
     if (mprotect(codeBase(), functionBytes(), PROT_READ | PROT_WRITE | PROT_EXEC))
-        MOZ_CRASH("PROT_READ | PROT_WRITE | PROT_EXEC failed");
+        MOZ_CRASH();
 #endif
 }
 
 bool
 AsmJSModule::codeIsProtected(JSRuntime *rt) const
 {
     JS_ASSERT(isDynamicallyLinked());
     JS_ASSERT(rt->currentThreadOwnsInterruptLock());
--- a/js/src/jit/BacktrackingAllocator.cpp
+++ b/js/src/jit/BacktrackingAllocator.cpp
@@ -1262,17 +1262,17 @@ BacktrackingAllocator::populateSafepoint
                     safepoint->addNunboxPayload(i, *a);
                     break;
 #else
                   case LDefinition::BOX:
                     safepoint->addBoxedValue(*a);
                     break;
 #endif
                   default:
-                    MOZ_CRASH("Bad register type");
+                    MOZ_ASSUME_UNREACHABLE("Bad register type");
                 }
             }
         }
     }
 
     return true;
 }
 
@@ -1501,17 +1501,17 @@ BacktrackingAllocator::computeSpillWeigh
             usesTotal += 2000;
             break;
 
           case LUse::KEEPALIVE:
             break;
 
           default:
             // Note: RECOVERED_INPUT will not appear in UsePositionIterator.
-            MOZ_CRASH("Bad use");
+            MOZ_ASSUME_UNREACHABLE("Bad use");
         }
     }
 
     // Intervals for registers in groups get higher weights.
     if (interval->hint()->kind() != Requirement::NONE)
         usesTotal += 2000;
 
     // Compute spill weight as a use density, lowering the weight for long
--- a/js/src/jit/BaselineBailouts.cpp
+++ b/js/src/jit/BaselineBailouts.cpp
@@ -1719,16 +1719,16 @@ jit::FinishBailoutToBaseline(BaselineBai
         if (!HandleShapeGuardFailure(cx, outerScript, innerScript))
             return false;
         break;
       case Bailout_IonExceptionDebugMode:
         // Return false to resume in HandleException with reconstructed
         // baseline frame.
         return false;
       default:
-        MOZ_CRASH("Unknown bailout kind!");
+        MOZ_ASSUME_UNREACHABLE("Unknown bailout kind!");
     }
 
     if (!CheckFrequentBailouts(cx, outerScript))
         return false;
 
     return true;
 }
--- a/js/src/jit/BaselineCompiler.cpp
+++ b/js/src/jit/BaselineCompiler.cpp
@@ -1356,17 +1356,17 @@ BaselineCompiler::storeValue(const Stack
         masm.loadValue(frame.addressOfThis(), scratch);
         masm.storeValue(scratch, dest);
         break;
       case StackValue::Stack:
         masm.loadValue(frame.addressOfStackValue(source), scratch);
         masm.storeValue(scratch, dest);
         break;
       default:
-        MOZ_CRASH("Invalid kind");
+        MOZ_ASSUME_UNREACHABLE("Invalid kind");
     }
 }
 
 bool
 BaselineCompiler::emit_JSOP_BITOR()
 {
     return emitBinaryArith();
 }
--- a/js/src/jit/BaselineDebugModeOSR.cpp
+++ b/js/src/jit/BaselineDebugModeOSR.cpp
@@ -246,17 +246,17 @@ ICEntryKindToString(ICEntry::Kind kind)
         return "callVM";
       case ICEntry::Kind_DebugTrap:
         return "debug trap";
       case ICEntry::Kind_DebugPrologue:
         return "debug prologue";
       case ICEntry::Kind_DebugEpilogue:
         return "debug epilogue";
       default:
-        MOZ_CRASH("bad ICEntry kind");
+        MOZ_ASSUME_UNREACHABLE("bad ICEntry kind");
     }
 }
 
 static void
 SpewPatchBaselineFrame(uint8_t *oldReturnAddress, uint8_t *newReturnAddress,
                        JSScript *script, ICEntry::Kind frameKind, jsbytecode *pc)
 {
     IonSpew(IonSpew_BaselineDebugModeOSR,
@@ -605,17 +605,17 @@ CloneOldBaselineStub(JSContext *cx, Debu
         break;
         PATCHABLE_ICSTUB_KIND_LIST(CASE_KIND)
 #if JS_HAS_NO_SUCH_METHOD
         PATCHABLE_NSM_ICSTUB_KIND_LIST(CASE_KIND)
 #endif
 #undef CASE_KIND
 
       default:
-        MOZ_CRASH("Bad stub kind");
+        MOZ_ASSUME_UNREACHABLE("Bad stub kind");
     }
 
     if (!entry.newStub)
         return false;
 
     fallbackStub->addNewStub(entry.newStub);
     return true;
 }
@@ -702,17 +702,17 @@ BaselineDebugModeOSRInfo::popValueInto(P
         valueR0 = vp[stackAdjust];
         break;
       case PCMappingSlotInfo::SlotInR1:
         valueR1 = vp[stackAdjust];
         break;
       case PCMappingSlotInfo::SlotIgnore:
         break;
       default:
-        MOZ_CRASH("Bad slot location");
+        MOZ_ASSUME_UNREACHABLE("Bad slot location");
     }
 
     stackAdjust++;
 }
 
 static inline bool
 HasForcedReturn(BaselineDebugModeOSRInfo *info, bool rv)
 {
--- a/js/src/jit/BaselineFrameInfo.cpp
+++ b/js/src/jit/BaselineFrameInfo.cpp
@@ -41,17 +41,17 @@ FrameInfo::sync(StackValue *val)
         break;
       case StackValue::Register:
         masm.pushValue(val->reg());
         break;
       case StackValue::Constant:
         masm.pushValue(val->constant());
         break;
       default:
-        MOZ_CRASH("Invalid kind");
+        MOZ_ASSUME_UNREACHABLE("Invalid kind");
     }
 
     val->setStack();
 }
 
 void
 FrameInfo::syncStack(uint32_t uses)
 {
@@ -97,17 +97,17 @@ FrameInfo::popValue(ValueOperand dest)
         break;
       case StackValue::Stack:
         masm.popValue(dest);
         break;
       case StackValue::Register:
         masm.moveValue(val->reg(), dest);
         break;
       default:
-        MOZ_CRASH("Invalid kind");
+        MOZ_ASSUME_UNREACHABLE("Invalid kind");
     }
 
     // masm.popValue already adjusted the stack pointer, don't do it twice.
     pop(DontAdjustStack);
 }
 
 void
 FrameInfo::popRegsAndSync(uint32_t uses)
@@ -133,17 +133,17 @@ FrameInfo::popRegsAndSync(uint32_t uses)
             masm.moveValue(R1, R2);
             val->setRegister(R2);
         }
         popValue(R1);
         popValue(R0);
         break;
       }
       default:
-        MOZ_CRASH("Invalid uses");
+        MOZ_ASSUME_UNREACHABLE("Invalid uses");
     }
 }
 
 #ifdef DEBUG
 void
 FrameInfo::assertValidState(const BytecodeInfo &info)
 {
     // Check stack depth.
@@ -170,14 +170,14 @@ FrameInfo::assertValidState(const Byteco
             ValueOperand reg = stack[i].reg();
             if (reg == R0) {
                 JS_ASSERT(!usedR0);
                 usedR0 = true;
             } else if (reg == R1) {
                 JS_ASSERT(!usedR1);
                 usedR1 = true;
             } else {
-                MOZ_CRASH("Invalid register");
+                MOZ_ASSUME_UNREACHABLE("Invalid register");
             }
         }
     }
 }
 #endif
--- a/js/src/jit/BaselineIC.cpp
+++ b/js/src/jit/BaselineIC.cpp
@@ -248,17 +248,17 @@ ICStub::trace(JSTracer *trc)
         JS_STATIC_ASSERT(ICSetElem_DenseAdd::MAX_PROTO_CHAIN_DEPTH == 4);
 
         switch (setElemStub->protoChainDepth()) {
           case 0: setElemStub->toImpl<0>()->traceShapes(trc); break;
           case 1: setElemStub->toImpl<1>()->traceShapes(trc); break;
           case 2: setElemStub->toImpl<2>()->traceShapes(trc); break;
           case 3: setElemStub->toImpl<3>()->traceShapes(trc); break;
           case 4: setElemStub->toImpl<4>()->traceShapes(trc); break;
-          default: MOZ_CRASH("Invalid proto stub.");
+          default: MOZ_ASSUME_UNREACHABLE("Invalid proto stub.");
         }
         break;
       }
       case ICStub::SetElem_TypedArray: {
         ICSetElem_TypedArray *setElemStub = toSetElem_TypedArray();
         MarkShape(trc, &setElemStub->shape(), "baseline-setelem-typedarray-shape");
         break;
       }
@@ -343,17 +343,17 @@ ICStub::trace(JSTracer *trc)
           case 1: propStub->toImpl<1>()->traceShapes(trc); break;
           case 2: propStub->toImpl<2>()->traceShapes(trc); break;
           case 3: propStub->toImpl<3>()->traceShapes(trc); break;
           case 4: propStub->toImpl<4>()->traceShapes(trc); break;
           case 5: propStub->toImpl<5>()->traceShapes(trc); break;
           case 6: propStub->toImpl<6>()->traceShapes(trc); break;
           case 7: propStub->toImpl<7>()->traceShapes(trc); break;
           case 8: propStub->toImpl<8>()->traceShapes(trc); break;
-          default: MOZ_CRASH("Invalid proto stub.");
+          default: MOZ_ASSUME_UNREACHABLE("Invalid proto stub.");
         }
         break;
       }
       case ICStub::GetProp_CallDOMProxyNative:
       case ICStub::GetProp_CallDOMProxyWithGenerationNative: {
         ICGetPropCallDOMProxyNativeStub *propStub;
         if (kind() ==  ICStub::GetProp_CallDOMProxyNative)
             propStub = toGetProp_CallDOMProxyNative();
@@ -410,17 +410,17 @@ ICStub::trace(JSTracer *trc)
         MarkShape(trc, &propStub->newShape(), "baseline-setpropnativeadd-stub-newshape");
         JS_STATIC_ASSERT(ICSetProp_NativeAdd::MAX_PROTO_CHAIN_DEPTH == 4);
         switch (propStub->protoChainDepth()) {
           case 0: propStub->toImpl<0>()->traceShapes(trc); break;
           case 1: propStub->toImpl<1>()->traceShapes(trc); break;
           case 2: propStub->toImpl<2>()->traceShapes(trc); break;
           case 3: propStub->toImpl<3>()->traceShapes(trc); break;
           case 4: propStub->toImpl<4>()->traceShapes(trc); break;
-          default: MOZ_CRASH("Invalid proto stub.");
+          default: MOZ_ASSUME_UNREACHABLE("Invalid proto stub.");
         }
         break;
       }
       case ICStub::SetProp_CallScripted: {
         ICSetProp_CallScripted *callStub = toSetProp_CallScripted();
         MarkShape(trc, &callStub->shape(), "baseline-setpropcallscripted-stub-shape");
         MarkObject(trc, &callStub->holder(), "baseline-setpropcallscripted-stub-holder");
         MarkShape(trc, &callStub->holderShape(), "baseline-setpropcallscripted-stub-holdershape");
@@ -822,17 +822,17 @@ EnsureCanEnterIon(JSContext *cx, ICUseCo
 
     if (stat == Method_CantCompile)
         IonSpew(IonSpew_BaselineOSR, "  Can't compile with Ion!");
     else if (stat == Method_Skipped)
         IonSpew(IonSpew_BaselineOSR, "  Skipped compile with Ion!");
     else if (stat == Method_Compiled)
         IonSpew(IonSpew_BaselineOSR, "  Compiled with Ion!");
     else
-        MOZ_CRASH("Invalid MethodStatus!");
+        MOZ_ASSUME_UNREACHABLE("Invalid MethodStatus!");
 
     // Failed to compile.  Reset use count and return.
     if (stat != Method_Compiled) {
         // TODO: If stat == Method_CantCompile, insert stub that just skips the useCount
         // entirely, instead of resetting it.
         bool bailoutExpected = script->hasIonScript() && script->ionScript()->bailoutExpected();
         if (stat == Method_CantCompile || bailoutExpected) {
             IonSpew(IonSpew_BaselineOSR, "  Reset UseCount cantCompile=%s bailoutExpected=%s!",
@@ -1539,17 +1539,17 @@ DoTypeUpdateFallback(JSContext *cx, Base
         if (*pc == JSOP_SETALIASEDVAR)
             id = NameToId(ScopeCoordinateName(cx->runtime()->scopeCoordinateNameCache, script, pc));
         else
             id = NameToId(script->getName(pc));
         types::AddTypePropertyId(cx, obj, id, value);
         break;
       }
       default:
-        MOZ_CRASH("Invalid stub");
+        MOZ_ASSUME_UNREACHABLE("Invalid stub");
     }
 
     return stub->addUpdateStubForValue(cx, script, obj, id, value);
 }
 
 typedef bool (*DoTypeUpdateFallbackFn)(JSContext *, BaselineFrame *, ICUpdatedStub *, HandleValue,
                                        HandleValue);
 const VMFunction DoTypeUpdateFallbackInfo =
@@ -2585,17 +2585,17 @@ DoBinaryArithFallback(JSContext *cx, Bas
         break;
       }
       case JSOP_URSH: {
         if (!UrshOperation(cx, lhs, rhs, ret))
             return false;
         break;
       }
       default:
-        MOZ_CRASH("Unhandled baseline arith op");
+        MOZ_ASSUME_UNREACHABLE("Unhandled baseline arith op");
     }
 
     // Check if debug mode toggling made the stub invalid.
     if (stub.invalid())
         return true;
 
     if (ret.isDouble())
         stub->setSawDoubleResult();
@@ -2909,17 +2909,17 @@ ICBinaryArith_Double::Compiler::generate
       case JSOP_MOD:
         masm.setupUnalignedABICall(2, R0.scratchReg());
         masm.passABIArg(FloatReg0, MoveOp::DOUBLE);
         masm.passABIArg(FloatReg1, MoveOp::DOUBLE);
         masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, NumberMod), MoveOp::DOUBLE);
         JS_ASSERT(ReturnDoubleReg == FloatReg0);
         break;
       default:
-        MOZ_CRASH("Unexpected op");
+        MOZ_ASSUME_UNREACHABLE("Unexpected op");
     }
 
     masm.boxDouble(FloatReg0, R0);
     EmitReturnFromIC(masm);
 
     // Failure case - jump to next stub
     masm.bind(&failure);
     EmitStubGuardFailure(masm);
@@ -2987,17 +2987,17 @@ ICBinaryArith_BooleanWithInt32::Compiler
       }
       case JSOP_BITAND: {
         masm.andPtr(rhsReg, lhsReg);
         masm.tagValue(JSVAL_TYPE_INT32, lhsReg, R0);
         EmitReturnFromIC(masm);
         break;
       }
       default:
-       MOZ_CRASH("Unhandled op for BinaryArith_BooleanWithInt32.");
+       MOZ_ASSUME_UNREACHABLE("Unhandled op for BinaryArith_BooleanWithInt32.");
     }
 
     // Failure case - jump to next stub
     masm.bind(&failure);
     EmitStubGuardFailure(masm);
     return true;
 }
 
@@ -3049,17 +3049,17 @@ ICBinaryArith_DoubleWithInt32::Compiler:
         break;
       case JSOP_BITXOR:
         masm.xorPtr(intReg, intReg2);
         break;
       case JSOP_BITAND:
         masm.andPtr(intReg, intReg2);
         break;
       default:
-       MOZ_CRASH("Unhandled op for BinaryArith_DoubleWithInt32.");
+       MOZ_ASSUME_UNREACHABLE("Unhandled op for BinaryArith_DoubleWithInt32.");
     }
     masm.tagValue(JSVAL_TYPE_INT32, intReg2, R0);
     EmitReturnFromIC(masm);
 
     // Failure case - jump to next stub
     masm.bind(&failure);
     EmitStubGuardFailure(masm);
     return true;
@@ -3093,17 +3093,17 @@ DoUnaryArithFallback(JSContext *cx, Base
         res.setInt32(result);
         break;
       }
       case JSOP_NEG:
         if (!NegOperation(cx, script, pc, val, res))
             return false;
         break;
       default:
-        MOZ_CRASH("Unexpected op");
+        MOZ_ASSUME_UNREACHABLE("Unexpected op");
     }
 
     // Check if debug mode toggling made the stub invalid.
     if (stub.invalid())
         return true;
 
     if (res.isDouble())
         stub->setSawDoubleResult();
@@ -3731,17 +3731,17 @@ RemoveExistingGetElemNativeStubs(JSConte
         // remove the old stub.
         if (needsAtomize && !getElemNativeStub->needsAtomize()) {
             iter.unlink(cx);
             continue;
         }
 
         // Should never get here, because this means a matching stub exists, and if
         // a matching stub exists, this procedure should never have been called.
-        MOZ_CRASH("Procedure should never have been called.");
+        MOZ_ASSUME_UNREACHABLE("Procedure should never have been called.");
     }
 }
 
 static bool
 TypedArrayGetElemStubExists(ICGetElem_Fallback *stub, HandleObject obj)
 {
     for (ICStubConstIterator iter = stub->beginChainConst(); !iter.atEnd(); iter++) {
         if (!iter->isGetElem_TypedArray())
@@ -5337,17 +5337,17 @@ ICSetElemDenseAddCompiler::getStub(ICStu
 
     ICUpdatedStub *stub = nullptr;
     switch (protoChainDepth_) {
       case 0: stub = getStubSpecific<0>(space, &shapes); break;
       case 1: stub = getStubSpecific<1>(space, &shapes); break;
       case 2: stub = getStubSpecific<2>(space, &shapes); break;
       case 3: stub = getStubSpecific<3>(space, &shapes); break;
       case 4: stub = getStubSpecific<4>(space, &shapes); break;
-      default: MOZ_CRASH("ProtoChainDepth too high.");
+      default: MOZ_ASSUME_UNREACHABLE("ProtoChainDepth too high.");
     }
     if (!stub || !stub->initUpdatingChain(cx, space))
         return nullptr;
     return stub;
 }
 
 bool
 ICSetElemDenseAddCompiler::generateStubCode(MacroAssembler &masm)
@@ -6690,17 +6690,17 @@ ICGetProp_Primitive::Compiler::generateS
         break;
       case JSVAL_TYPE_DOUBLE: // Also used for int32.
         masm.branchTestNumber(Assembler::NotEqual, R0, &failure);
         break;
       case JSVAL_TYPE_BOOLEAN:
         masm.branchTestBoolean(Assembler::NotEqual, R0, &failure);
         break;
       default:
-        MOZ_CRASH("unexpected type");
+        MOZ_ASSUME_UNREACHABLE("unexpected type");
     }
 
     GeneralRegisterSet regs(availableGeneralRegs(1));
     Register holderReg = regs.takeAny();
     Register scratchReg = regs.takeAny();
 
     // Verify the shape of the prototype.
     masm.movePtr(ImmGCPtr(prototype_.get()), holderReg);
@@ -6845,17 +6845,17 @@ ICGetPropNativeDoesNotExistCompiler::get
       case 1: stub = getStubSpecific<1>(space, &shapes); break;
       case 2: stub = getStubSpecific<2>(space, &shapes); break;
       case 3: stub = getStubSpecific<3>(space, &shapes); break;
       case 4: stub = getStubSpecific<4>(space, &shapes); break;
       case 5: stub = getStubSpecific<5>(space, &shapes); break;
       case 6: stub = getStubSpecific<6>(space, &shapes); break;
       case 7: stub = getStubSpecific<7>(space, &shapes); break;
       case 8: stub = getStubSpecific<8>(space, &shapes); break;
-      default: MOZ_CRASH("ProtoChainDepth too high.");
+      default: MOZ_ASSUME_UNREACHABLE("ProtoChainDepth too high.");
     }
     if (!stub)
         return nullptr;
     return stub;
 }
 
 bool
 ICGetPropNativeDoesNotExistCompiler::generateStubCode(MacroAssembler &masm)
@@ -7724,17 +7724,17 @@ ICSetPropNativeAddCompiler::getStub(ICSt
 
     ICUpdatedStub *stub = nullptr;
     switch(protoChainDepth_) {
       case 0: stub = getStubSpecific<0>(space, &shapes); break;
       case 1: stub = getStubSpecific<1>(space, &shapes); break;
       case 2: stub = getStubSpecific<2>(space, &shapes); break;
       case 3: stub = getStubSpecific<3>(space, &shapes); break;
       case 4: stub = getStubSpecific<4>(space, &shapes); break;
-      default: MOZ_CRASH("ProtoChainDepth too high.");
+      default: MOZ_ASSUME_UNREACHABLE("ProtoChainDepth too high.");
     }
     if (!stub || !stub->initUpdatingChain(cx, space))
         return nullptr;
     return stub;
 }
 
 bool
 ICSetPropNativeAddCompiler::generateStubCode(MacroAssembler &masm)
@@ -10023,17 +10023,17 @@ ICTypeOf_Typed::Compiler::generateStubCo
         masm.branchTestBoolean(Assembler::NotEqual, R0, &failure);
         break;
 
       case JSTYPE_SYMBOL:
         masm.branchTestSymbol(Assembler::NotEqual, R0, &failure);
         break;
 
       default:
-        MOZ_CRASH("Unexpected type");
+        MOZ_ASSUME_UNREACHABLE("Unexpected type");
     }
 
     masm.movePtr(ImmGCPtr(typeString_), R0.scratchReg());
     masm.tagValue(JSVAL_TYPE_STRING, R0.scratchReg(), R0);
     EmitReturnFromIC(masm);
 
     masm.bind(&failure);
     EmitStubGuardFailure(masm);
--- a/js/src/jit/BaselineIC.h
+++ b/js/src/jit/BaselineIC.h
@@ -592,17 +592,17 @@ class ICStub
     }
 
     static const char *KindString(Kind k) {
         switch(k) {
 #define DEF_KIND_STR(kindName) case kindName: return #kindName;
             IC_STUB_KIND_LIST(DEF_KIND_STR)
 #undef DEF_KIND_STR
           default:
-            MOZ_CRASH("Invalid kind.");
+            MOZ_ASSUME_UNREACHABLE("Invalid kind.");
         }
     }
 
     enum Trait {
         Regular             = 0x0,
         Fallback            = 0x1,
         Monitored           = 0x2,
         MonitoredFallback   = 0x3,
@@ -1127,17 +1127,17 @@ class ICStubCompiler
           case 1:
             regs.take(R0);
             break;
           case 2:
             regs.take(R0);
             regs.take(R1);
             break;
           default:
-            MOZ_CRASH("Invalid numInputs");
+            MOZ_ASSUME_UNREACHABLE("Invalid numInputs");
         }
 
         return regs;
     }
 
 #ifdef JSGC_GENERATIONAL
     inline bool emitPostWriteBarrierSlot(MacroAssembler &masm, Register obj, ValueOperand val,
                                          Register scratch, GeneralRegisterSet saveRegs);
@@ -3303,17 +3303,18 @@ class ICGetElemNativeCompiler : public I
 
         JS_ASSERT(kind == ICStub::GetElem_NativePrototypeCallScripted);
         if (kind == ICStub::GetElem_NativePrototypeCallScripted) {
             return ICGetElem_NativePrototypeCallScripted::New(
                     space, getStubCode(), firstMonitorStub_, shape, name_, acctype_, needsAtomize_,
                     getter_, pcOffset_, holder_, holderShape);
         }
 
-        MOZ_CRASH("Invalid kind.");
+        MOZ_ASSUME_UNREACHABLE("Invalid kind.");
+        return nullptr;
     }
 };
 
 class ICGetElem_String : public ICStub
 {
     friend class ICStubSpace;
 
     explicit ICGetElem_String(JitCode *stubCode)
--- a/js/src/jit/BaselineJIT.cpp
+++ b/js/src/jit/BaselineJIT.cpp
@@ -547,17 +547,17 @@ BaselineScript::icEntryFromPCOffset(uint
     for (size_t i = mid; i < numICEntries() && icEntry(i).pcOffset() == pcOffset; i--) {
         if (icEntry(i).isForOp())
             return icEntry(i);
     }
     for (size_t i = mid+1; i < numICEntries() && icEntry(i).pcOffset() == pcOffset; i++) {
         if (icEntry(i).isForOp())
             return icEntry(i);
     }
-    MOZ_CRASH("Invalid PC offset for IC entry.");
+    MOZ_ASSUME_UNREACHABLE("Invalid PC offset for IC entry.");
 }
 
 ICEntry &
 BaselineScript::icEntryFromPCOffset(uint32_t pcOffset, ICEntry *prevLookedUpEntry)
 {
     // Do a linear forward search from the last queried PC offset, or fallback to a
     // binary search if the last offset is too far away.
     if (prevLookedUpEntry && pcOffset >= prevLookedUpEntry->pcOffset() &&
@@ -690,17 +690,17 @@ BaselineScript::nativeCodeForPC(JSScript
             if (slotInfo)
                 *slotInfo = PCMappingSlotInfo(b & ~0x80);
             return method_->raw() + nativeOffset;
         }
 
         curPC += GetBytecodeLength(curPC);
     }
 
-    MOZ_CRASH("Invalid pc");
+    MOZ_ASSUME_UNREACHABLE("Invalid pc");
 }
 
 jsbytecode *
 BaselineScript::pcForReturnOffset(JSScript *script, uint32_t nativeOffset)
 {
     JS_ASSERT(script->baselineScript() == this);
     JS_ASSERT(nativeOffset < method_->instructionsSize());
 
@@ -734,17 +734,17 @@ BaselineScript::pcForReturnOffset(JSScri
             curNativeOffset += reader.readUnsigned();
 
         if (curNativeOffset == nativeOffset)
             return curPC;
 
         curPC += GetBytecodeLength(curPC);
     }
 
-    MOZ_CRASH("Invalid pc");
+    MOZ_ASSUME_UNREACHABLE("Invalid pc");
 }
 
 jsbytecode *
 BaselineScript::pcForReturnAddress(JSScript *script, uint8_t *nativeAddress)
 {
     JS_ASSERT(script->baselineScript() == this);
     JS_ASSERT(nativeAddress >= method_->raw());
     JS_ASSERT(nativeAddress < method_->raw() + method_->instructionsSize());
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -1547,17 +1547,17 @@ CodeGenerator::visitMoveGroup(LMoveGroup
           case LDefinition::PAYLOAD:
 #else
           case LDefinition::BOX:
 #endif
           case LDefinition::GENERAL: moveType = MoveOp::GENERAL; break;
           case LDefinition::INT32:   moveType = MoveOp::INT32;   break;
           case LDefinition::FLOAT32: moveType = MoveOp::FLOAT32; break;
           case LDefinition::DOUBLE:  moveType = MoveOp::DOUBLE;  break;
-          default: MOZ_CRASH("Unexpected move type");
+          default: MOZ_ASSUME_UNREACHABLE("Unexpected move type");
         }
 
         if (!resolver.addMove(toMoveOperand(from), toMoveOperand(to), moveType))
             return false;
     }
 
     if (!resolver.resolve())
         return false;
@@ -2135,17 +2135,17 @@ CodeGenerator::visitCallNative(LCallNati
         masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, target->native()));
         break;
 
       case ParallelExecution:
         masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, target->parallelNative()));
         break;
 
       default:
-        MOZ_CRASH("No such execution mode");
+        MOZ_ASSUME_UNREACHABLE("No such execution mode");
     }
 
     // Test for failure.
     masm.branchIfFalseBool(ReturnReg, masm.failureLabel(executionMode));
 
     // Load the outparam vp[0] into output register(s).
     masm.loadValue(Address(StackPointer, IonNativeExitFrameLayout::offsetOfResult()), JSReturnOperand);
 
@@ -2381,17 +2381,17 @@ CodeGenerator::visitCallGeneric(LCallGen
         break;
 
       case ParallelExecution:
         if (!emitCallToUncompiledScriptPar(call, calleereg))
             return false;
         break;
 
       default:
-        MOZ_CRASH("No such execution mode");
+        MOZ_ASSUME_UNREACHABLE("No such execution mode");
     }
 
     masm.bind(&end);
 
     // If the return value of the constructing function is Primitive,
     // replace the return value with the Object from CreateThis.
     if (call->mir()->isConstructing()) {
         Label notPrimitive;
@@ -2481,17 +2481,17 @@ CodeGenerator::visitCallKnown(LCallKnown
         break;
 
       case ParallelExecution:
         if (!emitCallToUncompiledScriptPar(call, calleereg))
             return false;
         break;
 
       default:
-        MOZ_CRASH("No such execution mode");
+        MOZ_ASSUME_UNREACHABLE("No such execution mode");
     }
 
     masm.bind(&end);
 
     // If the return value of the constructing function is Primitive,
     // replace the return value with the Object from CreateThis.
     if (call->mir()->isConstructing()) {
         Label notPrimitive;
@@ -3664,17 +3664,17 @@ ShouldInitFixedSlots(LInstruction *lir, 
             }
 
             // Unhandled instruction, assume it bails or reads object slots.
             return true;
         }
         iter = block->begin();
     }
 
-    MOZ_CRASH("Shouldn't get here");
+    MOZ_ASSUME_UNREACHABLE("Shouldn't get here");
 }
 
 bool
 CodeGenerator::visitNewObject(LNewObject *lir)
 {
     JS_ASSERT(gen->info().executionMode() == SequentialExecution);
     Register objReg = ToRegister(lir->output());
     Register tempReg = ToRegister(lir->temp());
@@ -4546,17 +4546,17 @@ CodeGenerator::visitMathFunctionD(LMathF
         break;
       case MMathFunction::Ceil:
         funptr = JS_FUNC_TO_DATA_PTR(void *, js::math_ceil_impl);
         break;
       case MMathFunction::Round:
         funptr = JS_FUNC_TO_DATA_PTR(void *, js::math_round_impl);
         break;
       default:
-        MOZ_CRASH("Unknown math function");
+        MOZ_ASSUME_UNREACHABLE("Unknown math function");
     }
 
 #   undef MAYBE_CACHED
 
     masm.callWithABI(funptr, MoveOp::DOUBLE);
     return true;
 }
 
@@ -4571,17 +4571,17 @@ CodeGenerator::visitMathFunctionF(LMathF
     masm.passABIArg(input, MoveOp::FLOAT32);
 
     void *funptr = nullptr;
     switch (ins->mir()->function()) {
       case MMathFunction::Floor: funptr = JS_FUNC_TO_DATA_PTR(void *, floorf);           break;
       case MMathFunction::Round: funptr = JS_FUNC_TO_DATA_PTR(void *, math_roundf_impl); break;
       case MMathFunction::Ceil:  funptr = JS_FUNC_TO_DATA_PTR(void *, ceilf);            break;
       default:
-        MOZ_CRASH("Unknown or unsupported float32 math function");
+        MOZ_ASSUME_UNREACHABLE("Unknown or unsupported float32 math function");
     }
 
     masm.callWithABI(funptr, MoveOp::FLOAT32);
     return true;
 }
 
 bool
 CodeGenerator::visitModD(LModD *ins)
@@ -4636,17 +4636,17 @@ CodeGenerator::visitBinaryV(LBinaryV *li
 
       case JSOP_MOD:
         return callVM(ModInfo, lir);
 
       case JSOP_URSH:
         return callVM(UrshInfo, lir);
 
       default:
-        MOZ_CRASH("Unexpected binary op");
+        MOZ_ASSUME_UNREACHABLE("Unexpected binary op");
     }
 }
 
 typedef bool (*StringCompareFn)(JSContext *, HandleString, HandleString, bool *);
 typedef bool (*StringCompareParFn)(ForkJoinContext *, HandleString, HandleString, bool *);
 static const VMFunctionsModal StringsEqualInfo = VMFunctionsModal(
     FunctionInfo<StringCompareFn>(jit::StringsEqual<true>),
     FunctionInfo<StringCompareParFn>(jit::StringsEqualPar));
@@ -4769,17 +4769,17 @@ CodeGenerator::visitCompareVM(LCompareVM
 
       case JSOP_GT:
         return callVM(GtInfo, lir);
 
       case JSOP_GE:
         return callVM(GeInfo, lir);
 
       default:
-        MOZ_CRASH("Unexpected compare op");
+        MOZ_ASSUME_UNREACHABLE("Unexpected compare op");
     }
 }
 
 bool
 CodeGenerator::visitIsNullOrLikeUndefined(LIsNullOrLikeUndefined *lir)
 {
     JSOp op = lir->mir()->jsop();
     MCompare::CompareType compareType = lir->mir()->compareType();
@@ -5136,17 +5136,17 @@ ConcatFatInlineString(MacroAssembler &ma
       case ParallelExecution:
         masm.push(temp1);
         masm.push(temp2);
         masm.newGCFatInlineStringPar(output, forkJoinContext, temp1, temp2, failurePopTemps);
         masm.pop(temp2);
         masm.pop(temp1);
         break;
       default:
-        MOZ_CRASH("No such execution mode");
+        MOZ_ASSUME_UNREACHABLE("No such execution mode");
     }
 
     // Store length and flags.
     uint32_t flags = JSString::INIT_FAT_INLINE_FLAGS;
     if (!isTwoByte)
         flags |= JSString::LATIN1_CHARS_BIT;
     masm.store32(Imm32(flags), Address(output, JSString::offsetOfFlags()));
     masm.store32(temp2, Address(output, JSString::offsetOfLength()));
@@ -5257,17 +5257,17 @@ JitCompartment::generateStringConcatStub
       case ParallelExecution:
         masm.push(temp1);
         masm.push(temp2);
         masm.newGCStringPar(output, forkJoinContext, temp1, temp2, &failurePopTemps);
         masm.pop(temp2);
         masm.pop(temp1);
         break;
       default:
-        MOZ_CRASH("No such execution mode");
+        MOZ_ASSUME_UNREACHABLE("No such execution mode");
     }
 
     // Store rope length and flags. temp1 still holds the result of AND'ing the
     // lhs and rhs flags, so we just have to clear the other flags to get our
     // rope flags (Latin1 if both lhs and rhs are Latin1).
     static_assert(JSString::ROPE_FLAGS == 0, "Rope flags must be 0");
     masm.and32(Imm32(JSString::LATIN1_CHARS_BIT), temp1);
     masm.store32(temp1, Address(output, JSString::offsetOfFlags()));
@@ -6804,17 +6804,17 @@ CodeGenerator::link(JSContext *cx, types
         if (cx->zone()->needsBarrier())
             ionScript->toggleBarriers(true);
         break;
       case ParallelExecution:
         // We don't run incremental GC during parallel execution; no need to
         // turn on barriers.
         break;
       default:
-        MOZ_CRASH("No such execution mode");
+        MOZ_ASSUME_UNREACHABLE("No such execution mode");
     }
 
     // Attach any generated script counts to the script.
     if (IonScriptCounts *counts = extractScriptCounts())
         script->addIonCounts(counts);
 
     return true;
 }
@@ -7082,17 +7082,17 @@ CodeGenerator::addGetPropertyCache(LInst
         return addCache(ins, allocateCache(cache));
       }
       case ParallelExecution: {
         GetPropertyParIC cache(objReg, name, output);
         cache.setProfilerLeavePC(profilerLeavePc);
         return addCache(ins, allocateCache(cache));
       }
       default:
-        MOZ_CRASH("Bad execution mode");
+        MOZ_ASSUME_UNREACHABLE("Bad execution mode");
     }
 }
 
 bool
 CodeGenerator::addSetPropertyCache(LInstruction *ins, RegisterSet liveRegs, Register objReg,
                                    PropertyName *name, ConstantOrRegister value, bool strict,
                                    bool needsTypeBarrier, jsbytecode *profilerLeavePc)
 {
@@ -7103,17 +7103,17 @@ CodeGenerator::addSetPropertyCache(LInst
           return addCache(ins, allocateCache(cache));
       }
       case ParallelExecution: {
           SetPropertyParIC cache(objReg, name, value, strict, needsTypeBarrier);
             cache.setProfilerLeavePC(profilerLeavePc);
           return addCache(ins, allocateCache(cache));
       }
       default:
-        MOZ_CRASH("Bad execution mode");
+        MOZ_ASSUME_UNREACHABLE("Bad execution mode");
     }
 }
 
 bool
 CodeGenerator::addSetElementCache(LInstruction *ins, Register obj, Register unboxIndex,
                                   Register temp, FloatRegister tempDouble,
                                   FloatRegister tempFloat32, ValueOperand index,
                                   ConstantOrRegister value, bool strict, bool guardHoles,
@@ -7128,17 +7128,17 @@ CodeGenerator::addSetElementCache(LInstr
       }
       case ParallelExecution: {
           SetElementParIC cache(obj, unboxIndex, temp, tempDouble, tempFloat32, index, value, strict,
                               guardHoles);
         cache.setProfilerLeavePC(profilerLeavePc);
         return addCache(ins, allocateCache(cache));
       }
       default:
-        MOZ_CRASH("Bad execution mode");
+        MOZ_ASSUME_UNREACHABLE("Bad execution mode");
     }
 }
 
 bool
 CodeGenerator::visitGetPropertyCacheV(LGetPropertyCacheV *ins)
 {
     RegisterSet liveRegs = ins->safepoint()->liveRegs();
     Register objReg = ToRegister(ins->getOperand(0));
@@ -7226,17 +7226,17 @@ CodeGenerator::addGetElementCache(LInstr
         return addCache(ins, allocateCache(cache));
       }
       case ParallelExecution: {
         GetElementParIC cache(obj, index, output, monitoredResult, allowDoubleResult);
         cache.setProfilerLeavePC(profilerLeavePc);
         return addCache(ins, allocateCache(cache));
       }
       default:
-        MOZ_CRASH("No such execution mode");
+        MOZ_ASSUME_UNREACHABLE("No such execution mode");
     }
 }
 
 bool
 CodeGenerator::visitGetElementCacheV(LGetElementCacheV *ins)
 {
     Register obj = ToRegister(ins->object());
     ConstantOrRegister index = TypedOrValueRegister(ToValue(ins, LGetElementCacheV::Index));
@@ -7605,17 +7605,17 @@ CodeGenerator::visitBitOpV(LBitOpV *lir)
         return callVM(BitXorInfo, lir);
       case JSOP_LSH:
         return callVM(BitLhsInfo, lir);
       case JSOP_RSH:
         return callVM(BitRhsInfo, lir);
       default:
         break;
     }
-    MOZ_CRASH("unexpected bitop");
+    MOZ_ASSUME_UNREACHABLE("unexpected bitop");
 }
 
 class OutOfLineTypeOfV : public OutOfLineCodeBase<CodeGenerator>
 {
     LTypeOfV *ins_;
 
   public:
     explicit OutOfLineTypeOfV(LTypeOfV *ins)
@@ -8453,17 +8453,17 @@ CodeGenerator::visitProfilerStackOp(LPro
                 restoreLive(lir);
                 return true;
             }
 
             sps_.pop(masm, temp, /* inlinedFunction = */ false);
             return true;
 
         default:
-            MOZ_CRASH("invalid LProfilerStackOp type");
+            MOZ_ASSUME_UNREACHABLE("invalid LProfilerStackOp type");
     }
 }
 
 bool
 CodeGenerator::visitIsCallable(LIsCallable *ins)
 {
     Register object = ToRegister(ins->object());
     Register output = ToRegister(ins->output());
--- a/js/src/jit/CompactBuffer.h
+++ b/js/src/jit/CompactBuffer.h
@@ -38,17 +38,17 @@ class CompactBufferReader
         while (true) {
             JS_ASSERT(shift < 32);
             byte = readByte();
             val |= (uint32_t(byte) >> 1) << shift;
             shift += 7;
             if (!(byte & 1))
                 return val;
         }
-        MOZ_CRASH("unreachable");
+        MOZ_ASSUME_UNREACHABLE("unreachable");
     }
 
   public:
     CompactBufferReader(const uint8_t *start, const uint8_t *end)
       : buffer_(start),
         end_(end)
     { }
     inline explicit CompactBufferReader(const CompactBufferWriter &writer);
--- a/js/src/jit/ExecutionMode-inl.h
+++ b/js/src/jit/ExecutionMode-inl.h
@@ -19,86 +19,86 @@ namespace jit {
 static inline bool
 HasIonScript(JSScript *script, ExecutionMode cmode)
 {
     switch (cmode) {
       case SequentialExecution: return script->hasIonScript();
       case ParallelExecution: return script->hasParallelIonScript();
       default:;
     }
-    MOZ_CRASH("No such execution mode");
+    MOZ_ASSUME_UNREACHABLE("No such execution mode");
 }
 
 static inline IonScript *
 GetIonScript(JSScript *script, ExecutionMode cmode)
 {
     switch (cmode) {
       case SequentialExecution: return script->maybeIonScript();
       case ParallelExecution: return script->maybeParallelIonScript();
       default:;
     }
-    MOZ_CRASH("No such execution mode");
+    MOZ_ASSUME_UNREACHABLE("No such execution mode");
 }
 
 static inline void
 SetIonScript(JSScript *script, ExecutionMode cmode, IonScript *ionScript)
 {
     switch (cmode) {
       case SequentialExecution: script->setIonScript(ionScript); return;
       case ParallelExecution: script->setParallelIonScript(ionScript); return;
       default:;
     }
-    MOZ_CRASH("No such execution mode");
+    MOZ_ASSUME_UNREACHABLE("No such execution mode");
 }
 
 static inline size_t
 OffsetOfIonInJSScript(ExecutionMode cmode)
 {
     switch (cmode) {
       case SequentialExecution: return JSScript::offsetOfIonScript();
       case ParallelExecution: return JSScript::offsetOfParallelIonScript();
       default:;
     }
-    MOZ_CRASH("No such execution mode");
+    MOZ_ASSUME_UNREACHABLE("No such execution mode");
 }
 
 static inline bool
 CanIonCompile(JSScript *script, ExecutionMode cmode)
 {
     switch (cmode) {
       case SequentialExecution: return script->canIonCompile();
       case ParallelExecution: return script->canParallelIonCompile();
       case DefinitePropertiesAnalysis: return true;
       case ArgumentsUsageAnalysis: return true;
       default:;
     }
-    MOZ_CRASH("No such execution mode");
+    MOZ_ASSUME_UNREACHABLE("No such execution mode");
     return false;
 }
 
 static inline bool
 CompilingOffThread(JSScript *script, ExecutionMode cmode)
 {
     switch (cmode) {
       case SequentialExecution: return script->isIonCompilingOffThread();
       case ParallelExecution: return script->isParallelIonCompilingOffThread();
       default:;
     }
-    MOZ_CRASH("No such execution mode");
+    MOZ_ASSUME_UNREACHABLE("No such execution mode");
 }
 
 static inline bool
 CompilingOffThread(HandleScript script, ExecutionMode cmode)
 {
     switch (cmode) {
       case SequentialExecution: return script->isIonCompilingOffThread();
       case ParallelExecution: return script->isParallelIonCompilingOffThread();
       default:;
     }
-    MOZ_CRASH("No such execution mode");
+    MOZ_ASSUME_UNREACHABLE("No such execution mode");
 }
 
 } // namespace jit
 } // namespace js
 
 #endif  // JS_ION
 
 #endif /* jit_ExecutionMode_inl_h */
--- a/js/src/jit/Ion.cpp
+++ b/js/src/jit/Ion.cpp
@@ -463,17 +463,17 @@ jit::RequestInterruptForIonCode(JSRuntim
 
       case JSRuntime::RequestInterruptAnyThreadDontStopIon:
       case JSRuntime::RequestInterruptAnyThreadForkJoin:
         // The caller does not require Ion code to be interrupted.
         // Nothing more needs to be done.
         break;
 
       default:
-        MOZ_CRASH("Bad interrupt mode");
+        MOZ_ASSUME_UNREACHABLE("Bad interrupt mode");
     }
 }
 
 JitCompartment::JitCompartment()
   : stubCodes_(nullptr),
     baselineCallReturnAddr_(nullptr),
     baselineGetPropReturnAddr_(nullptr),
     baselineSetPropReturnAddr_(nullptr),
@@ -1131,31 +1131,31 @@ IonScript::getSafepointIndex(uint32_t di
         while (++guess <= maxEntry) {
             guessDisp = table[guess].displacement();
             JS_ASSERT(guessDisp <= disp);
             if (guessDisp == disp)
                 return &table[guess];
         }
     }
 
-    MOZ_CRASH("displacement not found.");
+    MOZ_ASSUME_UNREACHABLE("displacement not found.");
 }
 
 const OsiIndex *
 IonScript::getOsiIndex(uint32_t disp) const
 {
     for (const OsiIndex *it = osiIndices(), *end = osiIndices() + osiIndexEntries_;
          it != end;
          ++it)
     {
         if (it->returnPointDisplacement() == disp)
             return it;
     }
 
-    MOZ_CRASH("Failed to find OSI point return address");
+    MOZ_ASSUME_UNREACHABLE("Failed to find OSI point return address");
 }
 
 const OsiIndex *
 IonScript::getOsiIndex(uint8_t *retAddr) const
 {
     IonSpew(IonSpew_Invalidate, "IonScript %p has method %p raw %p", (void *) this, (void *)
             method(), method()->raw());
 
@@ -1645,17 +1645,17 @@ GenerateLIR(MIRGenerator *mir)
                 return nullptr;
             if (!integrity.check(true))
                 return nullptr;
             IonSpewPass("Allocate Registers [Stupid]");
             break;
           }
 
           default:
-            MOZ_CRASH("Bad regalloc");
+            MOZ_ASSUME_UNREACHABLE("Bad regalloc");
         }
 
         if (mir->shouldCancel("Allocate Registers"))
             return nullptr;
     }
 
     return lir;
 }
@@ -2536,17 +2536,17 @@ InvalidateActivation(FreeOp *fop, uint8_
           case JitFrame_BaselineStub:
             IonSpew(IonSpew_Invalidate, "#%d baseline stub frame @ %p", frameno, it.fp());
             break;
           case JitFrame_Rectifier:
             IonSpew(IonSpew_Invalidate, "#%d rectifier frame @ %p", frameno, it.fp());
             break;
           case JitFrame_Unwound_IonJS:
           case JitFrame_Unwound_BaselineStub:
-            MOZ_CRASH("invalid");
+            MOZ_ASSUME_UNREACHABLE("invalid");
           case JitFrame_Unwound_Rectifier:
             IonSpew(IonSpew_Invalidate, "#%d unwound rectifier frame @ %p", frameno, it.fp());
             break;
           case JitFrame_Entry:
             IonSpew(IonSpew_Invalidate, "#%d entry frame @ %p", frameno, it.fp());
             break;
         }
 #endif
@@ -2780,17 +2780,17 @@ jit::Invalidate(JSContext *cx, JSScript 
             return false;
         break;
       case ParallelExecution:
         JS_ASSERT(script->hasParallelIonScript());
         if (!scripts.append(script->parallelIonScript()->recompileInfo()))
             return false;
         break;
       default:
-        MOZ_CRASH("No such execution mode");
+        MOZ_ASSUME_UNREACHABLE("No such execution mode");
     }
 
     Invalidate(cx, scripts, resetUses, cancelOffThread);
     return true;
 }
 
 bool
 jit::Invalidate(JSContext *cx, JSScript *script, bool resetUses, bool cancelOffThread)
@@ -2833,17 +2833,17 @@ jit::FinishInvalidation(FreeOp *fop, JSS
         if (script->hasParallelIonScript()) {
             IonScript *parallelIon = script->parallelIonScript();
             script->setParallelIonScript(nullptr);
             FinishInvalidationOf(fop, script, parallelIon);
         }
         return;
 
       default:
-        MOZ_CRASH("bad execution mode");
+        MOZ_ASSUME_UNREACHABLE("bad execution mode");
     }
 }
 
 template void
 jit::FinishInvalidation<SequentialExecution>(FreeOp *fop, JSScript *script);
 
 template void
 jit::FinishInvalidation<ParallelExecution>(FreeOp *fop, JSScript *script);
@@ -2894,20 +2894,20 @@ jit::ForbidCompilation(JSContext *cx, JS
             if (!Invalidate(cx, script, mode, false))
                 return;
         }
 
         script->setParallelIonScript(ION_DISABLED_SCRIPT);
         return;
 
       default:
-        MOZ_CRASH("No such execution mode");
+        MOZ_ASSUME_UNREACHABLE("No such execution mode");
     }
 
-    MOZ_CRASH("No such execution mode");
+    MOZ_ASSUME_UNREACHABLE("No such execution mode");
 }
 
 AutoFlushICache *
 PerThreadData::autoFlushICache() const
 {
     return autoFlushICache_;
 }
 
--- a/js/src/jit/IonAnalysis.cpp
+++ b/js/src/jit/IonAnalysis.cpp
@@ -721,17 +721,17 @@ TypeAnalyzer::replaceRedundantPhi(MPhi *
         break;
       case MIRType_MagicOptimizedArguments:
         v = MagicValue(JS_OPTIMIZED_ARGUMENTS);
         break;
       case MIRType_MagicOptimizedOut:
         v = MagicValue(JS_OPTIMIZED_OUT);
         break;
       default:
-        MOZ_CRASH("unexpected type");
+        MOZ_ASSUME_UNREACHABLE("unexpected type");
     }
     MConstant *c = MConstant::New(alloc(), v);
     // The instruction pass will insert the box
     block->insertBefore(*(block->begin()), c);
     phi->replaceAllUsesWith(c);
 }
 
 bool
--- a/js/src/jit/IonBuilder.cpp
+++ b/js/src/jit/IonBuilder.cpp
@@ -1369,28 +1369,28 @@ IonBuilder::snoopControlFlow(JSOp op)
           case SRC_WHILE:
           case SRC_FOR_IN:
           case SRC_FOR_OF:
             // while (cond) { }
             return whileOrForInLoop(sn);
 
           default:
             // Hard assert for now - make an error later.
-            MOZ_CRASH("unknown goto case");
+            MOZ_ASSUME_UNREACHABLE("unknown goto case");
         }
         break;
       }
 
       case JSOP_TABLESWITCH:
         return tableSwitch(op, info().getNote(gsn, pc));
 
       case JSOP_IFNE:
         // We should never reach an IFNE, it's a stopAt point, which will
         // trigger closing the loop.
-        MOZ_CRASH("we should never reach an ifne!");
+        MOZ_ASSUME_UNREACHABLE("we should never reach an ifne!");
 
       default:
         break;
     }
     return ControlStatus_None;
 }
 
 bool
@@ -1657,17 +1657,17 @@ IonBuilder::inspectOpcode(JSOp op)
       case JSOP_UINT24:
         return pushConstant(Int32Value(GET_UINT24(pc)));
 
       case JSOP_INT32:
         return pushConstant(Int32Value(GET_INT32(pc)));
 
       case JSOP_LOOPHEAD:
         // JSOP_LOOPHEAD is handled when processing the loop header.
-        MOZ_CRASH("JSOP_LOOPHEAD outside loop");
+        MOZ_ASSUME_UNREACHABLE("JSOP_LOOPHEAD outside loop");
 
       case JSOP_GETELEM:
       case JSOP_CALLELEM:
         return jsop_getelem();
 
       case JSOP_SETELEM:
         return jsop_setelem();
 
@@ -1866,17 +1866,17 @@ IonBuilder::processCfgEntry(CFGState &st
 
       case CFGState::LABEL:
         return processLabelEnd(state);
 
       case CFGState::TRY:
         return processTryEnd(state);
 
       default:
-        MOZ_CRASH("unknown cfgstate");
+        MOZ_ASSUME_UNREACHABLE("unknown cfgstate");
     }
 }
 
 IonBuilder::ControlStatus
 IonBuilder::processIfEnd(CFGState &state)
 {
     if (current) {
         // Here, the false block is the join point. Create an edge from the
@@ -2574,17 +2574,17 @@ IonBuilder::processSwitchBreak(JSOp op)
     switch (state.state) {
       case CFGState::TABLE_SWITCH:
         breaks = &state.tableswitch.breaks;
         break;
       case CFGState::COND_SWITCH_BODY:
         breaks = &state.condswitch.breaks;
         break;
       default:
-        MOZ_CRASH("Unexpected switch state.");
+        MOZ_ASSUME_UNREACHABLE("Unexpected switch state.");
     }
 
     *breaks = new(alloc()) DeferredEdge(current, *breaks);
 
     setCurrent(nullptr);
     pc += js_CodeSpec[op].length;
     return processControlEnd();
 }
@@ -2653,17 +2653,17 @@ IonBuilder::maybeLoop(JSOp op, jssrcnote
 
             // for (; ; update?)
             if (SN_TYPE(sn) == SRC_FOR)
                 return forLoop(op, sn);
         }
         break;
 
       default:
-        MOZ_CRASH("unexpected opcode");
+        MOZ_ASSUME_UNREACHABLE("unexpected opcode");
     }
 
     return ControlStatus_None;
 }
 
 void
 IonBuilder::assertValidLoopHeadOp(jsbytecode *pc)
 {
@@ -2683,17 +2683,17 @@ IonBuilder::assertValidLoopHeadOp(jsbyte
 
         jsbytecode *expected_ifne;
         switch (state.state) {
           case CFGState::DO_WHILE_LOOP_BODY:
             expected_ifne = state.loop.updateEnd;
             break;
 
           default:
-            MOZ_CRASH("JSOP_LOOPHEAD unexpected source note");
+            MOZ_ASSUME_UNREACHABLE("JSOP_LOOPHEAD unexpected source note");
         }
 
         // Make sure this loop goes to the same ifne as the loop header's
         // source notes or GOTO.
         JS_ASSERT(ifne == expected_ifne);
     } else {
         JS_ASSERT(state.state != CFGState::DO_WHILE_LOOP_BODY);
     }
@@ -3580,17 +3580,17 @@ IonBuilder::jsop_ifeq(JSOp op)
         JS_ASSERT(falseEnd >= falseStart);
 
         if (!cfgStack_.append(CFGState::IfElse(trueEnd, falseEnd, test)))
             return false;
         break;
       }
 
       default:
-        MOZ_CRASH("unexpected source note type");
+        MOZ_ASSUME_UNREACHABLE("unexpected source note type");
     }
 
     // Switch to parsing the true branch. Note that no PC update is needed,
     // it's the next instruction.
     if (!setCurrentAndSpecializePhis(ifTrue))
         return false;
 
     // Filter the types in the true branch.
@@ -3701,17 +3701,18 @@ IonBuilder::processReturn(JSOp op)
             def = ins;
             break;
         }
 
         def = current->getSlot(info().returnValueSlot());
         break;
 
       default:
-        MOZ_CRASH("unknown return op");
+        def = nullptr;
+        MOZ_ASSUME_UNREACHABLE("unknown return op");
     }
 
     if (instrumentedProfiling() && inliningDepth_ == 0) {
         current->add(MProfilerStackOp::New(alloc(), script(), MProfilerStackOp::Exit));
     }
     MReturn *ret = MReturn::New(alloc(), def);
     current->end(ret);
 
@@ -3820,17 +3821,17 @@ IonBuilder::jsop_bitop(JSOp op)
         ins = MRsh::New(alloc(), left, right);
         break;
 
       case JSOP_URSH:
         ins = MUrsh::New(alloc(), left, right);
         break;
 
       default:
-        MOZ_CRASH("unexpected bitop");
+        MOZ_ASSUME_UNREACHABLE("unexpected bitop");
     }
 
     current->add(ins);
     ins->infer(inspector, pc);
 
     current->push(ins);
     if (ins->isEffectful() && !resumeAfter(ins))
         return false;
@@ -3877,17 +3878,17 @@ IonBuilder::jsop_binary(JSOp op, MDefini
         ins = MDiv::New(alloc(), left, right);
         break;
 
       case JSOP_MOD:
         ins = MMod::New(alloc(), left, right);
         break;
 
       default:
-        MOZ_CRASH("unexpected binary opcode");
+        MOZ_ASSUME_UNREACHABLE("unexpected binary opcode");
     }
 
     current->add(ins);
     ins->infer(alloc(), inspector, pc);
     current->push(ins);
 
     if (ins->isEffectful())
         return resumeAfter(ins);
@@ -4223,17 +4224,17 @@ IonBuilder::selectInliningTargets(Object
             return false;
           case InliningDecision_DontInline:
             inlineable = false;
             break;
           case InliningDecision_Inline:
             inlineable = true;
             break;
           default:
-            MOZ_CRASH("Unhandled InliningDecision value!");
+            MOZ_ASSUME_UNREACHABLE("Unhandled InliningDecision value!");
         }
 
         // Enforce a maximum inlined bytecode limit at the callsite.
         if (inlineable && target->isInterpreted()) {
             totalSize += target->nonLazyScript()->length();
             if (totalSize > optimizationInfo().inlineMaxTotalBytecodeLength())
                 inlineable = false;
         }
@@ -6530,17 +6531,17 @@ jit::TypeSetIncludes(types::TypeSet *typ
 
       case MIRType_Object:
         return types->unknownObject() || (inputTypes && inputTypes->isSubset(types));
 
       case MIRType_Value:
         return types->unknown() || (inputTypes && inputTypes->isSubset(types));
 
       default:
-        MOZ_CRASH("Bad input type");
+        MOZ_ASSUME_UNREACHABLE("Bad input type");
     }
 }
 
 // Whether a write of the given value may need a post-write barrier for GC purposes.
 bool
 jit::NeedsPostBarrier(CompileInfo &info, MDefinition *value)
 {
 #ifdef JSGC_GENERATIONAL
@@ -6814,20 +6815,20 @@ IonBuilder::getElemTryTypedObject(bool *
                                                  objPrediction,
                                                  elemPrediction,
                                                  elemSize);
 
       case type::Reference:
         return true;
 
       case type::UnsizedArray:
-        MOZ_CRASH("Unsized arrays cannot be element types");
-    }
-
-    MOZ_CRASH("Bad kind");
+        MOZ_ASSUME_UNREACHABLE("Unsized arrays cannot be element types");
+    }
+
+    MOZ_ASSUME_UNREACHABLE("Bad kind");
 }
 
 static MIRType
 MIRTypeForTypedArrayRead(Scalar::Type arrayType, bool observedDouble);
 
 bool
 IonBuilder::checkTypedObjectIndexInBounds(int32_t elemSize,
                                           MDefinition *obj,
@@ -7559,17 +7560,17 @@ MIRTypeForTypedArrayRead(Scalar::Type ar
         return observedDouble ? MIRType_Double : MIRType_Int32;
       case Scalar::Float32:
         return (LIRGenerator::allowFloat32Optimizations()) ? MIRType_Float32 : MIRType_Double;
       case Scalar::Float64:
         return MIRType_Double;
       default:
         break;
     }
-    MOZ_CRASH("Unknown typed array type");
+    MOZ_ASSUME_UNREACHABLE("Unknown typed array type");
 }
 
 bool
 IonBuilder::jsop_getelem_typed(MDefinition *obj, MDefinition *index,
                                Scalar::Type arrayType)
 {
     types::TemporaryTypeSet *types = bytecodeTypes(pc);
 
@@ -7627,17 +7628,17 @@ IonBuilder::jsop_getelem_typed(MDefiniti
                 barrier = BarrierKind::NoBarrier;
             break;
           case Scalar::Float32:
           case Scalar::Float64:
             if (allowDouble)
                 barrier = BarrierKind::NoBarrier;
             break;
           default:
-            MOZ_CRASH("Unknown typed array type");
+            MOZ_ASSUME_UNREACHABLE("Unknown typed array type");
         }
 
         // Assume we will read out-of-bound values. In this case the
         // bounds check will be part of the instruction, and the instruction
         // will always return a Value.
         MLoadTypedArrayElementHole *load =
             MLoadTypedArrayElementHole::New(alloc(), obj, index, arrayType, allowDouble);
         current->add(load);
@@ -7725,17 +7726,17 @@ IonBuilder::setElemTryTypedObject(bool *
                                                  obj,
                                                  index,
                                                  objPrediction,
                                                  value,
                                                  elemPrediction,
                                                  elemSize);
     }
 
-    MOZ_CRASH("Bad kind");
+    MOZ_ASSUME_UNREACHABLE("Bad kind");
 }
 
 bool
 IonBuilder::setElemTryScalarElemOfTypedObject(bool *emitted,
                                               MDefinition *obj,
                                               MDefinition *index,
                                               TypedObjectPrediction objPrediction,
                                               MDefinition *value,
@@ -7988,17 +7989,17 @@ IonBuilder::jsop_setelem_dense(types::Te
         newValue = maybeDouble;
         break;
       }
 
       case types::TemporaryTypeSet::DontConvertToDoubles:
         break;
 
       default:
-        MOZ_CRASH("Unknown double conversion");
+        MOZ_ASSUME_UNREACHABLE("Unknown double conversion");
     }
 
     bool writeHole = false;
     if (safety == SetElem_Normal) {
         SetElemICInspector icInspect(inspector->setElemICInspector(pc));
         writeHole = icInspect.sawOOBDenseWrite();
     }
 
@@ -8794,20 +8795,20 @@ IonBuilder::getPropTryTypedObject(bool *
       case type::Scalar:
         return getPropTryScalarPropOfTypedObject(emitted,
                                                  obj,
                                                  fieldOffset,
                                                  fieldPrediction,
                                                  resultTypes);
 
       case type::UnsizedArray:
-        MOZ_CRASH("Field of unsized array type");
-    }
-
-    MOZ_CRASH("Bad kind");
+        MOZ_ASSUME_UNREACHABLE("Field of unsized array type");
+    }
+
+    MOZ_ASSUME_UNREACHABLE("Bad kind");
 }
 
 bool
 IonBuilder::getPropTryScalarPropOfTypedObject(bool *emitted, MDefinition *typedObj,
                                               int32_t fieldOffset,
                                               TypedObjectPrediction fieldPrediction,
                                               types::TemporaryTypeSet *resultTypes)
 {
@@ -9431,17 +9432,17 @@ IonBuilder::setPropTryTypedObject(bool *
         // For now, only optimize storing scalars.
         return true;
 
       case type::Scalar:
         return setPropTryScalarPropOfTypedObject(emitted, obj, fieldOffset,
                                                  value, fieldPrediction);
     }
 
-    MOZ_CRASH("Unknown kind");
+    MOZ_ASSUME_UNREACHABLE("Unknown kind");
 }
 
 bool
 IonBuilder::setPropTryScalarPropOfTypedObject(bool *emitted,
                                               MDefinition *obj,
                                               int32_t fieldOffset,
                                               MDefinition *value,
                                               TypedObjectPrediction fieldPrediction)
--- a/js/src/jit/IonCaches.cpp
+++ b/js/src/jit/IonCaches.cpp
@@ -1237,17 +1237,17 @@ GetPropertyIC::tryAttachNative(JSContext
         break;
       case CanAttachArrayLength:
         if (!GenerateArrayLength(cx, masm, attacher, obj, object(), output()))
             return false;
 
         attachKind = "array length";
         break;
       default:
-        MOZ_CRASH("Bad NativeGetPropCacheability");
+        MOZ_ASSUME_UNREACHABLE("Bad NativeGetPropCacheability");
     }
     return linkAndAttachStub(cx, masm, attacher, ion, attachKind);
 }
 
 bool
 GetPropertyIC::tryAttachTypedArrayLength(JSContext *cx, HandleScript outerScript, IonScript *ion,
                                          HandleObject obj, HandlePropertyName name, bool *emitted)
 {
@@ -4154,17 +4154,17 @@ IsCacheableNonGlobalScopeChain(JSObject 
 
         scopeChain = &scopeChain->as<ScopeObject>().enclosingScope();
         if (!scopeChain) {
             IonSpew(IonSpew_InlineCaches, "Scope chain indirect hit");
             return false;
         }
     }
 
-    MOZ_CRASH("Invalid scope chain");
+    MOZ_ASSUME_UNREACHABLE("Invalid scope chain");
 }
 
 JSObject *
 BindNameIC::update(JSContext *cx, size_t cacheIndex, HandleObject scopeChain)
 {
     RootedScript outerScript(cx, GetTopIonJSScript(cx));
     IonScript *ion = outerScript->ionScript();
     BindNameIC &cache = ion->getCache(cacheIndex).toBindName();
--- a/js/src/jit/IonCaches.h
+++ b/js/src/jit/IonCaches.h
@@ -42,17 +42,17 @@ namespace jit {
 IONCACHE_KIND_LIST(FORWARD_DECLARE)
 #undef FORWARD_DECLARE
 
 class IonCacheVisitor
 {
   public:
 #define VISIT_INS(op)                                               \
     virtual bool visit##op##IC(CodeGenerator *codegen) {            \
-        MOZ_CRASH("NYI: " #op "IC");                                \
+        MOZ_ASSUME_UNREACHABLE("NYI: " #op "IC");                   \
     }
 
     IONCACHE_KIND_LIST(VISIT_INS)
 #undef VISIT_INS
 };
 
 // Common shared temporary state needed during codegen between the different
 // kinds of caches. Used by OutOfLineUpdateCache.
--- a/js/src/jit/IonFrames.cpp
+++ b/js/src/jit/IonFrames.cpp
@@ -278,17 +278,17 @@ SizeOfFramePrefix(FrameType type)
         return IonBaselineStubFrameLayout::Size();
       case JitFrame_Rectifier:
         return IonRectifierFrameLayout::Size();
       case JitFrame_Unwound_Rectifier:
         return IonUnwoundRectifierFrameLayout::Size();
       case JitFrame_Exit:
         return IonExitFrameLayout::Size();
       default:
-        MOZ_CRASH("unknown frame type");
+        MOZ_ASSUME_UNREACHABLE("unknown frame type");
     }
 }
 
 uint8_t *
 JitFrameIterator::prevFp() const
 {
     size_t currentSize = SizeOfFramePrefix(type_);
     // This quick fix must be removed as soon as bug 717297 land.  This is
@@ -449,17 +449,17 @@ HandleExceptionIon(JSContext *cx, const 
                     return;
 
                 // Error on bailout clears pending exception.
                 MOZ_ASSERT(!cx->isExceptionPending());
             }
             break;
 
           default:
-            MOZ_CRASH("Unexpected try note");
+            MOZ_ASSUME_UNREACHABLE("Unexpected try note");
         }
     }
 }
 
 static void
 ForcedReturn(JSContext *cx, const JitFrameIterator &frame, jsbytecode *pc,
              ResumeFromException *rfe, bool *calledDebugEpilogue)
 {
@@ -510,17 +510,17 @@ HandleExceptionBaseline(JSContext *cx, c
             JS_ASSERT(cx->isExceptionPending());
             break;
 
           case JSTRAP_RETURN:
             ForcedReturn(cx, frame, pc, rfe, calledDebugEpilogue);
             return;
 
           default:
-            MOZ_CRASH("Invalid trap status");
+            MOZ_ASSUME_UNREACHABLE("Invalid trap status");
         }
     }
 
     if (!script->hasTrynotes())
         return;
 
     JSTryNote *tn = script->trynotes()->vector;
     JSTryNote *tnEnd = tn + script->trynotes()->length;
@@ -589,17 +589,17 @@ HandleExceptionBaseline(JSContext *cx, c
                 UnwindIteratorForUncatchableException(cx, iterObject);
             break;
           }
 
           case JSTRY_LOOP:
             break;
 
           default:
-            MOZ_CRASH("Invalid try note");
+            MOZ_ASSUME_UNREACHABLE("Invalid try note");
         }
     }
 
 }
 
 struct AutoDeleteDebugModeOSRInfo
 {
     BaselineFrame *frame;
@@ -824,17 +824,17 @@ MarkCalleeToken(JSTracer *trc, CalleeTok
       }
       case CalleeToken_Script:
       {
         JSScript *script = CalleeTokenToScript(token);
         MarkScriptRoot(trc, &script, "ion-entry");
         return CalleeToToken(script);
       }
       default:
-        MOZ_CRASH("unknown callee token type");
+        MOZ_ASSUME_UNREACHABLE("unknown callee token type");
     }
 }
 
 #ifdef JS_NUNBOX32
 static inline uintptr_t
 ReadAllocation(const JitFrameIterator &frame, const LAllocation *a)
 {
     if (a->isGeneralReg()) {
@@ -1028,17 +1028,17 @@ JitActivationIterator::jitStackRange(uin
         min = reinterpret_cast<uintptr_t *>(frames.fp());
     } else {
         IonExitFrameLayout *exitFrame = frames.exitFrame();
         IonExitFooterFrame *footer = exitFrame->footer();
         const VMFunction *f = footer->function();
         if (exitFrame->isWrapperExit() && f->outParam == Type_Handle) {
             switch (f->outParamRootType) {
               case VMFunction::RootNone:
-                MOZ_CRASH("Handle outparam must have root type");
+                MOZ_ASSUME_UNREACHABLE("Handle outparam must have root type");
               case VMFunction::RootObject:
               case VMFunction::RootString:
               case VMFunction::RootPropertyName:
               case VMFunction::RootFunction:
               case VMFunction::RootCell:
                 // These are all handles to GCThing pointers.
                 min = reinterpret_cast<uintptr_t *>(footer->outParam<void *>());
                 break;
@@ -1216,17 +1216,17 @@ MarkJitExitFrame(JSTracer *trc, const Ji
             argBase += 2 * sizeof(void *);
             break;
         }
     }
 
     if (f->outParam == Type_Handle) {
         switch (f->outParamRootType) {
           case VMFunction::RootNone:
-            MOZ_CRASH("Handle outparam must have root type");
+            MOZ_ASSUME_UNREACHABLE("Handle outparam must have root type");
           case VMFunction::RootObject:
             gc::MarkObjectRoot(trc, footer->outParam<JSObject *>(), "ion-vm-out");
             break;
           case VMFunction::RootString:
           case VMFunction::RootPropertyName:
             gc::MarkStringRoot(trc, footer->outParam<JSString *>(), "ion-vm-out");
             break;
           case VMFunction::RootFunction:
@@ -1281,24 +1281,24 @@ MarkJitActivation(JSTracer *trc, const J
             break;
           case JitFrame_BaselineStub:
             MarkBaselineStubFrame(trc, frames);
             break;
           case JitFrame_IonJS:
             MarkIonJSFrame(trc, frames);
             break;
           case JitFrame_Unwound_IonJS:
-            MOZ_CRASH("JitFrame_Unwound_IonJS");
+            MOZ_ASSUME_UNREACHABLE("invalid");
           case JitFrame_Rectifier:
             MarkRectifierFrame(trc, frames);
             break;
           case JitFrame_Unwound_Rectifier:
             break;
           default:
-            MOZ_CRASH("unexpected frame type");
+            MOZ_ASSUME_UNREACHABLE("unexpected frame type");
         }
     }
 }
 
 void
 MarkJitActivations(PerThreadData *ptd, JSTracer *trc)
 {
     for (JitActivationIterator activations(ptd); !activations.done(); ++activations)
@@ -1510,17 +1510,17 @@ FromTypedPayload(JSValueType type, uintp
         return BooleanValue(!!payload);
       case JSVAL_TYPE_STRING:
         return FromStringPayload(payload);
       case JSVAL_TYPE_SYMBOL:
         return FromSymbolPayload(payload);
       case JSVAL_TYPE_OBJECT:
         return FromObjectPayload(payload);
       default:
-        MOZ_CRASH("unexpected type - needs payload");
+        MOZ_ASSUME_UNREACHABLE("unexpected type - needs payload");
     }
 }
 
 bool
 SnapshotIterator::allocationReadable(const RValueAllocation &alloc)
 {
     switch (alloc.mode()) {
       case RValueAllocation::DOUBLE_REG:
@@ -1598,17 +1598,17 @@ SnapshotIterator::allocationValue(const 
             return BooleanValue(ReadFrameBooleanSlot(fp_, alloc.stackOffset2()));
           case JSVAL_TYPE_STRING:
             return FromStringPayload(fromStack(alloc.stackOffset2()));
           case JSVAL_TYPE_SYMBOL:
             return FromSymbolPayload(fromStack(alloc.stackOffset2()));
           case JSVAL_TYPE_OBJECT:
             return FromObjectPayload(fromStack(alloc.stackOffset2()));
           default:
-            MOZ_CRASH("Unexpected type");
+            MOZ_ASSUME_UNREACHABLE("Unexpected type");
         }
       }
 
 #if defined(JS_NUNBOX32)
       case RValueAllocation::UNTYPED_REG_REG:
       {
         jsval_layout layout;
         layout.s.tag = (JSValueTag) fromRegister(alloc.reg());
@@ -1654,17 +1654,17 @@ SnapshotIterator::allocationValue(const 
         return IMPL_TO_JSVAL(layout);
       }
 #endif
 
       case RValueAllocation::RECOVER_INSTRUCTION:
         return fromInstructionResult(alloc.index());
 
       default:
-        MOZ_CRASH("huh?");
+        MOZ_ASSUME_UNREACHABLE("huh?");
     }
 }
 
 const RResumePoint *
 SnapshotIterator::resumePoint() const
 {
     return instruction()->toResumePoint();
 }
@@ -1765,20 +1765,20 @@ JitFrameIterator::ionScriptFromCalleeTok
       case CalleeToken_Function:
       case CalleeToken_Script:
         switch (mode_) {
           case SequentialExecution:
             return script()->ionScript();
           case ParallelExecution:
             return script()->parallelIonScript();
           default:
-            MOZ_CRASH("No such execution mode");
+            MOZ_ASSUME_UNREACHABLE("No such execution mode");
         }
       default:
-        MOZ_CRASH("unknown callee token type");
+        MOZ_ASSUME_UNREACHABLE("unknown callee token type");
     }
 }
 
 const SafepointIndex *
 JitFrameIterator::safepoint() const
 {
     if (!cachedSafepointIndex_)
         cachedSafepointIndex_ = ionScript()->getSafepointIndex(returnAddressToFp());
--- a/js/src/jit/IonFrames.h
+++ b/js/src/jit/IonFrames.h
@@ -66,17 +66,17 @@ static inline JSScript *
 ScriptFromCalleeToken(CalleeToken token)
 {
     switch (GetCalleeTokenTag(token)) {
       case CalleeToken_Script:
         return CalleeTokenToScript(token);
       case CalleeToken_Function:
         return CalleeTokenToFunction(token)->nonLazyScript();
     }
-    MOZ_CRASH("invalid callee token tag");
+    MOZ_ASSUME_UNREACHABLE("invalid callee token tag");
 }
 
 // In between every two frames lies a small header describing both frames. This
 // header, minimally, contains a returnAddress word and a descriptor word. The
 // descriptor describes the size and type of the previous frame, whereas the
 // returnAddress describes the address the newer frame (the callee) will return
 // to. The exact mechanism in which frames are laid out is architecture
 // dependent.
--- a/js/src/jit/IonMacroAssembler.cpp
+++ b/js/src/jit/IonMacroAssembler.cpp
@@ -292,17 +292,17 @@ StoreToTypedFloatArray(MacroAssembler &m
       case Scalar::Float64:
 #ifdef JS_MORE_DETERMINISTIC
         // See the comment in TypedArrayObjectTemplate::doubleToNative.
         masm.canonicalizeDouble(value);
 #endif
         masm.storeDouble(value, dest);
         break;
       default:
-        MOZ_CRASH("Invalid typed array type");
+        MOZ_ASSUME_UNREACHABLE("Invalid typed array type");
     }
 }
 
 void
 MacroAssembler::storeToTypedFloatArray(Scalar::Type arrayType, FloatRegister value,
                                        const BaseIndex &dest)
 {
     StoreToTypedFloatArray(*this, arrayType, value, dest);
@@ -358,17 +358,17 @@ MacroAssembler::loadFromTypedArray(Scala
             canonicalizeDouble(dest.fpu());
         }
         break;
       case Scalar::Float64:
         loadDouble(src, dest.fpu());
         canonicalizeDouble(dest.fpu());
         break;
       default:
-        MOZ_CRASH("Invalid typed array type");
+        MOZ_ASSUME_UNREACHABLE("Invalid typed array type");
     }
 }
 
 template void MacroAssembler::loadFromTypedArray(Scalar::Type arrayType, const Address &src, AnyRegister dest,
                                                  Register temp, Label *fail);
 template void MacroAssembler::loadFromTypedArray(Scalar::Type arrayType, const BaseIndex &src, AnyRegister dest,
                                                  Register temp, Label *fail);
 
@@ -419,17 +419,17 @@ MacroAssembler::loadFromTypedArray(Scala
         boxDouble(ScratchDoubleReg, dest);
         break;
       case Scalar::Float64:
         loadFromTypedArray(arrayType, src, AnyRegister(ScratchDoubleReg), dest.scratchReg(),
                            nullptr);
         boxDouble(ScratchDoubleReg, dest);
         break;
       default:
-        MOZ_CRASH("Invalid typed array type");
+        MOZ_ASSUME_UNREACHABLE("Invalid typed array type");
     }
 }
 
 template void MacroAssembler::loadFromTypedArray(Scalar::Type arrayType, const Address &src, const ValueOperand &dest,
                                                  bool allowDouble, Register temp, Label *fail);
 template void MacroAssembler::loadFromTypedArray(Scalar::Type arrayType, const BaseIndex &src, const ValueOperand &dest,
                                                  bool allowDouble, Register temp, Label *fail);
 
@@ -973,17 +973,17 @@ MacroAssembler::loadStringChar(Register 
 
 void
 MacroAssembler::checkInterruptFlagPar(Register tempReg, Label *fail)
 {
 #ifdef JS_THREADSAFE
     movePtr(ImmPtr(GetIonContext()->runtime->addressOfInterruptPar()), tempReg);
     branch32(Assembler::NonZero, Address(tempReg, 0), Imm32(0), fail);
 #else
-    MOZ_CRASH("JSRuntime::interruptPar doesn't exist on non-threadsafe builds.");
+    MOZ_ASSUME_UNREACHABLE("JSRuntime::interruptPar doesn't exist on non-threadsafe builds.");
 #endif
 }
 
 // Save an exit frame (which must be aligned to the stack pointer) to
 // PerThreadData::jitTop of the main thread.
 void
 MacroAssembler::linkExitFrame()
 {
@@ -1231,17 +1231,17 @@ MacroAssembler::loadContext(Register cxR
       case SequentialExecution:
         // The scratch register is not used for sequential execution.
         loadJSContext(cxReg);
         break;
       case ParallelExecution:
         loadForkJoinContext(cxReg, scratch);
         break;
       default:
-        MOZ_CRASH("No such execution mode");
+        MOZ_ASSUME_UNREACHABLE("No such execution mode");
     }
 }
 
 void
 MacroAssembler::enterParallelExitFrameAndLoadContext(const VMFunction *f, Register cx,
                                                      Register scratch)
 {
     loadForkJoinContext(cx, scratch);
@@ -1274,17 +1274,17 @@ MacroAssembler::enterExitFrameAndLoadCon
         // The scratch register is not used for sequential execution.
         enterExitFrame(f);
         loadJSContext(cxReg);
         break;
       case ParallelExecution:
         enterParallelExitFrameAndLoadContext(f, cxReg, scratch);
         break;
       default:
-        MOZ_CRASH("No such execution mode");
+        MOZ_ASSUME_UNREACHABLE("No such execution mode");
     }
 }
 
 void
 MacroAssembler::enterFakeExitFrame(Register cxReg, Register scratch,
                                    ExecutionMode executionMode,
                                    JitCode *codeVal)
 {
@@ -1292,17 +1292,17 @@ MacroAssembler::enterFakeExitFrame(Regis
       case SequentialExecution:
         // The cx and scratch registers are not used for sequential execution.
         enterFakeExitFrame(codeVal);
         break;
       case ParallelExecution:
         enterFakeParallelExitFrame(cxReg, scratch, codeVal);
         break;
       default:
-        MOZ_CRASH("No such execution mode");
+        MOZ_ASSUME_UNREACHABLE("No such execution mode");
     }
 }
 
 void
 MacroAssembler::handleFailure(ExecutionMode executionMode)
 {
     // Re-entry code is irrelevant because the exception will leave the
     // running function and never come back
@@ -1314,17 +1314,17 @@ MacroAssembler::handleFailure(ExecutionM
     switch (executionMode) {
       case SequentialExecution:
         handler = JS_FUNC_TO_DATA_PTR(void *, jit::HandleException);
         break;
       case ParallelExecution:
         handler = JS_FUNC_TO_DATA_PTR(void *, jit::HandleParallelFailure);
         break;
       default:
-        MOZ_CRASH("No such execution mode");
+        MOZ_ASSUME_UNREACHABLE("No such execution mode");
     }
     MacroAssemblerSpecific::handleFailureWithHandler(handler);
 
     // Doesn't actually emit code, but balances the leave()
     if (sps_)
         sps_->reenter(*this, InvalidReg);
 }
 
@@ -1607,17 +1607,17 @@ MacroAssembler::convertValueToFloatingPo
     return true;
 }
 
 void
 MacroAssembler::PushEmptyRooted(VMFunction::RootType rootType)
 {
     switch (rootType) {
       case VMFunction::RootNone:
-        MOZ_CRASH("Handle must have root type");
+        MOZ_ASSUME_UNREACHABLE("Handle must have root type");
       case VMFunction::RootObject:
       case VMFunction::RootString:
       case VMFunction::RootPropertyName:
       case VMFunction::RootFunction:
       case VMFunction::RootCell:
         Push(ImmPtr(nullptr));
         break;
       case VMFunction::RootValue:
@@ -1627,17 +1627,17 @@ MacroAssembler::PushEmptyRooted(VMFuncti
 }
 
 void
 MacroAssembler::popRooted(VMFunction::RootType rootType, Register cellReg,
                           const ValueOperand &valueReg)
 {
     switch (rootType) {
       case VMFunction::RootNone:
-        MOZ_CRASH("Handle must have root type");
+        MOZ_ASSUME_UNREACHABLE("Handle must have root type");
       case VMFunction::RootObject:
       case VMFunction::RootString:
       case VMFunction::RootPropertyName:
       case VMFunction::RootFunction:
       case VMFunction::RootCell:
         Pop(cellReg);
         break;
       case VMFunction::RootValue:
@@ -1698,17 +1698,17 @@ MacroAssembler::convertTypedOrValueToFlo
       case MIRType_String:
       case MIRType_Symbol:
         jump(fail);
         break;
       case MIRType_Undefined:
         loadConstantFloatingPoint(GenericNaN(), float(GenericNaN()), output, outputType);
         break;
       default:
-        MOZ_CRASH("Bad MIRType");
+        MOZ_ASSUME_UNREACHABLE("Bad MIRType");
     }
 }
 
 void
 MacroAssembler::convertDoubleToInt(FloatRegister src, Register output, FloatRegister temp,
                                    Label *truncateFail, Label *fail,
                                    IntConversionBehavior behavior)
 {
@@ -1913,17 +1913,17 @@ MacroAssembler::convertTypedOrValueToInt
         convertDoubleToInt(temp, output, temp, nullptr, fail, behavior);
         break;
       case MIRType_String:
       case MIRType_Symbol:
       case MIRType_Object:
         jump(fail);
         break;
       default:
-        MOZ_CRASH("Bad MIRType");
+        MOZ_ASSUME_UNREACHABLE("Bad MIRType");
     }
 }
 
 void
 MacroAssembler::finish()
 {
     if (sequentialFailureLabel_.used()) {
         bind(&sequentialFailureLabel_);
@@ -1999,17 +1999,17 @@ MacroAssembler::branchEqualTypeIfNeeded(
             break;
           case MIRType_Symbol:
             branchTestSymbol(Equal, tag, label);
             break;
           case MIRType_Object:
             branchTestObject(Equal, tag, label);
             break;
           default:
-            MOZ_CRASH("Unsupported type");
+            MOZ_ASSUME_UNREACHABLE("Unsupported type");
         }
     }
 }
 
 
 // If a pseudostack frame has this as its label, its stack pointer
 // field points to the registers saved on entry to JIT code.  A native
 // stack unwinder could use that information to continue unwinding
--- a/js/src/jit/IonMacroAssembler.h
+++ b/js/src/jit/IonMacroAssembler.h
@@ -134,17 +134,17 @@ class MacroAssembler : public MacroAssem
             if (type_.isPrimitive()) {
                 if (type_.isMagicArguments())
                     mirType = MIRType_MagicOptimizedArguments;
                 else
                     mirType = MIRTypeFromValueType(type_.primitive());
             } else if (type_.isAnyObject()) {
                 mirType = MIRType_Object;
             } else {
-                MOZ_CRASH("Unknown conversion to mirtype");
+                MOZ_ASSUME_UNREACHABLE("Unknown conversion to mirtype");
             }
 
             if (mirType == MIRType_Double)
                 masm.branchTestNumber(cond(), reg(), jump());
             else
                 masm.branchTestMIRType(cond(), reg(), mirType, jump());
         }
 
@@ -336,17 +336,17 @@ class MacroAssembler : public MacroAssem
           case MIRType_String:    return branchTestString(cond, val, label);
           case MIRType_Symbol:    return branchTestSymbol(cond, val, label);
           case MIRType_Object:    return branchTestObject(cond, val, label);
           case MIRType_Double:    return branchTestDouble(cond, val, label);
           case MIRType_MagicOptimizedArguments: // Fall through.
           case MIRType_MagicIsConstructing:
           case MIRType_MagicHole: return branchTestMagic(cond, val, label);
           default:
-            MOZ_CRASH("Bad MIRType");
+            MOZ_ASSUME_UNREACHABLE("Bad MIRType");
         }
     }
 
     // Branches to |label| if |reg| is false. |reg| should be a C++ bool.
     void branchIfFalseBool(Register reg, Label *label) {
         // Note that C++ bool is only 1 byte, so ignore the higher-order bits.
         branchTest32(Assembler::Zero, reg, Imm32(0xFF), label);
     }
@@ -726,17 +726,17 @@ class MacroAssembler : public MacroAssem
           case Scalar::Uint16:
             store16(value, dest);
             break;
           case Scalar::Int32:
           case Scalar::Uint32:
             store32(value, dest);
             break;
           default:
-            MOZ_CRASH("Invalid typed array type");
+            MOZ_ASSUME_UNREACHABLE("Invalid typed array type");
         }
     }
 
     void storeToTypedFloatArray(Scalar::Type arrayType, FloatRegister value, const BaseIndex &dest);
     void storeToTypedFloatArray(Scalar::Type arrayType, FloatRegister value, const Address &dest);
 
     Register extractString(const Address &address, Register scratch) {
         return extractObject(address, scratch);
@@ -1154,17 +1154,17 @@ class MacroAssembler : public MacroAssem
         // Exceptions are currently handled the same way as sequential failures.
         return &sequentialFailureLabel_;
     }
 
     Label *failureLabel(ExecutionMode executionMode) {
         switch (executionMode) {
           case SequentialExecution: return &sequentialFailureLabel_;
           case ParallelExecution: return &parallelFailureLabel_;
-          default: MOZ_CRASH("Unexpected execution mode");
+          default: MOZ_ASSUME_UNREACHABLE("Unexpected execution mode");
         }
     }
 
     void finish();
 
     void assumeUnreachable(const char *output);
     void printf(const char *output);
     void printf(const char *output, Register value);
@@ -1441,17 +1441,17 @@ JSOpToDoubleCondition(JSOp op)
         return Assembler::DoubleLessThan;
       case JSOP_LE:
         return Assembler::DoubleLessThanOrEqual;
       case JSOP_GT:
         return Assembler::DoubleGreaterThan;
       case JSOP_GE:
         return Assembler::DoubleGreaterThanOrEqual;
       default:
-        MOZ_CRASH("Unexpected comparison operation");
+        MOZ_ASSUME_UNREACHABLE("Unexpected comparison operation");
     }
 }
 
 // Note: the op may have been inverted during lowering (to put constants in a
 // position where they can be immediates), so it is important to use the
 // lir->jsop() instead of the mir->jsop() when it is present.
 static inline Assembler::Condition
 JSOpToCondition(JSOp op, bool isSigned)
@@ -1468,17 +1468,17 @@ JSOpToCondition(JSOp op, bool isSigned)
             return Assembler::LessThan;
           case JSOP_LE:
             return Assembler::LessThanOrEqual;
           case JSOP_GT:
             return Assembler::GreaterThan;
           case JSOP_GE:
             return Assembler::GreaterThanOrEqual;
           default:
-            MOZ_CRASH("Unrecognized comparison operation");
+            MOZ_ASSUME_UNREACHABLE("Unrecognized comparison operation");
         }
     } else {
         switch (op) {
           case JSOP_EQ:
           case JSOP_STRICTEQ:
             return Assembler::Equal;
           case JSOP_NE:
           case JSOP_STRICTNE:
@@ -1487,17 +1487,17 @@ JSOpToCondition(JSOp op, bool isSigned)
             return Assembler::Below;
           case JSOP_LE:
             return Assembler::BelowOrEqual;
           case JSOP_GT:
             return Assembler::Above;
           case JSOP_GE:
             return Assembler::AboveOrEqual;
           default:
-            MOZ_CRASH("Unrecognized comparison operation");
+            MOZ_ASSUME_UNREACHABLE("Unrecognized comparison operation");
         }
     }
 }
 
 } // namespace jit
 } // namespace js
 
 #endif // JS_ION
--- a/js/src/jit/IonOptimizationLevels.cpp
+++ b/js/src/jit/IonOptimizationLevels.cpp
@@ -112,17 +112,17 @@ OptimizationInfos::OptimizationInfos()
 OptimizationLevel
 OptimizationInfos::nextLevel(OptimizationLevel level) const
 {
     JS_ASSERT(!isLastLevel(level));
     switch (level) {
       case Optimization_DontCompile:
         return Optimization_Normal;
       default:
-        MOZ_CRASH("Unknown optimization level.");
+        MOZ_ASSUME_UNREACHABLE("Unknown optimization level.");
     }
 }
 
 OptimizationLevel
 OptimizationInfos::firstLevel() const
 {
     return nextLevel(Optimization_DontCompile);
 }
--- a/js/src/jit/IonOptimizationLevels.h
+++ b/js/src/jit/IonOptimizationLevels.h
@@ -33,17 +33,17 @@ OptimizationLevelString(OptimizationLeve
     switch (level) {
       case Optimization_DontCompile:
         return "Optimization_DontCompile";
       case Optimization_Normal:
         return "Optimization_Normal";
       case Optimization_AsmJS:
         return "Optimization_AsmJS";
       default:
-        MOZ_CRASH("Invalid OptimizationLevel");
+        MOZ_ASSUME_UNREACHABLE("Invalid OptimizationLevel");
     }
 }
 #endif
 
 class OptimizationInfo
 {
   public:
     OptimizationLevel level_;
--- a/js/src/jit/IonTypes.h
+++ b/js/src/jit/IonTypes.h
@@ -216,17 +216,17 @@ BailoutKindString(BailoutKind kind)
         return "Bailout_BoundsCheck";
       case Bailout_Neutered:
         return "Bailout_Neutered";
       case Bailout_ShapeGuard:
         return "Bailout_ShapeGuard";
       case Bailout_IonExceptionDebugMode:
         return "Bailout_IonExceptionDebugMode";
       default:
-        MOZ_CRASH("Invalid BailoutKind");
+        MOZ_ASSUME_UNREACHABLE("Invalid BailoutKind");
     }
 }
 
 static const uint32_t ELEMENT_TYPE_BITS = 5;
 static const uint32_t ELEMENT_TYPE_SHIFT = 0;
 static const uint32_t ELEMENT_TYPE_MASK = (1 << ELEMENT_TYPE_BITS) - 1;
 static const uint32_t VECTOR_SCALE_BITS = 2;
 static const uint32_t VECTOR_SCALE_SHIFT = ELEMENT_TYPE_BITS + ELEMENT_TYPE_SHIFT;
@@ -296,17 +296,17 @@ MIRTypeFromValueType(JSValueType type)
         return MIRType_Boolean;
       case JSVAL_TYPE_NULL:
         return MIRType_Null;
       case JSVAL_TYPE_OBJECT:
         return MIRType_Object;
       case JSVAL_TYPE_UNKNOWN:
         return MIRType_Value;
       default:
-        MOZ_CRASH("unexpected jsval type");
+        MOZ_ASSUME_UNREACHABLE("unexpected jsval type");
     }
 }
 
 static inline JSValueType
 ValueTypeFromMIRType(MIRType type)
 {
   switch (type) {
     case MIRType_Undefined:
@@ -379,17 +379,17 @@ StringFromMIRType(MIRType type)
       return "Slots";
     case MIRType_Elements:
       return "Elements";
     case MIRType_Pointer:
       return "Pointer";
     case MIRType_ForkJoinContext:
       return "ForkJoinContext";
     default:
-      MOZ_CRASH("Unknown MIRType.");
+      MOZ_ASSUME_UNREACHABLE("Unknown MIRType.");
   }
 }
 
 static inline bool
 IsNumberType(MIRType type)
 {
     return type == MIRType_Int32 || type == MIRType_Double || type == MIRType_Float32;
 }
--- a/js/src/jit/JitCompartment.h
+++ b/js/src/jit/JitCompartment.h
@@ -306,17 +306,17 @@ class JitRuntime
     JitCode *debugTrapHandler(JSContext *cx);
     JitCode *getBaselineDebugModeOSRHandler(JSContext *cx);
     void *getBaselineDebugModeOSRHandlerAddress(JSContext *cx, bool popFrameReg);
 
     JitCode *getGenericBailoutHandler(ExecutionMode mode) const {
         switch (mode) {
           case SequentialExecution: return bailoutHandler_;
           case ParallelExecution:   return parallelBailoutHandler_;
-          default:                  MOZ_CRASH("No such execution mode");
+          default:                  MOZ_ASSUME_UNREACHABLE("No such execution mode");
         }
     }
 
     JitCode *getExceptionTail() const {
         return exceptionTail_;
     }
 
     JitCode *getBailoutTail() const {
@@ -324,17 +324,17 @@ class JitRuntime
     }
 
     JitCode *getBailoutTable(const FrameSizeClass &frameClass) const;
 
     JitCode *getArgumentsRectifier(ExecutionMode mode) const {
         switch (mode) {
           case SequentialExecution: return argumentsRectifier_;
           case ParallelExecution:   return parallelArgumentsRectifier_;
-          default:                  MOZ_CRASH("No such execution mode");
+          default:                  MOZ_ASSUME_UNREACHABLE("No such execution mode");
         }
     }
 
     void *getArgumentsRectifierReturnAddr() const {
         return argumentsRectifierReturnAddr_;
     }
 
     JitCode *getInvalidationThunk() const {
@@ -484,17 +484,17 @@ class JitCompartment
 
     void mark(JSTracer *trc, JSCompartment *compartment);
     void sweep(FreeOp *fop, JSCompartment *compartment);
 
     JitCode *stringConcatStubNoBarrier(ExecutionMode mode) const {
         switch (mode) {
           case SequentialExecution: return stringConcatStub_;
           case ParallelExecution:   return parallelStringConcatStub_;
-          default:                  MOZ_CRASH("No such execution mode");
+          default:                  MOZ_ASSUME_UNREACHABLE("No such execution mode");
         }
     }
 };
 
 // Called from JSCompartment::discardJitCode().
 void InvalidateAll(FreeOp *fop, JS::Zone *zone);
 template <ExecutionMode mode>
 void FinishInvalidation(FreeOp *fop, JSScript *script);
--- a/js/src/jit/LIR-Common.h
+++ b/js/src/jit/LIR-Common.h
@@ -5650,29 +5650,29 @@ class LPhi MOZ_FINAL : public LInstructi
     void setOperand(size_t index, const LAllocation &a) {
         JS_ASSERT(index < numOperands());
         inputs_[index] = a;
     }
     size_t numTemps() const {
         return 0;
     }
     LDefinition *getTemp(size_t index) {
-        MOZ_CRASH("no temps");
+        MOZ_ASSUME_UNREACHABLE("no temps");
     }
     void setTemp(size_t index, const LDefinition &temp) {
-        MOZ_CRASH("no temps");
+        MOZ_ASSUME_UNREACHABLE("no temps");
     }
     size_t numSuccessors() const {
         return 0;
     }
     MBasicBlock *getSuccessor(size_t i) const {
-        MOZ_CRASH("no successors");
+        MOZ_ASSUME_UNREACHABLE("no successors");
     }
     void setSuccessor(size_t i, MBasicBlock *) {
-        MOZ_CRASH("no successors");
+        MOZ_ASSUME_UNREACHABLE("no successors");
     }
 
     virtual void printInfo(FILE *fp) {
         printOperands(fp);
     }
 };
 
 class LIn : public LCallInstructionHelper<1, BOX_PIECES+1, 0>
@@ -5983,29 +5983,29 @@ class LAsmJSCall MOZ_FINAL : public LIns
     void setOperand(size_t index, const LAllocation &a) {
         JS_ASSERT(index < numOperands_);
         operands_[index] = a;
     }
     size_t numTemps() const {
         return 0;
     }
     LDefinition *getTemp(size_t index) {
-        MOZ_CRASH("no temps");
+        MOZ_ASSUME_UNREACHABLE("no temps");
     }
     void setTemp(size_t index, const LDefinition &a) {
-        MOZ_CRASH("no temps");
+        MOZ_ASSUME_UNREACHABLE("no temps");
     }
     size_t numSuccessors() const {
         return 0;
     }
     MBasicBlock *getSuccessor(size_t i) const {
-        MOZ_CRASH("no successors");
+        MOZ_ASSUME_UNREACHABLE("no successors");
     }
     void setSuccessor(size_t i, MBasicBlock *) {
-        MOZ_CRASH("no successors");
+        MOZ_ASSUME_UNREACHABLE("no successors");
     }
 };
 
 class LAssertRangeI : public LInstructionHelper<0, 1, 0>
 {
   public:
     LIR_HEADER(AssertRangeI)
 
--- a/js/src/jit/LIR.cpp
+++ b/js/src/jit/LIR.cpp
@@ -403,17 +403,17 @@ PrintUse(char *buf, size_t size, const L
         break;
       case LUse::KEEPALIVE:
         JS_snprintf(buf, size, "v%d:*", use->virtualRegister());
         break;
       case LUse::RECOVERED_INPUT:
         JS_snprintf(buf, size, "v%d:**", use->virtualRegister());
         break;
       default:
-        MOZ_CRASH("invalid use policy");
+        MOZ_ASSUME_UNREACHABLE("invalid use policy");
     }
 }
 
 const char *
 LAllocation::toString() const
 {
     // Not reentrant!
     static char buf[40];
@@ -433,17 +433,17 @@ LAllocation::toString() const
         return buf;
       case LAllocation::ARGUMENT_SLOT:
         JS_snprintf(buf, sizeof(buf), "arg:%d", toArgument()->index());
         return buf;
       case LAllocation::USE:
         PrintUse(buf, sizeof(buf), toUse());
         return buf;
       default:
-        MOZ_CRASH("what?");
+        MOZ_ASSUME_UNREACHABLE("what?");
     }
 }
 #endif // DEBUG
 
 void
 LAllocation::dump() const
 {
     fprintf(stderr, "%s\n", toString());
--- a/js/src/jit/LIR.h
+++ b/js/src/jit/LIR.h
@@ -565,17 +565,17 @@ class LDefinition
           case MIRType_Slots:
           case MIRType_Elements:
             return LDefinition::SLOTS;
           case MIRType_Pointer:
             return LDefinition::GENERAL;
           case MIRType_ForkJoinContext:
             return LDefinition::GENERAL;
           default:
-            MOZ_CRASH("unexpected type");
+            MOZ_ASSUME_UNREACHABLE("unexpected type");
         }
     }
 
 #ifdef DEBUG
     const char *toString() const;
 #else
     const char *toString() const { return "???"; }
 #endif
@@ -745,17 +745,17 @@ class LInstructionVisitor
 
     LInstructionVisitor()
       : ins_(nullptr),
         lastPC_(nullptr),
         lastNotInlinedPC_(nullptr)
     {}
 
   public:
-#define VISIT_INS(op) virtual bool visit##op(L##op *) { MOZ_CRASH("NYI: " #op); }
+#define VISIT_INS(op) virtual bool visit##op(L##op *) { MOZ_ASSUME_UNREACHABLE("NYI: " #op); }
     LIR_OPCODE_LIST(VISIT_INS)
 #undef VISIT_INS
 };
 
 typedef InlineList<LInstruction>::iterator LInstructionIterator;
 typedef InlineList<LInstruction>::reverse_iterator LInstructionReverseIterator;
 
 class LPhi;
--- a/js/src/jit/LiveRangeAllocator.cpp
+++ b/js/src/jit/LiveRangeAllocator.cpp
@@ -28,17 +28,17 @@ Requirement::priority() const
 
       case Requirement::REGISTER:
         return 1;
 
       case Requirement::NONE:
         return 2;
 
       default:
-        MOZ_CRASH("Unknown requirement kind.");
+        MOZ_ASSUME_UNREACHABLE("Unknown requirement kind.");
     }
 }
 
 const char *
 Requirement::toString() const
 {
 #ifdef DEBUG
     // Not reentrant!
--- a/js/src/jit/LiveRangeAllocator.h
+++ b/js/src/jit/LiveRangeAllocator.h
@@ -154,17 +154,17 @@ UseCompatibleWith(const LUse *use, LAllo
         return alloc.isRegister() || alloc.isMemory();
       case LUse::REGISTER:
         return alloc.isRegister();
       case LUse::FIXED:
           // Fixed uses are handled using fixed intervals. The
           // UsePosition is only used as hint.
         return alloc.isRegister();
       default:
-        MOZ_CRASH("Unknown use policy");
+        MOZ_ASSUME_UNREACHABLE("Unknown use policy");
     }
 }
 
 #ifdef DEBUG
 
 static inline bool
 DefinitionCompatibleWith(LInstruction *ins, const LDefinition *def, LAllocation alloc)
 {
@@ -183,17 +183,17 @@ DefinitionCompatibleWith(LInstruction *i
         return alloc == *def->output();
       case LDefinition::MUST_REUSE_INPUT:
         if (!alloc.isRegister() || !ins->numOperands())
             return false;
         return alloc == *ins->getOperand(def->getReusedInput());
       case LDefinition::PASSTHROUGH:
         return true;
       default:
-        MOZ_CRASH("Unknown definition policy");
+        MOZ_ASSUME_UNREACHABLE("Unknown definition policy");
     }
 }
 
 #endif // DEBUG
 
 static inline LDefinition *
 FindReusingDefinition(LInstruction *ins, LAllocation *alloc)
 {
--- a/js/src/jit/Lowering.cpp
+++ b/js/src/jit/Lowering.cpp
@@ -1027,17 +1027,17 @@ LIRGenerator::visitCompare(MCompare *com
         LCompareV *lir = new(alloc()) LCompareV();
         if (!useBoxAtStart(lir, LCompareV::LhsInput, left))
             return false;
         if (!useBoxAtStart(lir, LCompareV::RhsInput, right))
             return false;
         return define(lir, comp);
     }
 
-    MOZ_CRASH("Unrecognized compare type.");
+    MOZ_ASSUME_UNREACHABLE("Unrecognized compare type.");
 }
 
 bool
 LIRGenerator::lowerBitOp(JSOp op, MInstruction *ins)
 {
     MDefinition *lhs = ins->getOperand(0);
     MDefinition *rhs = ins->getOperand(1);
 
@@ -1764,17 +1764,17 @@ LIRGenerator::visitToDouble(MToDouble *c
       }
 
       case MIRType_Double:
         return redefine(convert, opd);
 
       default:
         // Objects might be effectful.
         // Strings are complicated - we don't handle them yet.
-        MOZ_CRASH("unexpected type");
+        MOZ_ASSUME_UNREACHABLE("unexpected type");
     }
 }
 
 bool
 LIRGenerator::visitToFloat32(MToFloat32 *convert)
 {
     MDefinition *opd = convert->input();
     mozilla::DebugOnly<MToFloat32::ConversionKind> conversion = convert->conversion();
@@ -1813,17 +1813,17 @@ LIRGenerator::visitToFloat32(MToFloat32 
       }
 
       case MIRType_Float32:
         return redefine(convert, opd);
 
       default:
         // Objects might be effectful.
         // Strings are complicated - we don't handle them yet.
-        MOZ_CRASH("unexpected type");
+        MOZ_ASSUME_UNREACHABLE("unexpected type");
         return false;
     }
 }
 
 bool
 LIRGenerator::visitToInt32(MToInt32 *convert)
 {
     MDefinition *opd = convert->input();
@@ -1859,21 +1859,21 @@ LIRGenerator::visitToInt32(MToInt32 *con
         return assignSnapshot(lir, Bailout_PrecisionLoss) && define(lir, convert);
       }
 
       case MIRType_String:
       case MIRType_Symbol:
       case MIRType_Object:
       case MIRType_Undefined:
         // Objects might be effectful. Undefined and symbols coerce to NaN, not int32.
-        MOZ_CRASH("ToInt32 invalid input type");
+        MOZ_ASSUME_UNREACHABLE("ToInt32 invalid input type");
         return false;
 
       default:
-        MOZ_CRASH("unexpected type");
+        MOZ_ASSUME_UNREACHABLE("unexpected type");
     }
 }
 
 bool
 LIRGenerator::visitTruncateToInt32(MTruncateToInt32 *truncate)
 {
     MDefinition *opd = truncate->input();
 
@@ -1902,17 +1902,17 @@ LIRGenerator::visitTruncateToInt32(MTrun
         return lowerTruncateDToInt32(truncate);
 
       case MIRType_Float32:
         return lowerTruncateFToInt32(truncate);
 
       default:
         // Objects might be effectful.
         // Strings are complicated - we don't handle them yet.
-        MOZ_CRASH("unexpected type");
+        MOZ_ASSUME_UNREACHABLE("unexpected type");
     }
 }
 
 bool
 LIRGenerator::visitToString(MToString *ins)
 {
     MDefinition *opd = ins->input();
 
@@ -1961,17 +1961,17 @@ LIRGenerator::visitToString(MToString *i
             return false;
         if (!define(lir, ins))
             return false;
         return assignSafepoint(lir, ins);
       }
 
       default:
         // Float32 and objects are not supported.
-        MOZ_CRASH("unexpected type");
+        MOZ_ASSUME_UNREACHABLE("unexpected type");
     }
 }
 
 static bool
 MustCloneRegExpForCall(MCall *call, uint32_t useIndex)
 {
     // We have a regex literal flowing into a call. Return |false| iff
     // this is a native call that does not let the regex escape.
@@ -2173,17 +2173,17 @@ bool
 LIRGenerator::visitLoadSlot(MLoadSlot *ins)
 {
     switch (ins->type()) {
       case MIRType_Value:
         return defineBox(new(alloc()) LLoadSlotV(useRegister(ins->slots())), ins);
 
       case MIRType_Undefined:
       case MIRType_Null:
-        MOZ_CRASH("typed load must have a payload");
+        MOZ_ASSUME_UNREACHABLE("typed load must have a payload");
 
       default:
         return define(new(alloc()) LLoadSlotT(useRegister(ins->slots())), ins);
     }
 }
 
 bool
 LIRGenerator::visitFunctionEnvironment(MFunctionEnvironment *ins)
@@ -2272,17 +2272,17 @@ LIRGenerator::visitStoreSlot(MStoreSlot 
         if (!useBox(lir, LStoreSlotV::Value, ins->value()))
             return false;
         return add(lir, ins);
 
       case MIRType_Double:
         return add(new(alloc()) LStoreSlotT(useRegister(ins->slots()), useRegister(ins->value())), ins);
 
       case MIRType_Float32:
-        MOZ_CRASH("Float32 shouldn't be stored in a slot.");
+        MOZ_ASSUME_UNREACHABLE("Float32 shouldn't be stored in a slot.");
 
       default:
         return add(new(alloc()) LStoreSlotT(useRegister(ins->slots()), useRegisterOrConstant(ins->value())),
                    ins);
     }
 
     return true;
 }
@@ -2515,17 +2515,17 @@ LIRGenerator::visitNot(MNot *ins)
 
         LNotV *lir = new(alloc()) LNotV(tempDouble(), temp0, temp1);
         if (!useBox(lir, LNotV::Input, op))
             return false;
         return define(lir, ins);
       }
 
       default:
-        MOZ_CRASH("Unexpected MIRType.");
+        MOZ_ASSUME_UNREACHABLE("Unexpected MIRType.");
     }
 }
 
 bool
 LIRGenerator::visitNeuterCheck(MNeuterCheck *ins)
 {
     LNeuterCheck *chk = new(alloc()) LNeuterCheck(useRegister(ins->object()),
                                                   temp());
@@ -2591,20 +2591,19 @@ LIRGenerator::visitLoadElement(MLoadElem
       case MIRType_Value:
       {
         LLoadElementV *lir = new(alloc()) LLoadElementV(useRegister(ins->elements()),
                                                         useRegisterOrConstant(ins->index()));
         if (ins->fallible() && !assignSnapshot(lir, Bailout_Hole))
             return false;
         return defineBox(lir, ins);
       }
-
       case MIRType_Undefined:
       case MIRType_Null:
-        MOZ_CRASH("typed load must have a payload");
+        MOZ_ASSUME_UNREACHABLE("typed load must have a payload");
 
       default:
       {
         LLoadElementT *lir = new(alloc()) LLoadElementT(useRegister(ins->elements()),
                                                         useRegisterOrConstant(ins->index()));
         if (ins->fallible() && !assignSnapshot(lir, Bailout_Hole))
             return false;
         return define(lir, ins);
@@ -2702,17 +2701,17 @@ LIRGenerator::visitArrayPopShift(MArrayP
     switch (ins->type()) {
       case MIRType_Value:
       {
         LArrayPopShiftV *lir = new(alloc()) LArrayPopShiftV(object, temp(), temp());
         return defineBox(lir, ins) && assignSafepoint(lir, ins);
       }
       case MIRType_Undefined:
       case MIRType_Null:
-        MOZ_CRASH("typed load must have a payload");
+        MOZ_ASSUME_UNREACHABLE("typed load must have a payload");
 
       default:
       {
         LArrayPopShiftT *lir = new(alloc()) LArrayPopShiftT(object, temp(), temp());
         return define(lir, ins) && assignSafepoint(lir, ins);
       }
     }
 }
@@ -2811,17 +2810,17 @@ LIRGenerator::visitClampToUint8(MClampTo
         if (!useBox(lir, LClampVToUint8::Input, in))
             return false;
         return assignSnapshot(lir, Bailout_NonPrimitiveInput)
                && define(lir, ins)
                && assignSafepoint(lir, ins);
       }
 
       default:
-        MOZ_CRASH("unexpected type");
+        MOZ_ASSUME_UNREACHABLE("unexpected type");
     }
 }
 
 bool
 LIRGenerator::visitLoadTypedArrayElementHole(MLoadTypedArrayElementHole *ins)
 {
     JS_ASSERT(ins->object()->type() == MIRType_Object);
     JS_ASSERT(ins->index()->type() == MIRType_Int32);
@@ -3124,17 +3123,18 @@ LIRGenerator::visitAssertRange(MAssertRa
       }
       case MIRType_Value:
         lir = new(alloc()) LAssertRangeV(tempToUnbox(), tempDouble(), tempDouble());
         if (!useBox(lir, LAssertRangeV::Input, input))
             return false;
         break;
 
       default:
-        MOZ_CRASH("Unexpected Range for MIRType");
+        MOZ_ASSUME_UNREACHABLE("Unexpected Range for MIRType");
+        break;
     }
 
     lir->setMir(ins);
     return add(lir);
 }
 
 bool
 LIRGenerator::visitCallGetProperty(MCallGetProperty *ins)
@@ -3527,17 +3527,17 @@ LIRGenerator::visitAsmJSReturn(MAsmJSRet
     LAsmJSReturn *lir = new(alloc()) LAsmJSReturn;
     if (rval->type() == MIRType_Float32)
         lir->setOperand(0, useFixed(rval, ReturnFloat32Reg));
     else if (rval->type() == MIRType_Double)
         lir->setOperand(0, useFixed(rval, ReturnDoubleReg));
     else if (rval->type() == MIRType_Int32)
         lir->setOperand(0, useFixed(rval, ReturnReg));
     else
-        MOZ_CRASH("Unexpected asm.js return type");
+        MOZ_ASSUME_UNREACHABLE("Unexpected asm.js return type");
     return add(lir);
 }
 
 bool
 LIRGenerator::visitAsmJSVoidReturn(MAsmJSVoidReturn *ins)
 {
     return add(new(alloc()) LAsmJSVoidReturn);
 }
--- a/js/src/jit/MCallOptimize.cpp
+++ b/js/src/jit/MCallOptimize.cpp
@@ -1430,17 +1430,17 @@ IonBuilder::inlineUnsafePutElements(Call
         }
 
         if (elementAccessIsTypedObjectArrayOfScalarType(obj, id, &arrayType)) {
             if (!inlineUnsafeSetTypedObjectArrayElement(callInfo, base, arrayType))
                 return InliningStatus_Error;
             continue;
         }
 
-        MOZ_CRASH("Element access not dense array nor typed array");
+        MOZ_ASSUME_UNREACHABLE("Element access not dense array nor typed array");
     }
 
     return InliningStatus_Inlined;
 }
 
 bool
 IonBuilder::elementAccessIsTypedObjectArrayOfScalarType(MDefinition* obj, MDefinition* id,
                                                         Scalar::Type *arrayType)
@@ -1545,17 +1545,17 @@ IonBuilder::inlineForceSequentialOrInPar
       }
 
       default:
         // In sequential mode, leave as is, because we'd have to
         // access the "in warmup" flag of the runtime.
         return InliningStatus_NotInlined;
     }
 
-    MOZ_CRASH("Invalid execution mode");
+    MOZ_ASSUME_UNREACHABLE("Invalid execution mode");
 }
 
 IonBuilder::InliningStatus
 IonBuilder::inlineForkJoinGetSlice(CallInfo &callInfo)
 {
     if (info().executionMode() != ParallelExecution)
         return InliningStatus_NotInlined;
 
@@ -1583,17 +1583,17 @@ IonBuilder::inlineForkJoinGetSlice(CallI
         return InliningStatus_NotInlined;
 
       default:
         // ForkJoinGetSlice acts as identity for sequential execution.
         current->push(callInfo.getArg(0));
         return InliningStatus_Inlined;
     }
 
-    MOZ_CRASH("Invalid execution mode");
+    MOZ_ASSUME_UNREACHABLE("Invalid execution mode");
 }
 
 IonBuilder::InliningStatus
 IonBuilder::inlineNewDenseArray(CallInfo &callInfo)
 {
     if (callInfo.constructing() || callInfo.argc() != 1)
         return InliningStatus_NotInlined;
 
@@ -1602,17 +1602,17 @@ IonBuilder::inlineNewDenseArray(CallInfo
     ExecutionMode executionMode = info().executionMode();
     switch (executionMode) {
       case ParallelExecution:
         return inlineNewDenseArrayForParallelExecution(callInfo);
       default:
         return inlineNewDenseArrayForSequentialExecution(callInfo);
     }
 
-    MOZ_CRASH("unknown ExecutionMode");
+    MOZ_ASSUME_UNREACHABLE("unknown ExecutionMode");
 }
 
 IonBuilder::InliningStatus
 IonBuilder::inlineNewDenseArrayForSequentialExecution(CallInfo &callInfo)
 {
     // not yet implemented; in seq. mode the C function is not so bad
     return InliningStatus_NotInlined;
 }
--- a/js/src/jit/MIR.cpp
+++ b/js/src/jit/MIR.cpp
@@ -113,17 +113,17 @@ EvaluateConstantOperands(TempAllocator &
         break;
       case MDefinition::Op_Div:
         ret.setNumber(NumberDiv(lhs.toNumber(), rhs.toNumber()));
         break;
       case MDefinition::Op_Mod:
         ret.setNumber(NumberMod(lhs.toNumber(), rhs.toNumber()));
         break;
       default:
-        MOZ_CRASH("NYI");
+        MOZ_ASSUME_UNREACHABLE("NYI");
     }
 
     // setNumber eagerly transforms a number to int32.
     // Transform back to double, if the output type is double.
     if (ins->type() == MIRType_Double && ret.isInt32())
         ret.setDouble(ret.toNumber());
 
     if (ins->type() != MIRTypeFromValue(ret)) {
@@ -560,17 +560,17 @@ MConstant::printOpcode(FILE *fp) const
         break;
       case MIRType_MagicIsConstructing:
         fprintf(fp, "magic is-constructing");
         break;
       case MIRType_MagicOptimizedOut:
         fprintf(fp, "magic optimized-out");
         break;
       default:
-        MOZ_CRASH("unexpected type");
+        MOZ_ASSUME_UNREACHABLE("unexpected type");
     }
 }
 
 bool
 MConstant::canProduceFloat32() const
 {
     if (!IsNumberType(type()))
         return false;
@@ -651,17 +651,17 @@ MMathFunction::FunctionName(Function fun
       case ATanH:  return "ATanH";
       case Sign:   return "Sign";
       case Trunc:  return "Trunc";
       case Cbrt:   return "Cbrt";
       case Floor:  return "Floor";
       case Ceil:   return "Ceil";
       case Round:  return "Round";
       default:
-        MOZ_CRASH("Unknown math function");
+        MOZ_ASSUME_UNREACHABLE("Unknown math function");
     }
 }
 
 void
 MMathFunction::printOpcode(FILE *fp) const
 {
     MDefinition::printOpcode(fp);
     fprintf(fp, " %s", FunctionName(function()));
@@ -1945,17 +1945,17 @@ MCompare::inputType()
       case Compare_StrictString:
         return MIRType_String;
       case Compare_Object:
         return MIRType_Object;
       case Compare_Unknown:
       case Compare_Value:
         return MIRType_Value;
       default:
-        MOZ_CRASH("No known conversion");
+        MOZ_ASSUME_UNREACHABLE("No known conversion");
     }
 }
 
 static inline bool
 MustBeUInt32(MDefinition *def, MDefinition **pwrapped)
 {
     if (def->isUrsh()) {
         *pwrapped = def->toUrsh()->getOperand(0);
@@ -2514,17 +2514,17 @@ MCompare::tryFold(bool *result)
           case MIRType_Double:
           case MIRType_Float32:
           case MIRType_String:
           case MIRType_Symbol:
           case MIRType_Boolean:
             *result = (op == JSOP_NE || op == JSOP_STRICTNE);
             return true;
           default:
-            MOZ_CRASH("Unexpected type");
+            MOZ_ASSUME_UNREACHABLE("Unexpected type");
         }
     }
 
     if (compareType_ == Compare_Boolean) {
         JS_ASSERT(op == JSOP_STRICTEQ || op == JSOP_STRICTNE);
         JS_ASSERT(rhs()->type() == MIRType_Boolean);
 
         switch (lhs()->type()) {
@@ -2537,19 +2537,19 @@ MCompare::tryFold(bool *result)
           case MIRType_Symbol:
           case MIRType_Object:
           case MIRType_Null:
           case MIRType_Undefined:
             *result = (op == JSOP_STRICTNE);
             return true;
           case MIRType_Boolean:
             // Int32 specialization should handle this.
-            MOZ_CRASH("Wrong specialization");
+            MOZ_ASSUME_UNREACHABLE("Wrong specialization");
           default:
-            MOZ_CRASH("Unexpected type");
+            MOZ_ASSUME_UNREACHABLE("Unexpected type");
         }
     }
 
     if (compareType_ == Compare_StrictString) {
         JS_ASSERT(op == JSOP_STRICTEQ || op == JSOP_STRICTNE);
         JS_ASSERT(rhs()->type() == MIRType_String);
 
         switch (lhs()->type()) {
@@ -2562,19 +2562,19 @@ MCompare::tryFold(bool *result)
           case MIRType_Symbol:
           case MIRType_Object:
           case MIRType_Null:
           case MIRType_Undefined:
             *result = (op == JSOP_STRICTNE);
             return true;
           case MIRType_String:
             // Compare_String specialization should handle this.
-            MOZ_CRASH("Wrong specialization");
+            MOZ_ASSUME_UNREACHABLE("Wrong specialization");
           default:
-            MOZ_CRASH("Unexpected type");
+            MOZ_ASSUME_UNREACHABLE("Unexpected type");
         }
     }
 
     return false;
 }
 
 bool
 MCompare::evaluateConstantOperands(bool *result)
@@ -2614,17 +2614,17 @@ MCompare::evaluateConstantOperands(bool 
           case JSOP_EQ:
             *result = (comp == 0);
             break;
           case JSOP_STRICTNE: // Fall through.
           case JSOP_NE:
             *result = (comp != 0);
             break;
           default:
-            MOZ_CRASH("Unexpected op.");
+            MOZ_ASSUME_UNREACHABLE("Unexpected op.");
         }
 
         return true;
     }
 
     if (compareType_ == Compare_UInt32) {
         uint32_t lhsUint = uint32_t(lhs.toInt32());
         uint32_t rhsUint = uint32_t(rhs.toInt32());
@@ -2646,17 +2646,17 @@ MCompare::evaluateConstantOperands(bool 
           case JSOP_STRICTEQ:
             *result = (lhsUint == rhsUint);
             break;
           case JSOP_NE:
           case JSOP_STRICTNE:
             *result = (lhsUint != rhsUint);
             break;
           default:
-            MOZ_CRASH("Unexpected op.");
+            MOZ_ASSUME_UNREACHABLE("Unexpected op.");
         }
 
         return true;
     }
 
     if (!lhs.isNumber() || !rhs.isNumber())
         return false;
 
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -2726,17 +2726,17 @@ class MUnbox : public MUnaryInstruction,
             break;
           case MIRType_Symbol:
             kind = Bailout_NonSymbolInput;
             break;
           case MIRType_Object:
             kind = Bailout_NonObjectInput;
             break;
           default:
-            MOZ_CRASH("Given MIRType cannot be unboxed.");
+            MOZ_ASSUME_UNREACHABLE("Given MIRType cannot be unboxed.");
         }
 
         return new(alloc) MUnbox(ins, type, mode, kind);
     }
 
     static MUnbox *New(TempAllocator &alloc, MDefinition *ins, MIRType type, Mode mode,
                        BailoutKind kind)
     {
@@ -4564,17 +4564,17 @@ class MDiv : public MBinaryArithInstruct
         return div;
     }
 
     MDefinition *foldsTo(TempAllocator &alloc);
     void analyzeEdgeCasesForward();
     void analyzeEdgeCasesBackward();
 
     double getIdentity() {
-        MOZ_CRASH("not used");
+        MOZ_ASSUME_UNREACHABLE("not used");
     }
 
     bool canBeNegativeZero() const {
         return canBeNegativeZero_;
     }
     void setCanBeNegativeZero(bool negativeZero) {
         canBeNegativeZero_ = negativeZero;
     }
@@ -4658,17 +4658,17 @@ class MMod : public MBinaryArithInstruct
         if (type == MIRType_Int32)
             mod->setTruncateKind(Truncate);
         return mod;
     }
 
     MDefinition *foldsTo(TempAllocator &alloc);
 
     double getIdentity() {
-        MOZ_CRASH("not used");
+        MOZ_ASSUME_UNREACHABLE("not used");
     }
 
     bool canBeNegativeDividend() const {
         JS_ASSERT(specialization_ == MIRType_Int32);
         return canBeNegativeDividend_;
     }
 
     bool canBeDivideByZero() const {
--- a/js/src/jit/MIRGraph.cpp
+++ b/js/src/jit/MIRGraph.cpp
@@ -1071,17 +1071,17 @@ MBasicBlock::getSuccessor(size_t index) 
 size_t
 MBasicBlock::getSuccessorIndex(MBasicBlock *block) const
 {
     JS_ASSERT(lastIns());
     for (size_t i = 0; i < numSuccessors(); i++) {
         if (getSuccessor(i) == block)
             return i;
     }
-    MOZ_CRASH("Invalid successor");
+    MOZ_ASSUME_UNREACHABLE("Invalid successor");
 }
 
 void
 MBasicBlock::replaceSuccessor(size_t pos, MBasicBlock *split)
 {
     JS_ASSERT(lastIns());
 
     // Note, during split-critical-edges, successors-with-phis is not yet set.
@@ -1103,17 +1103,17 @@ MBasicBlock::replacePredecessor(MBasicBl
             for (size_t j = i; j < numPredecessors(); j++)
                 JS_ASSERT(predecessors_[j] != old);
 #endif
 
             return;
         }
     }
 
-    MOZ_CRASH("predecessor was not found");
+    MOZ_ASSUME_UNREACHABLE("predecessor was not found");
 }
 
 void
 MBasicBlock::clearDominatorInfo()
 {
     setImmediateDominator(nullptr);
     immediatelyDominated_.clear();
     numDominated_ = 0;
@@ -1143,17 +1143,17 @@ MBasicBlock::removePredecessor(MBasicBlo
         }
 
         // Remove from pred list.
         MBasicBlock **ptr = predecessors_.begin() + i;
         predecessors_.erase(ptr);
         return;
     }
 
-    MOZ_CRASH("predecessor was not found");
+    MOZ_ASSUME_UNREACHABLE("predecessor was not found");
 }
 
 void
 MBasicBlock::inheritPhis(MBasicBlock *header)
 {
     MResumePoint *headerRp = header->entryResumePoint();
     size_t stackDepth = headerRp->numOperands();
     for (size_t slot = 0; slot < stackDepth; slot++) {
--- a/js/src/jit/MOpcodes.h
+++ b/js/src/jit/MOpcodes.h
@@ -238,17 +238,17 @@ class MInstructionVisitor // interface i
 #define VISIT_INS(op) virtual bool visit##op(M##op *) = 0;
     MIR_OPCODE_LIST(VISIT_INS)
 #undef VISIT_INS
 };
 
 class MInstructionVisitorWithDefaults : public MInstructionVisitor
 {
   public:
-#define VISIT_INS(op) virtual bool visit##op(M##op *) { MOZ_CRASH("NYI: " #op); }
+#define VISIT_INS(op) virtual bool visit##op(M##op *) { MOZ_ASSUME_UNREACHABLE("NYI: " #op); }
     MIR_OPCODE_LIST(VISIT_INS)
 #undef VISIT_INS
 };
 
 } // namespace jit
 } // namespace js
 
 #endif /* jit_MOpcodes_h */
--- a/js/src/jit/RangeAnalysis.cpp
+++ b/js/src/jit/RangeAnalysis.cpp
@@ -498,33 +498,33 @@ Range::Range(const MDefinition *def)
         switch (def->type()) {
           case MIRType_Int32:
             wrapAroundToInt32();
             break;
           case MIRType_Boolean:
             wrapAroundToBoolean();
             break;
           case MIRType_None:
-            MOZ_CRASH("Asking for the range of an instruction with no value");
+            MOZ_ASSUME_UNREACHABLE("Asking for the range of an instruction with no value");
           default:
             break;
         }
     } else {
         // Otherwise just use type information. We can trust the type here
         // because we don't care what value the instruction actually produces,
         // but what value we might get after we get past the bailouts.
         switch (def->type()) {
           case MIRType_Int32:
             setInt32(JSVAL_INT_MIN, JSVAL_INT_MAX);
             break;
           case MIRType_Boolean:
             setInt32(0, 1);
             break;
           case MIRType_None:
-            MOZ_CRASH("Asking for the range of an instruction with no value");
+            MOZ_ASSUME_UNREACHABLE("Asking for the range of an instruction with no value");
           default:
             setUnknown();
             break;
         }
     }
 
     // As a special case, MUrsh is permitted to claim a result type of
     // MIRType_Int32 while actually returning values in [0,UINT32_MAX] without
--- a/js/src/jit/Recover.cpp
+++ b/js/src/jit/Recover.cpp
@@ -22,17 +22,18 @@
 #include "vm/Interpreter-inl.h"
 
 using namespace js;
 using namespace js::jit;
 
 bool
 MNode::writeRecoverData(CompactBufferWriter &writer) const
 {
-    MOZ_CRASH("This instruction is not serializable");
+    MOZ_ASSUME_UNREACHABLE("This instruction is not serializable");
+    return false;
 }
 
 void
 RInstruction::readRecoverData(CompactBufferReader &reader, RInstructionStorage *raw)
 {
     uint32_t op = reader.readUnsigned();
     switch (Opcode(op)) {
 #   define MATCH_OPCODES_(op)                                           \
@@ -42,17 +43,17 @@ RInstruction::readRecoverData(CompactBuf
         new (raw->addr()) R##op(reader);                                \
         break;
 
         RECOVER_OPCODE_LIST(MATCH_OPCODES_)
 #   undef DEFINE_OPCODES_
 
       case Recover_Invalid:
       default:
-        MOZ_CRASH("Bad decoding of the previous instruction?");
+        MOZ_ASSUME_UNREACHABLE("Bad decoding of the previous instruction?");
         break;
     }
 }
 
 bool
 MResumePoint::writeRecoverData(CompactBufferWriter &writer) const
 {
     writer.writeUnsigned(uint32_t(RInstruction::Recover_ResumePoint));
@@ -130,17 +131,17 @@ RResumePoint::RResumePoint(CompactBuffer
     numOperands_ = reader.readUnsigned();
     IonSpew(IonSpew_Snapshots, "Read RResumePoint (pc offset %u, nslots %u)",
             pcOffset_, numOperands_);
 }
 
 bool
 RResumePoint::recover(JSContext *cx, SnapshotIterator &iter) const
 {
-    MOZ_CRASH("This instruction is not recoverable.");
+    MOZ_ASSUME_UNREACHABLE("This instruction is not recoverable.");
 }
 
 bool
 MBitNot::writeRecoverData(CompactBufferWriter &writer) const
 {
     MOZ_ASSERT(canRecoverOnBailout());
     writer.writeUnsigned(uint32_t(RInstruction::Recover_BitNot));
     return true;
@@ -819,17 +820,18 @@ bool
 MMathFunction::writeRecoverData(CompactBufferWriter &writer) const
 {
     MOZ_ASSERT(canRecoverOnBailout());
     switch (function_) {
       case Round:
         writer.writeUnsigned(uint32_t(RInstruction::Recover_Round));
         return true;
       default:
-        MOZ_CRASH("Unknown math function.");
+        MOZ_ASSUME_UNREACHABLE("Unknown math function.");
+        return false;
     }
 }
 
 bool
 MStringSplit::writeRecoverData(CompactBufferWriter &writer) const
 {
     MOZ_ASSERT(canRecoverOnBailout());
     writer.writeUnsigned(uint32_t(RInstruction::Recover_StringSplit));
--- a/js/src/jit/Snapshots.cpp
+++ b/js/src/jit/Snapshots.cpp
@@ -246,17 +246,17 @@ RValueAllocation::layoutFromMode(Mode mo
 
         if (mode >= TYPED_REG_MIN && mode <= TYPED_REG_MAX)
             return regLayout;
         if (mode >= TYPED_STACK_MIN && mode <= TYPED_STACK_MAX)
             return stackLayout;
       }
     }
 
-    MOZ_CRASH("Wrong mode type?");
+    MOZ_ASSUME_UNREACHABLE("Wrong mode type?");
 }
 
 // Pad serialized RValueAllocations by a multiple of X bytes in the allocation
 // buffer.  By padding serialized value allocations, we are building an
 // indexable table of elements of X bytes, and thus we can safely divide any
 // offset within the buffer by X to obtain an index.
 //
 // By padding, we are loosing space within the allocation buffer, but we
@@ -396,17 +396,17 @@ ValTypeToString(JSValueType type)
         return "symbol";
       case JSVAL_TYPE_BOOLEAN:
         return "boolean";
       case JSVAL_TYPE_OBJECT:
         return "object";
       case JSVAL_TYPE_MAGIC:
         return "magic";
       default:
-        MOZ_CRASH("no payload");
+        MOZ_ASSUME_UNREACHABLE("no payload");
     }
 }
 
 void
 RValueAllocation::dumpPayload(FILE *fp, PayloadType type, Payload p)
 {
     switch (type) {
       case PAYLOAD_NONE:
--- a/js/src/jit/StackSlotAllocator.h
+++ b/js/src/jit/StackSlotAllocator.h
@@ -64,17 +64,17 @@ class StackSlotAllocator
 #ifdef JS_PUNBOX64
           case LDefinition::BOX:
 #endif
 #ifdef JS_NUNBOX32
           case LDefinition::TYPE:
           case LDefinition::PAYLOAD:
 #endif
           case LDefinition::DOUBLE:  return freeDoubleSlot(index);
-          default: MOZ_CRASH("Unknown slot type");
+          default: MOZ_ASSUME_UNREACHABLE("Unknown slot type");
         }
     }
 
     uint32_t allocateSlot(LDefinition::Type type) {
         switch (type) {
 #if JS_BITS_PER_WORD == 32
           case LDefinition::GENERAL:
           case LDefinition::OBJECT:
@@ -90,17 +90,17 @@ class StackSlotAllocator
 #ifdef JS_PUNBOX64
           case LDefinition::BOX:
 #endif
 #ifdef JS_NUNBOX32
           case LDefinition::TYPE:
           case LDefinition::PAYLOAD:
 #endif
           case LDefinition::DOUBLE:  return allocateDoubleSlot();
-          default: MOZ_CRASH("Unknown slot type");
+          default: MOZ_ASSUME_UNREACHABLE("Unknown slot type");
         }
     }
 
     uint32_t stackHeight() const {
         return height_;
     }
 };
 
--- a/js/src/jit/StupidAllocator.cpp
+++ b/js/src/jit/StupidAllocator.cpp
@@ -29,17 +29,17 @@ StupidAllocator::stackLocation(uint32_t 
 
 StupidAllocator::RegisterIndex
 StupidAllocator::registerIndex(AnyRegister reg)
 {
     for (size_t i = 0; i < registerCount; i++) {
         if (reg == registers[i].reg)
             return i;
     }
-    MOZ_CRASH("Bad register");
+    MOZ_ASSUME_UNREACHABLE("Bad register");
 }
 
 bool
 StupidAllocator::init()
 {
     if (!RegisterAllocator::init())
         return false;
 
--- a/js/src/jit/TypePolicy.cpp
+++ b/js/src/jit/TypePolicy.cpp
@@ -256,17 +256,17 @@ ComparePolicy::adjustInputs(TempAllocato
           }
           case MIRType_Object:
             replace = MUnbox::New(alloc, in, MIRType_Object, MUnbox::Infallible);
             break;
           case MIRType_String:
             replace = MUnbox::New(alloc, in, MIRType_String, MUnbox::Infallible);
             break;
           default:
-            MOZ_CRASH("Unknown compare specialization");
+            MOZ_ASSUME_UNREACHABLE("Unknown compare specialization");
         }
 
         def->block()->insertBefore(def, replace);
         def->replaceOperand(i, replace);
     }
 
     return true;
 }
@@ -741,17 +741,17 @@ StoreTypedArrayPolicy::adjustValueInput(
         ins->block()->insertBefore(ins, value->toInstruction());
         break;
       case MIRType_Object:
       case MIRType_String:
       case MIRType_Symbol:
         value = boxAt(alloc, ins, value);
         break;
       default:
-        MOZ_CRASH("Unexpected type");
+        MOZ_ASSUME_UNREACHABLE("Unexpected type");
     }
 
     if (value != curValue) {
         ins->replaceOperand(valueOperand, value);
         curValue = value;
     }
 
     JS_ASSERT(value->type() == MIRType_Int32 ||
@@ -788,17 +788,17 @@ StoreTypedArrayPolicy::adjustValueInput(
         // stored value to be a double.
       case Scalar::Float64:
         if (value->type() != MIRType_Double) {
             value = MToDouble::New(alloc, value);
             ins->block()->insertBefore(ins, value->toInstruction());
         }
         break;
       default:
-        MOZ_CRASH("Invalid array type");
+        MOZ_ASSUME_UNREACHABLE("Invalid array type");
     }
 
     if (value != curValue)
         ins->replaceOperand(valueOperand, value);
 
     return true;
 }
 
--- a/js/src/jit/TypedObjectPrediction.cpp
+++ b/js/src/jit/TypedObjectPrediction.cpp
@@ -93,17 +93,17 @@ TypedObjectPrediction::addProto(const Ty
             return markInconsistent();
 
         markAsCommonPrefix(*data_.prefix.descr,
                            proto.typeDescr().as<StructTypeDescr>(),
                            data_.prefix.fields);
         return;
     }
 
-    MOZ_CRASH("Bad predictionKind");
+    MOZ_ASSUME_UNREACHABLE("Bad predictionKind");
 }
 
 type::Kind
 TypedObjectPrediction::kind() const
 {
     switch (predictionKind()) {
       case TypedObjectPrediction::Empty:
       case TypedObjectPrediction::Inconsistent:
@@ -114,17 +114,17 @@ TypedObjectPrediction::kind() const
 
       case TypedObjectPrediction::Descr:
         return descr().kind();
 
       case TypedObjectPrediction::Prefix:
         return prefix().descr->kind();
     }
 
-    MOZ_CRASH("Bad prediction kind");
+    MOZ_ASSUME_UNREACHABLE("Bad prediction kind");
 }
 
 bool
 TypedObjectPrediction::ofArrayKind() const
 {
     switch (kind()) {
       case type::Scalar:
       case type::Reference:
@@ -132,17 +132,17 @@ TypedObjectPrediction::ofArrayKind() con
       case type::Struct:
         return false;
 
       case type::SizedArray:
       case type::UnsizedArray:
         return true;
     }
 
-    MOZ_CRASH("Bad kind");
+    MOZ_ASSUME_UNREACHABLE("Bad kind");
 }
 
 static bool
 DescrHasKnownSize(const TypeDescr &descr, int32_t *out)
 {
     if (!descr.is<SizedTypeDescr>())
         return false;
 
@@ -167,28 +167,28 @@ TypedObjectPrediction::hasKnownSize(int3
             *out = proto().typeDescr().as<SizedTypeDescr>().size();
             return true;
 
           case type::SizedArray:
           case type::UnsizedArray:
             // The prototype does not track the precise dimensions of arrays.
             return false;
         }
-        MOZ_CRASH("Unknown kind");
+        MOZ_ASSUME_UNREACHABLE("Unknown kind");
 
       case TypedObjectPrediction::Descr:
         return DescrHasKnownSize(descr(), out);
 
       case TypedObjectPrediction::Prefix:
         // We only know a prefix of the struct fields, hence we do not
         // know its complete size.
         return false;
     }
 
-    MOZ_CRASH("Bad prediction kind");
+    MOZ_ASSUME_UNREACHABLE("Bad prediction kind");
 }
 
 const TypedProto *
 TypedObjectPrediction::getKnownPrototype() const
 {
     switch (predictionKind()) {
       case TypedObjectPrediction::Empty:
       case TypedObjectPrediction::Inconsistent:
@@ -201,30 +201,30 @@ TypedObjectPrediction::getKnownPrototype
             return nullptr;
 
           case type::X4:
           case type::Struct:
           case type::SizedArray:
           case type::UnsizedArray:
             return &proto();
         }
-        MOZ_CRASH("Invalid proto().kind()");
+        MOZ_ASSUME_UNREACHABLE("Invalid proto().kind()");
 
       case TypedObjectPrediction::Descr:
         if (descr().is<ComplexTypeDescr>())
             return &descr().as<ComplexTypeDescr>().instancePrototype();
         return nullptr;
 
       case TypedObjectPrediction::Prefix:
         // We only know a prefix of the struct fields, hence we cannot
         // say for certain what its prototype will be.
         return nullptr;
     }
 
-    MOZ_CRASH("Bad prediction kind");
+    MOZ_ASSUME_UNREACHABLE("Bad prediction kind");
 }
 
 template<typename T>
 typename T::Type
 TypedObjectPrediction::extractType() const
 {
     JS_ASSERT(kind() == T::Kind);
     switch (predictionKind()) {
@@ -237,17 +237,17 @@ TypedObjectPrediction::extractType() con
 
       case TypedObjectPrediction::Descr:
         return descr().as<T>().type();
 
       case TypedObjectPrediction::Prefix:
         break; // Prefixes are always structs, never scalars etc
     }
 
-    MOZ_CRASH("Bad prediction kind");
+    MOZ_ASSUME_UNREACHABLE("Bad prediction kind");
 }
 
 ScalarTypeDescr::Type
 TypedObjectPrediction::scalarType() const
 {
     return extractType<ScalarTypeDescr>();
 }
 
@@ -283,17 +283,17 @@ TypedObjectPrediction::hasKnownArrayLeng
             *length = descr().as<SizedArrayTypeDescr>().length();
             return true;
         }
         return false;
 
       case TypedObjectPrediction::Prefix:
         break; // Prefixes are always structs, never arrays
     }
-    MOZ_CRASH("Bad prediction kind");
+    MOZ_ASSUME_UNREACHABLE("Bad prediction kind");
 }
 
 static TypeDescr &
 DescrArrayElementType(const TypeDescr &descr) {
     return (descr.is<SizedArrayTypeDescr>()
             ? descr.as<SizedArrayTypeDescr>().elementType()
             : descr.as<UnsizedArrayTypeDescr>().elementType());
 }
@@ -311,17 +311,17 @@ TypedObjectPrediction::arrayElementType(
         return TypedObjectPrediction(DescrArrayElementType(proto().typeDescr()));
 
       case TypedObjectPrediction::Descr:
         return TypedObjectPrediction(DescrArrayElementType(descr()));
 
       case TypedObjectPrediction::Prefix:
         break; // Prefixes are always structs, never arrays
     }
-    MOZ_CRASH("Bad prediction kind");
+    MOZ_ASSUME_UNREACHABLE("Bad prediction kind");
 }
 
 bool
 TypedObjectPrediction::hasFieldNamedPrefix(const StructTypeDescr &descr,
                                            size_t fieldCount,
                                            jsid id,
                                            size_t *fieldOffset,
                                            TypedObjectPrediction *out,
@@ -364,10 +364,10 @@ TypedObjectPrediction::hasFieldNamed(jsi
             descr().as<StructTypeDescr>(), ALL_FIELDS,
             id, fieldOffset, fieldType, fieldIndex);
 
       case TypedObjectPrediction::Prefix:
         return hasFieldNamedPrefix(
             *prefix().descr, prefix().fields,
             id, fieldOffset, fieldType, fieldIndex);
     }
-    MOZ_CRASH("Bad prediction kind");
+    MOZ_ASSUME_UNREACHABLE("Bad prediction kind");
 }
--- a/js/src/jit/VMFunctions.cpp
+++ b/js/src/jit/VMFunctions.cpp
@@ -755,17 +755,17 @@ DebugPrologue(JSContext *cx, BaselineFra
         *mustReturn = true;
         return jit::DebugEpilogue(cx, frame, pc, true);
 
       case JSTRAP_THROW:
       case JSTRAP_ERROR:
         return false;
 
       default:
-        MOZ_CRASH("Invalid trap status");
+        MOZ_ASSUME_UNREACHABLE("Invalid trap status");
     }
 }
 
 bool
 DebugEpilogueOnBaselineReturn(JSContext *cx, BaselineFrame *frame, jsbytecode *pc)
 {
     if (!DebugEpilogue(cx, frame, pc, true)) {
         // DebugEpilogue popped the frame by updating jitTop, so run the stop event
@@ -912,17 +912,17 @@ HandleDebugTrap(JSContext *cx, BaselineF
         frame->setReturnValue(rval);
         return jit::DebugEpilogue(cx, frame, pc, true);
 
       case JSTRAP_THROW:
         cx->setPendingException(rval);
         return false;
 
       default:
-        MOZ_CRASH("Invalid trap status");
+        MOZ_ASSUME_UNREACHABLE("Invalid trap status");
     }
 
     return true;
 }
 
 bool
 OnDebuggerStatement(JSContext *cx, BaselineFrame *frame, jsbytecode *pc, bool *mustReturn)
 {
@@ -950,17 +950,17 @@ OnDebuggerStatement(JSContext *cx, Basel
         *mustReturn = true;
         return jit::DebugEpilogue(cx, frame, pc, true);
 
       case JSTRAP_THROW:
         cx->setPendingException(rval);
         return false;
 
       default:
-        MOZ_CRASH("Invalid trap status");
+        MOZ_ASSUME_UNREACHABLE("Invalid trap status");
     }
 }
 
 bool
 PushBlockScope(JSContext *cx, BaselineFrame *frame, Handle<StaticBlockObject *> block)
 {
     return frame->pushBlock(cx, block);
 }
--- a/js/src/jit/arm/Architecture-arm.cpp
+++ b/js/src/jit/arm/Architecture-arm.cpp
@@ -347,13 +347,13 @@ VFPRegister::GetPushSizeInBytes(const Fl
 }
 uint32_t
 VFPRegister::getRegisterDumpOffsetInBytes()
 {
     if (isSingle())
         return id() * sizeof(float);
     if (isDouble())
         return id() * sizeof(double);
-    MOZ_CRASH("Unexpected register dump offset");
+    MOZ_ASSUME_UNREACHABLE();
 }
 
 } // namespace jit
 } // namespace js
--- a/js/src/jit/arm/Assembler-arm.cpp
+++ b/js/src/jit/arm/Assembler-arm.cpp
@@ -53,17 +53,17 @@ ABIArgGenerator::next(MIRType type)
             current_ = ABIArg(stackOffset_);
             stackOffset_ += sizeof(uint64_t);
             break;
         }
         current_ = ABIArg(FloatRegister::FromCode(floatRegIndex_));
         floatRegIndex_++;
         break;
       default:
-        MOZ_CRASH("Unexpected argument type");
+        MOZ_ASSUME_UNREACHABLE("Unexpected argument type");
     }
 
     return current_;
 }
 const Register ABIArgGenerator::NonArgReturnVolatileReg0 = r4;
 const Register ABIArgGenerator::NonArgReturnVolatileReg1 = r5;
 
 // Encode a standard register when it is being used as src1, the dest, and an
@@ -694,17 +694,17 @@ Assembler::GetCF32Target(Iter *iter)
         if (iu != IsUp) {
             offset = - offset;
         }
         uint32_t **ptr = (uint32_t **)&dataInst[offset + 8];
         return *ptr;
 
     }
 
-    MOZ_CRASH("unsupported branch relocation");
+    MOZ_ASSUME_UNREACHABLE("unsupported branch relocation");
 }
 
 uintptr_t
 Assembler::GetPointer(uint8_t *instPtr)
 {
     InstructionIterator iter((Instruction*)instPtr);
     uintptr_t ret = (uintptr_t)GetPtr32Target(&iter, nullptr, nullptr);
     return ret;
@@ -758,17 +758,17 @@ Assembler::GetPtr32Target(Iter *start, R
         if (dest)
             *dest = toRD(*load);
         if (style)
             *style = L_LDR;
         uint32_t **ptr = (uint32_t **)&dataInst[offset + 8];
         return *ptr;
     }
 
-    MOZ_CRASH("unsupported relocation");
+    MOZ_ASSUME_UNREACHABLE("unsupported relocation");
 }
 
 static JitCode *
 CodeFromJump(InstructionIterator *jump)
 {
     uint8_t *target = (uint8_t *)Assembler::GetCF32Target(jump);
     return JitCode::FromExecutable(target);
 }
@@ -1659,17 +1659,17 @@ Assembler::as_extdtr(LoadStore ls, int s
             extra_bits2 |= 0x2;
         }
         break;
       case 64:
         extra_bits2 = (ls == IsStore) ? 0x3 : 0x2;
         extra_bits1 = 0;
         break;
       default:
-        MOZ_CRASH("SAY WHAT?");
+        MOZ_ASSUME_UNREACHABLE("SAY WHAT?");
     }
     return writeInst(extra_bits2 << 5 | extra_bits1 << 20 | 0x90 |
                      addr.encode() | RT(rt) | mode | c, dest);
 }
 
 BufferOffset
 Assembler::as_dtm(LoadStore ls, Register rn, uint32_t mask,
                 DTMMode mode, DTMWriteBack wb, Condition c)
@@ -1765,17 +1765,17 @@ Assembler::InsertTokenIntoTag(uint32_t i
 bool
 Assembler::PatchConstantPoolLoad(void* loadAddr, void* constPoolAddr)
 {
     PoolHintData data = *(PoolHintData*)loadAddr;
     uint32_t *instAddr = (uint32_t*) loadAddr;
     int offset = (char *)constPoolAddr - (char *)loadAddr;
     switch(data.getLoadType()) {
       case PoolHintData::PoolBOGUS:
-        MOZ_CRASH("bogus load type!");
+        MOZ_ASSUME_UNREACHABLE("bogus load type!");
       case PoolHintData::PoolDTR:
         Dummy->as_dtr(IsLoad, 32, Offset, data.getReg(),
                       DTRAddr(pc, DtrOffImm(offset+4*data.getIndex() - 8)), data.getCond(), instAddr);
         break;
       case PoolHintData::PoolBranch:
         // Either this used to be a poolBranch, and the label was already bound,
         // so it was replaced with a real branch, or this may happen in the
         // future. If this is going to happen in the future, then the actual
@@ -1995,30 +1995,32 @@ Assembler::as_vmul(VFPRegister vd, VFPRe
     return as_vfp_float(vd, vn, vm, OpvMul, c);
 }
 
 BufferOffset
 Assembler::as_vnmul(VFPRegister vd, VFPRegister vn, VFPRegister vm,
                   Condition c)
 {
     return as_vfp_float(vd, vn, vm, OpvMul, c);
+    MOZ_ASSUME_UNREACHABLE("Feature NYI");
 }
 
 BufferOffset
 Assembler::as_vnmla(VFPRegister vd, VFPRegister vn, VFPRegister vm,
                   Condition c)
 {
-    MOZ_CRASH("Feature NYI");
+    MOZ_ASSUME_UNREACHABLE("Feature NYI");
 }
 
 BufferOffset
 Assembler::as_vnmls(VFPRegister vd, VFPRegister vn, VFPRegister vm,
                   Condition c)
 {
-    MOZ_CRASH("Feature NYI");
+    MOZ_ASSUME_UNREACHABLE("Feature NYI");
+    return BufferOffset();
 }
 
 BufferOffset
 Assembler::as_vneg(VFPRegister vd, VFPRegister vm, Condition c)
 {
     return as_vfp_float(vd, NoVFPRegister, vm, OpvNeg, c);
 }
 
@@ -2242,17 +2244,17 @@ Assembler::bind(Label *label, BufferOffs
             Instruction branch = *editSrc(b);
             Condition c;
             branch.extractCond(&c);
             if (branch.is<InstBImm>())
                 as_b(dest.diffB<BOffImm>(b), c, b);
             else if (branch.is<InstBLImm>())
                 as_bl(dest.diffB<BOffImm>(b), c, b);
             else
-                MOZ_CRASH("crazy fixup!");
+                MOZ_ASSUME_UNREACHABLE("crazy fixup!");
             b = next;
         } while (more);
     }
     label->bind(nextOffset().getOffset());
 }
 
 void
 Assembler::bind(RepatchLabel *label)
@@ -2299,17 +2301,17 @@ Assembler::retarget(Label *label, Label 
             Condition c;
             branch.extractCond(&c);
             int32_t prev = target->use(label->offset());
             if (branch.is<InstBImm>())
                 as_b(BOffImm(prev), c, labelBranchOffset);
             else if (branch.is<InstBLImm>())
                 as_bl(BOffImm(prev), c, labelBranchOffset);
             else
-                MOZ_CRASH("crazy fixup!");
+                MOZ_ASSUME_UNREACHABLE("crazy fixup!");
         } else {
             // The target is unbound and unused. We can just take the head of
             // the list hanging off of label, and dump that into target.
             DebugOnly<uint32_t> prev = target->use(label->offset());
             JS_ASSERT((int32_t)prev == Label::INVALID_OFFSET);
         }
     }
     label->reset();
--- a/js/src/jit/arm/Assembler-arm.h
+++ b/js/src/jit/arm/Assembler-arm.h
@@ -1579,17 +1579,17 @@ class Assembler : public AssemblerShared
         dtmMode = mode;
     }
 
     void transferReg(Register rn) {
         JS_ASSERT(dtmActive);
         JS_ASSERT(rn.code() > dtmLastReg);
         dtmRegBitField |= 1 << rn.code();
         if (dtmLoadStore == IsLoad && rn.code() == 13 && dtmBase.code() == 13) {
-            MOZ_CRASH("ARM Spec says this is invalid");
+            MOZ_ASSUME_UNREACHABLE("ARM Spec says this is invalid");
         }
     }
     void finishDataTransfer() {
         dtmActive = false;
         as_dtm(dtmLoadStore, dtmBase, dtmRegBitField, dtmMode, dtmUpdate, dtmCond);
     }
 
     void startFloatTransferM(LoadStore ls, Register rm,
@@ -1684,17 +1684,17 @@ class Assembler : public AssemblerShared
     static void PatchWrite_NearCall(CodeLocationLabel start, CodeLocationLabel toCall);
     static void PatchDataWithValueCheck(CodeLocationLabel label, PatchedImmPtr newValue,
                                         PatchedImmPtr expectedValue);
     static void PatchDataWithValueCheck(CodeLocationLabel label, ImmPtr newValue,
                                         ImmPtr expectedValue);
     static void PatchWrite_Imm32(CodeLocationLabel label, Imm32 imm);
 
     static void PatchInstructionImmediate(uint8_t *code, PatchedImmPtr imm) {
-        MOZ_CRASH("Unused.");
+        MOZ_ASSUME_UNREACHABLE("Unused.");
     }
 
     static uint32_t AlignDoubleArg(uint32_t offset) {
         return (offset + 1) & ~1;
     }
     static uint8_t *NextInstruction(uint8_t *instruction, uint32_t *count = nullptr);
 
     // Toggle a jmp or cmp emitted by toggledJump().
--- a/js/src/jit/arm/Bailouts-arm.cpp
+++ b/js/src/jit/arm/Bailouts-arm.cpp
@@ -79,17 +79,17 @@ IonBailoutIterator::IonBailoutIterator(c
 
     kind_ = Kind_BailoutIterator;
     current_ = fp;
     type_ = JitFrame_IonJS;
     topFrameSize_ = current_ - sp;
     switch (mode_) {
       case SequentialExecution: topIonScript_ = script()->ionScript(); break;
       case ParallelExecution: topIonScript_ = script()->parallelIonScript(); break;
-      default: MOZ_CRASH("No such execution mode");
+      default: MOZ_ASSUME_UNREACHABLE("No such execution mode");
     }
 
     if (bailout->frameClass() == FrameSizeClass::None()) {
         snapshotOffset_ = bailout->snapshotOffset();
         return;
     }
 
     // Compute the snapshot offset from the bailout ID.
--- a/js/src/jit/arm/BaselineIC-arm.cpp
+++ b/js/src/jit/arm/BaselineIC-arm.cpp
@@ -192,17 +192,17 @@ ICBinaryArith_Int32::Compiler::generateS
             masm.boxDouble(ScratchDoubleReg, R0);
         } else {
             masm.j(Assembler::LessThan, &failure);
             // Move result for return.
             masm.mov(scratchReg, R0.payloadReg());
         }
         break;
       default:
-        MOZ_CRASH("Unhandled op for BinaryArith_Int32.");
+        MOZ_ASSUME_UNREACHABLE("Unhandled op for BinaryArith_Int32.");
     }
 
     EmitReturnFromIC(masm);
 
     switch (op_) {
       case JSOP_MUL:
         masm.bind(&maybeNegZero);
 
@@ -243,17 +243,17 @@ ICUnaryArith_Int32::Compiler::generateSt
       case JSOP_NEG:
         // Guard against 0 and MIN_INT, both result in a double.
         masm.branchTest32(Assembler::Zero, R0.payloadReg(), Imm32(0x7fffffff), &failure);
 
         // Compile -x as 0 - x.
         masm.ma_rsb(R0.payloadReg(), Imm32(0), R0.payloadReg());
         break;
       default:
-        MOZ_CRASH("Unexpected op");
+        MOZ_ASSUME_UNREACHABLE("Unexpected op");
     }
 
     EmitReturnFromIC(masm);
 
     masm.bind(&failure);
     EmitStubGuardFailure(masm);
     return true;
 }
--- a/js/src/jit/arm/CodeGenerator-arm.cpp
+++ b/js/src/jit/arm/CodeGenerator-arm.cpp
@@ -889,17 +889,17 @@ CodeGeneratorARM::visitBitOpI(LBitOpI *i
         break;
       case JSOP_BITAND:
         if (rhs->isConstant())
             masm.ma_and(Imm32(ToInt32(rhs)), ToRegister(lhs), ToRegister(dest));
         else
             masm.ma_and(ToRegister(rhs), ToRegister(lhs), ToRegister(dest));
         break;
       default:
-        MOZ_CRASH("unexpected binary opcode");
+        MOZ_ASSUME_UNREACHABLE("unexpected binary opcode");
     }
 
     return true;
 }
 
 bool
 CodeGeneratorARM::visitShiftI(LShiftI *ins)
 {
@@ -931,17 +931,17 @@ CodeGeneratorARM::visitShiftI(LShiftI *i
                 if (ins->mir()->toUrsh()->fallible()) {
                     masm.ma_cmp(dest, Imm32(0));
                     if (!bailoutIf(Assembler::LessThan, ins->snapshot()))
                         return false;
                 }
             }
             break;
           default:
-            MOZ_CRASH("Unexpected shift op");
+            MOZ_ASSUME_UNREACHABLE("Unexpected shift op");
         }
     } else {
         // The shift amounts should be AND'ed into the 0-31 range since arm
         // shifts by the lower byte of the register (it will attempt to shift by
         // 250 if you ask it to).
         masm.ma_and(Imm32(0x1F), ToRegister(rhs), dest);
 
         switch (ins->bitop()) {
@@ -956,17 +956,17 @@ CodeGeneratorARM::visitShiftI(LShiftI *i
             if (ins->mir()->toUrsh()->fallible()) {
                 // x >>> 0 can overflow.
                 masm.ma_cmp(dest, Imm32(0));
                 if (!bailoutIf(Assembler::LessThan, ins->snapshot()))
                     return false;
             }
             break;
           default:
-            MOZ_CRASH("Unexpected shift op");
+            MOZ_ASSUME_UNREACHABLE("Unexpected shift op");
         }
     }
 
     return true;
 }
 
 bool
 CodeGeneratorARM::visitUrshD(LUrshD *ins)
@@ -1149,17 +1149,17 @@ CodeGeneratorARM::visitMathD(LMathD *mat
         break;
       case JSOP_MUL:
         masm.ma_vmul(ToFloatRegister(src1), ToFloatRegister(src2), ToFloatRegister(output));
         break;
       case JSOP_DIV:
         masm.ma_vdiv(ToFloatRegister(src1), ToFloatRegister(src2), ToFloatRegister(output));
         break;
       default:
-        MOZ_CRASH("unexpected opcode");
+        MOZ_ASSUME_UNREACHABLE("unexpected opcode");
     }
     return true;
 }
 
 bool
 CodeGeneratorARM::visitMathF(LMathF *math)
 {
     const LAllocation *src1 = math->getOperand(0);
@@ -1175,17 +1175,17 @@ CodeGeneratorARM::visitMathF(LMathF *mat
         break;
       case JSOP_MUL:
         masm.ma_vmul_f32(ToFloatRegister(src1), ToFloatRegister(src2), ToFloatRegister(output));
         break;
       case JSOP_DIV:
         masm.ma_vdiv_f32(ToFloatRegister(src1), ToFloatRegister(src2), ToFloatRegister(output));
         break;
       default:
-        MOZ_CRASH("unexpected opcode");
+        MOZ_ASSUME_UNREACHABLE("unexpected opcode");
     }
     return true;
 }
 
 bool
 CodeGeneratorARM::visitFloor(LFloor *lir)
 {
     FloatRegister input = ToFloatRegister(lir->input());
@@ -1776,23 +1776,23 @@ getBase(U *mir)
       case U::Global: return GlobalReg;
     }
     return InvalidReg;
 }
 
 bool
 CodeGeneratorARM::visitLoadTypedArrayElementStatic(LLoadTypedArrayElementStatic *ins)
 {
-    MOZ_CRASH("NYI");
+    MOZ_ASSUME_UNREACHABLE("NYI");
 }
 
 bool
 CodeGeneratorARM::visitStoreTypedArrayElementStatic(LStoreTypedArrayElementStatic *ins)
 {
-    MOZ_CRASH("NYI");
+    MOZ_ASSUME_UNREACHABLE("NYI");
 }
 
 bool
 CodeGeneratorARM::visitAsmJSLoadHeap(LAsmJSLoadHeap *ins)
 {
     const MAsmJSLoadHeap *mir = ins->mir();
     bool isSigned;
     int size;
@@ -1801,17 +1801,17 @@ CodeGeneratorARM::visitAsmJSLoadHeap(LAs
       case Scalar::Int8:    isSigned = true;  size =  8; break;
       case Scalar::Uint8:   isSigned = false; size =  8; break;
       case Scalar::Int16:   isSigned = true;  size = 16; break;
       case Scalar::Uint16:  isSigned = false; size = 16; break;
       case Scalar::Int32:
       case Scalar::Uint32:  isSigned = true;  size = 32; break;
       case Scalar::Float64: isFloat = true;   size = 64; break;
       case Scalar::Float32: isFloat = true;   size = 32; break;
-      default: MOZ_CRASH("unexpected array type");
+      default: MOZ_ASSUME_UNREACHABLE("unexpected array type");
     }
 
     const LAllocation *ptr = ins->ptr();
 
     if (ptr->isConstant()) {
         JS_ASSERT(mir->skipBoundsCheck());
         int32_t ptrImm = ptr->toConstant()->toInt32();
         JS_ASSERT(ptrImm >= 0);
@@ -1875,17 +1875,17 @@ CodeGeneratorARM::visitAsmJSStoreHeap(LA
       case Scalar::Int8:
       case Scalar::Uint8:   isSigned = false; size = 8; break;
       case Scalar::Int16:
       case Scalar::Uint16:  isSigned = false; size = 16; break;
       case Scalar::Int32:
       case Scalar::Uint32:  isSigned = true;  size = 32; break;
       case Scalar::Float64: isFloat  = true;  size = 64; break;
       case Scalar::Float32: isFloat = true;   size = 32; break;
-      default: MOZ_CRASH("unexpected array type");
+      default: MOZ_ASSUME_UNREACHABLE("unexpected array type");
     }
     const LAllocation *ptr = ins->ptr();
     if (ptr->isConstant()) {
         JS_ASSERT(mir->skipBoundsCheck());
         int32_t ptrImm = ptr->toConstant()->toInt32();
         JS_ASSERT(ptrImm >= 0);
         if (isFloat) {
             VFPRegister vd(ToFloatRegister(ins->value()));
@@ -2151,16 +2151,16 @@ CodeGeneratorARM::visitNegF(LNegF *ins)
     FloatRegister input = ToFloatRegister(ins->input());
     masm.ma_vneg_f32(input, ToFloatRegister(ins->output()));
     return true;
 }
 
 bool
 CodeGeneratorARM::visitForkJoinGetSlice(LForkJoinGetSlice *ins)
 {
-    MOZ_CRASH("NYI");
+    MOZ_ASSUME_UNREACHABLE("NYI");
 }
 
 JitCode *
 JitRuntime::generateForkJoinGetSliceStub(JSContext *cx)
 {
-    MOZ_CRASH("NYI");
+    MOZ_ASSUME_UNREACHABLE("NYI");
 }
--- a/js/src/jit/arm/Lowering-arm.cpp
+++ b/js/src/jit/arm/Lowering-arm.cpp
@@ -536,18 +536,18 @@ LIRGeneratorARM::lowerTruncateFToInt32(M
     JS_ASSERT(opd->type() == MIRType_Float32);
 
     return define(new(alloc()) LTruncateFToInt32(useRegister(opd), LDefinition::BogusTemp()), ins);
 }
 
 bool
 LIRGeneratorARM::visitStoreTypedArrayElementStatic(MStoreTypedArrayElementStatic *ins)
 {
-    MOZ_CRASH("NYI");
+    MOZ_ASSUME_UNREACHABLE("NYI");
 }
 
 bool
 LIRGeneratorARM::visitForkJoinGetSlice(MForkJoinGetSlice *ins)
 {
-    MOZ_CRASH("NYI");
+    MOZ_ASSUME_UNREACHABLE("NYI");
 }
 
 //__aeabi_uidiv
--- a/js/src/jit/arm/MacroAssembler-arm.cpp
+++ b/js/src/jit/arm/MacroAssembler-arm.cpp
@@ -775,17 +775,17 @@ MacroAssemblerARM::ma_cmn(Register src1,
 void
 MacroAssemblerARM::ma_cmn(Register src1, Register src2, Condition c)
 {
     as_alu(InvalidReg, src2, O2Reg(src1), OpCmn, SetCond, c);
 }
 void
 MacroAssemblerARM::ma_cmn(Register src1, Operand op, Condition c)
 {
-    MOZ_CRASH("Feature NYI");
+    MOZ_ASSUME_UNREACHABLE("Feature NYI");
 }
 
 // Compare (src - src2).
 void
 MacroAssemblerARM::ma_cmp(Register src1, Imm32 imm, Condition c)
 {
     ma_alu(src1, imm, InvalidReg, OpCmp, SetCond, c);
 }
@@ -809,17 +809,17 @@ MacroAssemblerARM::ma_cmp(Register src1,
       case Operand::OP2:
         as_cmp(src1, op.toOp2(), c);
         break;
       case Operand::MEM:
         ma_ldr(op, ScratchRegister);
         as_cmp(src1, O2Reg(ScratchRegister), c);
         break;
       default:
-        MOZ_CRASH("trying to compare FP and integer registers");
+        MOZ_ASSUME_UNREACHABLE("trying to compare FP and integer registers");
     }
 }
 void
 MacroAssemblerARM::ma_cmp(Register src1, Register src2, Condition c)
 {
     as_cmp(src1, O2Reg(src2), c);
 }
 
@@ -882,17 +882,17 @@ MacroAssemblerARM::ma_check_mul(Register
     }
 
     if (cond == Overflow) {
         as_smull(ScratchRegister, dest, src1, src2);
         as_cmp(ScratchRegister, asr(dest, 31));
         return NotEqual;
     }
 
-    MOZ_CRASH("Condition NYI");
+    MOZ_ASSUME_UNREACHABLE("Condition NYI");
 }
 
 Assembler::Condition
 MacroAssemblerARM::ma_check_mul(Register src1, Imm32 imm, Register dest, Condition cond)
 {
     ma_mov(imm, ScratchRegister);
     if (cond == Equal || cond == NotEqual) {
         as_smull(ScratchRegister, dest, ScratchRegister, src1, SetCond);
@@ -900,17 +900,17 @@ MacroAssemblerARM::ma_check_mul(Register
     }
 
     if (cond == Overflow) {
         as_smull(ScratchRegister, dest, ScratchRegister, src1);
         as_cmp(ScratchRegister, asr(dest, 31));
         return NotEqual;
     }
 
-    MOZ_CRASH("Condition NYI");
+    MOZ_ASSUME_UNREACHABLE("Condition NYI");
 }
 
 void
 MacroAssemblerARM::ma_mod_mask(Register src, Register dest, Register hold, Register tmp,
                                int32_t shift)
 {
     // We wish to compute x % (1<<y) - 1 for a known constant, y.
     //
@@ -1011,17 +1011,17 @@ MacroAssemblerARM::ma_dtr(LoadStore ls, 
 {
     ma_dataTransferN(ls, 32, true, rn, offset, rt, mode, cc);
 }
 
 void
 MacroAssemblerARM::ma_dtr(LoadStore ls, Register rn, Register rm, Register rt,
                           Index mode, Assembler::Condition cc)
 {
-    MOZ_CRASH("Feature NYI");
+    MOZ_ASSUME_UNREACHABLE("Feature NYI");
 }
 
 void
 MacroAssemblerARM::ma_str(Register rt, DTRAddr addr, Index mode, Condition cc)
 {
     as_dtr(IsStore, 32, mode, rt, addr, cc);
 }
 
@@ -1357,17 +1357,17 @@ MacroAssemblerARM::ma_b(void *target, Re
         as_bx(ScratchRegister, c);
         break;
       case Assembler::B_LDR:
         as_Imm32Pool(pc, trg, c);
         if (c == Always)
             m_buffer.markGuard();
         break;
       default:
-        MOZ_CRASH("Other methods of generating tracable jumps NYI");
+        MOZ_ASSUME_UNREACHABLE("Other methods of generating tracable jumps NYI");
     }
 }
 
 // This is almost NEVER necessary: we'll basically never be calling a label,
 // except possibly in the crazy bailout-table case.
 void
 MacroAssemblerARM::ma_bl(Label *dest, Assembler::Condition c)
 {
@@ -3481,17 +3481,17 @@ MacroAssemblerARMCompat::loadValue(Addre
                 break;
               case 0:
                 mode = IA;
                 break;
               case 4:
                 mode = IB;
                 break;
               default:
-                MOZ_CRASH("Bogus Offset for LoadValue as DTM");
+                MOZ_ASSUME_UNREACHABLE("Bogus Offset for LoadValue as DTM");
             }
             startDataTransferM(IsLoad, Register::FromCode(srcOp.base()), mode);
             transferReg(val.payloadReg());
             transferReg(val.typeReg());
             finishDataTransfer();
             return;
         }
     }
@@ -3551,17 +3551,18 @@ MacroAssemblerARMCompat::storePayload(co
 }
 void
 MacroAssemblerARMCompat::storePayload(Register src, Operand dest)
 {
     if (dest.getTag() == Operand::MEM) {
         ma_str(src, ToPayload(dest));
         return;
     }
-    MOZ_CRASH("unexpected operand");
+    MOZ_ASSUME_UNREACHABLE("why do we do all of these things?");
+
 }
 
 void
 MacroAssemblerARMCompat::storePayload(const Value &val, const BaseIndex &dest)
 {
     unsigned shift = ScaleToShift(dest.scale);
     MOZ_ASSERT(dest.offset == 0);
 
@@ -3599,17 +3600,19 @@ MacroAssemblerARMCompat::storePayload(Re
 
 void
 MacroAssemblerARMCompat::storeTypeTag(ImmTag tag, Operand dest) {
     if (dest.getTag() == Operand::MEM) {
         ma_mov(tag, secondScratchReg_);
         ma_str(secondScratchReg_, ToType(dest));
         return;
     }
-    MOZ_CRASH("unexpected operand");
+
+    MOZ_ASSUME_UNREACHABLE("why do we do all of these things?");
+
 }
 
 void
 MacroAssemblerARMCompat::storeTypeTag(ImmTag tag, const BaseIndex &dest)
 {
     Register base = dest.base;
     Register index = dest.index;
     unsigned shift = ScaleToShift(dest.scale);
@@ -3813,17 +3816,17 @@ MacroAssemblerARMCompat::passHardFpABIAr
             uint32_t disp = GetIntArgStackDisp(usedIntSlots_, usedFloatSlots_, &padding_);
             to = MoveOperand(sp, disp);
         }
         usedIntSlots_++;
         passedArgTypes_ = (passedArgTypes_ << ArgType_Shift) | ArgType_General;
         break;
       }
       default:
-        MOZ_CRASH("Unexpected argument type");
+        MOZ_ASSUME_UNREACHABLE("Unexpected argument type");
     }
 
     enoughMemory_ = moveResolver_.addMove(from, to, type);
 }
 #endif
 
 #if !defined(JS_CODEGEN_ARM_HARDFP) || defined(JS_ARM_SIMULATOR)
 void
@@ -3843,17 +3846,17 @@ MacroAssemblerARMCompat::passSoftFpABIAr
         break;
       case MoveOp::FLOAT32:
         passedArgTypes_ = (passedArgTypes_ << ArgType_Shift) | ArgType_Float32;
         break;
       case MoveOp::GENERAL:
         passedArgTypes_ = (passedArgTypes_ << ArgType_Shift) | ArgType_General;
         break;
       default:
-        MOZ_CRASH("Unexpected argument type");
+        MOZ_ASSUME_UNREACHABLE("Unexpected argument type");
     }
 
     Register destReg;
     MoveOperand dest;
     if (GetIntArgReg(usedIntSlots_, 0, &destReg)) {
         if (type == MoveOp::DOUBLE || type == MoveOp::FLOAT32) {
             floatArgsInGPR[destReg.code() >> 1] = from;
             floatArgsInGPRValid[destReg.code() >> 1] = true;
@@ -3990,17 +3993,17 @@ MacroAssemblerARMCompat::callWithABIPost
             // Move float32 from r0 to ReturnFloatReg.
             as_vxfer(r0, InvalidReg, ReturnFloat32Reg.singleOverlay(), CoreToFloat);
             break;
         }
       case MoveOp::GENERAL:
         break;
 
       default:
-        MOZ_CRASH("unexpected callWithABI result");
+        MOZ_ASSUME_UNREACHABLE("unexpected callWithABI result");
     }
 
     freeStack(stackAdjust);
 
     if (dynamicAlignment_) {
         // While the x86 supports pop esp, on ARM that isn't well defined, so
         // just do it manually.
         as_dtr(IsLoad, 32, Offset, sp, DTRAddr(sp, DtrOffImm(0)));
@@ -4030,32 +4033,32 @@ AssertValidABIFunctionType(uint32_t pass
       case Args_Double_Double:
       case Args_Double_Int:
       case Args_Double_DoubleInt:
       case Args_Double_DoubleDouble:
       case Args_Double_IntDouble:
       case Args_Int_IntDouble:
         break;
       default:
-        MOZ_CRASH("Unexpected type");
+        MOZ_ASSUME_UNREACHABLE("Unexpected type");
     }
 }
 #endif
 
 void
 MacroAssemblerARMCompat::callWithABI(void *fun, MoveOp::Type result)
 {
 #ifdef JS_ARM_SIMULATOR
     MOZ_ASSERT(passedArgs_ <= 15);
     passedArgTypes_ <<= ArgType_Shift;
     switch (result) {
       case MoveOp::GENERAL: passedArgTypes_ |= ArgType_General; break;
       case MoveOp::DOUBLE:  passedArgTypes_ |= ArgType_Double;  break;
       case MoveOp::FLOAT32: passedArgTypes_ |= ArgType_Float32; break;
-      default: MOZ_CRASH("Invalid return type");
+      default: MOZ_ASSUME_UNREACHABLE("Invalid return type");
     }
 #ifdef DEBUG
     AssertValidABIFunctionType(passedArgTypes_);
 #endif
     ABIFunctionType type = ABIFunctionType(passedArgTypes_);
     fun = Simulator::RedirectNativeFunction(fun, type);
 #endif
 
--- a/js/src/jit/arm/MacroAssembler-arm.h
+++ b/js/src/jit/arm/MacroAssembler-arm.h
@@ -415,17 +415,17 @@ class MacroAssemblerARM : public Assembl
         if (mode == IA) {
             return transferMultipleByRunsImpl
                 <FloatRegisterForwardIterator>(set, ls, rm, mode, 1);
         }
         if (mode == DB) {
             return transferMultipleByRunsImpl
                 <FloatRegisterBackwardIterator>(set, ls, rm, mode, -1);
         }
-        MOZ_CRASH("Invalid data transfer addressing mode");
+        MOZ_ASSUME_UNREACHABLE("Invalid data transfer addressing mode");
     }
 
 private:
     // Implementation for transferMultipleByRuns so we can use different
     // iterators for forward/backward traversals. The sign argument should be 1
     // if we traverse forwards, -1 if we traverse backwards.
     template<typename RegisterIterator> int32_t
     transferMultipleByRunsImpl(FloatRegisterSet set, LoadStore ls,
@@ -525,20 +525,20 @@ class MacroAssemblerARMCompat : public M
     }
     void mov(ImmWord imm, Register dest) {
         ma_mov(Imm32(imm.value), dest);
     }
     void mov(ImmPtr imm, Register dest) {
         mov(ImmWord(uintptr_t(imm.value)), dest);
     }
     void mov(Register src, Address dest) {
-        MOZ_CRASH("NYI-IC");
+        MOZ_ASSUME_UNREACHABLE("NYI-IC");
     }
     void mov(Address src, Register dest) {
-        MOZ_CRASH("NYI-IC");
+        MOZ_ASSUME_UNREACHABLE("NYI-IC");
     }
 
     void call(const Register reg) {
         as_blx(reg);
     }
     void call(Label *label) {
         // For now, assume that it'll be nearby?
         as_bl(label, Always);
--- a/js/src/jit/arm/MoveEmitter-arm.cpp
+++ b/js/src/jit/arm/MoveEmitter-arm.cpp
@@ -131,17 +131,17 @@ MoveEmitterARM::breakCycle(const MoveOpe
                 // If the destination was spilled, restore it first.
                 masm.ma_ldr(spillSlot(), spilledReg_);
                 spilledReg_ = InvalidReg;
             }
             masm.ma_str(to.reg(), cycleSlot());
         }
         break;
       default:
-        MOZ_CRASH("Unexpected move type");
+        MOZ_ASSUME_UNREACHABLE("Unexpected move type");
     }
 }
 
 void
 MoveEmitterARM::completeCycle(const MoveOperand &from, const MoveOperand &to, MoveOp::Type type)
 {
     // There is some pattern:
     //   (A -> B)
@@ -170,17 +170,17 @@ MoveEmitterARM::completeCycle(const Move
             if (to.reg() == spilledReg_) {
                 // Make sure we don't re-clobber the spilled register later.
                 spilledReg_ = InvalidReg;
             }
             masm.ma_ldr(cycleSlot(), to.reg());
         }
         break;
       default:
-        MOZ_CRASH("Unexpected move type");
+        MOZ_ASSUME_UNREACHABLE("Unexpected move type");
     }
 }
 
 void
 MoveEmitterARM::emitMove(const MoveOperand &from, const MoveOperand &to)
 {
     if (to.isGeneralReg() && to.reg() == spilledReg_) {
         // If the destination is the spilled register, make sure we
@@ -199,17 +199,17 @@ MoveEmitterARM::emitMove(const MoveOpera
           case Operand::OP2:
             // secretly must be a register
             masm.ma_mov(from.reg(), to.reg());
             break;
           case Operand::MEM:
             masm.ma_str(from.reg(), toOperand(to, false));
             break;
           default:
-            MOZ_CRASH("strange move!");
+            MOZ_ASSUME_UNREACHABLE("strange move!");
         }
     } else if (to.isGeneralReg()) {
         JS_ASSERT(from.isMemoryOrEffectiveAddress());
         if (from.isMemory())
             masm.ma_ldr(toOperand(from, false), to.reg());
         else
             masm.ma_add(from.base(), Imm32(from.disp()), to.reg());
     } else {
@@ -294,17 +294,17 @@ MoveEmitterARM::emit(const MoveOp &move)
       case MoveOp::DOUBLE:
         emitDoubleMove(from, to);
         break;
       case MoveOp::INT32:
       case MoveOp::GENERAL:
         emitMove(from, to);
         break;
       default:
-        MOZ_CRASH("Unexpected move type");
+        MOZ_ASSUME_UNREACHABLE("Unexpected move type");
     }
 }
 
 void
 MoveEmitterARM::assertDone()
 {
     JS_ASSERT(!inCycle_);
 }
--- a/js/src/jit/arm/Simulator-arm.cpp
+++ b/js/src/jit/arm/Simulator-arm.cpp
@@ -1648,18 +1648,19 @@ Simulator::conditionallyExecute(SimInstr
       case Assembler::VC: return !v_flag_;
       case Assembler::HI: return c_flag_ && !z_flag_;
       case Assembler::LS: return !c_flag_ || z_flag_;
       case Assembler::GE: return n_flag_ == v_flag_;
       case Assembler::LT: return n_flag_ != v_flag_;
       case Assembler::GT: return !z_flag_ && (n_flag_ == v_flag_);
       case Assembler::LE: return z_flag_ || (n_flag_ != v_flag_);
       case Assembler::AL: return true;
+      default: MOZ_ASSUME_UNREACHABLE();
     }
-    MOZ_CRASH("unexpected condition field");
+    return false;
 }
 
 // Calculate and set the Negative and Zero flags.
 void
 Simulator::setNZFlags(int32_t val)
 {
     n_flag_ = (val < 0);
     z_flag_ = (val == 0);
@@ -1762,17 +1763,18 @@ int32_t
 Simulator::getShiftRm(SimInstruction *instr, bool *carry_out)
 {
     ShiftType shift = instr->shifttypeValue();
     int shift_amount = instr->shiftAmountValue();
     int32_t result = get_register(instr->rmValue());
     if (instr->bit(4) == 0) {
         // By immediate.
         if (shift == ROR && shift_amount == 0) {
-            MOZ_CRASH("NYI");
+            MOZ_ASSUME_UNREACHABLE("NYI");
+            return result;
         }
         if ((shift == LSR || shift == ASR) && shift_amount == 0)
             shift_amount = 32;
         switch (shift) {
           case ASR: {
             if (shift_amount == 0) {
                 if (result < 0) {
                     result = 0xffffffff;
@@ -1822,17 +1824,18 @@ Simulator::getShiftRm(SimInstruction *in
                 uint32_t right = static_cast<uint32_t>(result) << (32 - shift_amount);
                 result = right | left;
                 *carry_out = (static_cast<uint32_t>(result) >> 31) != 0;
             }
             break;
           }
 
           default:
-            MOZ_CRASH("Unexpected shift");
+            MOZ_ASSUME_UNREACHABLE();
+            break;
         }
     } else {
         // By register.
         int rs = instr->rsValue();
         shift_amount = get_register(rs) &0xff;
         switch (shift) {
           case ASR: {
             if (shift_amount == 0) {
@@ -1899,17 +1902,18 @@ Simulator::getShiftRm(SimInstruction *in
                 uint32_t right = static_cast<uint32_t>(result) << (32 - shift_amount);
                 result = right | left;
                 *carry_out = (static_cast<uint32_t>(result) >> 31) != 0;
             }
             break;
           }
 
           default:
-            MOZ_CRASH("Unexpected shift");
+            MOZ_ASSUME_UNREACHABLE();
+            break;
         }
     }
     return result;
 }
 
 // Addressing Mode 1 - Data-processing operands:
 // Get the value based on the shifter_operand with immediate.
 int32_t
@@ -1925,34 +1929,36 @@ Simulator::getImm(SimInstruction *instr,
 int32_t
 Simulator::processPU(SimInstruction *instr, int num_regs, int reg_size,
                      intptr_t *start_address, intptr_t *end_address)
 {
     int rn = instr->rnValue();
     int32_t rn_val = get_register(rn);
     switch (instr->PUField()) {
       case da_x:
-        MOZ_CRASH("Unexpected PUField: da_x");
+        MOZ_CRASH();
+        break;
       case ia_x:
         *start_address = rn_val;
         *end_address = rn_val + (num_regs * reg_size) - reg_size;
         rn_val = rn_val + (num_regs * reg_size);
         break;
       case db_x:
         *start_address = rn_val - (num_regs * reg_size);
         *end_address = rn_val - reg_size;
         rn_val = *start_address;
         break;
       case ib_x:
         *start_address = rn_val + reg_size;
         *end_address = rn_val + (num_regs * reg_size);
         rn_val = *end_address;
         break;
       default:
-        MOZ_CRASH("Unexpected PUField");
+        MOZ_ASSUME_UNREACHABLE();
+        break;
     }
     return rn_val;
 }
 
 // Addressing Mode 4 - Load and Store Multiple
 void
 Simulator::handleRList(SimInstruction *instr, bool load)
 {
@@ -2280,17 +2286,17 @@ Simulator::softwareInterrupt(SimInstruct
                 dval0 = get_double_from_register_pair(2);
             Prototype_Int_IntDouble target = reinterpret_cast<Prototype_Int_IntDouble>(external);
             int32_t result = target(ival, dval0);
             scratchVolatileRegisters(/* scratchFloat = true */);
             set_register(r0, result);
             break;
           }
           default:
-            MOZ_CRASH("call");
+            MOZ_ASSUME_UNREACHABLE("call");
         }
 
         set_register(lr, saved_lr);
         set_pc(get_register(lr));
         break;
       }
       case kBreakpoint: {
         ArmDebugger dbg(this);
@@ -3321,17 +3327,17 @@ Simulator::decodeTypeVFP(SimInstruction 
                 dd_value = canonicalizeNaN(dd_value);
                 set_d_register_from_double(vd, dd_value);
             }
         } else if ((instr->opc1Value() == 0x0)) {
             // vmla, vmls
             const bool is_vmls = (instr->opc3Value() & 0x1);
 
             if (instr->szValue() != 0x1)
-                MOZ_CRASH("Not used by V8.");
+                MOZ_ASSUME_UNREACHABLE();  // Not used by V8.
 
             const double dd_val = get_double_from_d_register(vd);
             const double dn_val = get_double_from_d_register(vn);
             const double dm_val = get_double_from_d_register(vm);
 
             // Note: we do the mul and add/sub in separate steps to avoid
             // getting a result with too high precision.
             set_d_register_from_double(vd, dn_val * dm_val);
@@ -3728,17 +3734,17 @@ Simulator::decodeVCVTBetweenFloatingPoin
         if (double_precision) {
             uint32_t dbl[2];
             dbl[0] = temp; dbl[1] = 0;
             set_d_register(dst, dbl);
         } else {
             set_s_register_from_sinteger(dst, temp);
         }
     } else {
-        MOZ_CRASH("Not implemented, fixed to float.");
+        MOZ_ASSUME_UNREACHABLE();  // Not implemented, fixed to float.
     }
 }
 
 void
 Simulator::decodeType6CoprocessorIns(SimInstruction *instr)
 {
     MOZ_ASSERT(instr->typeValue() == 6);
 
--- a/js/src/jit/arm/Trampoline-arm.cpp
+++ b/js/src/jit/arm/Trampoline-arm.cpp
@@ -686,17 +686,17 @@ JitRuntime::generateBailoutHandler(JSCon
     switch (mode) {
       case SequentialExecution:
         GenerateBailoutThunk(cx, masm, NO_FRAME_SIZE_CLASS_ID);
         break;
       case ParallelExecution:
         GenerateParallelBailoutThunk(masm, NO_FRAME_SIZE_CLASS_ID);
         break;
       default:
-        MOZ_CRASH("No such execution mode");
+        MOZ_ASSUME_UNREACHABLE("No such execution mode");
     }
 
     Linker linker(masm);
     AutoFlushICache afc("BailoutHandler");
     JitCode *code = linker.newCode<NoGC>(cx, JSC::OTHER_CODE);
 
 #ifdef JS_ION_PERF
     writePerfSpewerJitCodeProfile(code, "BailoutHandler");
@@ -820,17 +820,17 @@ JitRuntime::generateVMWrapper(JSContext 
     switch (f.failType()) {
       case Type_Object:
         masm.branchTestPtr(Assembler::Zero, r0, r0, masm.failureLabel(f.executionMode));
         break;
       case Type_Bool:
         masm.branchIfFalseBool(r0, masm.failureLabel(f.executionMode));
         break;
       default:
-        MOZ_CRASH("unknown failure kind");
+        MOZ_ASSUME_UNREACHABLE("unknown failure kind");
     }
 
     // Load the outparam and free any allocated stack.
     switch (f.outParam) {
       case Type_Handle:
         masm.popRooted(f.outParamRootType, ReturnReg, JSReturnOperand);
         break;
 
--- a/js/src/jit/mips/Assembler-mips.cpp
+++ b/js/src/jit/mips/Assembler-mips.cpp
@@ -54,17 +54,17 @@ ABIArgGenerator::next(MIRType type)
             usedArgSlots_ = 4;
         } else {
             usedArgSlots_ += usedArgSlots_ % 2;
             current_ = ABIArg(usedArgSlots_ * sizeof(intptr_t));
             usedArgSlots_ += 2;
         }
         break;
       default:
-        MOZ_CRASH("Unexpected argument type");
+        MOZ_ASSUME_UNREACHABLE("Unexpected argument type");
     }
     return current_;
 
 }
 const Register ABIArgGenerator::NonArgReturnVolatileReg0 = t0;
 const Register ABIArgGenerator::NonArgReturnVolatileReg1 = t1;
 
 // Encode a standard register when it is being used as rd, the rs, and
@@ -378,17 +378,18 @@ Assembler::InvertCondition(Condition con
         return AboveOrEqual;
       case BelowOrEqual:
         return Above;
       case Signed:
         return NotSigned;
       case NotSigned:
         return Signed;
       default:
-        MOZ_CRASH("unexpected condition");
+        MOZ_ASSUME_UNREACHABLE("unexpected condition");
+        return Equal;
     }
 }
 
 Assembler::DoubleCondition
 Assembler::InvertCondition(DoubleCondition cond)
 {
     switch (cond) {
       case DoubleOrdered:
@@ -415,17 +416,18 @@ Assembler::InvertCondition(DoubleConditi
         return DoubleLessThanOrEqual;
       case DoubleGreaterThanOrEqualOrUnordered:
         return DoubleLessThan;
       case DoubleLessThanOrUnordered:
         return DoubleGreaterThanOrEqual;
       case DoubleLessThanOrEqualOrUnordered:
         return DoubleGreaterThan;
       default:
-        MOZ_CRASH("unexpected condition");
+        MOZ_ASSUME_UNREACHABLE("unexpected condition");
+        return DoubleEqual;
     }
 }
 
 BOffImm16::BOffImm16(InstImm inst)
   : data(inst.encode() & Imm16Mask)
 {
 }
 
@@ -615,17 +617,17 @@ Assembler::getBranchCode(Register s, Con
       case Assembler::NotSigned:
         return InstImm(op_regimm, s, rt_bgez, BOffImm16(0));
       case Assembler::LessThan:
       case Assembler::Signed:
         return InstImm(op_regimm, s, rt_bltz, BOffImm16(0));
       case Assembler::LessThanOrEqual:
         return InstImm(op_blez, s, zero, BOffImm16(0));
       default:
-        MOZ_CRASH("Condition not supported.");
+        MOZ_ASSUME_UNREACHABLE("Condition not supported.");
     }
 }
 
 InstImm
 Assembler::getBranchCode(FloatTestKind testKind, FPConditionBit fcc)
 {
     MOZ_ASSERT(!(fcc && FccMask));
     uint32_t rtField = ((testKind == TestForTrue ? 1 : 0) | (fcc << FccShift)) << RTShift;
@@ -1505,31 +1507,33 @@ InstImm Assembler::invertBranch(InstImm 
             branch.setRT(rt_bgez);
             return branch;
         }
         if (rt == (rt_bgez >> RTShift)) {
             branch.setRT(rt_bltz);
             return branch;
         }
 
-        MOZ_CRASH("Error creating long branch.");
+        MOZ_ASSUME_UNREACHABLE("Error creating long branch.");
+        return branch;
 
       case op_cop1:
         MOZ_ASSERT(branch.extractRS() == rs_bc1 >> RSShift);
 
         branch.setBOffImm16(skipOffset);
         rt = branch.extractRT();
         if (rt & 0x1)
             branch.setRT((RTField) ((rt & ~0x1) << RTShift));
         else
             branch.setRT((RTField) ((rt | 0x1) << RTShift));
         return branch;
     }
 
-    MOZ_CRASH("Error creating long branch.");
+    MOZ_ASSUME_UNREACHABLE("Error creating long branch.");
+    return branch;
 }
 
 void
 Assembler::ToggleToJmp(CodeLocationLabel inst_)
 {
     InstImm * inst = (InstImm *)inst_.raw();
 
     MOZ_ASSERT(inst->extractOpcode() == ((uint32_t)op_andi >> OpcodeShift));
--- a/js/src/jit/mips/Bailouts-mips.cpp
+++ b/js/src/jit/mips/Bailouts-mips.cpp
@@ -22,17 +22,17 @@ IonBailoutIterator::IonBailoutIterator(c
 
     kind_ = Kind_BailoutIterator;
     current_ = fp;
     type_ = JitFrame_IonJS;
     topFrameSize_ = current_ - sp;
     switch (mode_) {
       case SequentialExecution: topIonScript_ = script()->ionScript(); break;
       case ParallelExecution: topIonScript_ = script()->parallelIonScript(); break;
-      default: MOZ_CRASH("No such execution mode");
+      default: MOZ_ASSUME_UNREACHABLE("No such execution mode");
     }
 
     if (bailout->frameClass() == FrameSizeClass::None()) {
         snapshotOffset_ = bailout->snapshotOffset();
         return;
     }
 
     // Compute the snapshot offset from the bailout ID.
--- a/js/src/jit/mips/BaselineIC-mips.cpp
+++ b/js/src/jit/mips/BaselineIC-mips.cpp
@@ -175,17 +175,17 @@ ICBinaryArith_Int32::Compiler::generateS
             masm.boxDouble(FloatReg1, R0);
         } else {
             masm.ma_b(scratchReg, Imm32(0), &failure, Assembler::LessThan, ShortJump);
             // Move result for return.
             masm.move32(scratchReg, R0.payloadReg());
         }
         break;
       default:
-        MOZ_CRASH("Unhandled op for BinaryArith_Int32.");
+        MOZ_ASSUME_UNREACHABLE("Unhandled op for BinaryArith_Int32.");
     }
 
     EmitReturnFromIC(masm);
 
     // Failure case - jump to next stub
     masm.bind(&failure);
     EmitStubGuardFailure(masm);
 
@@ -204,17 +204,17 @@ ICUnaryArith_Int32::Compiler::generateSt
         break;
       case JSOP_NEG:
         // Guard against 0 and MIN_INT, both result in a double.
         masm.branchTest32(Assembler::Zero, R0.payloadReg(), Imm32(INT32_MAX), &failure);
 
         masm.neg32(R0.payloadReg());
         break;
       default:
-        MOZ_CRASH("Unexpected op");
+        MOZ_ASSUME_UNREACHABLE("Unexpected op");
         return false;
     }
 
     EmitReturnFromIC(masm);
 
     masm.bind(&failure);
     EmitStubGuardFailure(masm);
     return true;
--- a/js/src/jit/mips/CodeGenerator-mips.cpp
+++ b/js/src/jit/mips/CodeGenerator-mips.cpp
@@ -842,17 +842,17 @@ CodeGeneratorMIPS::visitBitOpI(LBitOpI *
         break;
       case JSOP_BITAND:
         if (rhs->isConstant())
             masm.ma_and(ToRegister(dest), ToRegister(lhs), Imm32(ToInt32(rhs)));
         else
             masm.ma_and(ToRegister(dest), ToRegister(lhs), ToRegister(rhs));
         break;
       default:
-        MOZ_CRASH("unexpected binary opcode");
+        MOZ_ASSUME_UNREACHABLE("unexpected binary opcode");
     }
 
     return true;
 }
 
 bool
 CodeGeneratorMIPS::visitShiftI(LShiftI *ins)
 {
@@ -883,17 +883,17 @@ CodeGeneratorMIPS::visitShiftI(LShiftI *
                 masm.move32(lhs, dest);
                 if (ins->mir()->toUrsh()->fallible()) {
                     if (!bailoutCmp32(Assembler::LessThan, dest, Imm32(0), ins->snapshot()))
                         return false;
                 }
             }
             break;
           default:
-            MOZ_CRASH("Unexpected shift op");
+            MOZ_ASSUME_UNREACHABLE("Unexpected shift op");
         }
     } else {
         // The shift amounts should be AND'ed into the 0-31 range
         masm.ma_and(dest, ToRegister(rhs), Imm32(0x1F));
 
         switch (ins->bitop()) {
           case JSOP_LSH:
             masm.ma_sll(dest, lhs, dest);
@@ -905,17 +905,17 @@ CodeGeneratorMIPS::visitShiftI(LShiftI *
             masm.ma_srl(dest, lhs, dest);
             if (ins->mir()->toUrsh()->fallible()) {
                 // x >>> 0 can overflow.
                 if (!bailoutCmp32(Assembler::LessThan, dest, Imm32(0), ins->snapshot()))
                     return false;
             }
             break;
           default:
-            MOZ_CRASH("Unexpected shift op");
+            MOZ_ASSUME_UNREACHABLE("Unexpected shift op");
         }
     }
 
     return true;
 }
 
 bool
 CodeGeneratorMIPS::visitUrshD(LUrshD *ins)
@@ -1072,17 +1072,17 @@ CodeGeneratorMIPS::visitMathD(LMathD *ma
         break;
       case JSOP_MUL:
         masm.as_muld(ToFloatRegister(output), ToFloatRegister(src1), ToFloatRegister(src2));
         break;
       case JSOP_DIV:
         masm.as_divd(ToFloatRegister(output), ToFloatRegister(src1), ToFloatRegister(src2));
         break;
       default:
-        MOZ_CRASH("unexpected opcode");
+        MOZ_ASSUME_UNREACHABLE("unexpected opcode");
     }
     return true;
 }
 
 bool
 CodeGeneratorMIPS::visitMathF(LMathF *math)
 {
     const LAllocation *src1 = math->getOperand(0);
@@ -1098,17 +1098,17 @@ CodeGeneratorMIPS::visitMathF(LMathF *ma
         break;
       case JSOP_MUL:
         masm.as_muls(ToFloatRegister(output), ToFloatRegister(src1), ToFloatRegister(src2));
         break;
       case JSOP_DIV:
         masm.as_divs(ToFloatRegister(output), ToFloatRegister(src1), ToFloatRegister(src2));
         break;
       default:
-        MOZ_CRASH("unexpected opcode");
+        MOZ_ASSUME_UNREACHABLE("unexpected opcode");
     }
     return true;
 }
 
 bool
 CodeGeneratorMIPS::visitFloor(LFloor *lir)
 {
     FloatRegister input = ToFloatRegister(lir->input());
@@ -1888,23 +1888,23 @@ DispatchIonCache::initializeAddCacheStat
 {
     // Can always use the scratch register on MIPS.
     addState->dispatchScratch = ScratchRegister;
 }
 
 bool
 CodeGeneratorMIPS::visitLoadTypedArrayElementStatic(LLoadTypedArrayElementStatic *ins)
 {
-    MOZ_CRASH("NYI");
+    MOZ_ASSUME_UNREACHABLE("NYI");
 }
 
 bool
 CodeGeneratorMIPS::visitStoreTypedArrayElementStatic(LStoreTypedArrayElementStatic *ins)
 {
-    MOZ_CRASH("NYI");
+    MOZ_ASSUME_UNREACHABLE("NYI");
 }
 
 bool
 CodeGeneratorMIPS::visitAsmJSLoadHeap(LAsmJSLoadHeap *ins)
 {
     const MAsmJSLoadHeap *mir = ins->mir();
     const LAllocation *ptr = ins->ptr();
     const LDefinition *out = ins->output();
@@ -1916,17 +1916,17 @@ CodeGeneratorMIPS::visitAsmJSLoadHeap(LA
       case ArrayBufferView::TYPE_INT8:    isSigned = true;  size =  8; break;
       case ArrayBufferView::TYPE_UINT8:   isSigned = false; size =  8; break;
       case ArrayBufferView::TYPE_INT16:   isSigned = true;  size = 16; break;
       case ArrayBufferView::TYPE_UINT16:  isSigned = false; size = 16; break;
       case ArrayBufferView::TYPE_INT32:   isSigned = true;  size = 32; break;
       case ArrayBufferView::TYPE_UINT32:  isSigned = false; size = 32; break;
       case ArrayBufferView::TYPE_FLOAT64: isFloat  = true;  size = 64; break;
       case ArrayBufferView::TYPE_FLOAT32: isFloat  = true;  size = 32; break;
-      default: MOZ_CRASH("unexpected array type");
+      default: MOZ_ASSUME_UNREACHABLE("unexpected array type");
     }
 
     if (ptr->isConstant()) {
         MOZ_ASSERT(mir->skipBoundsCheck());
         int32_t ptrImm = ptr->toConstant()->toInt32();
         MOZ_ASSERT(ptrImm >= 0);
         if (isFloat) {
             if (size == 32) {
@@ -2003,17 +2003,17 @@ CodeGeneratorMIPS::visitAsmJSStoreHeap(L
       case ArrayBufferView::TYPE_INT8:    isSigned = true;  size = 8;  break;
       case ArrayBufferView::TYPE_UINT8:   isSigned = false; size = 8;  break;
       case ArrayBufferView::TYPE_INT16:   isSigned = true;  size = 16; break;
       case ArrayBufferView::TYPE_UINT16:  isSigned = false; size = 16; break;
       case ArrayBufferView::TYPE_INT32:   isSigned = true;  size = 32; break;
       case ArrayBufferView::TYPE_UINT32:  isSigned = false; size = 32; break;
       case ArrayBufferView::TYPE_FLOAT64: isFloat  = true;  size = 64; break;
       case ArrayBufferView::TYPE_FLOAT32: isFloat  = true;  size = 32; break;
-      default: MOZ_CRASH("unexpected array type");
+      default: MOZ_ASSUME_UNREACHABLE("unexpected array type");
     }
 
     if (ptr->isConstant()) {
         MOZ_ASSERT(mir->skipBoundsCheck());
         int32_t ptrImm = ptr->toConstant()->toInt32();
         MOZ_ASSERT(ptrImm >= 0);
 
         if (isFloat) {
@@ -2247,16 +2247,16 @@ CodeGeneratorMIPS::visitNegF(LNegF *ins)
 
     masm.as_negs(output, input);
     return true;
 }
 
 bool
 CodeGeneratorMIPS::visitForkJoinGetSlice(LForkJoinGetSlice *ins)
 {
-    MOZ_CRASH("NYI");
+    MOZ_ASSUME_UNREACHABLE("NYI");
 }
 
 JitCode *
 JitRuntime::generateForkJoinGetSliceStub(JSContext *cx)
 {
-    MOZ_CRASH("NYI");
+    MOZ_ASSUME_UNREACHABLE("NYI");
 }
--- a/js/src/jit/mips/CodeGenerator-mips.h
+++ b/js/src/jit/mips/CodeGenerator-mips.h
@@ -70,17 +70,17 @@ class CodeGeneratorMIPS : public CodeGen
         return goodBailout;
     }
     template<typename T>
     bool bailoutCmp32(Assembler::Condition c, Operand lhs, T rhs, LSnapshot *snapshot) {
         if (lhs.getTag() == Operand::REG)
               return bailoutCmp32(c, lhs.toReg(), rhs, snapshot);
         if (lhs.getTag() == Operand::MEM)
               return bailoutCmp32(c, lhs.toAddress(), rhs, snapshot);
-        MOZ_CRASH("Invalid operand tag.");
+        MOZ_ASSUME_UNREACHABLE("Invalid operand tag.");
         return false;
     }
     template<typename T>
     bool bailoutTest32(Assembler::Condition c, Register lhs, T rhs, LSnapshot *snapshot) {
         Label bail;
         masm.branchTest32(c, lhs, rhs, &bail);
         return bailoutFrom(&bail, snapshot);
     }
--- a/js/src/jit/mips/Lowering-mips.cpp
+++ b/js/src/jit/mips/Lowering-mips.cpp
@@ -518,16 +518,16 @@ LIRGeneratorMIPS::lowerTruncateFToInt32(
     MOZ_ASSERT(opd->type() == MIRType_Float32);
 
     return define(new(alloc()) LTruncateFToInt32(useRegister(opd), LDefinition::BogusTemp()), ins);
 }
 
 bool
 LIRGeneratorMIPS::visitStoreTypedArrayElementStatic(MStoreTypedArrayElementStatic *ins)
 {
-    MOZ_CRASH("NYI");
+    MOZ_ASSUME_UNREACHABLE("NYI");
 }
 
 bool
 LIRGeneratorMIPS::visitForkJoinGetSlice(MForkJoinGetSlice *ins)
 {
-    MOZ_CRASH("NYI");
+    MOZ_ASSUME_UNREACHABLE("NYI");
 }
--- a/js/src/jit/mips/MacroAssembler-mips.cpp
+++ b/js/src/jit/mips/MacroAssembler-mips.cpp
@@ -723,17 +723,18 @@ MacroAssemblerMIPS::ma_load(Register des
             as_lhu(dest, base, encodedOffset);
         else
             as_lh(dest, base, encodedOffset);
         break;
       case SizeWord:
         as_lw(dest, base, encodedOffset);
         break;
       default:
-        MOZ_CRASH("Invalid argument for ma_load");
+        MOZ_ASSUME_UNREACHABLE("Invalid argument for ma_load");
+        break;
     }
 }
 
 void
 MacroAssemblerMIPS::ma_load(Register dest, const BaseIndex &src,
                             LoadStoreSize size, LoadStoreExtension extension)
 {
     computeScaledAddress(src, SecondScratchReg);
@@ -762,17 +763,18 @@ MacroAssemblerMIPS::ma_store(Register da
         break;
       case SizeHalfWord:
         as_sh(data, base, encodedOffset);
         break;
       case SizeWord:
         as_sw(data, base, encodedOffset);
         break;
       default:
-        MOZ_CRASH("Invalid argument for ma_store");
+        MOZ_ASSUME_UNREACHABLE("Invalid argument for ma_store");
+        break;
     }
 }
 
 void
 MacroAssemblerMIPS::ma_store(Register data, const BaseIndex &dest,
                              LoadStoreSize size, LoadStoreExtension extension)
 {
     computeScaledAddress(dest, SecondScratchReg);
@@ -1063,21 +1065,23 @@ MacroAssemblerMIPS::ma_cmp(Register scra
         return Equal;
       case Equal :
       case NotEqual:
       case Zero:
       case NonZero:
       case Always:
       case Signed:
       case NotSigned:
-        MOZ_CRASH("There is a better way to compare for equality.");
+        MOZ_ASSUME_UNREACHABLE("There is a better way to compare for equality.");
+        break;
       case Overflow:
-        MOZ_CRASH("Overflow condition not supported for MIPS.");
+        MOZ_ASSUME_UNREACHABLE("Overflow condition not supported for MIPS.");
+        break;
       default:
-        MOZ_CRASH("Invalid condition for branch.");
+        MOZ_ASSUME_UNREACHABLE("Invalid condition for branch.");
     }
     return Always;
 }
 
 void
 MacroAssemblerMIPS::ma_cmp_set(Register rd, Register rs, Register rt, Condition c)
 {
     switch (c) {
@@ -1162,17 +1166,18 @@ MacroAssemblerMIPS::ma_cmp_set(Register 
       case NotSigned:
         // sge d,s,$zero =>
         //   slt d,s,$zero
         //   xori d,d,1
         as_slt(rd, rs, zero);
         as_xori(rd, rd, 1);
         break;
       default:
-        MOZ_CRASH("Invalid condition for ma_cmp_set.");
+        MOZ_ASSUME_UNREACHABLE("Invalid condition for ma_cmp_set.");
+        break;
     }
 }
 
 void
 MacroAssemblerMIPS::compareFloatingPoint(FloatFormat fmt, FloatRegister lhs, FloatRegister rhs,
                                          DoubleCondition c, FloatTestKind *testKind,
                                          FPConditionBit fcc)
 {
@@ -1229,17 +1234,18 @@ MacroAssemblerMIPS::compareFloatingPoint
         as_cult(fmt, lhs, rhs, fcc);
         *testKind = TestForTrue;
         break;
       case DoubleLessThanOrEqualOrUnordered:
         as_cule(fmt, lhs, rhs, fcc);
         *testKind = TestForTrue;
         break;
       default:
-        MOZ_CRASH("Invalid DoubleCondition.");
+        MOZ_ASSUME_UNREACHABLE("Invalid DoubleCondition.");
+        break;
     }
 }
 
 void
 MacroAssemblerMIPS::ma_cmp_set_double(Register dest, FloatRegister lhs, FloatRegister rhs,
                                       DoubleCondition c)
 {
     ma_li(dest, Imm32(0));
@@ -3179,17 +3185,17 @@ MacroAssemblerMIPSCompat::passABIArg(con
         } else {
             uint32_t disp = GetArgStackDisp(usedArgSlots_);
             enoughMemory_ = moveResolver_.addMove(from, MoveOperand(sp, disp), type);
         }
         usedArgSlots_++;
         passedArgTypes_ = (passedArgTypes_ << ArgType_Shift) | ArgType_General;
         break;
       default:
-        MOZ_CRASH("Unexpected argument type");
+        MOZ_ASSUME_UNREACHABLE("Unexpected argument type");
     }
 }
 
 void
 MacroAssemblerMIPSCompat::passABIArg(Register reg)
 {
     passABIArg(MoveOperand(reg), MoveOp::GENERAL);
 }
@@ -3328,32 +3334,32 @@ AssertValidABIFunctionType(uint32_t pass
       case Args_Double_Double:
       case Args_Double_Int:
       case Args_Double_DoubleInt:
       case Args_Double_DoubleDouble:
       case Args_Double_IntDouble:
       case Args_Int_IntDouble:
         break;
       default:
-        MOZ_CRASH("Unexpected type");
+        MOZ_ASSUME_UNREACHABLE("Unexpected type");
     }
 }
 #endif
 
 void
 MacroAssemblerMIPSCompat::callWithABI(void *fun, MoveOp::Type result)
 {
 #ifdef JS_MIPS_SIMULATOR
     MOZ_ASSERT(passedArgs_ <= 15);
     passedArgTypes_ <<= ArgType_Shift;
     switch (result) {
       case MoveOp::GENERAL: passedArgTypes_ |= ArgType_General; break;
       case MoveOp::DOUBLE:  passedArgTypes_ |= ArgType_Double;  break;
       case MoveOp::FLOAT32: passedArgTypes_ |= ArgType_Float32; break;
-      default: MOZ_CRASH("Invalid return type");
+      default: MOZ_ASSUME_UNREACHABLE("Invalid return type");
     }
 #ifdef DEBUG
     AssertValidABIFunctionType(passedArgTypes_);
 #endif
     ABIFunctionType type = ABIFunctionType(passedArgTypes_);
     fun = Simulator::RedirectNativeFunction(fun, type);
 #endif
 
--- a/js/src/jit/mips/MacroAssembler-mips.h
+++ b/js/src/jit/mips/MacroAssembler-mips.h
@@ -374,20 +374,20 @@ class MacroAssemblerMIPSCompat : public 
     }
     void mov(ImmWord imm, Register dest) {
         ma_li(dest, Imm32(imm.value));
     }
     void mov(ImmPtr imm, Register dest) {
         mov(ImmWord(uintptr_t(imm.value)), dest);
     }
     void mov(Register src, Address dest) {
-        MOZ_CRASH("NYI-IC");
+        MOZ_ASSUME_UNREACHABLE("NYI-IC");
     }
     void mov(Address src, Register dest) {
-        MOZ_CRASH("NYI-IC");
+        MOZ_ASSUME_UNREACHABLE("NYI-IC");
     }
 
     void call(const Register reg) {
         as_jalr(reg);
         as_nop();
     }
 
     void call(Label *label) {
@@ -992,32 +992,32 @@ public:
 
     template <typename T>
     void branchAdd32(Condition cond, T src, Register dest, Label *overflow) {
         switch (cond) {
           case Overflow:
             ma_addTestOverflow(dest, dest, src, overflow);
             break;
           default:
-            MOZ_CRASH("NYI");
+            MOZ_ASSUME_UNREACHABLE("NYI");
         }
     }
     template <typename T>
     void branchSub32(Condition cond, T src, Register dest, Label *overflow) {
         switch (cond) {
           case Overflow:
             ma_subTestOverflow(dest, dest, src, overflow);
             break;
           case NonZero:
           case Zero:
             sub32(src, dest);
             ma_b(dest, dest, overflow, cond);
             break;
           default:
-            MOZ_CRASH("NYI");
+            MOZ_ASSUME_UNREACHABLE("NYI");
         }
     }
 
     void and32(Register src, Register dest);
     void and32(Imm32 imm, Register dest);
     void and32(Imm32 imm, const Address &dest);
     void and32(const Address &src, Register dest);
     void or32(Imm32 imm, Register dest);
--- a/js/src/jit/mips/MoveEmitter-mips.cpp
+++ b/js/src/jit/mips/MoveEmitter-mips.cpp
@@ -108,17 +108,17 @@ MoveEmitterMIPS::breakCycle(const MoveOp
             masm.storePtr(temp, cycleSlot());
         } else {
             // Second scratch register should not be moved by MoveEmitter.
             MOZ_ASSERT(to.reg() != spilledReg_);
             masm.storePtr(to.reg(), cycleSlot());
         }
         break;
       default:
-        MOZ_CRASH("Unexpected move type");
+        MOZ_ASSUME_UNREACHABLE("Unexpected move type");
     }
 }
 
 void
 MoveEmitterMIPS::completeCycle(const MoveOperand &from, const MoveOperand &to, MoveOp::Type type)
 {
     // There is some pattern:
     //   (A -> B)
@@ -154,53 +154,53 @@ MoveEmitterMIPS::completeCycle(const Mov
             masm.storePtr(temp, getAdjustedAddress(to));
         } else {
             // Second scratch register should not be moved by MoveEmitter.
             MOZ_ASSERT(to.reg() != spilledReg_);
             masm.loadPtr(cycleSlot(), to.reg());
         }
         break;
       default:
-        MOZ_CRASH("Unexpected move type");
+        MOZ_ASSUME_UNREACHABLE("Unexpected move type");
     }
 }
 
 void
 MoveEmitterMIPS::emitMove(const MoveOperand &from, const MoveOperand &to)
 {
     if (from.isGeneralReg()) {
         // Second scratch register should not be moved by MoveEmitter.
         MOZ_ASSERT(from.reg() != spilledReg_);
 
         if (to.isGeneralReg())
             masm.movePtr(from.reg(), to.reg());
         else if (to.isMemory())
             masm.storePtr(from.reg(), getAdjustedAddress(to));
         else
-            MOZ_CRASH("Invalid emitMove arguments.");
+            MOZ_ASSUME_UNREACHABLE("Invalid emitMove arguments.");
     } else if (from.isMemory()) {
         if (to.isGeneralReg()) {
             masm.loadPtr(getAdjustedAddress(from), to.reg());
         } else if (to.isMemory()) {
             masm.loadPtr(getAdjustedAddress(from), tempReg());
             masm.storePtr(tempReg(), getAdjustedAddress(to));
         } else {
-            MOZ_CRASH("Invalid emitMove arguments.");
+            MOZ_ASSUME_UNREACHABLE("Invalid emitMove arguments.");
         }
     } else if (from.isEffectiveAddress()) {
         if (to.isGeneralReg()) {
             masm.computeEffectiveAddress(getAdjustedAddress(from), to.reg());
         } else if (to.isMemory()) {
             masm.computeEffectiveAddress(getAdjustedAddress(from), tempReg());
             masm.storePtr(tempReg(), getAdjustedAddress(to));
         } else {
-            MOZ_CRASH("Invalid emitMove arguments.");
+            MOZ_ASSUME_UNREACHABLE("Invalid emitMove arguments.");
         }
     } else {
-        MOZ_CRASH("Invalid emitMove arguments.");
+        MOZ_ASSUME_UNREACHABLE("Invalid emitMove arguments.");
     }
 }
 
 void
 MoveEmitterMIPS::emitFloat32Move(const MoveOperand &from, const MoveOperand &to)
 {
     // Ensure that we can use ScratchFloatReg in memory move.
     MOZ_ASSERT_IF(from.isFloatReg(), from.floatReg() != ScratchFloatReg);
@@ -247,17 +247,17 @@ MoveEmitterMIPS::emitDoubleMove(const Mo
             // Used for passing double parameter in a2,a3 register pair.
             // Two moves are added for one double parameter by
             // MacroAssemblerMIPSCompat::passABIArg
             if(to.reg() == a2)
                 masm.moveFromDoubleLo(from.floatReg(), a2);
             else if(to.reg() == a3)
                 masm.moveFromDoubleHi(from.floatReg(), a3);
             else
-                MOZ_CRASH("Invalid emitDoubleMove arguments.");
+                MOZ_ASSUME_UNREACHABLE("Invalid emitDoubleMove arguments.");
         } else {
             MOZ_ASSERT(to.isMemory());
             masm.storeDouble(from.floatReg(), getAdjustedAddress(to));
         }
     } else if (to.isFloatReg()) {
         MOZ_ASSERT(from.isMemory());
         masm.loadDouble(getAdjustedAddress(from), to.floatReg());
     } else if (to.isGeneralReg()) {
@@ -265,17 +265,17 @@ MoveEmitterMIPS::emitDoubleMove(const Mo
         // Used for passing double parameter in a2,a3 register pair.
         // Two moves are added for one double parameter by
         // MacroAssemblerMIPSCompat::passABIArg
         if(to.reg() == a2)
             masm.loadPtr(getAdjustedAddress(from), a2);
         else if(to.reg() == a3)
             masm.loadPtr(Address(from.base(), getAdjustedOffset(from) + sizeof(uint32_t)), a3);
         else
-            MOZ_CRASH("Invalid emitDoubleMove arguments.");
+            MOZ_ASSUME_UNREACHABLE("Invalid emitDoubleMove arguments.");
     } else {
         MOZ_ASSERT(from.isMemory());
         MOZ_ASSERT(to.isMemory());
         masm.loadDouble(getAdjustedAddress(from), ScratchFloatReg);
         masm.storeDouble(ScratchFloatReg, getAdjustedAddress(to));
     }
 }
 
@@ -306,17 +306,17 @@ MoveEmitterMIPS::emit(const MoveOp &move
         emitDoubleMove(from, to);
         break;
       case MoveOp::INT32:
         MOZ_ASSERT(sizeof(uintptr_t) == sizeof(int32_t));
       case MoveOp::GENERAL:
         emitMove(from, to);
         break;
       default:
-        MOZ_CRASH("Unexpected move type");
+        MOZ_ASSUME_UNREACHABLE("Unexpected move type");
     }
 }
 
 void
 MoveEmitterMIPS::assertDone()
 {
     MOZ_ASSERT(!inCycle_);
 }
--- a/js/src/jit/mips/Simulator-mips.cpp
+++ b/js/src/jit/mips/Simulator-mips.cpp
@@ -939,17 +939,17 @@ MipsDebugger::debug()
                         printAllRegsIncludingFPU();
                     } else {
                         Register reg = Register::FromName(arg1);
                         FloatRegister fReg = FloatRegister::FromName(arg1);
                         if (reg != InvalidReg) {
                             value = getRegisterValue(reg.code());
                             printf("%s: 0x%08x %d \n", arg1, value, value);
                         } else if (fReg.code() != FloatRegisters::Invalid) {
-                            MOZ_CRASH("NYI");
+                            MOZ_ASSUME_UNREACHABLE("NYI");
                         } else {
                             printf("%s unrecognized\n", arg1);
                         }
                     }
                 } else {
                     printf("print <register> or print <fpu register> single\n");
                 }
             } else if (strcmp(cmd, "stack") == 0 || strcmp(cmd, "mem") == 0) {
@@ -1860,17 +1860,17 @@ void
 Simulator::softwareInterrupt(SimInstruction *instr)
 {
     int32_t func = instr->functionFieldRaw();
     uint32_t code = (func == ff_break) ? instr->bits(25, 6) : -1;
 
     // We first check if we met a call_rt_redirected.
     if (instr->instructionBits() == kCallRedirInstr) {
 #if !defined(USES_O32_ABI)
-        MOZ_CRASH("Only O32 ABI supported.");
+        MOZ_ASSUME_UNREACHABLE("Only O32 ABI supported.");
 #else
         Redirection *redirection = Redirection::FromSwiInstruction(instr);
         int32_t arg0 = getRegister(a0);
         int32_t arg1 = getRegister(a1);
         int32_t arg2 = getRegister(a2);
         int32_t arg3 = getRegister(a3);
 
         int32_t *stack_pointer = reinterpret_cast<int32_t*>(getRegister(sp));
@@ -2016,17 +2016,17 @@ Simulator::softwareInterrupt(SimInstruct
             int32_t ival = getRegister(a0);
             double dval0 = getDoubleFromRegisterPair(a2);
             Prototype_Int_IntDouble target = reinterpret_cast<Prototype_Int_IntDouble>(external);
             int32_t result = target(ival, dval0);
             setRegister(v0, result);
             break;
           }
           default:
-            MOZ_CRASH("call");
+            MOZ_ASSUME_UNREACHABLE("call");
         }
 
         setRegister(ra, saved_ra);
         set_pc(getRegister(ra));
 #endif
     } else if (func == ff_break && code <= kMaxStopCode) {
         if (isWatchpoint(code)) {
             printWatchpoint(code);
@@ -2141,17 +2141,17 @@ Simulator::printStopInfo(uint32_t code)
     }
 }
 
 void
 Simulator::signalExceptions()
 {
     for (int i = 1; i < kNumExceptions; i++) {
         if (exceptions[i] != 0)
-            MOZ_CRASH("Error: Exception raised.");
+            MOZ_ASSUME_UNREACHABLE("Error: Exception raised.");
     }
 }
 
 // Handle execution based on instruction types.
 void
 Simulator::configureTypeRegister(SimInstruction *instr,
                                  int32_t& alu_out,
                                  int64_t& i64hilo,
@@ -3293,17 +3293,17 @@ Simulator::branchDelayInstructionDecode(
 {
     if (instr->instructionBits() == NopInst) {
         // Short-cut generic nop instructions. They are always valid and they
         // never change the simulator state.
         return;
     }
 
     if (instr->isForbiddenInBranchDelay()) {
-        MOZ_CRASH("Eror:Unexpected opcode in a branch delay slot.");
+        MOZ_ASSUME_UNREACHABLE("Eror:Unexpected opcode in a branch delay slot.");
     }
     instructionDecode(instr);
 }
 
 template<bool enableStopSimAt>
 void
 Simulator::execute()
 {
--- a/js/src/jit/mips/Trampoline-mips.cpp
+++ b/js/src/jit/mips/Trampoline-mips.cpp
@@ -685,17 +685,17 @@ JitRuntime::generateBailoutHandler(JSCon
     switch (mode) {
       case SequentialExecution:
         GenerateBailoutThunk(cx, masm, NO_FRAME_SIZE_CLASS_ID);
         break;
       case ParallelExecution:
         GenerateParallelBailoutThunk(masm, NO_FRAME_SIZE_CLASS_ID);
         break;
       default:
-        MOZ_CRASH("No such execution mode");
+        MOZ_ASSUME_UNREACHABLE("No such execution mode");
     }
 
     Linker linker(masm);
     AutoFlushICache afc("BailoutHandler");
     JitCode *code = linker.newCode<NoGC>(cx, JSC::OTHER_CODE);
 
 #ifdef JS_ION_PERF
     writePerfSpewerJitCodeProfile(code, "BailoutHandler");
@@ -838,17 +838,17 @@ JitRuntime::generateVMWrapper(JSContext 
       case Type_Object:
         masm.branchTestPtr(Assembler::Zero, v0, v0, masm.failureLabel(f.executionMode));
         break;
       case Type_Bool:
         // Called functions return bools, which are 0/false and non-zero/true
         masm.branchIfFalseBool(v0, masm.failureLabel(f.executionMode));
         break;
       default:
-        MOZ_CRASH("unknown failure kind");
+        MOZ_ASSUME_UNREACHABLE("unknown failure kind");
     }
 
     masm.freeStack(outParamOffset);
 
     // Load the outparam and free any allocated stack.
     switch (f.outParam) {
       case Type_Handle:
         masm.popRooted(f.outParamRootType, ReturnReg, JSReturnOperand);
--- a/js/src/jit/shared/Assembler-shared.h
+++ b/js/src/jit/shared/Assembler-shared.h
@@ -60,17 +60,17 @@ ScaleFromElemWidth(int shift)
       case 2:
         return TimesTwo;
       case 4:
         return TimesFour;
       case 8:
         return TimesEight;
     }
 
-    MOZ_CRASH("Invalid scale");
+    MOZ_ASSUME_UNREACHABLE("Invalid scale");
 }
 
 // Used for 32-bit immediates which do not require relocation.
 struct Imm32
 {
     int32_t value;
 
     explicit Imm32(int32_t value) : value(value)
@@ -82,17 +82,17 @@ struct Imm32
             return Imm32(0);
           case TimesTwo:
             return Imm32(1);
           case TimesFour:
             return Imm32(2);
           case TimesEight:
             return Imm32(3);
         };
-        MOZ_CRASH("Invalid scale");
+        MOZ_ASSUME_UNREACHABLE("Invalid scale");
     }
 
     static inline Imm32 FactorOf(enum Scale s) {
         return Imm32(1 << ShiftOf(s).value);
     }
 };
 
 // Pointer-sized integer to be embedded as an immediate in an instruction.
--- a/js/src/jit/shared/Assembler-x86-shared.cpp
+++ b/js/src/jit/shared/Assembler-x86-shared.cpp
@@ -123,11 +123,11 @@ AssemblerX86Shared::InvertCondition(Cond
         return BelowOrEqual;
       case AboveOrEqual:
         return Below;
       case Below:
         return AboveOrEqual;
       case BelowOrEqual:
         return Above;
       default:
-        MOZ_CRASH("unexpected condition");
+        MOZ_ASSUME_UNREACHABLE("unexpected condition");
     }
 }
--- a/js/src/jit/shared/Assembler-x86-shared.h
+++ b/js/src/jit/shared/Assembler-x86-shared.h
@@ -240,17 +240,17 @@ class AssemblerX86Shared : public Assemb
           case DoubleLessThanOrEqualOrUnordered:
             return NaN_HandledByCond;
           case DoubleEqual:
             return NaN_IsFalse;
           case DoubleNotEqualOrUnordered:
             return NaN_IsTrue;
         }
 
-        MOZ_CRASH("Unknown double condition");
+        MOZ_ASSUME_UNREACHABLE("Unknown double condition");
     }
 
     static void StaticAsserts() {
         // DoubleConditionBits should not interfere with x86 condition codes.
         JS_STATIC_ASSERT(!((Equal | NotEqual | Above | AboveOrEqual | Below |
                             BelowOrEqual | Parity | NoParity) & DoubleConditionBits));
     }
 
@@ -356,17 +356,17 @@ class AssemblerX86Shared : public Assemb
             break;
           case Operand::MEM_SCALE:
             masm.movl_mr(src.disp(), src.base(), src.index(), src.scale(), dest.code());
             break;
           case Operand::MEM_ADDRESS32:
             masm.movl_mr(src.address(), dest.code());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void movl(Register src, const Operand &dest) {
         switch (dest.kind()) {
           case Operand::REG:
             masm.movl_rr(src.code(), dest.reg());
             break;
           case Operand::MEM_REG_DISP:
@@ -374,32 +374,32 @@ class AssemblerX86Shared : public Assemb
             break;
           case Operand::MEM_SCALE:
             masm.movl_rm(src.code(), dest.disp(), dest.base(), dest.index(), dest.scale());
             break;
           case Operand::MEM_ADDRESS32:
             masm.movl_rm(src.code(), dest.address());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void movl(Imm32 imm32, const Operand &dest) {
         switch (dest.kind()) {
           case Operand::REG:
             masm.movl_i32r(imm32.value, dest.reg());
             break;
           case Operand::MEM_REG_DISP:
             masm.movl_i32m(imm32.value, dest.disp(), dest.base());
             break;
           case Operand::MEM_SCALE:
             masm.movl_i32m(imm32.value, dest.disp(), dest.base(), dest.index(), dest.scale());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
 
     void xchgl(Register src, Register dest) {
         masm.xchgl_rr(src.code(), dest.code());
     }
 
     // Eventually movapd and movaps should be overloaded to support loads and
@@ -445,30 +445,30 @@ class AssemblerX86Shared : public Assemb
         switch (src.kind()) {
           case Operand::MEM_REG_DISP:
             masm.movdqa_mr(src.disp(), src.base(), dest.code());
             break;
           case Operand::MEM_SCALE:
             masm.movdqa_mr(src.disp(), src.base(), src.index(), src.scale(), dest.code());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void movdqa(FloatRegister src, const Operand &dest) {
         JS_ASSERT(HasSSE2());
         switch (dest.kind()) {
           case Operand::MEM_REG_DISP:
             masm.movdqa_rm(src.code(), dest.disp(), dest.base());
             break;
           case Operand::MEM_SCALE:
             masm.movdqa_rm(src.code(), dest.disp(), dest.base(), dest.index(), dest.scale());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void cvtss2sd(FloatRegister src, FloatRegister dest) {
         JS_ASSERT(HasSSE2());
         masm.cvtss2sd_rr(src.code(), dest.code());
     }
     void cvtsd2ss(FloatRegister src, FloatRegister dest) {
         JS_ASSERT(HasSSE2());
@@ -478,119 +478,119 @@ class AssemblerX86Shared : public Assemb
         switch (src.kind()) {
           case Operand::MEM_REG_DISP:
             masm.movzbl_mr(src.disp(), src.base(), dest.code());
             break;
           case Operand::MEM_SCALE:
             masm.movzbl_mr(src.disp(), src.base(), src.index(), src.scale(), dest.code());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void movsbl(const Operand &src, Register dest) {
         switch (src.kind()) {
           case Operand::MEM_REG_DISP:
             masm.movsbl_mr(src.disp(), src.base(), dest.code());
             break;
           case Operand::MEM_SCALE:
             masm.movsbl_mr(src.disp(), src.base(), src.index(), src.scale(), dest.code());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void movb(Register src, const Operand &dest) {
         switch (dest.kind()) {
           case Operand::MEM_REG_DISP:
             masm.movb_rm(src.code(), dest.disp(), dest.base());
             break;
           case Operand::MEM_SCALE:
             masm.movb_rm(src.code(), dest.disp(), dest.base(), dest.index(), dest.scale());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void movb(Imm32 src, const Operand &dest) {
         switch (dest.kind()) {
           case Operand::MEM_REG_DISP:
             masm.movb_i8m(src.value, dest.disp(), dest.base());
             break;
           case Operand::MEM_SCALE:
             masm.movb_i8m(src.value, dest.disp(), dest.base(), dest.index(), dest.scale());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void movzwl(const Operand &src, Register dest) {
         switch (src.kind()) {
           case Operand::REG:
             masm.movzwl_rr(src.reg(), dest.code());
             break;
           case Operand::MEM_REG_DISP:
             masm.movzwl_mr(src.disp(), src.base(), dest.code());
             break;
           case Operand::MEM_SCALE:
             masm.movzwl_mr(src.disp(), src.base(), src.index(), src.scale(), dest.code());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void movzwl(Register src, Register dest) {
         masm.movzwl_rr(src.code(), dest.code());
     }
     void movw(Register src, const Operand &dest) {
         switch (dest.kind()) {
           case Operand::MEM_REG_DISP:
             masm.movw_rm(src.code(), dest.disp(), dest.base());
             break;
           case Operand::MEM_SCALE:
             masm.movw_rm(src.code(), dest.disp(), dest.base(), dest.index(), dest.scale());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void movw(Imm32 src, const Operand &dest) {
         switch (dest.kind()) {
           case Operand::MEM_REG_DISP:
             masm.movw_i16m(src.value, dest.disp(), dest.base());
             break;
           case Operand::MEM_SCALE:
             masm.movw_i16m(src.value, dest.disp(), dest.base(), dest.index(), dest.scale());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void movswl(const Operand &src, Register dest) {
         switch (src.kind()) {
           case Operand::MEM_REG_DISP:
             masm.movswl_mr(src.disp(), src.base(), dest.code());
             break;
           case Operand::MEM_SCALE:
             masm.movswl_mr(src.disp(), src.base(), src.index(), src.scale(), dest.code());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void leal(const Operand &src, Register dest) {
         switch (src.kind()) {
           case Operand::MEM_REG_DISP:
             masm.leal_mr(src.disp(), src.base(), dest.code());
             break;
           case Operand::MEM_SCALE:
             masm.leal_mr(src.disp(), src.base(), src.index(), src.scale(), dest.code());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
 
   protected:
     JmpSrc jSrc(Condition cond, Label *label) {
         JmpSrc j = masm.jCC(static_cast<JSC::X86Assembler::Condition>(cond));
         if (label->bound()) {
             // The jump can be immediately patched to the correct destination.
@@ -665,17 +665,17 @@ class AssemblerX86Shared : public Assemb
             break;
           case Operand::MEM_SCALE:
             masm.jmp_m(op.disp(), op.base(), op.index(), op.scale());
             break;
           case Operand::REG:
             masm.jmp_r(op.reg());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void cmpEAX(Label *label) { cmpSrc(label); }
     void bind(Label *label) {
         JSC::X86Assembler::JmpDst dst(masm.label());
         if (label->used()) {
             bool more;
             JSC::X86Assembler::JmpSrc jmp(label->offset());
@@ -764,17 +764,17 @@ class AssemblerX86Shared : public Assemb
         switch (op.kind()) {
           case Operand::REG:
             masm.call(op.reg());
             break;
           case Operand::MEM_REG_DISP:
             masm.call_m(op.disp(), op.base());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
 
     void breakpoint() {
         masm.int3();
     }
 
 #ifdef DEBUG
@@ -799,17 +799,17 @@ class AssemblerX86Shared : public Assemb
         switch (rhs.kind()) {
           case Operand::REG:
             masm.cmpl_rr(rhs.reg(), lhs.code());
             break;
           case Operand::MEM_REG_DISP:
             masm.cmpl_mr(rhs.disp(), rhs.base(), lhs.code());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void cmpl(Register src, Imm32 imm) {
         masm.cmpl_ir(imm.value, src.code());
     }
     void cmpl(const Operand &op, Imm32 imm) {
         switch (op.kind()) {
           case Operand::REG:
@@ -820,47 +820,47 @@ class AssemblerX86Shared : public Assemb
             break;
           case Operand::MEM_SCALE:
             masm.cmpl_im(imm.value, op.disp(), op.base(), op.index(), op.scale());
             break;
           case Operand::MEM_ADDRESS32:
             masm.cmpl_im(imm.value, op.address());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void cmpl(const Operand &lhs, Register rhs) {
         switch (lhs.kind()) {
           case Operand::REG:
             masm.cmpl_rr(rhs.code(), lhs.reg());
             break;
           case Operand::MEM_REG_DISP:
             masm.cmpl_rm(rhs.code(), lhs.disp(), lhs.base());
             break;
           case Operand::MEM_ADDRESS32:
             masm.cmpl_rm(rhs.code(), lhs.address());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void cmpl(const Operand &op, ImmWord imm) {
         switch (op.kind()) {
           case Operand::REG:
             masm.cmpl_ir(imm.value, op.reg());
             break;
           case Operand::MEM_REG_DISP:
             masm.cmpl_im(imm.value, op.disp(), op.base());
             break;
           case Operand::MEM_ADDRESS32:
             masm.cmpl_im(imm.value, op.address());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void cmpl(const Operand &op, ImmPtr imm) {
         cmpl(op, ImmWord(uintptr_t(imm.value)));
     }
     void cmpw(Register lhs, Register rhs) {
         masm.cmpw_rr(lhs.code(), rhs.code());
     }
@@ -888,17 +888,17 @@ class AssemblerX86Shared : public Assemb
             break;
           case Operand::MEM_REG_DISP:
             masm.testl_i32m(rhs.value, lhs.disp(), lhs.base());
             break;
           case Operand::MEM_ADDRESS32:
             masm.testl_i32m(rhs.value, lhs.address());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
             break;
         }
     }
 
     void addl(Imm32 imm, Register dest) {
         masm.addl_ir(imm.value, dest.code());
     }
     void addl(Imm32 imm, const Operand &op) {
@@ -908,32 +908,32 @@ class AssemblerX86Shared : public Assemb
             break;
           case Operand::MEM_REG_DISP:
             masm.addl_im(imm.value, op.disp(), op.base());
             break;
           case Operand::MEM_ADDRESS32:
             masm.addl_im(imm.value, op.address());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void subl(Imm32 imm, Register dest) {
         masm.subl_ir(imm.value, dest.code());
     }
     void subl(Imm32 imm, const Operand &op) {
         switch (op.kind()) {
           case Operand::REG:
             masm.subl_ir(imm.value, op.reg());
             break;
           case Operand::MEM_REG_DISP:
             masm.subl_im(imm.value, op.disp(), op.base());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void addl(Register src, Register dest) {
         masm.addl_rr(src.code(), dest.code());
     }
     void subl(Register src, Register dest) {
         masm.subl_rr(src.code(), dest.code());
     }
@@ -941,29 +941,29 @@ class AssemblerX86Shared : public Assemb
         switch (src.kind()) {
           case Operand::REG:
             masm.subl_rr(src.reg(), dest.code());
             break;
           case Operand::MEM_REG_DISP:
             masm.subl_mr(src.disp(), src.base(), dest.code());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void subl(Register src, const Operand &dest) {
         switch (dest.kind()) {
           case Operand::REG:
             masm.subl_rr(src.code(), dest.reg());
             break;
           case Operand::MEM_REG_DISP:
             masm.subl_rm(src.code(), dest.disp(), dest.base());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void orl(Register reg, Register dest) {
         masm.orl_rr(reg.code(), dest.code());
     }
     void orl(Imm32 imm, Register reg) {
         masm.orl_ir(imm.value, reg.code());
     }
@@ -971,17 +971,17 @@ class AssemblerX86Shared : public Assemb
         switch (op.kind()) {
           case Operand::REG:
             masm.orl_ir(imm.value, op.reg());
             break;
           case Operand::MEM_REG_DISP:
             masm.orl_im(imm.value, op.disp(), op.base());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void xorl(Register src, Register dest) {
         masm.xorl_rr(src.code(), dest.code());
     }
     void xorl(Imm32 imm, Register reg) {
         masm.xorl_ir(imm.value, reg.code());
     }
@@ -989,17 +989,17 @@ class AssemblerX86Shared : public Assemb
         switch (op.kind()) {
           case Operand::REG:
             masm.xorl_ir(imm.value, op.reg());
             break;
           case Operand::MEM_REG_DISP:
             masm.xorl_im(imm.value, op.disp(), op.base());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void andl(Register src, Register dest) {
         masm.andl_rr(src.code(), dest.code());
     }
     void andl(Imm32 imm, Register dest) {
         masm.andl_ir(imm.value, dest.code());
     }
@@ -1007,65 +1007,65 @@ class AssemblerX86Shared : public Assemb
         switch (op.kind()) {
           case Operand::REG:
             masm.andl_ir(imm.value, op.reg());
             break;
           case Operand::MEM_REG_DISP:
             masm.andl_im(imm.value, op.disp(), op.base());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void addl(const Operand &src, Register dest) {
         switch (src.kind()) {
           case Operand::REG:
             masm.addl_rr(src.reg(), dest.code());
             break;
           case Operand::MEM_REG_DISP:
             masm.addl_mr(src.disp(), src.base(), dest.code());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void orl(const Operand &src, Register dest) {
         switch (src.kind()) {
           case Operand::REG:
             masm.orl_rr(src.reg(), dest.code());
             break;
           case Operand::MEM_REG_DISP:
             masm.orl_mr(src.disp(), src.base(), dest.code());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void xorl(const Operand &src, Register dest) {
         switch (src.kind()) {
           case Operand::REG:
             masm.xorl_rr(src.reg(), dest.code());
             break;
           case Operand::MEM_REG_DISP:
             masm.xorl_mr(src.disp(), src.base(), dest.code());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void andl(const Operand &src, Register dest) {
         switch (src.kind()) {
           case Operand::REG:
             masm.andl_rr(src.reg(), dest.code());
             break;
           case Operand::MEM_REG_DISP:
             masm.andl_mr(src.disp(), src.base(), dest.code());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void imull(Register multiplier) {
         masm.imull_r(multiplier.code());
     }
     void imull(Imm32 imm, Register dest) {
         masm.imull_i32r(dest.code(), imm.value, dest.code());
     }
@@ -1079,44 +1079,44 @@ class AssemblerX86Shared : public Assemb
         switch (src.kind()) {
           case Operand::REG:
             masm.imull_rr(src.reg(), dest.code());
             break;
           case Operand::MEM_REG_DISP:
             masm.imull_mr(src.disp(), src.base(), dest.code());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void negl(const Operand &src) {
         switch (src.kind()) {
           case Operand::REG:
             masm.negl_r(src.reg());
             break;
           case Operand::MEM_REG_DISP:
             masm.negl_m(src.disp(), src.base());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void negl(Register reg) {
         masm.negl_r(reg.code());
     }
     void notl(const Operand &src) {
         switch (src.kind()) {
           case Operand::REG:
             masm.notl_r(src.reg());
             break;
           case Operand::MEM_REG_DISP:
             masm.notl_m(src.disp(), src.base());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void notl(Register reg) {
         masm.notl_r(reg.code());
     }
     void shrl(const Imm32 imm, Register dest) {
         masm.shrl_i8r(imm.value, dest.code());
     }
@@ -1137,76 +1137,76 @@ class AssemblerX86Shared : public Assemb
     }
 
     void incl(const Operand &op) {
         switch (op.kind()) {
           case Operand::MEM_REG_DISP:
             masm.incl_m32(op.disp(), op.base());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void lock_incl(const Operand &op) {
         masm.prefix_lock();
         incl(op);
     }
 
     void decl(const Operand &op) {
         switch (op.kind()) {
           case Operand::MEM_REG_DISP:
             masm.decl_m32(op.disp(), op.base());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void lock_decl(const Operand &op) {
         masm.prefix_lock();
         decl(op);
     }
 
     void lock_cmpxchg32(Register src, const Operand &op) {
         masm.prefix_lock();
         switch (op.kind()) {
           case Operand::MEM_REG_DISP:
             masm.cmpxchg32(src.code(), op.disp(), op.base());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
 
     void xaddl(Register srcdest, const Operand &mem) {
         switch (mem.kind()) {
           case Operand::MEM_REG_DISP:
             masm.xaddl_rm(srcdest.code(), mem.disp(), mem.base());
             break;
           case Operand::MEM_SCALE:
             masm.xaddl_rm(srcdest.code(), mem.disp(), mem.base(), mem.index(), mem.scale());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
 
     void push(const Imm32 imm) {
         masm.push_i32(imm.value);
     }
 
     void push(const Operand &src) {
         switch (src.kind()) {
           case Operand::REG:
             masm.push_r(src.reg());
             break;
           case Operand::MEM_REG_DISP:
             masm.push_m(src.disp(), src.base());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void push(Register src) {
         masm.push_r(src.code());
     }
     void push(const Address &src) {
         masm.push_m(src.offset, src.base.code());
     }
@@ -1215,17 +1215,17 @@ class AssemblerX86Shared : public Assemb
         switch (src.kind()) {
           case Operand::REG:
             masm.pop_r(src.reg());
             break;
           case Operand::MEM_REG_DISP:
             masm.pop_m(src.disp(), src.base());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void pop(Register src) {
         masm.pop_r(src.code());
     }
 
     void pushFlags() {
         masm.push_flags();
@@ -1271,17 +1271,17 @@ class AssemblerX86Shared : public Assemb
         switch (src.kind()) {
           case Operand::REG:
             masm.pinsrd_rr(src.reg(), dest.code());
             break;
           case Operand::MEM_REG_DISP:
             masm.pinsrd_mr(src.disp(), src.base(), dest.code());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void psrldq(Imm32 shift, FloatRegister dest) {
         JS_ASSERT(HasSSE2());
         masm.psrldq_ir(shift.value, dest.code());
     }
     void psllq(Imm32 shift, FloatRegister dest) {
         JS_ASSERT(HasSSE2());
@@ -1300,17 +1300,17 @@ class AssemblerX86Shared : public Assemb
             break;
           case Operand::MEM_REG_DISP:
             masm.cvtsi2sd_mr(src.disp(), src.base(), dest.code());
             break;
           case Operand::MEM_SCALE:
             masm.cvtsi2sd_mr(src.disp(), src.base(), src.index(), src.scale(), dest.code());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void cvttsd2si(FloatRegister src, Register dest) {
         JS_ASSERT(HasSSE2());
         masm.cvttsd2si_rr(src.code(), dest.code());
     }
     void cvttss2si(FloatRegister src, Register dest) {
         JS_ASSERT(HasSSE2());
@@ -1324,17 +1324,17 @@ class AssemblerX86Shared : public Assemb
             break;
           case Operand::MEM_REG_DISP:
             masm.cvtsi2ss_mr(src.disp(), src.base(), dest.code());
             break;
           case Operand::MEM_SCALE:
             masm.cvtsi2ss_mr(src.disp(), src.base(), src.index(), src.scale(), dest.code());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void cvtsi2ss(Register src, FloatRegister dest) {
         JS_ASSERT(HasSSE2());
         masm.cvtsi2ss_rr(src.code(), dest.code());
     }
     void cvtsi2sd(Register src, FloatRegister dest) {
         JS_ASSERT(HasSSE2());
@@ -1388,33 +1388,33 @@ class AssemblerX86Shared : public Assemb
             break;
           case Operand::MEM_REG_DISP:
             masm.addsd_mr(src.disp(), src.base(), dest.code());
             break;
           case Operand::MEM_ADDRESS32:
             masm.addsd_mr(src.address(), dest.code());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void addss(const Operand &src, FloatRegister dest) {
         JS_ASSERT(HasSSE2());
         switch (src.kind()) {
           case Operand::FPREG:
             masm.addss_rr(src.fpu(), dest.code());
             break;
           case Operand::MEM_REG_DISP:
             masm.addss_mr(src.disp(), src.base(), dest.code());
             break;
           case Operand::MEM_ADDRESS32:
             masm.addss_mr(src.address(), dest.code());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void subsd(FloatRegister src, FloatRegister dest) {
         JS_ASSERT(HasSSE2());
         masm.subsd_rr(src.code(), dest.code());
     }
     void subss(FloatRegister src, FloatRegister dest) {
         JS_ASSERT(HasSSE2());
@@ -1425,60 +1425,60 @@ class AssemblerX86Shared : public Assemb
         switch (src.kind()) {
           case Operand::FPREG:
             masm.subsd_rr(src.fpu(), dest.code());
             break;
           case Operand::MEM_REG_DISP:
             masm.subsd_mr(src.disp(), src.base(), dest.code());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void subss(const Operand &src, FloatRegister dest) {
         JS_ASSERT(HasSSE2());
         switch (src.kind()) {
           case Operand::FPREG:
             masm.subss_rr(src.fpu(), dest.code());
             break;
           case Operand::MEM_REG_DISP:
             masm.subss_mr(src.disp(), src.base(), dest.code());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void mulsd(FloatRegister src, FloatRegister dest) {
         JS_ASSERT(HasSSE2());
         masm.mulsd_rr(src.code(), dest.code());
     }
     void mulsd(const Operand &src, FloatRegister dest) {
         JS_ASSERT(HasSSE2());
         switch (src.kind()) {
           case Operand::FPREG:
             masm.mulsd_rr(src.fpu(), dest.code());
             break;
           case Operand::MEM_REG_DISP:
             masm.mulsd_mr(src.disp(), src.base(), dest.code());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void mulss(const Operand &src, FloatRegister dest) {
         JS_ASSERT(HasSSE2());
         switch (src.kind()) {
           case Operand::FPREG:
             masm.mulss_rr(src.fpu(), dest.code());
             break;
           case Operand::MEM_REG_DISP:
             masm.mulss_mr(src.disp(), src.base(), dest.code());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void mulss(FloatRegister src, FloatRegister dest) {
         JS_ASSERT(HasSSE2());
         masm.mulss_rr(src.code(), dest.code());
     }
     void divsd(FloatRegister src, FloatRegister dest) {
         JS_ASSERT(HasSSE2());
@@ -1493,30 +1493,30 @@ class AssemblerX86Shared : public Assemb
         switch (src.kind()) {
           case Operand::FPREG:
             masm.divsd_rr(src.fpu(), dest.code());
             break;
           case Operand::MEM_REG_DISP:
             masm.divsd_mr(src.disp(), src.base(), dest.code());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void divss(const Operand &src, FloatRegister dest) {
         JS_ASSERT(HasSSE2());
         switch (src.kind()) {
           case Operand::FPREG:
             masm.divss_rr(src.fpu(), dest.code());
             break;
           case Operand::MEM_REG_DISP:
             masm.divss_mr(src.disp(), src.base(), dest.code());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void xorpd(FloatRegister src, FloatRegister dest) {
         JS_ASSERT(HasSSE2());
         masm.xorpd_rr(src.code(), dest.code());
     }
     void xorps(FloatRegister src, FloatRegister dest) {
         JS_ASSERT(HasSSE2());
@@ -1563,71 +1563,71 @@ class AssemblerX86Shared : public Assemb
         switch (src.kind()) {
           case Operand::FPREG:
             masm.minsd_rr(src.fpu(), dest.code());
             break;
           case Operand::MEM_REG_DISP:
             masm.minsd_mr(src.disp(), src.base(), dest.code());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void maxsd(FloatRegister src, FloatRegister dest) {
         JS_ASSERT(HasSSE2());
         masm.maxsd_rr(src.code(), dest.code());
     }
     void maxsd(const Operand &src, FloatRegister dest) {
         JS_ASSERT(HasSSE2());
         switch (src.kind()) {
           case Operand::FPREG:
             masm.maxsd_rr(src.fpu(), dest.code());
             break;
           case Operand::MEM_REG_DISP:
             masm.maxsd_mr(src.disp(), src.base(), dest.code());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void fisttp(const Operand &dest) {
         JS_ASSERT(HasSSE3());
         switch (dest.kind()) {
           case Operand::MEM_REG_DISP:
             masm.fisttp_m(dest.disp(), dest.base());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void fld(const Operand &dest) {
         switch (dest.kind()) {
           case Operand::MEM_REG_DISP:
             masm.fld_m(dest.disp(), dest.base());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void fstp(const Operand &src) {
         switch (src.kind()) {
           case Operand::MEM_REG_DISP:
             masm.fstp_m(src.disp(), src.base());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void fstp32(const Operand &src) {
         switch (src.kind()) {
           case Operand::MEM_REG_DISP:
             masm.fstp32_m(src.disp(), src.base());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
 
     // Defined for compatibility with ARM's assembler
     uint32_t actualOffset(uint32_t x) {
         return x;
     }
 
@@ -1668,24 +1668,24 @@ class AssemblerX86Shared : public Assemb
         JS_ASSERT(*ptr == (uintptr_t)expectedData.value);
         *ptr = (uintptr_t)newData.value;
     }
     static void PatchDataWithValueCheck(CodeLocationLabel data, ImmPtr newData, ImmPtr expectedData) {
         PatchDataWithValueCheck(data, PatchedImmPtr(newData.value), PatchedImmPtr(expectedData.value));
     }
 
     static void PatchInstructionImmediate(uint8_t *code, PatchedImmPtr imm) {
-        MOZ_CRASH("Unused.");
+        MOZ_ASSUME_UNREACHABLE("Unused.");
     }
 
     static uint32_t NopSize() {
         return 1;
     }
     static uint8_t *NextInstruction(uint8_t *cur, uint32_t *count) {
-        MOZ_CRASH("nextInstruction NYI on x86");
+        MOZ_ASSUME_UNREACHABLE("nextInstruction NYI on x86");
     }
 
     // Toggle a jmp or cmp emitted by toggledJump().
     static void ToggleToJmp(CodeLocationLabel inst) {
         uint8_t *ptr = (uint8_t *)inst.raw();
         JS_ASSERT(*ptr == 0x3D);
         *ptr = 0xE9;
     }
--- a/js/src/jit/shared/CodeGenerator-shared-inl.h
+++ b/js/src/jit/shared/CodeGenerator-shared-inl.h
@@ -14,17 +14,17 @@ namespace jit {
 
 static inline int32_t
 ToInt32(const LAllocation *a)
 {
     if (a->isConstantValue())
         return a->toConstant()->toInt32();
     if (a->isConstantIndex())
         return a->toConstantIndex()->index();
-    MOZ_CRASH("this is not a constant!");
+    MOZ_ASSUME_UNREACHABLE("this is not a constant!");
 }
 static inline double
 ToDouble(const LAllocation *a)
 {
     return a->toConstant()->toNumber();
 }
 
 static inline Register
--- a/js/src/jit/shared/CodeGenerator-shared.cpp
+++ b/js/src/jit/shared/CodeGenerator-shared.cpp
@@ -338,17 +338,17 @@ CodeGeneratorShared::assignBailoutId(LSn
     // Can we not use bailout tables at all?
     if (!deoptTable_)
         return false;
 
     // We do not generate a bailout table for parallel code.
     switch (gen->info().executionMode()) {
       case SequentialExecution: break;
       case ParallelExecution: return false;
-      default: MOZ_CRASH("No such execution mode");
+      default: MOZ_ASSUME_UNREACHABLE("No such execution mode");
     }
 
     JS_ASSERT(frameClass_ != FrameSizeClass::None());
 
     if (snapshot->bailoutId() != INVALID_BAILOUT_ID)
         return true;
 
     // Is the bailout table full?
--- a/js/src/jit/shared/CodeGenerator-x86-shared.cpp
+++ b/js/src/jit/shared/CodeGenerator-x86-shared.cpp
@@ -1321,17 +1321,17 @@ CodeGeneratorX86Shared::visitBitOpI(LBit
             break;
         case JSOP_BITAND:
             if (rhs->isConstant())
                 masm.andl(Imm32(ToInt32(rhs)), ToOperand(lhs));
             else
                 masm.andl(ToOperand(rhs), ToRegister(lhs));
             break;
         default:
-            MOZ_CRASH("unexpected binary opcode");
+            MOZ_ASSUME_UNREACHABLE("unexpected binary opcode");
     }
 
     return true;
 }
 
 bool
 CodeGeneratorX86Shared::visitShiftI(LShiftI *ins)
 {
@@ -1355,17 +1355,17 @@ CodeGeneratorX86Shared::visitShiftI(LShi
             } else if (ins->mir()->toUrsh()->fallible()) {
                 // x >>> 0 can overflow.
                 masm.testl(lhs, lhs);
                 if (!bailoutIf(Assembler::Signed, ins->snapshot()))
                     return false;
             }
             break;
           default:
-            MOZ_CRASH("Unexpected shift op");
+            MOZ_ASSUME_UNREACHABLE("Unexpected shift op");
         }
     } else {
         JS_ASSERT(ToRegister(rhs) == ecx);
         switch (ins->bitop()) {
           case JSOP_LSH:
             masm.shll_cl(lhs);
             break;
           case JSOP_RSH:
@@ -1376,17 +1376,17 @@ CodeGeneratorX86Shared::visitShiftI(LShi
             if (ins->mir()->toUrsh()->fallible()) {
                 // x >>> 0 can overflow.
                 masm.testl(lhs, lhs);
                 if (!bailoutIf(Assembler::Signed, ins->snapshot()))
                     return false;
             }
             break;
           default:
-            MOZ_CRASH("Unexpected shift op");
+            MOZ_ASSUME_UNREACHABLE("Unexpected shift op");
         }
     }
 
     return true;
 }
 
 bool
 CodeGeneratorX86Shared::visitUrshD(LUrshD *ins)
@@ -1518,17 +1518,17 @@ CodeGeneratorX86Shared::visitMathD(LMath
         break;
       case JSOP_MUL:
         masm.mulsd(rhs, lhs);
         break;
       case JSOP_DIV:
         masm.divsd(rhs, lhs);
         break;
       default:
-        MOZ_CRASH("unexpected opcode");
+        MOZ_ASSUME_UNREACHABLE("unexpected opcode");
     }
     return true;
 }
 
 bool
 CodeGeneratorX86Shared::visitMathF(LMathF *math)
 {
     FloatRegister lhs = ToFloatRegister(math->lhs());
@@ -1545,17 +1545,17 @@ CodeGeneratorX86Shared::visitMathF(LMath
         break;
       case JSOP_MUL:
         masm.mulss(rhs, lhs);
         break;
       case JSOP_DIV:
         masm.divss(rhs, lhs);
         break;
       default:
-        MOZ_CRASH("unexpected opcode");
+        MOZ_ASSUME_UNREACHABLE("unexpected opcode");
         return false;
     }
     return true;
 }
 
 bool
 CodeGeneratorX86Shared::visitFloor(LFloor *lir)
 {
--- a/js/src/jit/shared/IonAssemblerBuffer.h
+++ b/js/src/jit/shared/IonAssemblerBuffer.h
@@ -238,17 +238,17 @@ struct AssemblerBuffer
     }
     BufferOffset nextOffset() const {
         if (tail != nullptr)
             return BufferOffset(bufferSize + tail->size());
         else
             return BufferOffset(bufferSize);
     }
     BufferOffset prevOffset() const {
-        MOZ_CRASH("Don't current record lastInstSize");
+        MOZ_ASSUME_UNREACHABLE("Don't current record lastInstSize");
     }
 
     // Break the instruction stream so we can go back and edit it at this point
     void perforate() {
         Slice *tmp = newSlice(LifoAlloc_);
         if (!tmp) {
             m_oom = true;
             return;
--- a/js/src/jit/shared/IonAssemblerBufferWithConstantPools.h
+++ b/js/src/jit/shared/IonAssemblerBufferWithConstantPools.h
@@ -1197,17 +1197,17 @@ struct AssemblerBufferWithConstantPool :
             start = poolGroup[idx].addPoolSize(start);
         }
         for (int idx = numPoolKinds - 1; idx >= 0; idx--) {
             if (poolGroup[idx].other == realPool) {
                 return start + offset;
             }
             start = poolGroup[idx].other->addPoolSize(start);
         }
-        MOZ_CRASH("Entry is not in a pool");
+        MOZ_ASSUME_UNREACHABLE("Entry is not in a pool");
     }
     void writePoolEntry(PoolEntry pe, uint8_t *buff) {
         size_t size = getPoolEntrySize(pe);
         uint8_t *entry = getPoolEntry(pe);
         memcpy(entry, buff, size);
     }
     void readPoolEntry(PoolEntry pe, uint8_t *buff) {
         size_t size = getPoolEntrySize(pe);
--- a/js/src/jit/shared/MacroAssembler-x86-shared.h
+++ b/js/src/jit/shared/MacroAssembler-x86-shared.h
@@ -399,17 +399,17 @@ class MacroAssemblerX86Shared : public A
         switch (src.kind()) {
           case Operand::MEM_REG_DISP:
             loadDouble(src.toAddress(), dest);
             break;
           case Operand::MEM_SCALE:
             loadDouble(src.toBaseIndex(), dest);
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void storeDouble(FloatRegister src, const Address &dest) {
         movsd(src, dest);
     }
     void storeDouble(FloatRegister src, const BaseIndex &dest) {
         movsd(src, dest);
     }
@@ -417,17 +417,17 @@ class MacroAssemblerX86Shared : public A
         switch (dest.kind()) {
           case Operand::MEM_REG_DISP:
             storeDouble(src, dest.toAddress());
             break;
           case Operand::MEM_SCALE:
             storeDouble(src, dest.toBaseIndex());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void moveDouble(FloatRegister src, FloatRegister dest) {
         // Use movapd instead of movsd to avoid dependencies.
         movapd(src, dest);
     }
     void zeroDouble(FloatRegister reg) {
         xorpd(reg, reg);
@@ -494,17 +494,17 @@ class MacroAssemblerX86Shared : public A
         switch (src.kind()) {
           case Operand::MEM_REG_DISP:
             loadFloat32(src.toAddress(), dest);
             break;
           case Operand::MEM_SCALE:
             loadFloat32(src.toBaseIndex(), dest);
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void storeFloat32(FloatRegister src, const Address &dest) {
         movss(src, dest);
     }
     void storeFloat32(FloatRegister src, const BaseIndex &dest) {
         movss(src, dest);
     }
@@ -512,17 +512,17 @@ class MacroAssemblerX86Shared : public A
         switch (dest.kind()) {
           case Operand::MEM_REG_DISP:
             storeFloat32(src, dest.toAddress());
             break;
           case Operand::MEM_SCALE:
             storeFloat32(src, dest.toBaseIndex());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void moveFloat32(FloatRegister src, FloatRegister dest) {
         // Use movaps instead of movss to avoid dependencies.
         movaps(src, dest);
     }
 
     // Checks whether a double is representable as a 32-bit integer. If so, the
--- a/js/src/jit/shared/MoveEmitter-x86-shared.cpp
+++ b/js/src/jit/shared/MoveEmitter-x86-shared.cpp
@@ -137,17 +137,17 @@ MoveEmitterX86::emit(const MoveResolver 
             break;
           case MoveOp::INT32:
             emitInt32Move(from, to);
             break;
           case MoveOp::GENERAL:
             emitGeneralMove(from, to);
             break;
           default:
-            MOZ_CRASH("Unexpected move type");
+            MOZ_ASSUME_UNREACHABLE("Unexpected move type");
         }
     }
 }
 
 MoveEmitterX86::~MoveEmitterX86()
 {
     assertDone();
 }
@@ -251,17 +251,17 @@ MoveEmitterX86::breakCycle(const MoveOpe
             masm.store32(to.reg(), cycleSlot());
         }
         break;
 #endif
       case MoveOp::GENERAL:
         masm.Push(toOperand(to));
         break;
       default:
-        MOZ_CRASH("Unexpected move type");
+        MOZ_ASSUME_UNREACHABLE("Unexpected move type");
     }
 }
 
 void
 MoveEmitterX86::completeCycle(const MoveOperand &to, MoveOp::Type type)
 {
     // There is some pattern:
     //   (A -> B)
@@ -303,17 +303,17 @@ MoveEmitterX86::completeCycle(const Move
         }
         break;
 #endif
       case MoveOp::GENERAL:
         JS_ASSERT(masm.framePushed() - pushedAtStart_ >= sizeof(intptr_t));
         masm.Pop(toPopOperand(to));
         break;
       default:
-        MOZ_CRASH("Unexpected move type");
+        MOZ_ASSUME_UNREACHABLE("Unexpected move type");
     }
 }
 
 void
 MoveEmitterX86::emitInt32Move(const MoveOperand &from, const MoveOperand &to)
 {
     if (from.isGeneralReg()) {
         masm.move32(from.reg(), toOperand(to));
--- a/js/src/jit/x64/Assembler-x64.cpp
+++ b/js/src/jit/x64/Assembler-x64.cpp
@@ -39,17 +39,17 @@ ABIArgGenerator::next(MIRType type)
       case MIRType_Pointer:
         current_ = ABIArg(IntArgRegs[regIndex_++]);
         break;
       case MIRType_Float32:
       case MIRType_Double:
         current_ = ABIArg(FloatArgRegs[regIndex_++]);
         break;
       default:
-        MOZ_CRASH("Unexpected argument type");
+        MOZ_ASSUME_UNREACHABLE("Unexpected argument type");
     }
     return current_;
 #else
     switch (type) {
       case MIRType_Int32:
       case MIRType_Pointer:
         if (intRegIndex_ == NumIntArgRegs) {
             current_ = ABIArg(stackOffset_);
@@ -63,17 +63,17 @@ ABIArgGenerator::next(MIRType type)
         if (floatRegIndex_ == NumFloatArgRegs) {
             current_ = ABIArg(stackOffset_);
             stackOffset_ += sizeof(uint64_t);
             break;
         }
         current_ = ABIArg(FloatArgRegs[floatRegIndex_++]);
         break;
       default:
-        MOZ_CRASH("Unexpected argument type");
+        MOZ_ASSUME_UNREACHABLE("Unexpected argument type");
     }
     return current_;
 #endif
 }
 
 // Avoid r11, which is the MacroAssembler's ScratchReg.
 const Register ABIArgGenerator::NonArgReturnVolatileReg0 = r10;
 const Register ABIArgGenerator::NonArgReturnVolatileReg1 = r12;
--- a/js/src/jit/x64/Assembler-x64.h
+++ b/js/src/jit/x64/Assembler-x64.h
@@ -339,17 +339,17 @@ class Assembler : public AssemblerX86Sha
             break;
           case Operand::MEM_SCALE:
             masm.movq_mr(src.disp(), src.base(), src.index(), src.scale(), dest.code());
             break;
           case Operand::MEM_ADDRESS32:
             masm.movq_mr(src.address(), dest.code());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void movq(Register src, const Operand &dest) {
         switch (dest.kind()) {
           case Operand::REG:
             masm.movq_rr(src.code(), dest.reg());
             break;
           case Operand::MEM_REG_DISP:
@@ -357,17 +357,17 @@ class Assembler : public AssemblerX86Sha
             break;
           case Operand::MEM_SCALE:
             masm.movq_rm(src.code(), dest.disp(), dest.base(), dest.index(), dest.scale());
             break;
           case Operand::MEM_ADDRESS32:
             masm.movq_rm(src.code(), dest.address());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void movq(Imm32 imm32, const Operand &dest) {
         switch (dest.kind()) {
           case Operand::REG:
             masm.movl_i32r(imm32.value, dest.reg());
             break;
           case Operand::MEM_REG_DISP:
@@ -375,17 +375,17 @@ class Assembler : public AssemblerX86Sha
             break;
           case Operand::MEM_SCALE:
             masm.movq_i32m(imm32.value, dest.disp(), dest.base(), dest.index(), dest.scale());
             break;
           case Operand::MEM_ADDRESS32:
             masm.movq_i32m(imm32.value, dest.address());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void movq(Register src, FloatRegister dest) {
         masm.movq_rr(src.code(), dest.code());
     }
     void movq(FloatRegister src, Register dest) {
         masm.movq_rr(src.code(), dest.code());
     }
@@ -413,17 +413,17 @@ class Assembler : public AssemblerX86Sha
             break;
           case Operand::MEM_SCALE:
             masm.andq_mr(src.disp(), src.base(), src.index(), src.scale(), dest.code());
             break;
           case Operand::MEM_ADDRESS32:
             masm.andq_mr(src.address(), dest.code());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
 
     void addq(Imm32 imm, Register dest) {
         masm.addq_ir(imm.value, dest.code());
     }
     void addq(Imm32 imm, const Operand &dest) {
         switch (dest.kind()) {
@@ -432,17 +432,17 @@ class Assembler : public AssemblerX86Sha
             break;
           case Operand::MEM_REG_DISP:
             masm.addq_im(imm.value, dest.disp(), dest.base());
             break;
           case Operand::MEM_ADDRESS32:
             masm.addq_im(imm.value, dest.address());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void addq(Register src, Register dest) {
         masm.addq_rr(src.code(), dest.code());
     }
     void addq(const Operand &src, Register dest) {
         switch (src.kind()) {
           case Operand::REG:
@@ -450,17 +450,17 @@ class Assembler : public AssemblerX86Sha
             break;
           case Operand::MEM_REG_DISP:
             masm.addq_mr(src.disp(), src.base(), dest.code());
             break;
           case Operand::MEM_ADDRESS32:
             masm.addq_mr(src.address(), dest.code());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
 
     void subq(Imm32 imm, Register dest) {
         masm.subq_ir(imm.value, dest.code());
     }
     void subq(Register src, Register dest) {
         masm.subq_rr(src.code(), dest.code());
@@ -472,29 +472,29 @@ class Assembler : public AssemblerX86Sha
             break;
           case Operand::MEM_REG_DISP:
             masm.subq_mr(src.disp(), src.base(), dest.code());
             break;
           case Operand::MEM_ADDRESS32:
             masm.subq_mr(src.address(), dest.code());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void subq(Register src, const Operand &dest) {
         switch (dest.kind()) {
           case Operand::REG:
             masm.subq_rr(src.code(), dest.reg());
             break;
           case Operand::MEM_REG_DISP:
             masm.subq_rm(src.code(), dest.disp(), dest.base());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void shlq(Imm32 imm, Register dest) {
         masm.shlq_i8r(imm.value, dest.code());
     }
     void shrq(Imm32 imm, Register dest) {
         masm.shrq_i8r(imm.value, dest.code());
     }
@@ -514,17 +514,17 @@ class Assembler : public AssemblerX86Sha
             break;
           case Operand::MEM_REG_DISP:
             masm.orq_mr(src.disp(), src.base(), dest.code());
             break;
           case Operand::MEM_ADDRESS32:
             masm.orq_mr(src.address(), dest.code());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void xorq(Register src, Register dest) {
         masm.xorq_rr(src.code(), dest.code());
     }
     void xorq(Imm32 imm, Register dest) {
         masm.xorq_ir(imm.value, dest.code());
     }
@@ -573,17 +573,17 @@ class Assembler : public AssemblerX86Sha
         switch (src.kind()) {
           case Operand::MEM_REG_DISP:
             masm.leaq_mr(src.disp(), src.base(), dest.code());
             break;
           case Operand::MEM_SCALE:
             masm.leaq_mr(src.disp(), src.base(), src.index(), src.scale(), dest.code());
             break;
           default:
-            MOZ_CRASH("unexepcted operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexepcted operand kind");
         }
     }
 
     CodeOffsetLabel loadRipRelativeInt32(Register dest) {
         return CodeOffsetLabel(masm.movl_ripr(dest.code()).offset());
     }
     CodeOffsetLabel loadRipRelativeInt64(Register dest) {
         return CodeOffsetLabel(masm.movq_ripr(dest.code()).offset());
@@ -611,44 +611,44 @@ class Assembler : public AssemblerX86Sha
             break;
           case Operand::MEM_REG_DISP:
             masm.cmpq_rm(rhs.code(), lhs.disp(), lhs.base());
             break;
           case Operand::MEM_ADDRESS32:
             masm.cmpq_rm(rhs.code(), lhs.address());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void cmpq(const Operand &lhs, Imm32 rhs) {
         switch (lhs.kind()) {
           case Operand::REG:
             masm.cmpq_ir(rhs.value, lhs.reg());
             break;
           case Operand::MEM_REG_DISP:
             masm.cmpq_im(rhs.value, lhs.disp(), lhs.base());
             break;
           case Operand::MEM_ADDRESS32:
             masm.cmpq_im(rhs.value, lhs.address());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void cmpq(Register lhs, const Operand &rhs) {
         switch (rhs.kind()) {
           case Operand::REG:
             masm.cmpq_rr(rhs.reg(), lhs.code());
             break;
           case Operand::MEM_REG_DISP:
             masm.cmpq_mr(rhs.disp(), rhs.base(), lhs.code());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void cmpq(Register lhs, Register rhs) {
         masm.cmpq_rr(rhs.code(), lhs.code());
     }
     void cmpq(Register lhs, Imm32 rhs) {
         masm.cmpq_ir(rhs.value, lhs.code());
     }
@@ -663,17 +663,18 @@ class Assembler : public AssemblerX86Sha
         switch (lhs.kind()) {
           case Operand::REG:
             masm.testq_i32r(rhs.value, lhs.reg());
             break;
           case Operand::MEM_REG_DISP:
             masm.testq_i32m(rhs.value, lhs.disp(), lhs.base());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
+            break;
         }
     }
 
     void jmp(ImmPtr target, Relocation::Kind reloc = Relocation::HARDCODED) {
         JmpSrc src = masm.jmp();
         addPendingJump(src, target, reloc);
     }
     void j(Condition cond, ImmPtr target,
--- a/js/src/jit/x64/Bailouts-x64.cpp
+++ b/js/src/jit/x64/Bailouts-x64.cpp
@@ -55,17 +55,17 @@ IonBailoutIterator::IonBailoutIterator(c
 
     kind_ = Kind_BailoutIterator;
     current_ = fp;
     type_ = JitFrame_IonJS;
     topFrameSize_ = current_ - sp;
     switch (mode_) {
       case SequentialExecution: topIonScript_ = script()->ionScript(); break;
       case ParallelExecution: topIonScript_ = script()->parallelIonScript(); break;
-      default: MOZ_CRASH("No such execution mode");
+      default: MOZ_ASSUME_UNREACHABLE("No such execution mode");
     }
     snapshotOffset_ = bailout->snapshotOffset();
 }
 
 IonBailoutIterator::IonBailoutIterator(const JitActivationIterator &activations,
                                        InvalidationBailoutStack *bailout)
   : JitFrameIterator(activations),
     machine_(bailout->machine())
--- a/js/src/jit/x64/BaselineIC-x64.cpp
+++ b/js/src/jit/x64/BaselineIC-x64.cpp
@@ -179,17 +179,17 @@ ICBinaryArith_Int32::Compiler::generateS
             masm.convertUInt32ToDouble(ExtractTemp0, ScratchDoubleReg);
             masm.boxDouble(ScratchDoubleReg, R0);
         } else {
             masm.j(Assembler::Signed, &revertRegister);
             masm.boxValue(JSVAL_TYPE_INT32, ExtractTemp0, R0.valueReg());
         }
         break;
       default:
-        MOZ_CRASH("Unhandled op in BinaryArith_Int32");
+        MOZ_ASSUME_UNREACHABLE("Unhandled op in BinaryArith_Int32");
     }
 
     // Return from stub.
     EmitReturnFromIC(masm);
 
     if (op_ == JSOP_MUL) {
         masm.bind(&maybeNegZero);
 
@@ -228,17 +228,17 @@ ICUnaryArith_Int32::Compiler::generateSt
         masm.notl(R0.valueReg());
         break;
       case JSOP_NEG:
         // Guard against 0 and MIN_INT, both result in a double.
         masm.branchTest32(Assembler::Zero, R0.valueReg(), Imm32(0x7fffffff), &failure);
         masm.negl(R0.valueReg());
         break;
       default:
-        MOZ_CRASH("Unexpected op");
+        MOZ_ASSUME_UNREACHABLE("Unexpected op");
     }
 
     masm.tagValue(JSVAL_TYPE_INT32, R0.valueReg(), R0);
 
     EmitReturnFromIC(masm);
 
     masm.bind(&failure);
     EmitStubGuardFailure(masm);
--- a/js/src/jit/x64/CodeGenerator-x64.cpp
+++ b/js/src/jit/x64/CodeGenerator-x64.cpp
@@ -49,17 +49,17 @@ FrameSizeClass
 FrameSizeClass::ClassLimit()
 {
     return FrameSizeClass(0);
 }
 
 uint32_t
 FrameSizeClass::frameSize() const
 {
-    MOZ_CRASH("x64 does not use frame size classes");
+    MOZ_ASSUME_UNREACHABLE("x64 does not use frame size classes");
 }
 
 bool
 CodeGeneratorX64::visitValue(LValue *value)
 {
     LDefinition *reg = value->getDef(0);
     masm.moveValue(value->value(), ToRegister(reg));
     return true;
@@ -105,17 +105,17 @@ CodeGeneratorX64::visitUnbox(LUnbox *unb
             break;
           case MIRType_String:
             cond = masm.testString(Assembler::NotEqual, value);
             break;
           case MIRType_Symbol:
             cond = masm.testSymbol(Assembler::NotEqual, value);
             break;
           default:
-            MOZ_CRASH("Given MIRType cannot be unboxed.");
+            MOZ_ASSUME_UNREACHABLE("Given MIRType cannot be unboxed.");
         }
         if (!bailoutIf(cond, unbox->snapshot()))
             return false;
     }
 
     switch (mir->type()) {
       case MIRType_Int32:
         masm.unboxInt32(value, ToRegister(result));
@@ -128,17 +128,17 @@ CodeGeneratorX64::visitUnbox(LUnbox *unb
         break;
       case MIRType_String:
         masm.unboxString(value, ToRegister(result));
         break;
       case MIRType_Symbol:
         masm.unboxSymbol(value, ToRegister(result));
         break;
       default:
-        MOZ_CRASH("Given MIRType cannot be unboxed.");
+        MOZ_ASSUME_UNREACHABLE("Given MIRType cannot be unboxed.");
     }
 
     return true;
 }
 
 bool
 CodeGeneratorX64::visitCompareB(LCompareB *lir)
 {
@@ -226,23 +226,23 @@ CodeGeneratorX64::visitAsmJSUInt32ToFloa
 {
     masm.convertUInt32ToFloat32(ToRegister(lir->input()), ToFloatRegister(lir->output()));
     return true;
 }
 
 bool
 CodeGeneratorX64::visitLoadTypedArrayElementStatic(LLoadTypedArrayElementStatic *ins)
 {
-    MOZ_CRASH("NYI");
+    MOZ_ASSUME_UNREACHABLE("NYI");
 }
 
 bool
 CodeGeneratorX64::visitStoreTypedArrayElementStatic(LStoreTypedArrayElementStatic *ins)
 {
-    MOZ_CRASH("NYI");
+    MOZ_ASSUME_UNREACHABLE("NYI");
 }
 
 bool
 CodeGeneratorX64::visitAsmJSLoadHeap(LAsmJSLoadHeap *ins)
 {
     MAsmJSLoadHeap *mir = ins->mir();
     Scalar::Type vt = mir->viewType();
     const LAllocation *ptr = ins->ptr();
@@ -266,17 +266,17 @@ CodeGeneratorX64::visitAsmJSLoadHeap(LAs
       case Scalar::Int8:    masm.movsbl(srcAddr, ToRegister(ins->output())); break;
       case Scalar::Uint8:   masm.movzbl(srcAddr, ToRegister(ins->output())); break;
       case Scalar::Int16:   masm.movswl(srcAddr, ToRegister(ins->output())); break;
       case Scalar::Uint16:  masm.movzwl(srcAddr, ToRegister(ins->output())); break;
       case Scalar::Int32:
       case Scalar::Uint32:  masm.movl(srcAddr, ToRegister(ins->output())); break;
       case Scalar::Float32: masm.loadFloat32(srcAddr, ToFloatRegister(ins->output())); break;
       case Scalar::Float64: masm.loadDouble(srcAddr, ToFloatRegister(ins->output())); break;
-      default: MOZ_CRASH("unexpected array type");
+      default: MOZ_ASSUME_UNREACHABLE("unexpected array type");
     }
     uint32_t after = masm.size();
     if (!skipNote)
         masm.append(AsmJSHeapAccess(before, after, vt, ToAnyRegister(ins->output())));
     return true;
 }
 
 bool
@@ -303,29 +303,29 @@ CodeGeneratorX64::visitAsmJSStoreHeap(LA
     if (ins->value()->isConstant()) {
         switch (vt) {
           case Scalar::Int8:
           case Scalar::Uint8:   masm.movb(Imm32(ToInt32(ins->value())), dstAddr); break;
           case Scalar::Int16:
           case Scalar::Uint16:  masm.movw(Imm32(ToInt32(ins->value())), dstAddr); break;
           case Scalar::Int32:
           case Scalar::Uint32:  masm.movl(Imm32(ToInt32(ins->value())), dstAddr); break;
-          default: MOZ_CRASH("unexpected array type");
+          default: MOZ_ASSUME_UNREACHABLE("unexpected array type");
         }
     } else {
         switch (vt) {
           case Scalar::Int8:
           case Scalar::Uint8:   masm.movb(ToRegister(ins->value()), dstAddr); break;
           case Scalar::Int16:
           case Scalar::Uint16:  masm.movw(ToRegister(ins->value()), dstAddr); break;
           case Scalar::Int32:
           case Scalar::Uint32:  masm.movl(ToRegister(ins->value()), dstAddr); break;
           case Scalar::Float32: masm.storeFloat32(ToFloatRegister(ins->value()), dstAddr); break;
           case Scalar::Float64: masm.storeDouble(ToFloatRegister(ins->value()), dstAddr); break;
-          default: MOZ_CRASH("unexpected array type");
+          default: MOZ_ASSUME_UNREACHABLE("unexpected array type");
         }
     }
     uint32_t after = masm.size();
     if (!skipNote)
         masm.append(AsmJSHeapAccess(before, after));
     return true;
 }
 
--- a/js/src/jit/x64/Lowering-x64.cpp
+++ b/js/src/jit/x64/Lowering-x64.cpp
@@ -163,25 +163,25 @@ LIRGeneratorX64::visitAsmJSStoreHeap(MAs
       case Scalar::Uint32:
         lir = new(alloc()) LAsmJSStoreHeap(ptrAlloc, useRegisterOrConstantAtStart(ins->value()));
         break;
       case Scalar::Float32:
       case Scalar::Float64:
         lir = new(alloc()) LAsmJSStoreHeap(ptrAlloc, useRegisterAtStart(ins->value()));
         break;
       default:
-        MOZ_CRASH("unexpected array type");
+        MOZ_ASSUME_UNREACHABLE("unexpected array type");
     }
 
     return add(lir, ins);
 }
 
 bool
 LIRGeneratorX64::visitAsmJSLoadFuncPtr(MAsmJSLoadFuncPtr *ins)
 {
     return define(new(alloc()) LAsmJSLoadFuncPtr(useRegister(ins->index()), temp()), ins);
 }
 
 bool
 LIRGeneratorX64::visitStoreTypedArrayElementStatic(MStoreTypedArrayElementStatic *ins)
 {
-    MOZ_CRASH("NYI");
+    MOZ_ASSUME_UNREACHABLE("NYI");
 }
--- a/js/src/jit/x64/MacroAssembler-x64.cpp
+++ b/js/src/jit/x64/MacroAssembler-x64.cpp
@@ -145,17 +145,17 @@ MacroAssemblerX64::passABIArg(const Move
                 return;
             }
             to = MoveOperand(dest);
         } else {
             to = MoveOperand(StackPointer, stackForCall_);
             switch (type) {
               case MoveOp::FLOAT32: stackForCall_ += sizeof(float);  break;
               case MoveOp::DOUBLE:  stackForCall_ += sizeof(double); break;
-              default: MOZ_CRASH("Unexpected float register class argument type");
+              default: MOZ_ASSUME_UNREACHABLE("Unexpected float register class argument type");
             }
         }
         break;
       }
       case MoveOp::GENERAL: {
         Register dest;
         if (GetIntArgReg(passedIntArgs_++, passedFloatArgs_, &dest)) {
             if (from.isGeneralReg() && from.reg() == dest) {
@@ -165,17 +165,17 @@ MacroAssemblerX64::passABIArg(const Move
             to = MoveOperand(dest);
         } else {
             to = MoveOperand(StackPointer, stackForCall_);
             stackForCall_ += sizeof(int64_t);
         }
         break;
       }
       default:
-        MOZ_CRASH("Unexpected argument type");
+        MOZ_ASSUME_UNREACHABLE("Unexpected argument type");
     }
 
     enoughMemory_ = moveResolver_.addMove(from, to, type);
 }
 
 void
 MacroAssemblerX64::passABIArg(Register reg)
 {
--- a/js/src/jit/x64/MacroAssembler-x64.h
+++ b/js/src/jit/x64/MacroAssembler-x64.h
@@ -108,17 +108,17 @@ class MacroAssemblerX64 : public MacroAs
           case Operand::MEM_REG_DISP:
             return Operand(Register::FromCode(base.base()), base.disp() + 4);
 
           case Operand::MEM_SCALE:
             return Operand(Register::FromCode(base.base()), Register::FromCode(base.index()),
                            base.scale(), base.disp() + 4);
 
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     static inline Operand ToUpper32(const Address &address) {
         return Operand(address.base, address.offset + 4);
     }
     static inline Operand ToUpper32(const BaseIndex &address) {
         return Operand(address.base, address.index, address.scale, address.offset + 4);
     }
--- a/js/src/jit/x64/Trampoline-x64.cpp
+++ b/js/src/jit/x64/Trampoline-x64.cpp
@@ -514,33 +514,33 @@ GenerateParallelBailoutThunk(MacroAssemb
     masm.moveValue(MagicValue(JS_ION_ERROR), JSReturnOperand);
     masm.loadPtr(Address(rsp, 0), rsp);
     masm.ret();
 }
 
 JitCode *
 JitRuntime::generateBailoutTable(JSContext *cx, uint32_t frameClass)
 {
-    MOZ_CRASH("x64 does not use bailout tables");
+    MOZ_ASSUME_UNREACHABLE("x64 does not use bailout tables");
 }
 
 JitCode *
 JitRuntime::generateBailoutHandler(JSContext *cx, ExecutionMode mode)
 {
     MacroAssembler masm;
 
     switch (mode) {
       case SequentialExecution:
         GenerateBailoutThunk(cx, masm, NO_FRAME_SIZE_CLASS_ID);
         break;
       case ParallelExecution:
         GenerateParallelBailoutThunk(masm);
         break;
       default:
-        MOZ_CRASH("No such execution mode");
+        MOZ_ASSUME_UNREACHABLE("No such execution mode");
     }
 
     Linker linker(masm);
     JitCode *code = linker.newCode<NoGC>(cx, JSC::OTHER_CODE);
 
 #ifdef JS_ION_PERF
     writePerfSpewerJitCodeProfile(code, "BailoutHandler");
 #endif
@@ -646,17 +646,17 @@ JitRuntime::generateVMWrapper(JSContext 
             break;
           case VMFunction::WordByRef:
             masm.passABIArg(MoveOperand(argsBase, argDisp, MoveOperand::EFFECTIVE_ADDRESS),
                             MoveOp::GENERAL);
             argDisp += sizeof(void *);
             break;
           case VMFunction::DoubleByValue:
           case VMFunction::DoubleByRef:
-            MOZ_CRASH("NYI: x64 callVM should not be used with 128bits values.");
+            MOZ_ASSUME_UNREACHABLE("NYI: x64 callVM should not be used with 128bits values.");
         }
     }
 
     // Copy the implicit outparam, if any.
     if (outReg != InvalidReg)
         masm.passABIArg(outReg);
 
     masm.callWithABI(f.wrapped);
@@ -666,17 +666,17 @@ JitRuntime::generateVMWrapper(JSContext 
       case Type_Object:
         masm.branchTestPtr(Assembler::Zero, rax, rax, masm.failureLabel(f.executionMode));
         break;
       case Type_Bool:
         masm.testb(rax, rax);
         masm.j(Assembler::Zero, masm.failureLabel(f.executionMode));
         break;
       default:
-        MOZ_CRASH("unknown failure kind");
+        MOZ_ASSUME_UNREACHABLE("unknown failure kind");
     }
 
     // Load the outparam and free any allocated stack.
     switch (f.outParam) {
       case Type_Handle:
         masm.popRooted(f.outParamRootType, ReturnReg, JSReturnOperand);
         break;
 
--- a/js/src/jit/x86/Assembler-x86.cpp
+++ b/js/src/jit/x86/Assembler-x86.cpp
@@ -25,17 +25,17 @@ ABIArgGenerator::next(MIRType type)
       case MIRType_Pointer:
         stackOffset_ += sizeof(uint32_t);
         break;
       case MIRType_Float32: // Float32 moves are actually double moves
       case MIRType_Double:
         stackOffset_ += sizeof(uint64_t);
         break;
       default:
-        MOZ_CRASH("Unexpected argument type");
+        MOZ_ASSUME_UNREACHABLE("Unexpected argument type");
     }
     return current_;
 }
 
 const Register ABIArgGenerator::NonArgReturnVolatileReg0 = ecx;
 const Register ABIArgGenerator::NonArgReturnVolatileReg1 = edx;
 const Register ABIArgGenerator::NonVolatileReg = ebx;
 
--- a/js/src/jit/x86/Assembler-x86.h
+++ b/js/src/jit/x86/Assembler-x86.h
@@ -232,17 +232,17 @@ class Assembler : public AssemblerX86Sha
             masm.movl_i32m(uintptr_t(ptr.value), dest.disp(), dest.base());
             writeDataRelocation(ptr);
             break;
           case Operand::MEM_SCALE:
             masm.movl_i32m(uintptr_t(ptr.value), dest.disp(), dest.base(), dest.index(), dest.scale());
             writeDataRelocation(ptr);
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void movl(ImmWord imm, Register dest) {
         masm.movl_i32r(imm.value, dest.code());
     }
     void movl(ImmPtr imm, Register dest) {
         movl(ImmWord(uintptr_t(imm.value)), dest);
     }
@@ -289,27 +289,27 @@ class Assembler : public AssemblerX86Sha
     }
 
     void fld32(const Operand &dest) {
         switch (dest.kind()) {
           case Operand::MEM_REG_DISP:
             masm.fld32_m(dest.disp(), dest.base());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
 
     void fstp32(const Operand &src) {
         switch (src.kind()) {
           case Operand::MEM_REG_DISP:
             masm.fstp32_m(src.disp(), src.base());
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
 
     void cmpl(const Register src, ImmWord ptr) {
         masm.cmpl_ir(ptr.value, src.code());
     }
     void cmpl(const Register src, ImmPtr imm) {
         cmpl(src, ImmWord(uintptr_t(imm.value)));
@@ -331,17 +331,17 @@ class Assembler : public AssemblerX86Sha
             masm.cmpl_im_force32(uintptr_t(imm.value), op.disp(), op.base());
             writeDataRelocation(imm);
             break;
           case Operand::MEM_ADDRESS32:
             masm.cmpl_im(uintptr_t(imm.value), op.address());
             writeDataRelocation(imm);
             break;
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     void cmpl(AsmJSAbsoluteAddress lhs, Register rhs) {
         masm.cmpl_rm_force32(rhs.code(), (void*)-1);
         append(AsmJSAbsoluteLink(CodeOffsetLabel(masm.currentOffset()), lhs.kind()));
     }
     CodeOffsetLabel cmplWithPatch(Register lhs, Imm32 rhs) {
         masm.cmpl_ir_force32(rhs.value, lhs.code());
--- a/js/src/jit/x86/Bailouts-x86.cpp
+++ b/js/src/jit/x86/Bailouts-x86.cpp
@@ -75,17 +75,17 @@ IonBailoutIterator::IonBailoutIterator(c
 
     kind_ = Kind_BailoutIterator;
     current_ = fp;
     type_ = JitFrame_IonJS;
     topFrameSize_ = current_ - sp;
     switch (mode_) {
       case SequentialExecution: topIonScript_ = script()->ionScript(); break;
       case ParallelExecution: topIonScript_ = script()->parallelIonScript(); break;
-      default: MOZ_CRASH("No such execution mode");
+      default: MOZ_ASSUME_UNREACHABLE("No such execution mode");
     }
 
     if (bailout->frameClass() == FrameSizeClass::None()) {
         snapshotOffset_ = bailout->snapshotOffset();
         return;
     }
 
     // Compute the snapshot offset from the bailout ID.
--- a/js/src/jit/x86/BaselineIC-x86.cpp
+++ b/js/src/jit/x86/BaselineIC-x86.cpp
@@ -186,17 +186,17 @@ ICBinaryArith_Int32::Compiler::generateS
             masm.convertUInt32ToDouble(R0.payloadReg(), ScratchDoubleReg);
             masm.boxDouble(ScratchDoubleReg, R0);
         } else {
             masm.j(Assembler::Signed, &revertRegister);
             masm.tagValue(JSVAL_TYPE_INT32, R0.payloadReg(), R0);
         }
         break;
       default:
-       MOZ_CRASH("Unhandled op for BinaryArith_Int32.  ");
+       MOZ_ASSUME_UNREACHABLE("Unhandled op for BinaryArith_Int32.  ");
     }
 
     // Return.
     EmitReturnFromIC(masm);
 
     switch(op_) {
       case JSOP_MUL:
         masm.bind(&maybeNegZero);
@@ -247,17 +247,17 @@ ICUnaryArith_Int32::Compiler::generateSt
         masm.notl(R0.payloadReg());
         break;
       case JSOP_NEG:
         // Guard against 0 and MIN_INT, both result in a double.
         masm.branchTest32(Assembler::Zero, R0.payloadReg(), Imm32(0x7fffffff), &failure);
         masm.negl(R0.payloadReg());
         break;
       default:
-        MOZ_CRASH("Unexpected op");
+        MOZ_ASSUME_UNREACHABLE("Unexpected op");
     }
 
     EmitReturnFromIC(masm);
 
     masm.bind(&failure);
     EmitStubGuardFailure(masm);
     return true;
 }
--- a/js/src/jit/x86/CodeGenerator-x86.cpp
+++ b/js/src/jit/x86/CodeGenerator-x86.cpp
@@ -291,17 +291,17 @@ CodeGeneratorX86::loadViewTypeElement(Sc
       case Scalar::Uint8Clamped:
       case Scalar::Uint8:   masm.movzblWithPatch(srcAddr, ToRegister(out)); break;
       case Scalar::Int16:   masm.movswlWithPatch(srcAddr, ToRegister(out)); break;
       case Scalar::Uint16:  masm.movzwlWithPatch(srcAddr, ToRegister(out)); break;
       case Scalar::Int32:
       case Scalar::Uint32:  masm.movlWithPatch(srcAddr, ToRegister(out)); break;
       case Scalar::Float32: masm.movssWithPatch(srcAddr, ToFloatRegister(out)); break;
       case Scalar::Float64: masm.movsdWithPatch(srcAddr, ToFloatRegister(out)); break;
-      default: MOZ_CRASH("unexpected array type");
+      default: MOZ_ASSUME_UNREACHABLE("unexpected array type");
     }
 }
 
 template<typename T>
 bool
 CodeGeneratorX86::loadAndNoteViewTypeElement(Scalar::Type vt, const T &srcAddr,
                                              const LDefinition *out)
 {
@@ -412,17 +412,17 @@ CodeGeneratorX86::storeViewTypeElement(S
       case Scalar::Uint8Clamped:
       case Scalar::Uint8:   masm.movbWithPatch(ToRegister(value), dstAddr); break;
       case Scalar::Int16:
       case Scalar::Uint16:  masm.movwWithPatch(ToRegister(value), dstAddr); break;
       case Scalar::Int32:
       case Scalar::Uint32:  masm.movlWithPatch(ToRegister(value), dstAddr); break;
       case Scalar::Float32: masm.movssWithPatch(ToFloatRegister(value), dstAddr); break;
       case Scalar::Float64: masm.movsdWithPatch(ToFloatRegister(value), dstAddr); break;
-      default: MOZ_CRASH("unexpected array type");
+      default: MOZ_ASSUME_UNREACHABLE("unexpected array type");
     }
 }
 
 template<typename T>
 void
 CodeGeneratorX86::storeAndNoteViewTypeElement(Scalar::Type vt, const LAllocation *value,
                                               const T &dstAddr)
 {
@@ -571,17 +571,17 @@ CodeGeneratorX86::postAsmJSCall(LAsmJSCa
     }
 }
 
 void
 DispatchIonCache::initializeAddCacheState(LInstruction *ins, AddCacheState *addState)
 {
     // On x86, where there is no general purpose scratch register available,
     // child cache classes must manually specify a dispatch scratch register.
-    MOZ_CRASH("x86 needs manual assignment of dispatchScratch");
+    MOZ_ASSUME_UNREACHABLE("x86 needs manual assignment of dispatchScratch");
 }
 
 void
 GetPropertyParIC::initializeAddCacheState(LInstruction *ins, AddCacheState *addState)
 {
     // We don't have a scratch register, but only use the temp if we needed
     // one, it's BogusTemp otherwise.
     JS_ASSERT(ins->isGetPropertyCacheV() || ins->isGetPropertyCacheT());
--- a/js/src/jit/x86/Lowering-x86.cpp
+++ b/js/src/jit/x86/Lowering-x86.cpp
@@ -249,34 +249,34 @@ LIRGeneratorX86::visitAsmJSStoreHeap(MAs
             lir = new(alloc()) LAsmJSStoreHeap(ptrAlloc, useFixed(ins->value(), eax));
             break;
           case Scalar::Int16: case Scalar::Uint16:
           case Scalar::Int32: case Scalar::Uint32:
           case Scalar::Float32: case Scalar::Float64:
             // See comment below.
             lir = new(alloc()) LAsmJSStoreHeap(ptrAlloc, useRegisterAtStart(ins->value()));
             break;
-          default: MOZ_CRASH("unexpected array type");
+          default: MOZ_ASSUME_UNREACHABLE("unexpected array type");
         }
         return add(lir, ins);
     }
 
     switch (ins->viewType()) {
       case Scalar::Int8: case Scalar::Uint8:
         // See comment for LIRGeneratorX86::useByteOpRegister.
         lir = new(alloc()) LAsmJSStoreHeap(useRegister(ins->ptr()), useFixed(ins->value(), eax));
         break;
       case Scalar::Int16: case Scalar::Uint16:
       case Scalar::Int32: case Scalar::Uint32:
       case Scalar::Float32: case Scalar::Float64:
         // For now, don't allow constant values. The immediate operand
         // affects instruction layout which affects patching.
         lir = new(alloc()) LAsmJSStoreHeap(useRegisterAtStart(ptr), useRegisterAtStart(ins->value()));
         break;
-      default: MOZ_CRASH("unexpected array type");
+      default: MOZ_ASSUME_UNREACHABLE("unexpected array type");
     }
 
     return add(lir, ins);
 }
 
 bool
 LIRGeneratorX86::visitStoreTypedArrayElementStatic(MStoreTypedArrayElementStatic *ins)
 {
@@ -290,17 +290,17 @@ LIRGeneratorX86::visitStoreTypedArrayEle
                                                          useFixed(ins->value(), eax));
         break;
       case Scalar::Int16: case Scalar::Uint16:
       case Scalar::Int32: case Scalar::Uint32:
       case Scalar::Float32: case Scalar::Float64:
         lir = new(alloc()) LStoreTypedArrayElementStatic(useRegisterAtStart(ins->ptr()),
                                                          useRegisterAtStart(ins->value()));
         break;
-      default: MOZ_CRASH("unexpected array type");
+      default: MOZ_ASSUME_UNREACHABLE("unexpected array type");
     }
 
     return add(lir, ins);
 }
 
 bool
 LIRGeneratorX86::visitAsmJSLoadFuncPtr(MAsmJSLoadFuncPtr *ins)
 {
--- a/js/src/jit/x86/MacroAssembler-x86.cpp
+++ b/js/src/jit/x86/MacroAssembler-x86.cpp
@@ -168,17 +168,17 @@ MacroAssemblerX86::passABIArg(const Move
 {
     ++passedArgs_;
     MoveOperand to = MoveOperand(StackPointer, stackForCall_);
     switch (type) {
       case MoveOp::FLOAT32: stackForCall_ += sizeof(float); break;
       case MoveOp::DOUBLE:  stackForCall_ += sizeof(double); break;
       case MoveOp::INT32:   stackForCall_ += sizeof(int32_t); break;
       case MoveOp::GENERAL: stackForCall_ += sizeof(intptr_t); break;
-      default: MOZ_CRASH("Unexpected argument type");
+      default: MOZ_ASSUME_UNREACHABLE("Unexpected argument type");
     }
     enoughMemory_ &= moveResolver_.addMove(from, to, type);
 }
 
 void
 MacroAssemblerX86::passABIArg(Register reg)
 {
     passABIArg(MoveOperand(reg), MoveOp::GENERAL);
--- a/js/src/jit/x86/MacroAssembler-x86.h
+++ b/js/src/jit/x86/MacroAssembler-x86.h
@@ -97,17 +97,17 @@ class MacroAssemblerX86 : public MacroAs
           case Operand::MEM_REG_DISP:
             return Operand(Register::FromCode(base.base()), base.disp() + sizeof(void *));
 
           case Operand::MEM_SCALE:
             return Operand(Register::FromCode(base.base()), Register::FromCode(base.index()),
                            base.scale(), base.disp() + sizeof(void *));
 
           default:
-            MOZ_CRASH("unexpected operand kind");
+            MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
     Address ToType(Address base) {
         return ToType(Operand(base)).toAddress();
     }
     void moveValue(const Value &val, Register type, Register data) {
         jsval_layout jv = JSVAL_TO_IMPL(val);
         movl(Imm32(jv.s.tag), type);
--- a/js/src/jit/x86/Trampoline-x86.cpp
+++ b/js/src/jit/x86/Trampoline-x86.cpp
@@ -570,17 +570,17 @@ JitRuntime::generateBailoutHandler(JSCon
     switch (mode) {
       case SequentialExecution:
         GenerateBailoutThunk(cx, masm, NO_FRAME_SIZE_CLASS_ID);
         break;
       case ParallelExecution:
         GenerateParallelBailoutThunk(masm, NO_FRAME_SIZE_CLASS_ID);
         break;
       default:
-        MOZ_CRASH("No such execution mode");
+        MOZ_ASSUME_UNREACHABLE("No such execution mode");
     }
 
     Linker linker(masm);
     JitCode *code = linker.newCode<NoGC>(cx, JSC::OTHER_CODE);
 
 #ifdef JS_ION_PERF
     writePerfSpewerJitCodeProfile(code, "BailoutHandler");
 #endif
@@ -706,17 +706,17 @@ JitRuntime::generateVMWrapper(JSContext 
       case Type_Object:
         masm.branchTestPtr(Assembler::Zero, eax, eax, masm.failureLabel(f.executionMode));
         break;
       case Type_Bool:
         masm.testb(eax, eax);
         masm.j(Assembler::Zero, masm.failureLabel(f.executionMode));
         break;
       default:
-        MOZ_CRASH("unknown failure kind");
+        MOZ_ASSUME_UNREACHABLE("unknown failure kind");
     }
 
     // Load the outparam and free any allocated stack.
     switch (f.outParam) {
       case Type_Handle:
         masm.popRooted(f.outParamRootType, ReturnReg, JSReturnOperand);
         break;