Bug 1225028 - remove Atomics.fence. r=bbouvier
authorLars T Hansen <lhansen@mozilla.com>
Sat, 02 Apr 2016 08:55:24 -0700
changeset 291447 859f435f2ca001acc659cf47a2068fc94287e84a
parent 291446 88688664f228ff07d20d623c701a49dac9226f12
child 291448 63bdfecc99f488142d1601f381f6241fd22ddb92
push id74572
push userlhansen@mozilla.com
push dateSun, 03 Apr 2016 13:49:04 +0000
treeherdermozilla-inbound@fd3ca174abe0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbbouvier
bugs1225028
milestone48.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1225028 - remove Atomics.fence. r=bbouvier
js/src/asmjs/AsmJS.cpp
js/src/asmjs/WasmBinary.h
js/src/asmjs/WasmIonCompile.cpp
js/src/builtin/AtomicsObject.cpp
js/src/builtin/AtomicsObject.h
js/src/jit-test/tests/asm.js/testAtomics.js
js/src/jit-test/tests/atomics/basic-tests.js
js/src/jit-test/tests/atomics/inline-fence.js
js/src/jit/InlinableNatives.h
js/src/jit/IonBuilder.h
js/src/jit/Lowering.cpp
js/src/jit/Lowering.h
js/src/jit/MCallOptimize.cpp
js/src/jit/MIR.h
js/src/jit/MOpcodes.h
js/src/jit/shared/LIR-shared.h
--- a/js/src/asmjs/AsmJS.cpp
+++ b/js/src/asmjs/AsmJS.cpp
@@ -91,17 +91,16 @@ enum AsmJSMathBuiltinFunction
 
 // The asm.js spec will recognize this set of builtin Atomics functions.
 enum AsmJSAtomicsBuiltinFunction
 {
     AsmJSAtomicsBuiltin_compareExchange,
     AsmJSAtomicsBuiltin_exchange,
     AsmJSAtomicsBuiltin_load,
     AsmJSAtomicsBuiltin_store,
-    AsmJSAtomicsBuiltin_fence,
     AsmJSAtomicsBuiltin_add,
     AsmJSAtomicsBuiltin_sub,
     AsmJSAtomicsBuiltin_and,
     AsmJSAtomicsBuiltin_or,
     AsmJSAtomicsBuiltin_xor,
     AsmJSAtomicsBuiltin_isLockFree
 };
 
@@ -1730,17 +1729,16 @@ class MOZ_STACK_CLASS ModuleValidator
             return false;
         }
 
         if (!standardLibraryAtomicsNames_.init() ||
             !addStandardLibraryAtomicsName("compareExchange", AsmJSAtomicsBuiltin_compareExchange) ||
             !addStandardLibraryAtomicsName("exchange", AsmJSAtomicsBuiltin_exchange) ||
             !addStandardLibraryAtomicsName("load", AsmJSAtomicsBuiltin_load) ||
             !addStandardLibraryAtomicsName("store", AsmJSAtomicsBuiltin_store) ||
-            !addStandardLibraryAtomicsName("fence", AsmJSAtomicsBuiltin_fence) ||
             !addStandardLibraryAtomicsName("add", AsmJSAtomicsBuiltin_add) ||
             !addStandardLibraryAtomicsName("sub", AsmJSAtomicsBuiltin_sub) ||
             !addStandardLibraryAtomicsName("and", AsmJSAtomicsBuiltin_and) ||
             !addStandardLibraryAtomicsName("or", AsmJSAtomicsBuiltin_or) ||
             !addStandardLibraryAtomicsName("xor", AsmJSAtomicsBuiltin_xor) ||
             !addStandardLibraryAtomicsName("isLockFree", AsmJSAtomicsBuiltin_isLockFree))
         {
             return false;
@@ -4102,26 +4100,16 @@ CheckSharedArrayAtomicAccess(FunctionVal
       default:
         return f.failf(viewName, "not an integer array");
     }
 
     return true;
 }
 
 static bool
-CheckAtomicsFence(FunctionValidator& f, ParseNode* call, Type* type)
-{
-    if (CallArgListLength(call) != 0)
-        return f.fail(call, "Atomics.fence must be passed 0 arguments");
-
-    *type = Type::Void;
-    return f.encoder().writeExpr(Expr::AtomicsFence);
-}
-
-static bool
 WriteAtomicOperator(FunctionValidator& f, Expr opcode, size_t* viewTypeAt)
 {
     return f.encoder().writeExpr(opcode) &&
            f.encoder().writePatchableFixedU8(viewTypeAt);
 }
 
 static bool
 CheckAtomicsLoad(FunctionValidator& f, ParseNode* call, Type* type)
