Backed out 3 changesets (bug 977126) for mochitest-2 bustage on Windows
authorWes Kocher <wkocher@mozilla.com>
Thu, 03 Apr 2014 13:52:36 -0700
changeset 176979 90f74b01a4a59ba4b091fb1741958e08b4627198
parent 176978 0eec23f41606f270aae7e1fbcb7f7de7a639d6b7
child 176980 6519732bc27d94b76e013117331bbe3d1390caf8
push id41883
push userkwierso@gmail.com
push dateThu, 03 Apr 2014 20:53:15 +0000
treeherdermozilla-inbound@6519732bc27d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs977126
milestone31.0a1
backs out2daa537b62e6ec4a213061d0a8edbf4c1796cf9f
d87a13b71afc89264e66a87f09a8904ec4886df6
3bd335914852b71acefb2396c2c80600d437b4ea
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
Backed out 3 changesets (bug 977126) for mochitest-2 bustage on Windows Backed out changeset 2daa537b62e6 (bug 977126) Backed out changeset d87a13b71afc (bug 977126) Backed out changeset 3bd335914852 (bug 977126)
js/src/assembler/assembler/X86Assembler.h
js/src/builtin/TypedObject.cpp
js/src/builtin/TypedObject.h
js/src/jit/CodeGenerator.cpp
js/src/jit/CodeGenerator.h
js/src/jit/IonBuilder.h
js/src/jit/LIR-Common.h
js/src/jit/LOpcodes.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/ParallelSafetyAnalysis.cpp
js/src/jit/arm/MacroAssembler-arm.cpp
js/src/jit/arm/MacroAssembler-arm.h
js/src/jit/shared/Assembler-x86-shared.h
js/src/jit/x64/Assembler-x64.h
js/src/jit/x64/MacroAssembler-x64.h
js/src/jit/x86/MacroAssembler-x86.h
js/src/vm/SelfHosting.cpp
--- a/js/src/assembler/assembler/X86Assembler.h
+++ b/js/src/assembler/assembler/X86Assembler.h
@@ -937,23 +937,16 @@ public:
 #if WTF_CPU_X86_64
     void subq_rr(RegisterID src, RegisterID dst)
     {
         spew("subq       %s, %s",
              nameIReg(8,src), nameIReg(8,dst));
         m_formatter.oneByteOp64(OP_SUB_EvGv, src, dst);
     }
 
-    void subq_rm(RegisterID src, int offset, RegisterID base)
-    {
-        spew("subq       %s, %s0x%x(%s)",
-             nameIReg(8,src), PRETTY_PRINT_OFFSET(offset), nameIReg(8,base));
-        m_formatter.oneByteOp64(OP_SUB_EvGv, src, base, offset);
-    }
-
     void subq_mr(int offset, RegisterID base, RegisterID dst)
     {
         spew("subq       %s0x%x(%s), %s",
              PRETTY_PRINT_OFFSET(offset), nameIReg(8,base), nameIReg(8,dst));
         m_formatter.oneByteOp64(OP_SUB_GvEv, dst, base, offset);
     }
 
     void subq_mr(const void* addr, RegisterID dst)
--- a/js/src/builtin/TypedObject.cpp
+++ b/js/src/builtin/TypedObject.cpp
@@ -2210,34 +2210,28 @@ TypedObject::obj_enumerate(JSContext *cx
         }
         break;
     }
 
     return true;
 }
 
 /* static */ size_t
-TypedObject::offsetOfOwnerSlot()
+TypedObject::ownerOffset()
 {
     return JSObject::getFixedSlotOffset(JS_TYPEDOBJ_SLOT_OWNER);
 }
 
 /* static */ size_t
-TypedObject::offsetOfDataSlot()
+TypedObject::dataOffset()
 {
     // the offset of 7 is based on the alloc kind
     return JSObject::getPrivateDataOffset(JS_TYPEDOBJ_SLOT_DATA);
 }
 
-/* static */ size_t
-TypedObject::offsetOfByteOffsetSlot()
-{
-    return JSObject::getFixedSlotOffset(JS_TYPEDOBJ_SLOT_BYTEOFFSET);
-}
-
 void
 TypedObject::neuter(void *newData)
 {
     setSlot(JS_TYPEDOBJ_SLOT_LENGTH, Int32Value(0));
     setSlot(JS_TYPEDOBJ_SLOT_BYTELENGTH, Int32Value(0));
     setSlot(JS_TYPEDOBJ_SLOT_BYTEOFFSET, Int32Value(0));
     setPrivate(newData);
 }
