Bug 1225028 - remove Atomics.fence. r=bbouvier
authorLars T Hansen <lhansen@mozilla.com>
Sat, 02 Apr 2016 08:55:24 -0700
changeset 291510 859f435f2ca001acc659cf47a2068fc94287e84a
parent 291509 88688664f228ff07d20d623c701a49dac9226f12
child 291511 63bdfecc99f488142d1601f381f6241fd22ddb92
push id19656
push usergwagner@mozilla.com
push dateMon, 04 Apr 2016 13:43:23 +0000
treeherderb2g-inbound@e99061fde28a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbbouvier
bugs1225028
milestone48.0a1
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) {