@@ -4304,18 +4292,16 @@ CheckAtomicsBuiltinCall(FunctionValidato
       case AsmJSAtomicsBuiltin_compareExchange:
         return CheckAtomicsCompareExchange(f, callNode, type);
       case AsmJSAtomicsBuiltin_exchange:
         return CheckAtomicsExchange(f, callNode, type);
       case AsmJSAtomicsBuiltin_load:
         return CheckAtomicsLoad(f, callNode, type);
       case AsmJSAtomicsBuiltin_store:
         return CheckAtomicsStore(f, callNode, type);
-      case AsmJSAtomicsBuiltin_fence:
-        return CheckAtomicsFence(f, callNode, type);
       case AsmJSAtomicsBuiltin_add:
         return CheckAtomicsBinop(f, callNode, type, AtomicFetchAddOp);
       case AsmJSAtomicsBuiltin_sub:
         return CheckAtomicsBinop(f, callNode, type, AtomicFetchSubOp);
       case AsmJSAtomicsBuiltin_and:
         return CheckAtomicsBinop(f, callNode, type, AtomicFetchAndOp);
       case AsmJSAtomicsBuiltin_or:
         return CheckAtomicsBinop(f, callNode, type, AtomicFetchOrOp);
@@ -7366,17 +7352,16 @@ ValidateAtomicsBuiltinFunction(JSContext
         return false;
 
     Native native = nullptr;
     switch (global.atomicsBuiltinFunction()) {
       case AsmJSAtomicsBuiltin_compareExchange: native = atomics_compareExchange; break;
       case AsmJSAtomicsBuiltin_exchange: native = atomics_exchange; break;
       case AsmJSAtomicsBuiltin_load: native = atomics_load; break;
       case AsmJSAtomicsBuiltin_store: native = atomics_store; break;
-      case AsmJSAtomicsBuiltin_fence: native = atomics_fence; break;
       case AsmJSAtomicsBuiltin_add: native = atomics_add; break;
       case AsmJSAtomicsBuiltin_sub: native = atomics_sub; break;
       case AsmJSAtomicsBuiltin_and: native = atomics_and; break;
       case AsmJSAtomicsBuiltin_or: native = atomics_or; break;
       case AsmJSAtomicsBuiltin_xor: native = atomics_xor; break;
       case AsmJSAtomicsBuiltin_isLockFree: native = atomics_isLockFree; break;
     }
 
--- a/js/src/asmjs/WasmBinary.h
+++ b/js/src/asmjs/WasmBinary.h
@@ -270,17 +270,16 @@ enum class Expr
     F64Acos,
     F64Atan,
     F64Exp,
     F64Log,
     F64Pow,
     F64Atan2,
 
     // Atomics
-    AtomicsFence,
     I32AtomicsCompareExchange,
     I32AtomicsExchange,
     I32AtomicsLoad,
     I32AtomicsStore,
     I32AtomicsBinOp,
 
     // SIMD
 #define SIMD_OPCODE(TYPE, OP) TYPE##OP,
--- a/js/src/asmjs/WasmIonCompile.cpp
+++ b/js/src/asmjs/WasmIonCompile.cpp
@@ -572,24 +572,16 @@ class FunctionCompiler
             return;
 
         MOZ_ASSERT(Scalar::isSimdType(access.accessType()),
                    "storeSimdHeap can only load from a SIMD view");
         MAsmJSStoreHeap* store = MAsmJSStoreHeap::New(alloc(), base, access, v);
         curBlock_->add(store);
     }
 
-    void memoryBarrier(MemoryBarrierBits type)
-    {
-        if (inDeadCode())
-            return;
-        MMemoryBarrier* ins = MMemoryBarrier::New(alloc(), type);
-        curBlock_->add(ins);
-    }
-
     MDefinition* atomicLoadHeap(MDefinition* base, const MAsmJSHeapAccess& access)
     {
         if (inDeadCode())
             return nullptr;
 
         MAsmJSLoadHeap* load = MAsmJSLoadHeap::New(alloc(), base, access);
         curBlock_->add(load);
         return load;
@@ -3068,20 +3060,16 @@ EmitExpr(FunctionCompiler& f, MDefinitio
       case Expr::I32x4greaterThanOrEqualU:
         return EmitSimdOp(f, ValType::I32x4, SimdOperation::Fn_greaterThanOrEqual,
                           SimdSign::Unsigned, def);
       case Expr::I32x4fromFloat32x4U:
         return EmitSimdOp(f, ValType::I32x4, SimdOperation::Fn_fromFloat32x4,
                           SimdSign::Unsigned, def);
 
       // Atomics
-      case Expr::AtomicsFence:
-        *def = nullptr;
-        f.memoryBarrier(MembarFull);
-        return true;
       case Expr::I32AtomicsCompareExchange:
         return EmitAtomicsCompareExchange(f, def);
       case Expr::I32AtomicsExchange:
         return EmitAtomicsExchange(f, def);
       case Expr::I32AtomicsLoad:
         return EmitAtomicsLoad(f, def);
       case Expr::I32AtomicsStore:
         return EmitAtomicsStore(f, def);
--- a/js/src/builtin/AtomicsObject.cpp
+++ b/js/src/builtin/AtomicsObject.cpp
@@ -116,25 +116,16 @@ GetTypedArrayIndex(JSContext* cx, Handle
     if (!js::ToIntegerIndex(cx, v, &index))
         return false;
     if (index >= view->length())
         return ReportOutOfRange(cx);
     *offset = uint32_t(index);
     return true;
 }
 
-bool
-js::atomics_fence(JSContext* cx, unsigned argc, Value* vp)
-{
-    CallArgs args = CallArgsFromVp(argc, vp);
-    jit::AtomicOperations::fenceSeqCst();
-    args.rval().setUndefined();
-    return true;
-}
-
 static int32_t
 CompareExchange(Scalar::Type viewType, int32_t oldCandidate, int32_t newCandidate,
                 SharedMem<void*> viewData, uint32_t offset, bool* badArrayType = nullptr)
 {
     switch (viewType) {
       case Scalar::Int8: {
         int8_t oldval = (int8_t)oldCandidate;
         int8_t newval = (int8_t)newCandidate;
@@ -1107,17 +1098,16 @@ js::FutexRuntime::wake(WakeReason reason
     PR_NotifyCondVar(cond_);
 }
 
 const JSFunctionSpec AtomicsMethods[] = {
     JS_INLINABLE_FN("compareExchange",    atomics_compareExchange,    4,0, AtomicsCompareExchange),
     JS_INLINABLE_FN("load",               atomics_load,               2,0, AtomicsLoad),
     JS_INLINABLE_FN("store",              atomics_store,              3,0, AtomicsStore),
     JS_INLINABLE_FN("exchange",           atomics_exchange,           3,0, AtomicsExchange),
-    JS_INLINABLE_FN("fence",              atomics_fence,              0,0, AtomicsFence),
     JS_INLINABLE_FN("add",                atomics_add,                3,0, AtomicsAdd),
     JS_INLINABLE_FN("sub",                atomics_sub,                3,0, AtomicsSub),
     JS_INLINABLE_FN("and",                atomics_and,                3,0, AtomicsAnd),
     JS_INLINABLE_FN("or",                 atomics_or,                 3,0, AtomicsOr),
     JS_INLINABLE_FN("xor",                atomics_xor,                3,0, AtomicsXor),
     JS_INLINABLE_FN("isLockFree",         atomics_isLockFree,         1,0, AtomicsIsLockFree),
     JS_FN("futexWait",                    atomics_futexWait,          4,0),
     JS_FN("futexWake",                    atomics_futexWake,          3,0),
--- a/js/src/builtin/AtomicsObject.h
+++ b/js/src/builtin/AtomicsObject.h
@@ -28,17 +28,16 @@ class AtomicsObject : public JSObject
         FutexTimedout = -2
     };
 };
 
 bool atomics_compareExchange(JSContext* cx, unsigned argc, Value* vp);
 bool atomics_exchange(JSContext* cx, unsigned argc, Value* vp);
 bool atomics_load(JSContext* cx, unsigned argc, Value* vp);
 bool atomics_store(JSContext* cx, unsigned argc, Value* vp);
-bool atomics_fence(JSContext* cx, unsigned argc, Value* vp);
 bool atomics_add(JSContext* cx, unsigned argc, Value* vp);
 bool atomics_sub(JSContext* cx, unsigned argc, Value* vp);
 bool atomics_and(JSContext* cx, unsigned argc, Value* vp);
 bool atomics_or(JSContext* cx, unsigned argc, Value* vp);
 bool atomics_xor(JSContext* cx, unsigned argc, Value* vp);
 bool atomics_isLockFree(JSContext* cx, unsigned argc, Value* vp);
 bool atomics_futexWait(JSContext* cx, unsigned argc, Value* vp);
 bool atomics_futexWake(JSContext* cx, unsigned argc, Value* vp);
--- a/js/src/jit-test/tests/asm.js/testAtomics.js
+++ b/js/src/jit-test/tests/asm.js/testAtomics.js
@@ -6,33 +6,28 @@ if (!this.SharedArrayBuffer || !this.Ato
 // The code duplication below is very far from elegant but provides
 // flexibility that comes in handy several places.
 
 load(libdir + "asm.js");
 load(libdir + "asserts.js");
 
 var loadModule_int32_code =
     USE_ASM + `
-    var atomic_fence = stdlib.Atomics.fence;
     var atomic_load = stdlib.Atomics.load;
     var atomic_store = stdlib.Atomics.store;
     var atomic_cmpxchg = stdlib.Atomics.compareExchange;
     var atomic_exchange = stdlib.Atomics.exchange;
     var atomic_add = stdlib.Atomics.add;
     var atomic_sub = stdlib.Atomics.sub;
     var atomic_and = stdlib.Atomics.and;
     var atomic_or = stdlib.Atomics.or;
     var atomic_xor = stdlib.Atomics.xor;
 
     var i32a = new stdlib.Int32Array(heap);
 
-    function do_fence() {
-        atomic_fence();
-    }
-
     // Load element 0
     function do_load() {
         var v = 0;
         v = atomic_load(i32a, 0);
         return v|0;
     }
 
     // Load element i
@@ -199,18 +194,17 @@ var loadModule_int32_code =
     // CAS element i: -1 -> 0x5A5A5A5A
     function do_cas2_i(i) {
         i = i|0;
         var v = 0;
         v = atomic_cmpxchg(i32a, i>>2, -1, 0x5A5A5A5A);
         return v|0;
     }
 
-    return { fence: do_fence,
-        load: do_load,
+    return { load: do_load,
         load_i: do_load_i,
         store: do_store,
         store_i: do_store_i,
         xchg: do_xchg,
         xchg_i: do_xchg_i,
         xchg_intish: do_xchg_intish,
         add: do_add,
         add_i: do_add_i,
@@ -233,18 +227,16 @@ var loadModule_int32_code =
 var loadModule_int32 = asmCompile('stdlib', 'foreign', 'heap', loadModule_int32_code);
 
 function test_int32(heap) {
     var i32a = new Int32Array(heap);
     var i32m = asmLink(loadModule_int32, this, {}, heap);
 
     var size = Int32Array.BYTES_PER_ELEMENT;
 
-    i32m.fence();
-
     i32a[0] = 12345;
     assertEq(i32m.load(), 12345);
     assertEq(i32m.load_i(size*0), 12345);
 
     assertEq(i32m.store(), 37);
     assertEq(i32a[0], 37);
     assertEq(i32m.store_i(size*0), 37);
 
@@ -323,17 +315,16 @@ function test_int32(heap) {
     assertEq(i32m.store_i((i32a.length-1)*4), 37);
     assertEq(i32m.add_i((i32a.length-1)*4), 37);
     assertEq(i32m.load_i((i32a.length-1)*4), 37+37);
     i32a[i32a.length-1] = 0;
 }
 
 var loadModule_uint32_code =
     USE_ASM + `
-    var atomic_fence = stdlib.Atomics.fence;
     var atomic_load = stdlib.Atomics.load;
     var atomic_store = stdlib.Atomics.store;
     var atomic_cmpxchg = stdlib.Atomics.compareExchange;
     var atomic_exchange = stdlib.Atomics.exchange;
     var atomic_add = stdlib.Atomics.add;
     var atomic_sub = stdlib.Atomics.sub;
     var atomic_and = stdlib.Atomics.and;
     var atomic_or = stdlib.Atomics.or;
@@ -604,33 +595,28 @@ function test_uint32(heap) {
     assertEq(i32m.store_i((i32a.length-1)*4), 37);
     assertEq(i32m.add_i((i32a.length-1)*4), 37);
     assertEq(i32m.load_i((i32a.length-1)*4), 37+37);
     i32a[i32a.length-1] = 0;
 }
 
 var loadModule_int16_code =
     USE_ASM + `
-    var atomic_fence = stdlib.Atomics.fence;
     var atomic_load = stdlib.Atomics.load;
     var atomic_store = stdlib.Atomics.store;
     var atomic_cmpxchg = stdlib.Atomics.compareExchange;
     var atomic_exchange = stdlib.Atomics.exchange;
     var atomic_add = stdlib.Atomics.add;
     var atomic_sub = stdlib.Atomics.sub;
     var atomic_and = stdlib.Atomics.and;
     var atomic_or = stdlib.Atomics.or;
     var atomic_xor = stdlib.Atomics.xor;
 
     var i16a = new stdlib.Int16Array(heap);
 
-    function do_fence() {
-        atomic_fence();
-    }
-
     // Load element 0
     function do_load() {
         var v = 0;
         v = atomic_load(i16a, 0);
         return v|0;
     }
 
     // Load element i
@@ -771,18 +757,17 @@ var loadModule_int16_code =
     // CAS element i: -1 -> 0x5A5A
     function do_cas2_i(i) {
         i = i|0;
         var v = 0;
         v = atomic_cmpxchg(i16a, i>>1, -1, 0x5A5A);
         return v|0;
     }
 
-    return { fence: do_fence,
-        load: do_load,
+    return { load: do_load,
         load_i: do_load_i,
         store: do_store,
         store_i: do_store_i,
         xchg: do_xchg,
         xchg_i: do_xchg_i,
         add: do_add,
         add_i: do_add_i,
         sub: do_sub,
@@ -802,18 +787,16 @@ var loadModule_int16_code =
 var loadModule_int16 = asmCompile('stdlib', 'foreign', 'heap', loadModule_int16_code);
 
 function test_int16(heap) {
     var i16a = new Int16Array(heap);
     var i16m = loadModule_int16(this, {}, heap);
 
     var size = Int16Array.BYTES_PER_ELEMENT;
 
-    i16m.fence();
-
     i16a[0] = 12345;
     assertEq(i16m.load(), 12345);
     assertEq(i16m.load_i(size*0), 12345);
 
     i16a[0] = -38;
     assertEq(i16m.load(), -38);
     assertEq(i16m.load_i(size*0), -38);
 
--- a/js/src/jit-test/tests/atomics/basic-tests.js
+++ b/js/src/jit-test/tests/atomics/basic-tests.js
@@ -61,18 +61,16 @@ function testMethod(a, ...indices) {
 	// val = 9
 	assertEq(Atomics.store(a, x, 14), 14); // What about coercion?
 	// val = 14
 	assertEq(Atomics.load(a, x), 14);
 	// val = 14
 	Atomics.store(a, x, 0);
 	// val = 0
 
-	Atomics.fence();
-
 	// val = 0
 	assertEq(Atomics.add(a, x, 3), 0);
 	// val = 3
 	assertEq(Atomics.sub(a, x, 2), 3);
 	// val = 1
 	assertEq(Atomics.or(a, x, 6), 1);
 	// val = 7
 	assertEq(Atomics.and(a, x, 14), 7);
@@ -132,18 +130,16 @@ function testFunction(a, ...indices) {
 	// val = 9
 	assertEq(gAtomics_store(a, x, 14), 14); // What about coercion?
 	// val = 14
 	assertEq(gAtomics_load(a, x), 14);
 	// val = 14
 	gAtomics_store(a, x, 0);
 	// val = 0
 
-	gAtomics_fence();
-
 	// val = 0
 	assertEq(gAtomics_add(a, x, 3), 0);
 	// val = 3
 	assertEq(gAtomics_sub(a, x, 2), 3);
 	// val = 1
 	assertEq(gAtomics_or(a, x, 6), 1);
 	// val = 7
 	assertEq(gAtomics_and(a, x, 14), 7);
@@ -499,17 +495,16 @@ function runTests() {
     CLONE(testMethod)(new Int32Array(sab), 0, 42, 1023);
     CLONE(testMethod)(new Uint32Array(sab), 0, 42, 1023);
 
     // Test that invoking as v = Atomics.whatever; v() works, on correct arguments.
     gAtomics_compareExchange = Atomics.compareExchange;
     gAtomics_exchange = Atomics.exchange;
     gAtomics_load = Atomics.load;
     gAtomics_store = Atomics.store;
-    gAtomics_fence = Atomics.fence;
     gAtomics_add = Atomics.add;
     gAtomics_sub = Atomics.sub;
     gAtomics_and = Atomics.and;
     gAtomics_or = Atomics.or;
     gAtomics_xor = Atomics.xor;
 
     CLONE(testFunction)(new Int8Array(sab), 0, 42, 4095);
     CLONE(testFunction)(new Uint8Array(sab), 0, 42, 4095);
deleted file mode 100644
--- a/js/src/jit-test/tests/atomics/inline-fence.js
+++ /dev/null
@@ -1,31 +0,0 @@
-// |jit-test| slow;
-//
-// This is intended to be run manually with IONFLAGS=logs and
-// postprocessing by iongraph to verify manually (by inspecting the
-// MIR) that:
-//
-//  - the fence operation is inlined as it should be
-//  - loads and stores are not moved across the fence
-//
-// Be sure to run with --ion-eager --ion-offthread-compile=off.
-
-function fence(ta) {
-    var x = ta[0];
-    Atomics.fence();
-    var y = ta[1];
-    var z = y + 1;
-    var w = x + z;
-    return w;
-}
-
-if (!this.SharedArrayBuffer || !this.Atomics)
-    quit(0);
-
-var sab = new SharedArrayBuffer(4096);
-var ia = new Int32Array(sab);
-for ( var i=0, limit=ia.length ; i < limit ; i++ )
-    ia[i] = 37;
-var v = 0;
-for ( var i=0 ; i < 1000 ; i++ )
-    v += fence(ia);
-//print(v);
--- a/js/src/jit/InlinableNatives.h
+++ b/js/src/jit/InlinableNatives.h
@@ -17,17 +17,16 @@
     _(ArrayConcat)                  \
     _(ArraySlice)                   \
     _(ArraySplice)                  \
                                     \
     _(AtomicsCompareExchange)       \
     _(AtomicsExchange)              \
     _(AtomicsLoad)                  \
     _(AtomicsStore)                 \
-    _(AtomicsFence)                 \
     _(AtomicsAdd)                   \
     _(AtomicsSub)                   \
     _(AtomicsAnd)                   \
     _(AtomicsOr)                    \
     _(AtomicsXor)                   \
     _(AtomicsIsLockFree)            \
                                     \
     _(MathAbs)                      \
--- a/js/src/jit/IonBuilder.h
+++ b/js/src/jit/IonBuilder.h
@@ -827,17 +827,16 @@ class IonBuilder
     InliningStatus inlineObjectCreate(CallInfo& callInfo);
     InliningStatus inlineDefineDataProperty(CallInfo& callInfo);
 
     // Atomics natives.
     InliningStatus inlineAtomicsCompareExchange(CallInfo& callInfo);
     InliningStatus inlineAtomicsExchange(CallInfo& callInfo);
     InliningStatus inlineAtomicsLoad(CallInfo& callInfo);
     InliningStatus inlineAtomicsStore(CallInfo& callInfo);
-    InliningStatus inlineAtomicsFence(CallInfo& callInfo);
     InliningStatus inlineAtomicsBinop(CallInfo& callInfo, InlinableNative target);
     InliningStatus inlineAtomicsIsLockFree(CallInfo& callInfo);
 
     // Slot intrinsics.
     InliningStatus inlineUnsafeSetReservedSlot(CallInfo& callInfo);
     InliningStatus inlineUnsafeGetReservedSlot(CallInfo& callInfo,
                                                MIRType knownValueType);
 
--- a/js/src/jit/Lowering.cpp
+++ b/js/src/jit/Lowering.cpp
@@ -4200,23 +4200,16 @@ void
 LIRGenerator::visitRecompileCheck(MRecompileCheck* ins)
 {
     LRecompileCheck* lir = new(alloc()) LRecompileCheck(temp());
     add(lir, ins);
     assignSafepoint(lir, ins);
 }
 
 void
-LIRGenerator::visitMemoryBarrier(MMemoryBarrier* ins)
-{
-    LMemoryBarrier* lir = new(alloc()) LMemoryBarrier(ins->type());
-    add(lir, ins);
-}
-
-void
 LIRGenerator::visitSimdBox(MSimdBox* ins)
 {
     MOZ_ASSERT(IsSimdType(ins->input()->type()));
     LUse in = useRegister(ins->input());
     LSimdBox* lir = new(alloc()) LSimdBox(in, temp());
     define(lir, ins);
     assignSafepoint(lir, ins);
 }
--- a/js/src/jit/Lowering.h
+++ b/js/src/jit/Lowering.h
@@ -281,17 +281,16 @@ class LIRGenerator : public LIRGenerator
     void visitAsmJSReturn(MAsmJSReturn* ins);
     void visitAsmJSVoidReturn(MAsmJSVoidReturn* ins);
     void visitAsmJSPassStackArg(MAsmJSPassStackArg* ins);
     void visitAsmJSCall(MAsmJSCall* ins);
     void visitSetDOMProperty(MSetDOMProperty* ins);
     void visitGetDOMProperty(MGetDOMProperty* ins);
     void visitGetDOMMember(MGetDOMMember* ins);
     void visitRecompileCheck(MRecompileCheck* ins);
-    void visitMemoryBarrier(MMemoryBarrier* ins);
     void visitSimdBox(MSimdBox* ins);
     void visitSimdUnbox(MSimdUnbox* ins);
     void visitSimdExtractElement(MSimdExtractElement* ins);
     void visitSimdInsertElement(MSimdInsertElement* ins);
     void visitSimdSwizzle(MSimdSwizzle* ins);
     void visitSimdGeneralShuffle(MSimdGeneralShuffle* ins);
     void visitSimdShuffle(MSimdShuffle* ins);
     void visitSimdUnaryArith(MSimdUnaryArith* ins);
--- a/js/src/jit/MCallOptimize.cpp
+++ b/js/src/jit/MCallOptimize.cpp
@@ -88,18 +88,16 @@ IonBuilder::inlineNativeCall(CallInfo& c
       case InlinableNative::AtomicsCompareExchange:
         return inlineAtomicsCompareExchange(callInfo);
       case InlinableNative::AtomicsExchange:
         return inlineAtomicsExchange(callInfo);
       case InlinableNative::AtomicsLoad:
         return inlineAtomicsLoad(callInfo);
       case InlinableNative::AtomicsStore:
         return inlineAtomicsStore(callInfo);
-      case InlinableNative::AtomicsFence:
-        return inlineAtomicsFence(callInfo);
       case InlinableNative::AtomicsAdd:
       case InlinableNative::AtomicsSub:
       case InlinableNative::AtomicsAnd:
       case InlinableNative::AtomicsOr:
       case InlinableNative::AtomicsXor:
         return inlineAtomicsBinop(callInfo, inlNative);
       case InlinableNative::AtomicsIsLockFree:
         return inlineAtomicsIsLockFree(callInfo);
@@ -2911,40 +2909,16 @@ IonBuilder::inlineAtomicsStore(CallInfo&
 
     if (!resumeAfter(store))
         return InliningStatus_Error;
 
     return InliningStatus_Inlined;
 }
 
 IonBuilder::InliningStatus
-IonBuilder::inlineAtomicsFence(CallInfo& callInfo)
-{
-    if (callInfo.argc() != 0 || callInfo.constructing()) {
-        trackOptimizationOutcome(TrackedOutcome::CantInlineNativeBadForm);
-        return InliningStatus_NotInlined;
-    }
-
-    if (!JitSupportsAtomics())
-        return InliningStatus_NotInlined;
-
-    callInfo.setImplicitlyUsedUnchecked();
-
-    MMemoryBarrier* fence = MMemoryBarrier::New(alloc());
-    current->add(fence);
-    pushConstant(UndefinedValue());
-
-    // Fences are considered effectful (they execute a memory barrier).
-    if (!resumeAfter(fence))
-        return InliningStatus_Error;
-
-    return InliningStatus_Inlined;
-}
-
-IonBuilder::InliningStatus
 IonBuilder::inlineAtomicsBinop(CallInfo& callInfo, InlinableNative target)
 {
     if (callInfo.argc() != 3 || callInfo.constructing()) {
         trackOptimizationOutcome(TrackedOutcome::CantInlineNativeBadForm);
         return InliningStatus_NotInlined;
     }
 
     MDefinition* value = callInfo.getArg(2);
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -9990,25 +9990,39 @@ class MArrayJoin
     virtual AliasSet getAliasSet() const override {
         // Array.join might coerce the elements of the Array to strings.  This
         // coercion might cause the evaluation of the some JavaScript code.
         return AliasSet::Store(AliasSet::Any);
     }
     MDefinition* foldsTo(TempAllocator& alloc) override;
 };
 
-// See comments above MMemoryBarrier, below.
+// All barriered operations - MCompareExchangeTypedArrayElement,
+// MExchangeTypedArrayElement, and MAtomicTypedArrayElementBinop, as
+// well as MLoadUnboxedScalar and MStoreUnboxedScalar when they are
+// marked as requiring a memory barrer - have the following
+// attributes:
+//
+// - Not movable
+// - Not removable
+// - Not congruent with any other instruction
+// - Effectful (they alias every TypedArray store)
+//
+// The intended effect of those constraints is to prevent all loads
+// and stores preceding the barriered operation from being moved to
+// after the barriered operation, and vice versa, and to prevent the
+// barriered operation from being removed or hoisted.
 
 enum MemoryBarrierRequirement
 {
     DoesNotRequireMemoryBarrier,
     DoesRequireMemoryBarrier
 };
 
-// Also see comments above MMemoryBarrier, below.
+// Also see comments at MMemoryBarrierRequirement, above.
 
 // Load an unboxed scalar value from a typed array or other object.
 class MLoadUnboxedScalar
   : public MBinaryInstruction,
     public SingleObjectPolicy::Data
 {
     Scalar::Type storageType_;
     Scalar::Type readType_;
@@ -13643,59 +13657,16 @@ class MRecompileCheck : public MNullaryI
         return increaseWarmUpCounter_;
     }
 
     AliasSet getAliasSet() const override {
         return AliasSet::None();
     }
 };
 
-// All barriered operations - MMemoryBarrier, MCompareExchangeTypedArrayElement,
-// MExchangeTypedArrayElement, and MAtomicTypedArrayElementBinop, as well as
-// MLoadUnboxedScalar and MStoreUnboxedScalar when they are marked as requiring
-// a memory barrer - have the following attributes:
-//
-// - Not movable
-// - Not removable
-// - Not congruent with any other instruction
-// - Effectful (they alias every TypedArray store)
-//
-// The intended effect of those constraints is to prevent all loads
-// and stores preceding the barriered operation from being moved to
-// after the barriered operation, and vice versa, and to prevent the
-// barriered operation from being removed or hoisted.
-
-class MMemoryBarrier
-  : public MNullaryInstruction
-{
-    // The type is a combination of the memory barrier types in AtomicOp.h.
-    const MemoryBarrierBits type_;
-
-    explicit MMemoryBarrier(MemoryBarrierBits type)
-      : type_(type)
-    {
-        MOZ_ASSERT((type_ & ~MembarAllbits) == MembarNobits);
-        setGuard();             // Not removable
-    }
-
-  public:
-    INSTRUCTION_HEADER(MemoryBarrier)
-
-    static MMemoryBarrier* New(TempAllocator& alloc, MemoryBarrierBits type = MembarFull) {
-        return new(alloc) MMemoryBarrier(type);
-    }
-    MemoryBarrierBits type() const {
-        return type_;
-    }
-
-    AliasSet getAliasSet() const override {
-        return AliasSet::Store(AliasSet::UnboxedElement);
-    }
-};
-
 class MAtomicIsLockFree
   : public MUnaryInstruction,
     public ConvertToInt32Policy<0>::Data
 {
     explicit MAtomicIsLockFree(MDefinition* value)
       : MUnaryInstruction(value)
     {
         setResultType(MIRType_Boolean);
--- a/js/src/jit/MOpcodes.h
+++ b/js/src/jit/MOpcodes.h
@@ -275,17 +275,16 @@ namespace jit {
     _(AsmJSParameter)                                                       \
     _(AsmJSVoidReturn)                                                      \
     _(AsmJSPassStackArg)                                                    \
     _(AsmJSCall)                                                            \
     _(AsmSelect)                                                            \
     _(AsmReinterpret)                                                       \
     _(NewDerivedTypedObject)                                                \
     _(RecompileCheck)                                                       \
-    _(MemoryBarrier)                                                        \
     _(AsmJSCompareExchangeHeap)                                             \
     _(AsmJSAtomicExchangeHeap)                                              \
     _(AsmJSAtomicBinopHeap)                                                 \
     _(UnknownValue)                                                         \
     _(LexicalCheck)                                                         \
     _(ThrowRuntimeLexicalError)                                             \
     _(GlobalNameConflictsCheck)                                             \
     _(Debugger)                                                             \
--- a/js/src/jit/shared/LIR-shared.h
+++ b/js/src/jit/shared/LIR-shared.h
@@ -7958,20 +7958,16 @@ class LMemoryBarrier : public LInstructi
     explicit LMemoryBarrier(MemoryBarrierBits type) : type_(type)
     {
         MOZ_ASSERT((type_ & ~MembarAllbits) == MembarNobits);
     }
 
     MemoryBarrierBits type() const {
         return type_;
     }
-
-    const MMemoryBarrier* mir() const {
-        return mir_->toMemoryBarrier();
-    }
 };
 
 class LDebugger : public LCallInstructionHelper<0, 0, 2>
 {
   public:
     LIR_HEADER(Debugger)
 
     LDebugger(const LDefinition& temp1, const LDefinition& temp2) {