@@ -2713,31 +2707,22 @@ js::SetTypedObjectOffset(ThreadSafeConte
     TypedObject &typedObj = args[0].toObject().as<TypedObject>();
     int32_t offset = args[1].toInt32();
 
     JS_ASSERT(!typedObj.owner().isNeutered());
     JS_ASSERT(typedObj.typedMem() != nullptr); // must be attached already
 
     typedObj.setPrivate(typedObj.owner().dataPointer() + offset);
     typedObj.setReservedSlot(JS_TYPEDOBJ_SLOT_BYTEOFFSET, Int32Value(offset));
-    args.rval().setUndefined();
     return true;
 }
 
-bool
-js::intrinsic_SetTypedObjectOffset(JSContext *cx, unsigned argc, Value *vp)
-{
-    // Do not use JSNativeThreadSafeWrapper<> so that ion can reference
-    // this function more easily when inlining.
-    return SetTypedObjectOffset(cx, argc, vp);
-}
-
-JS_JITINFO_NATIVE_PARALLEL_THREADSAFE(js::intrinsic_SetTypedObjectOffsetJitInfo,
+JS_JITINFO_NATIVE_PARALLEL_THREADSAFE(js::SetTypedObjectOffsetJitInfo,
                                       SetTypedObjectJitInfo,
-                                      SetTypedObjectOffset);
+                                      js::SetTypedObjectOffset);
 
 bool
 js::ObjectIsTypeDescr(ThreadSafeContext *, unsigned argc, Value *vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     JS_ASSERT(args.length() == 1);
     JS_ASSERT(args[0].isObject());
     args.rval().setBoolean(args[0].toObject().is<TypeDescr>());
--- a/js/src/builtin/TypedObject.h
+++ b/js/src/builtin/TypedObject.h
@@ -580,28 +580,25 @@ class TypedObject : public ArrayBufferVi
                                    bool *succeeded);
     static bool obj_deleteElement(JSContext *cx, HandleObject obj, uint32_t index,
                                   bool *succeeded);
 
     static bool obj_enumerate(JSContext *cx, HandleObject obj, JSIterateOp enum_op,
                               MutableHandleValue statep, MutableHandleId idp);
 
   public:
-    static size_t offsetOfOwnerSlot();
+    static size_t ownerOffset();
 
     // Each typed object contains a void* pointer pointing at the
     // binary data that it represents. (That data may be owned by this
     // object or this object may alias data owned by someone else.)
     // This function returns the offset in bytes within the object
     // where the `void*` pointer can be found. It is intended for use
     // by the JIT.
-    static size_t offsetOfDataSlot();
-
-    // Offset of the byte offset slot.
-    static size_t offsetOfByteOffsetSlot();
+    static size_t dataOffset();
 
     // Helper for createUnattached()
     static TypedObject *createUnattachedWithClass(JSContext *cx,
                                                  const Class *clasp,
                                                  HandleTypeDescr type,
                                                  int32_t length);
 
     // Creates an unattached typed object or handle (depending on the
@@ -740,19 +737,18 @@ bool AttachTypedObject(ThreadSafeContext
 extern const JSJitInfo AttachTypedObjectJitInfo;
 
 /*
  * Usage: SetTypedObjectOffset(typedObj, offset)
  *
  * Changes the offset for `typedObj` within its buffer to `offset`.
  * `typedObj` must already be attached.
  */
-bool intrinsic_SetTypedObjectOffset(JSContext *cx, unsigned argc, Value *vp);
-bool SetTypedObjectOffset(ThreadSafeContext *, unsigned argc, Value *vp);
-extern const JSJitInfo intrinsic_SetTypedObjectOffsetJitInfo;
+bool SetTypedObjectOffset(ThreadSafeContext *cx, unsigned argc, Value *vp);
+extern const JSJitInfo SetTypedObjectOffsetJitInfo;
 
 /*
  * Usage: ObjectIsTypeDescr(obj)
  *
  * True if `obj` is a type object.
  */
 bool ObjectIsTypeDescr(ThreadSafeContext *cx, unsigned argc, Value *vp);
 extern const JSJitInfo ObjectIsTypeDescrJitInfo;
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -4107,80 +4107,31 @@ CodeGenerator::visitTypedArrayElements(L
 }
 
 bool
 CodeGenerator::visitNeuterCheck(LNeuterCheck *lir)
 {
     Register obj = ToRegister(lir->object());
     Register temp = ToRegister(lir->temp());
 
-    masm.extractObject(Address(obj, TypedObject::offsetOfOwnerSlot()), temp);
+    masm.extractObject(Address(obj, TypedObject::ownerOffset()), temp);
     masm.unboxInt32(Address(temp, ArrayBufferObject::flagsOffset()), temp);
     masm.and32(Imm32(ArrayBufferObject::neuteredFlag()), temp);
 
     if (!bailoutIf(Assembler::NonZero, lir->snapshot()))
         return false;
     return true;
 }
 
 bool
 CodeGenerator::visitTypedObjectElements(LTypedObjectElements *lir)
 {
     Register obj = ToRegister(lir->object());
     Register out = ToRegister(lir->output());
-    masm.loadPtr(Address(obj, TypedObject::offsetOfDataSlot()), out);
-    return true;
-}
-
-bool
-CodeGenerator::visitSetTypedObjectOffset(LSetTypedObjectOffset *lir)
-{
-    Register object = ToRegister(lir->object());
-    Register offset = ToRegister(lir->offset());
-    Register temp0 = ToRegister(lir->temp0());
-
-    // `offset` is an absolute offset into the base buffer. One way
-    // to implement this instruction would be load the base address
-    // from the buffer and add `offset`. But that'd be an extra load.
-    // We can instead load the current base pointer and current
-    // offset, compute the difference with `offset`, and then adjust
-    // the current base pointer. This is two loads but to adjacent
-    // fields in the same object, which should come in the same cache
-    // line.
-    //
-    // The C code I would probably write is the following:
-    //
-    // void SetTypedObjectOffset(TypedObject *obj, int32_t offset) {
-    //     int32_t temp0 = obj->byteOffset;
-    //     obj->pointer = obj->pointer - temp0 + offset;
-    //     obj->byteOffset = offset;
-    // }
-    //
-    // But what we actually compute is more like this, because it
-    // saves us a temporary to do it this way:
-    //
-    // void SetTypedObjectOffset(TypedObject *obj, int32_t offset) {
-    //     int32_t temp0 = obj->byteOffset;
-    //     obj->pointer = obj->pointer - (temp0 - offset);
-    //     obj->byteOffset = offset;
-    // }
-
-    // temp0 = typedObj->byteOffset;
-    masm.unboxInt32(Address(object, TypedObject::offsetOfByteOffsetSlot()), temp0);
-
-    // temp0 -= offset;
-    masm.subPtr(offset, temp0);
-
-    // obj->pointer -= temp0;
-    masm.subPtr(temp0, Address(object, TypedObject::offsetOfDataSlot()));
-
-    // obj->byteOffset = offset;
-    masm.storeValue(JSVAL_TYPE_INT32, offset,
-                    Address(object, TypedObject::offsetOfByteOffsetSlot()));
-
+    masm.loadPtr(Address(obj, TypedObject::dataOffset()), out);
     return true;
 }
 
 bool
 CodeGenerator::visitStringLength(LStringLength *lir)
 {
     Register input = ToRegister(lir->string());
     Register output = ToRegister(lir->output());
--- a/js/src/jit/CodeGenerator.h
+++ b/js/src/jit/CodeGenerator.h
@@ -162,17 +162,16 @@ class CodeGenerator : public CodeGenerat
     bool visitComputeThis(LComputeThis *lir);
     bool visitLoadArrowThis(LLoadArrowThis *lir);
     bool visitArrayLength(LArrayLength *lir);
     bool visitSetArrayLength(LSetArrayLength *lir);
     bool visitTypedArrayLength(LTypedArrayLength *lir);
     bool visitTypedArrayElements(LTypedArrayElements *lir);
     bool visitNeuterCheck(LNeuterCheck *lir);
     bool visitTypedObjectElements(LTypedObjectElements *lir);
-    bool visitSetTypedObjectOffset(LSetTypedObjectOffset *lir);
     bool visitStringLength(LStringLength *lir);
     bool visitInitializedLength(LInitializedLength *lir);
     bool visitSetInitializedLength(LSetInitializedLength *lir);
     bool visitNotO(LNotO *ins);
     bool visitNotV(LNotV *ins);
     bool visitBoundsCheck(LBoundsCheck *lir);
     bool visitBoundsCheckRange(LBoundsCheckRange *lir);
     bool visitBoundsCheckLower(LBoundsCheckLower *lir);
--- a/js/src/jit/IonBuilder.h
+++ b/js/src/jit/IonBuilder.h
@@ -691,17 +691,16 @@ class IonBuilder : public MIRGenerator
     InliningStatus inlineUnsafeSetReservedSlot(CallInfo &callInfo);
     InliningStatus inlineUnsafeGetReservedSlot(CallInfo &callInfo);
 
     // ForkJoin intrinsics
     InliningStatus inlineForkJoinGetSlice(CallInfo &callInfo);
 
     // TypedObject intrinsics.
     InliningStatus inlineObjectIsTypeDescr(CallInfo &callInfo);
-    InliningStatus inlineSetTypedObjectOffset(CallInfo &callInfo);
     bool elementAccessIsTypedObjectArrayOfScalarType(MDefinition* obj, MDefinition* id,
                                                      ScalarTypeDescr::Type *arrayType);
 
     // Utility intrinsics.
     InliningStatus inlineIsCallable(CallInfo &callInfo);
     InliningStatus inlineHaveSameClass(CallInfo &callInfo);
     InliningStatus inlineToObject(CallInfo &callInfo);
     InliningStatus inlineDump(CallInfo &callInfo);
--- a/js/src/jit/LIR-Common.h
+++ b/js/src/jit/LIR-Common.h
@@ -3720,41 +3720,16 @@ class LTypedObjectElements : public LIns
     const LAllocation *object() {
         return getOperand(0);
     }
     const MTypedObjectElements *mir() const {
         return mir_->toTypedObjectElements();
     }
 };
 
-// Load a typed array's elements vector.
-class LSetTypedObjectOffset : public LInstructionHelper<0, 2, 1>
-{
-  public:
-    LIR_HEADER(SetTypedObjectOffset)
-
-    LSetTypedObjectOffset(const LAllocation &object,
-                          const LAllocation &offset,
-                          const LDefinition &temp0)
-    {
-        setOperand(0, object);
-        setOperand(1, offset);
-        setTemp(0, temp0);
-    }
-    const LAllocation *object() {
-        return getOperand(0);
-    }
-    const LAllocation *offset() {
-        return getOperand(1);
-    }
-    const LDefinition *temp0() {
-        return getTemp(0);
-    }
-};
-
 // Check whether a typed object has a neutered owner buffer.
 class LNeuterCheck : public LInstructionHelper<0, 1, 1>
 {
   public:
     LIR_HEADER(NeuterCheck)
 
     LNeuterCheck(const LAllocation &object, const LDefinition &temp) {
         setOperand(0, object);
--- a/js/src/jit/LOpcodes.h
+++ b/js/src/jit/LOpcodes.h
@@ -244,17 +244,16 @@
     _(IteratorNext)                 \
     _(IteratorMore)                 \
     _(IteratorEnd)                  \
     _(ArrayLength)                  \
     _(SetArrayLength)               \
     _(TypedArrayLength)             \
     _(TypedArrayElements)           \
     _(TypedObjectElements)          \
-    _(SetTypedObjectOffset)         \
     _(StringLength)                 \
     _(ArgumentsLength)              \
     _(GetFrameArgument)             \
     _(SetFrameArgumentT)            \
     _(SetFrameArgumentC)            \
     _(SetFrameArgumentV)            \
     _(RunOncePrologue)              \
     _(Rest)                         \
--- a/js/src/jit/Lowering.cpp
+++ b/js/src/jit/Lowering.cpp
@@ -2374,26 +2374,16 @@ LIRGenerator::visitTypedArrayElements(MT
 bool
 LIRGenerator::visitTypedObjectElements(MTypedObjectElements *ins)
 {
     JS_ASSERT(ins->type() == MIRType_Elements);
     return define(new(alloc()) LTypedObjectElements(useRegisterAtStart(ins->object())), ins);
 }
 
 bool
-LIRGenerator::visitSetTypedObjectOffset(MSetTypedObjectOffset *ins)
-{
-    return add(new(alloc()) LSetTypedObjectOffset(
-                   useRegister(ins->object()),
-                   useRegister(ins->offset()),
-                   temp()),
-               ins);
-}
-
-bool
 LIRGenerator::visitInitializedLength(MInitializedLength *ins)
 {
     JS_ASSERT(ins->elements()->type() == MIRType_Elements);
     return define(new(alloc()) LInitializedLength(useRegisterAtStart(ins->elements())), ins);
 }
 
 bool
 LIRGenerator::visitSetInitializedLength(MSetInitializedLength *ins)
--- a/js/src/jit/Lowering.h
+++ b/js/src/jit/Lowering.h
@@ -173,17 +173,16 @@ class LIRGenerator : public LIRGenerator
     bool visitMonitorTypes(MMonitorTypes *ins);
     bool visitPostWriteBarrier(MPostWriteBarrier *ins);
     bool visitArrayLength(MArrayLength *ins);
     bool visitSetArrayLength(MSetArrayLength *ins);
     bool visitTypedArrayLength(MTypedArrayLength *ins);
     bool visitTypedArrayElements(MTypedArrayElements *ins);
     bool visitNeuterCheck(MNeuterCheck *lir);
     bool visitTypedObjectElements(MTypedObjectElements *ins);
-    bool visitSetTypedObjectOffset(MSetTypedObjectOffset *ins);
     bool visitInitializedLength(MInitializedLength *ins);
     bool visitSetInitializedLength(MSetInitializedLength *ins);
     bool visitNot(MNot *ins);
     bool visitBoundsCheck(MBoundsCheck *ins);
     bool visitBoundsCheckLower(MBoundsCheckLower *ins);
     bool visitLoadElement(MLoadElement *ins);
     bool visitLoadElementHole(MLoadElementHole *ins);
     bool visitStoreElement(MStoreElement *ins);
--- a/js/src/jit/MCallOptimize.cpp
+++ b/js/src/jit/MCallOptimize.cpp
@@ -2,17 +2,16 @@
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "jsmath.h"
 
 #include "builtin/TestingFunctions.h"
-#include "builtin/TypedObject.h"
 #include "jit/BaselineInspector.h"
 #include "jit/IonBuilder.h"
 #include "jit/Lowering.h"
 #include "jit/MIR.h"
 #include "jit/MIRGraph.h"
 
 #include "jsscriptinlines.h"
 
@@ -173,18 +172,16 @@ IonBuilder::inlineNativeCall(CallInfo &c
                                 &ScalarTypeDescr::class_, &ReferenceTypeDescr::class_);
     if (native == intrinsic_TypeDescrIsArrayType)
         return inlineHasClasses(callInfo,
                                 &SizedArrayTypeDescr::class_, &UnsizedArrayTypeDescr::class_);
     if (native == intrinsic_TypeDescrIsSizedArrayType)
         return inlineHasClass(callInfo, &SizedArrayTypeDescr::class_);
     if (native == intrinsic_TypeDescrIsUnsizedArrayType)
         return inlineHasClass(callInfo, &UnsizedArrayTypeDescr::class_);
-    if (native == intrinsic_SetTypedObjectOffset)
-        return inlineSetTypedObjectOffset(callInfo);
 
     // Testing Functions
     if (native == testingFunc_inParallelSection)
         return inlineForceSequentialOrInParallelSection(callInfo);
     if (native == testingFunc_bailout)
         return inlineBailout(callInfo);
     if (native == testingFunc_assertFloat32)
         return inlineAssertFloat32(callInfo);
@@ -1648,58 +1645,16 @@ IonBuilder::inlineObjectIsTypeDescr(Call
 
     pushConstant(BooleanValue(result));
 
     callInfo.setImplicitlyUsedUnchecked();
     return InliningStatus_Inlined;
 }
 
 IonBuilder::InliningStatus
-IonBuilder::inlineSetTypedObjectOffset(CallInfo &callInfo)
-{
-    if (callInfo.argc() != 2 || callInfo.constructing())
-        return InliningStatus_NotInlined;
-
-    MDefinition *typedObj = callInfo.getArg(0);
-    MDefinition *offset = callInfo.getArg(1);
-
-    // Return type should be undefined or something wacky is going on.
-    if (getInlineReturnType() != MIRType_Undefined)
-        return InliningStatus_NotInlined;
-
-    // Check typedObj is a, well, typed object. Go ahead and use TI
-    // data. If this check should fail, that is almost certainly a bug
-    // in self-hosted code -- either because it's not being careful
-    // with TI or because of something else -- but we'll just let it
-    // fall through to the SetTypedObjectOffset intrinsic in such
-    // cases.
-    types::TemporaryTypeSet *types = typedObj->resultTypeSet();
-    if (typedObj->type() != MIRType_Object || !types)
-        return InliningStatus_NotInlined;
-    switch (types->forAllClasses(IsTypedObjectClass)) {
-      case types::TemporaryTypeSet::ForAllResult::ALL_FALSE:
-      case types::TemporaryTypeSet::ForAllResult::EMPTY:
-      case types::TemporaryTypeSet::ForAllResult::MIXED:
-        return InliningStatus_NotInlined;
-      case types::TemporaryTypeSet::ForAllResult::ALL_TRUE:
-        break;
-    }
-
-    // Check type of offset argument is an integer.
-    if (offset->type() != MIRType_Int32)
-        return InliningStatus_NotInlined;
-
-    callInfo.setImplicitlyUsedUnchecked();
-    MInstruction *ins = MSetTypedObjectOffset::New(alloc(), typedObj, offset);
-    current->add(ins);
-    current->push(ins);
-    return InliningStatus_Inlined;
-}
-
-IonBuilder::InliningStatus
 IonBuilder::inlineUnsafeSetReservedSlot(CallInfo &callInfo)
 {
     if (callInfo.argc() != 3 || callInfo.constructing())
         return InliningStatus_NotInlined;
     if (getInlineReturnType() != MIRType_Undefined)
         return InliningStatus_NotInlined;
     if (callInfo.getArg(0)->type() != MIRType_Object)
         return InliningStatus_NotInlined;
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -1556,17 +1556,17 @@ class MNewDerivedTypedObject
 };
 
 // Abort parallel execution.
 class MAbortPar : public MAryControlInstruction<0, 0>
 {
     MAbortPar()
       : MAryControlInstruction<0, 0>()
     {
-        setResultType(MIRType_None);
+        setResultType(MIRType_Undefined);
         setGuard();
     }
 
   public:
     INSTRUCTION_HEADER(AbortPar);
 
     static MAbortPar *New(TempAllocator &alloc) {
         return new(alloc) MAbortPar();
@@ -5588,54 +5588,16 @@ class MTypedObjectElements
     bool congruentTo(MDefinition *ins) const {
         return congruentIfOperandsEqual(ins);
     }
     AliasSet getAliasSet() const {
         return AliasSet::Load(AliasSet::ObjectFields);
     }
 };
 
-// Inlined version of the js::SetTypedObjectOffset() intrinsic.
-class MSetTypedObjectOffset
-  : public MBinaryInstruction
-{
-  private:
-    MSetTypedObjectOffset(MDefinition *object, MDefinition *offset)
-      : MBinaryInstruction(object, offset)
-    {
-        JS_ASSERT(object->type() == MIRType_Object);
-        JS_ASSERT(offset->type() == MIRType_Int32);
-        setResultType(MIRType_None);
-    }
-
-  public:
-    INSTRUCTION_HEADER(SetTypedObjectOffset)
-
-    static MSetTypedObjectOffset *New(TempAllocator &alloc,
-                                      MDefinition *object,
-                                      MDefinition *offset)
-    {
-        return new(alloc) MSetTypedObjectOffset(object, offset);
-    }
-
-    MDefinition *object() const {
-        return getOperand(0);
-    }
-
-    MDefinition *offset() const {
-        return getOperand(1);
-    }
-
-    AliasSet getAliasSet() const {
-        // This affects the result of MTypedObjectElements,
-        // which is described as a load of ObjectFields.
-        return AliasSet::Store(AliasSet::ObjectFields);
-    }
-};
-
 // Perform !-operation
 class MNot
   : public MUnaryInstruction,
     public TestPolicy
 {
     bool operandMightEmulateUndefined_;
     bool operandIsNeverNaN_;
 
--- a/js/src/jit/MOpcodes.h
+++ b/js/src/jit/MOpcodes.h
@@ -130,17 +130,16 @@ namespace jit {
     _(GuardObjectType)                                                      \
     _(GuardObjectIdentity)                                                  \
     _(GuardClass)                                                           \
     _(ArrayLength)                                                          \
     _(SetArrayLength)                                                       \
     _(TypedArrayLength)                                                     \
     _(TypedArrayElements)                                                   \
     _(TypedObjectElements)                                                  \
-    _(SetTypedObjectOffset)                                                 \
     _(InitializedLength)                                                    \
     _(SetInitializedLength)                                                 \
     _(Not)                                                                  \
     _(NeuterCheck)                                                          \
     _(BoundsCheck)                                                          \
     _(BoundsCheckLower)                                                     \
     _(InArray)                                                              \
     _(LoadElement)                                                          \
--- a/js/src/jit/ParallelSafetyAnalysis.cpp
+++ b/js/src/jit/ParallelSafetyAnalysis.cpp
@@ -218,17 +218,16 @@ class ParallelSafetyVisitor : public MIn
     SAFE_OP(GuardObjectIdentity)
     SAFE_OP(GuardClass)
     SAFE_OP(AssertRange)
     SAFE_OP(ArrayLength)
     WRITE_GUARDED_OP(SetArrayLength, elements)
     SAFE_OP(TypedArrayLength)
     SAFE_OP(TypedArrayElements)
     SAFE_OP(TypedObjectElements)
-    SAFE_OP(SetTypedObjectOffset)
     SAFE_OP(InitializedLength)
     WRITE_GUARDED_OP(SetInitializedLength, elements)
     SAFE_OP(Not)
     SAFE_OP(NeuterCheck)
     SAFE_OP(BoundsCheck)
     SAFE_OP(BoundsCheckLower)
     SAFE_OP(LoadElement)
     SAFE_OP(LoadElementHole)
--- a/js/src/jit/arm/MacroAssembler-arm.cpp
+++ b/js/src/jit/arm/MacroAssembler-arm.cpp
@@ -2436,24 +2436,16 @@ MacroAssemblerARMCompat::subPtr(const Ad
 
 void
 MacroAssemblerARMCompat::subPtr(const Register &src, const Register &dest)
 {
     ma_sub(src, dest);
 }
 
 void
-MacroAssemblerARMCompat::subPtr(const Register &src, const Address &dest)
-{
-    loadPtr(dest, ScratchRegister);
-    ma_sub(src, ScratchRegister);
-    storePtr(ScratchRegister, dest);
-}
-
-void
 MacroAssemblerARMCompat::addPtr(Imm32 imm, const Register dest)
 {
     ma_add(imm, dest);
 }
 
 void
 MacroAssemblerARMCompat::addPtr(Imm32 imm, const Address &dest)
 {
--- a/js/src/jit/arm/MacroAssembler-arm.h
+++ b/js/src/jit/arm/MacroAssembler-arm.h
@@ -1352,17 +1352,16 @@ class MacroAssemblerARMCompat : public M
     void cmpPtr(const Register &lhs, const ImmGCPtr &rhs);
     void cmpPtr(const Address &lhs, const Register &rhs);
     void cmpPtr(const Address &lhs, const ImmWord &rhs);
     void cmpPtr(const Address &lhs, const ImmPtr &rhs);
 
     void subPtr(Imm32 imm, const Register dest);
     void subPtr(const Address &addr, const Register dest);
     void subPtr(const Register &src, const Register &dest);
-    void subPtr(const Register &src, const Address &dest);
     void addPtr(Imm32 imm, const Register dest);
     void addPtr(Imm32 imm, const Address &dest);
     void addPtr(ImmWord imm, const Register dest) {
         addPtr(Imm32(imm.value), dest);
     }
     void addPtr(ImmPtr imm, const Register dest) {
         addPtr(ImmWord(uintptr_t(imm.value)), dest);
     }
--- a/js/src/jit/shared/Assembler-x86-shared.h
+++ b/js/src/jit/shared/Assembler-x86-shared.h
@@ -943,28 +943,16 @@ class AssemblerX86Shared
             break;
           case Operand::MEM_REG_DISP:
             masm.subl_mr(src.disp(), src.base(), dest.code());
             break;
           default:
             MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
-    void subl(const 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_ASSUME_UNREACHABLE("unexpected operand kind");
-        }
-    }
     void orl(const Register &reg, const Register &dest) {
         masm.orl_rr(reg.code(), dest.code());
     }
     void orl(Imm32 imm, const Register &reg) {
         masm.orl_ir(imm.value, reg.code());
     }
     void orl(Imm32 imm, const Operand &op) {
         switch (op.kind()) {
--- a/js/src/jit/x64/Assembler-x64.h
+++ b/js/src/jit/x64/Assembler-x64.h
@@ -444,28 +444,16 @@ class Assembler : public AssemblerX86Sha
             break;
           case Operand::MEM_ADDRESS32:
             masm.subq_mr(src.address(), dest.code());
             break;
           default:
             MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
         }
     }
-    void subq(const 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_ASSUME_UNREACHABLE("unexpected operand kind");
-        }
-    }
     void shlq(Imm32 imm, const Register &dest) {
         masm.shlq_i8r(imm.value, dest.code());
     }
     void shrq(Imm32 imm, const Register &dest) {
         masm.shrq_i8r(imm.value, dest.code());
     }
     void sarq(Imm32 imm, const Register &dest) {
         masm.sarq_i8r(imm.value, dest.code());
--- a/js/src/jit/x64/MacroAssembler-x64.h
+++ b/js/src/jit/x64/MacroAssembler-x64.h
@@ -549,19 +549,16 @@ class MacroAssemblerX64 : public MacroAs
         subq(imm, dest);
     }
     void subPtr(const Register &src, const Register &dest) {
         subq(src, dest);
     }
     void subPtr(const Address &addr, const Register &dest) {
         subq(Operand(addr), dest);
     }
-    void subPtr(const Register &src, const Address &dest) {
-        subq(src, Operand(dest));
-    }
 
     void branch32(Condition cond, const AbsoluteAddress &lhs, Imm32 rhs, Label *label) {
         if (JSC::X86Assembler::isAddressImmediate(lhs.addr)) {
             branch32(cond, Operand(lhs), rhs, label);
         } else {
             mov(ImmPtr(lhs.addr), ScratchReg);
             branch32(cond, Address(ScratchReg, 0), rhs, label);
         }
--- a/js/src/jit/x86/MacroAssembler-x86.h
+++ b/js/src/jit/x86/MacroAssembler-x86.h
@@ -556,19 +556,16 @@ class MacroAssemblerX86 : public MacroAs
         subl(imm, dest);
     }
     void subPtr(const Register &src, const Register &dest) {
         subl(src, dest);
     }
     void subPtr(const Address &addr, const Register &dest) {
         subl(Operand(addr), dest);
     }
-    void subPtr(const Register &src, const Address &dest) {
-        subl(src, Operand(dest));
-    }
 
     void branch32(Condition cond, const AbsoluteAddress &lhs, Imm32 rhs, Label *label) {
         cmpl(Operand(lhs), rhs);
         j(cond, label);
     }
     void branch32(Condition cond, const AbsoluteAddress &lhs, Register rhs, Label *label) {
         cmpl(Operand(lhs), rhs);
         j(cond, label);
--- a/js/src/vm/SelfHosting.cpp
+++ b/js/src/vm/SelfHosting.cpp
@@ -743,18 +743,18 @@ static const JSFunctionSpec intrinsic_fu
           1, 0),
     JS_FN("NewDerivedTypedObject",
           js::NewDerivedTypedObject,
           3, 0),
     JS_FNINFO("AttachTypedObject",
               JSNativeThreadSafeWrapper<js::AttachTypedObject>,
               &js::AttachTypedObjectJitInfo, 3, 0),
     JS_FNINFO("SetTypedObjectOffset",
-              intrinsic_SetTypedObjectOffset,
-              &js::intrinsic_SetTypedObjectOffsetJitInfo, 2, 0),
+              JSNativeThreadSafeWrapper<js::SetTypedObjectOffset>,
+              &js::SetTypedObjectOffsetJitInfo, 2, 0),
     JS_FNINFO("ObjectIsTypeDescr",
               intrinsic_ObjectIsTypeDescr,
               &js::ObjectIsTypeDescrJitInfo, 1, 0),
     JS_FNINFO("ObjectIsTypedObject",
               intrinsic_ObjectIsTypedObject,
               &js::ObjectIsTypedObjectJitInfo, 1, 0),
     JS_FNINFO("ObjectIsTransparentTypedObject",
               intrinsic_ObjectIsTransparentTypedObject,