Bug 1214508: SharedStubs - Part 1: Move the getprop stubs in to shared stub files, r=jandem
authorHannes Verschore <hv1989@gmail.com>
Tue, 17 Nov 2015 17:57:48 +0100
changeset 273015 db0f569d52a336e9d6898c2c357303d8b34c938f
parent 273014 fe34d01fb2ecb2dd4cda82e788cf7b541d5cbdb4
child 273016 fcd698a31dbe805a151ade75c5aace875b161e75
push id29693
push usercbook@mozilla.com
push dateWed, 18 Nov 2015 13:50:33 +0000
treeherdermozilla-central@1d6155d7e6c9 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs1214508
milestone45.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 1214508: SharedStubs - Part 1: Move the getprop stubs in to shared stub files, r=jandem
js/src/jit/BaselineIC.cpp
js/src/jit/BaselineIC.h
js/src/jit/BaselineICList.h
js/src/jit/SharedIC.cpp
js/src/jit/SharedIC.h
js/src/jit/SharedICList.h
--- a/js/src/jit/BaselineIC.cpp
+++ b/js/src/jit/BaselineIC.cpp
@@ -41,54 +41,16 @@
 #include "vm/StringObject-inl.h"
 #include "vm/UnboxedObject-inl.h"
 
 using mozilla::DebugOnly;
 
 namespace js {
 namespace jit {
 
-static void
-GuardReceiverObject(MacroAssembler& masm, ReceiverGuard guard,
-                    Register object, Register scratch,
-                    size_t receiverGuardOffset, Label* failure)
-{
-    Address groupAddress(ICStubReg, receiverGuardOffset + HeapReceiverGuard::offsetOfGroup());
-    Address shapeAddress(ICStubReg, receiverGuardOffset + HeapReceiverGuard::offsetOfShape());
-    Address expandoAddress(object, UnboxedPlainObject::offsetOfExpando());
-
-    if (guard.group) {
-        masm.loadPtr(groupAddress, scratch);
-        masm.branchTestObjGroup(Assembler::NotEqual, object, scratch, failure);
-
-        if (guard.group->clasp() == &UnboxedPlainObject::class_ && !guard.shape) {
-            // Guard the unboxed object has no expando object.
-            masm.branchPtr(Assembler::NotEqual, expandoAddress, ImmWord(0), failure);
-        }
-    }
-
-    if (guard.shape) {
-        masm.loadPtr(shapeAddress, scratch);
-        if (guard.group && guard.group->clasp() == &UnboxedPlainObject::class_) {
-            // Guard the unboxed object has a matching expando object.
-            masm.branchPtr(Assembler::Equal, expandoAddress, ImmWord(0), failure);
-            Label done;
-            masm.push(object);
-            masm.loadPtr(expandoAddress, object);
-            masm.branchTestObjShape(Assembler::Equal, object, scratch, &done);
-            masm.pop(object);
-            masm.jump(failure);
-            masm.bind(&done);
-            masm.pop(object);
-        } else {
-            masm.branchTestObjShape(Assembler::NotEqual, object, scratch, failure);
-        }
-    }
-}
-
 //
 // WarmUpCounter_Fallback
 //
 
 static bool
 EnsureCanEnterIon(JSContext* cx, ICWarmUpCounter_Fallback* stub, BaselineFrame* frame,
                   HandleScript script, jsbytecode* pc, void** jitcodePtr)
 {
@@ -904,38 +866,16 @@ ICTypeUpdate_ObjectGroup::Compiler::gene
     masm.mov(ImmWord(1), R1.scratchReg());
     EmitReturnFromIC(masm);
 
     masm.bind(&failure);
     EmitStubGuardFailure(masm);
     return true;
 }
 
-//
-// VM function to help call native getters.
-//
-
-static bool
-DoCallNativeGetter(JSContext* cx, HandleFunction callee, HandleObject obj,
-                   MutableHandleValue result)
-{
-    MOZ_ASSERT(callee->isNative());
-    JSNative natfun = callee->native();
-
-    JS::AutoValueArray<2> vp(cx);
-    vp[0].setObject(*callee.get());
-    vp[1].setObject(*obj.get());
-
-    if (!natfun(cx, 0, vp.begin()))
-        return false;
-
-    result.set(vp[0]);
-    return true;
-}
-
 typedef bool (*DoCallNativeGetterFn)(JSContext*, HandleFunction, HandleObject, MutableHandleValue);
 static const VMFunction DoCallNativeGetterInfo =
     FunctionInfo<DoCallNativeGetterFn>(DoCallNativeGetter);
 
 //
 // This_Fallback
 //
 
@@ -1398,284 +1338,16 @@ ICToNumber_Fallback::Compiler::generateS
 
     return tailCallVM(DoToNumberFallbackInfo, masm);
 }
 
 //
 // GetElem_Fallback
 //
 
-static void GetFixedOrDynamicSlotOffset(Shape* shape, bool* isFixed, uint32_t* offset)
-{
-    MOZ_ASSERT(isFixed);
-    MOZ_ASSERT(offset);
-    *isFixed = shape->slot() < shape->numFixedSlots();
-    *offset = *isFixed ? NativeObject::getFixedSlotOffset(shape->slot())
-                       : (shape->slot() - shape->numFixedSlots()) * sizeof(Value);
-}
-
-static JSObject*
-GetDOMProxyProto(JSObject* obj)
-{
-    MOZ_ASSERT(IsCacheableDOMProxy(obj));
-    return obj->getTaggedProto().toObjectOrNull();
-}
-
-// Callers are expected to have already guarded on the shape of the
-// object, which guarantees the object is a DOM proxy.
-static void
-CheckDOMProxyExpandoDoesNotShadow(JSContext* cx, MacroAssembler& masm, Register object,
-                                  const Address& checkExpandoShapeAddr,
-                                  Address* expandoAndGenerationAddr,
-                                  Address* generationAddr,
-                                  Register scratch,
-                                  AllocatableGeneralRegisterSet& domProxyRegSet,
-                                  Label* checkFailed)
-{
-    // Guard that the object does not have expando properties, or has an expando
-    // which is known to not have the desired property.
-
-    // For the remaining code, we need to reserve some registers to load a value.
-    // This is ugly, but unavoidable.
-    ValueOperand tempVal = domProxyRegSet.takeAnyValue();
-    masm.pushValue(tempVal);
-
-    Label failDOMProxyCheck;
-    Label domProxyOk;
-
-    masm.loadPtr(Address(object, ProxyObject::offsetOfValues()), scratch);
-    Address expandoAddr(scratch, ProxyObject::offsetOfExtraSlotInValues(GetDOMProxyExpandoSlot()));
-
-    if (expandoAndGenerationAddr) {
-        MOZ_ASSERT(generationAddr);
-
-        masm.loadPtr(*expandoAndGenerationAddr, tempVal.scratchReg());
-        masm.branchPrivatePtr(Assembler::NotEqual, expandoAddr, tempVal.scratchReg(),
-                              &failDOMProxyCheck);
-
-        masm.load32(*generationAddr, scratch);
-        masm.branch32(Assembler::NotEqual,
-                      Address(tempVal.scratchReg(), offsetof(ExpandoAndGeneration, generation)),
-                      scratch, &failDOMProxyCheck);
-
-        masm.loadValue(Address(tempVal.scratchReg(), 0), tempVal);
-    } else {
-        masm.loadValue(expandoAddr, tempVal);
-    }
-
-    // If the incoming object does not have an expando object then we're sure we're not
-    // shadowing.
-    masm.branchTestUndefined(Assembler::Equal, tempVal, &domProxyOk);
-
-    // The reference object used to generate this check may not have had an
-    // expando object at all, in which case the presence of a non-undefined
-    // expando value in the incoming object is automatically a failure.
-    masm.loadPtr(checkExpandoShapeAddr, scratch);
-    masm.branchPtr(Assembler::Equal, scratch, ImmPtr(nullptr), &failDOMProxyCheck);
-
-    // Otherwise, ensure that the incoming object has an object for its expando value and that
-    // the shape matches.
-    masm.branchTestObject(Assembler::NotEqual, tempVal, &failDOMProxyCheck);
-    Register objReg = masm.extractObject(tempVal, tempVal.scratchReg());
-    masm.branchTestObjShape(Assembler::Equal, objReg, scratch, &domProxyOk);
-
-    // Failure case: restore the tempVal registers and jump to failures.
-    masm.bind(&failDOMProxyCheck);
-    masm.popValue(tempVal);
-    masm.jump(checkFailed);
-
-    // Success case: restore the tempval and proceed.
-    masm.bind(&domProxyOk);
-    masm.popValue(tempVal);
-}
-
-// Look up a property's shape on an object, being careful never to do any effectful
-// operations.  This procedure not yielding a shape should not be taken as a lack of
-// existence of the property on the object.
-static bool
-EffectlesslyLookupProperty(JSContext* cx, HandleObject obj, HandleId id,
-                           MutableHandleObject holder, MutableHandleShape shape,
-                           bool* checkDOMProxy=nullptr,
-                           DOMProxyShadowsResult* shadowsResult=nullptr,
-                           bool* domProxyHasGeneration=nullptr)
-{
-    shape.set(nullptr);
-    holder.set(nullptr);
-
-    if (checkDOMProxy) {
-        *checkDOMProxy = false;
-        *shadowsResult = ShadowCheckFailed;
-    }
-
-    // Check for list base if asked to.
-    RootedObject checkObj(cx, obj);
-    if (checkDOMProxy && IsCacheableDOMProxy(obj)) {
-        MOZ_ASSERT(domProxyHasGeneration);
-        MOZ_ASSERT(shadowsResult);
-
-        *checkDOMProxy = true;
-        if (obj->hasUncacheableProto())
-            return true;
-
-        *shadowsResult = GetDOMProxyShadowsCheck()(cx, obj, id);
-        if (*shadowsResult == ShadowCheckFailed)
-            return false;
-
-        if (DOMProxyIsShadowing(*shadowsResult)) {
-            holder.set(obj);
-            return true;
-        }
-
-        *domProxyHasGeneration = (*shadowsResult == DoesntShadowUnique);
-
-        checkObj = GetDOMProxyProto(obj);
-        if (!checkObj)
-            return true;
-    }
-
-    if (LookupPropertyPure(cx, checkObj, id, holder.address(), shape.address()))
-        return true;
-
-    holder.set(nullptr);
-    shape.set(nullptr);
-    return true;
-}
-
-static bool
-CheckHasNoSuchProperty(JSContext* cx, HandleObject obj, HandlePropertyName name,
-                       MutableHandleObject lastProto, size_t* protoChainDepthOut)
-{
-    MOZ_ASSERT(protoChainDepthOut != nullptr);
-
-    size_t depth = 0;
-    RootedObject curObj(cx, obj);
-    while (curObj) {
-        if (curObj->isNative()) {
-            // Don't handle proto chains with resolve hooks.
-            if (ClassMayResolveId(cx->names(), curObj->getClass(), NameToId(name), curObj))
-                return false;
-            if (curObj->as<NativeObject>().contains(cx, NameToId(name)))
-                return false;
-        } else if (curObj != obj) {
-            // Non-native objects are only handled as the original receiver.
-            return false;
-        } else if (curObj->is<UnboxedPlainObject>()) {
-            if (curObj->as<UnboxedPlainObject>().containsUnboxedOrExpandoProperty(cx, NameToId(name)))
-                return false;
-        } else if (curObj->is<UnboxedArrayObject>()) {
-            if (name == cx->names().length)
-                return false;
-        } else if (curObj->is<TypedObject>()) {
-            if (curObj->as<TypedObject>().typeDescr().hasProperty(cx->names(), NameToId(name)))
-                return false;
-        } else {
-            return false;
-        }
-
-        JSObject* proto = curObj->getTaggedProto().toObjectOrNull();
-        if (!proto)
-            break;
-
-        curObj = proto;
-        depth++;
-    }
-
-    lastProto.set(curObj);
-    *protoChainDepthOut = depth;
-    return true;
-}
-
-static bool
-IsCacheableProtoChain(JSObject* obj, JSObject* holder, bool isDOMProxy=false)
-{
-    MOZ_ASSERT_IF(isDOMProxy, IsCacheableDOMProxy(obj));
-
-    if (!isDOMProxy && !obj->isNative()) {
-        if (obj == holder)
-            return false;
-        if (!obj->is<UnboxedPlainObject>() &&
-            !obj->is<UnboxedArrayObject>() &&
-            !obj->is<TypedObject>())
-        {
-            return false;
-        }
-    }
-
-    // Don't handle objects which require a prototype guard. This should
-    // be uncommon so handling it is likely not worth the complexity.
-    if (obj->hasUncacheableProto())
-        return false;
-
-    JSObject* cur = obj;
-    while (cur != holder) {
-        // We cannot assume that we find the holder object on the prototype
-        // chain and must check for null proto. The prototype chain can be
-        // altered during the lookupProperty call.
-        JSObject* proto;
-        if (isDOMProxy && cur == obj)
-            proto = cur->getTaggedProto().toObjectOrNull();
-        else
-            proto = cur->getProto();
-
-        if (!proto || !proto->isNative())
-            return false;
-
-        if (proto->hasUncacheableProto())
-            return false;
-
-        cur = proto;
-    }
-    return true;
-}
-
-static bool
-IsCacheableGetPropReadSlot(JSObject* obj, JSObject* holder, Shape* shape, bool isDOMProxy=false)
-{
-    if (!shape || !IsCacheableProtoChain(obj, holder, isDOMProxy))
-        return false;
-
-    if (!shape->hasSlot() || !shape->hasDefaultGetter())
-        return false;
-
-    return true;
-}
-
-static bool
-IsCacheableGetPropCall(JSContext* cx, JSObject* obj, JSObject* holder, Shape* shape,
-                       bool* isScripted, bool* isTemporarilyUnoptimizable, bool isDOMProxy=false)
-{
-    MOZ_ASSERT(isScripted);
-
-    if (!shape || !IsCacheableProtoChain(obj, holder, isDOMProxy))
-        return false;
-
-    if (shape->hasSlot() || shape->hasDefaultGetter())
-        return false;
-
-    if (!shape->hasGetterValue())
-        return false;
-
-    if (!shape->getterValue().isObject() || !shape->getterObject()->is<JSFunction>())
-        return false;
-
-    JSFunction* func = &shape->getterObject()->as<JSFunction>();
-    if (func->isNative()) {
-        *isScripted = false;
-        return true;
-    }
-
-    if (!func->hasJITCode()) {
-        *isTemporarilyUnoptimizable = true;
-        return false;
-    }
-
-    *isScripted = true;
-    return true;
-}
-
 static Shape*
 LastPropertyForSetProp(JSObject* obj)
 {
     if (obj->isNative())
         return obj->as<NativeObject>().lastProperty();
 
     if (obj->is<UnboxedPlainObject>()) {
         UnboxedExpandoObject* expando = obj->as<UnboxedPlainObject>().maybeExpando();
@@ -3080,44 +2752,16 @@ LoadTypedThingLength(MacroAssembler& mas
         masm.loadPtr(Address(result, ObjectGroup::offsetOfAddendum()), result);
         masm.unboxInt32(Address(result, ArrayTypeDescr::offsetOfLength()), result);
         break;
       default:
         MOZ_CRASH();
     }
 }
 
-static void
-LoadTypedThingData(MacroAssembler& masm, TypedThingLayout layout, Register obj, Register result)
-{
-    switch (layout) {
-      case Layout_TypedArray:
-        masm.loadPtr(Address(obj, TypedArrayLayout::dataOffset()), result);
-        break;
-      case Layout_OutlineTypedObject:
-        masm.loadPtr(Address(obj, OutlineTypedObject::offsetOfData()), result);
-        break;
-      case Layout_InlineTypedObject:
-        masm.computeEffectiveAddress(Address(obj, InlineTypedObject::offsetOfDataStart()), result);
-        break;
-      default:
-        MOZ_CRASH();
-    }
-}
-
-static void
-CheckForNeuteredTypedObject(JSContext* cx, MacroAssembler& masm, Label* failure)
-{
-    // All stubs which manipulate typed objects need to check the compartment
-    // wide flag indicating whether the objects are neutered, and bail out in
-    // this case.
-    int32_t* address = &cx->compartment()->neuteredTypedObjects;
-    masm.branch32(Assembler::NotEqual, AbsoluteAddress(address), Imm32(0), failure);
-}
-
 bool
 ICGetElem_TypedArray::Compiler::generateStubCode(MacroAssembler& masm)
 {
     MOZ_ASSERT(engine_ == Engine::Baseline);
 
     Label failure;
 
     if (layout_ != Layout_TypedArray)
@@ -3853,29 +3497,16 @@ ICSetElem_DenseOrUnboxedArray::Compiler:
     }
 
     // Failure case - jump to next stub
     masm.bind(&failure);
     EmitStubGuardFailure(masm);
     return true;
 }
 
-static bool
-GetProtoShapes(JSObject* obj, size_t protoChainDepth, MutableHandle<ShapeVector> shapes)
-{
-    JSObject* curProto = obj->getProto();
-    for (size_t i = 0; i < protoChainDepth; i++) {
-        if (!shapes.append(curProto->as<NativeObject>().lastProperty()))
-            return false;
-        curProto = curProto->getProto();
-    }
-    MOZ_ASSERT(!curProto);
-    return true;
-}
-
 //
 // SetElem_DenseOrUnboxedArrayAdd
 //
 
 ICUpdatedStub*
 ICSetElemDenseOrUnboxedArrayAddCompiler::getStub(ICStubSpace* space)
 {
     Rooted<ShapeVector> shapes(cx, ShapeVector(cx));
@@ -4595,80 +4226,16 @@ ICIn_Dense::Compiler::generateStubCode(M
     EmitReturnFromIC(masm);
 
     // Failure case - jump to next stub
     masm.bind(&failure);
     EmitStubGuardFailure(masm);
     return true;
 }
 
-// Try to update all existing GetProp/GetName getter call stubs that match the
-// given holder in place with a new shape and getter.  fallbackStub can be
-// either an ICGetProp_Fallback or an ICGetName_Fallback.
-//
-// If 'getter' is an own property, holder == receiver must be true.
-static bool
-UpdateExistingGetPropCallStubs(ICFallbackStub* fallbackStub,
-                               ICStub::Kind kind,
-                               HandleNativeObject holder,
-                               HandleObject receiver,
-                               HandleFunction getter)
-{
-    MOZ_ASSERT(kind == ICStub::GetProp_CallScripted ||
-               kind == ICStub::GetProp_CallNative ||
-               kind == ICStub::GetProp_CallNativeGlobal);
-    MOZ_ASSERT(fallbackStub->isGetName_Fallback() ||
-               fallbackStub->isGetProp_Fallback());
-    MOZ_ASSERT(holder);
-    MOZ_ASSERT(receiver);
-
-    bool isOwnGetter = (holder == receiver);
-    bool foundMatchingStub = false;
-    ReceiverGuard receiverGuard(receiver);
-    for (ICStubConstIterator iter = fallbackStub->beginChainConst(); !iter.atEnd(); iter++) {
-        if (iter->kind() == kind) {
-            ICGetPropCallGetter* getPropStub = static_cast<ICGetPropCallGetter*>(*iter);
-            if (getPropStub->holder() == holder && getPropStub->isOwnGetter() == isOwnGetter) {
-                // If this is an own getter, update the receiver guard as well,
-                // since that's the shape we'll be guarding on. Furthermore,
-                // isOwnGetter() relies on holderShape_ and receiverGuard_ being
-                // the same shape.
-                if (isOwnGetter)
-                    getPropStub->receiverGuard().update(receiverGuard);
-
-                MOZ_ASSERT(getPropStub->holderShape() != holder->lastProperty() ||
-                           !getPropStub->receiverGuard().matches(receiverGuard) ||
-                           getPropStub->toGetProp_CallNativeGlobal()->globalShape() !=
-                           receiver->as<ClonedBlockObject>().global().lastProperty(),
-                           "Why didn't we end up using this stub?");
-
-                // We want to update the holder shape to match the new one no
-                // matter what, even if the receiver shape is different.
-                getPropStub->holderShape() = holder->lastProperty();
-
-                // Make sure to update the getter, since a shape change might
-                // have changed which getter we want to use.
-                getPropStub->getter() = getter;
-
-                if (getPropStub->isGetProp_CallNativeGlobal()) {
-                    ICGetProp_CallNativeGlobal* globalStub =
-                        getPropStub->toGetProp_CallNativeGlobal();
-                    globalStub->globalShape() =
-                        receiver->as<ClonedBlockObject>().global().lastProperty();
-                }
-
-                if (getPropStub->receiverGuard().matches(receiverGuard))
-                    foundMatchingStub = true;
-            }
-        }
-    }
-
-    return foundMatchingStub;
-}
-
 // Try to update existing SetProp setter call stubs for the given holder in
 // place with a new shape and setter.
 static bool
 UpdateExistingSetPropCallStubs(ICSetProp_Fallback* fallbackStub,
                                ICStub::Kind kind,
                                NativeObject* holder,
                                JSObject* receiver,
                                JSFunction* setter)
@@ -5235,1805 +4802,16 @@ ICGetIntrinsic_Constant::Compiler::gener
 
     masm.loadValue(Address(ICStubReg, ICGetIntrinsic_Constant::offsetOfValue()), R0);
 
     EmitReturnFromIC(masm);
     return true;
 }
 
 //
-// GetProp_Fallback
-//
-
-static bool
-TryAttachMagicArgumentsGetPropStub(JSContext* cx, JSScript* script, ICGetProp_Fallback* stub,
-                                   HandlePropertyName name, HandleValue val, HandleValue res,
-                                   bool* attached)
-{
-    MOZ_ASSERT(!*attached);
-
-    if (!val.isMagic(JS_OPTIMIZED_ARGUMENTS))
-        return true;
-
-    // Try handling arguments.callee on optimized arguments.
-    if (name == cx->names().callee) {
-        MOZ_ASSERT(script->hasMappedArgsObj());
-
-        JitSpew(JitSpew_BaselineIC, "  Generating GetProp(MagicArgs.callee) stub");
-
-        // Unlike ICGetProp_ArgumentsLength, only magic argument stubs are
-        // supported at the moment.
-        ICStub* monitorStub = stub->fallbackMonitorStub()->firstMonitorStub();
-        ICGetProp_ArgumentsCallee::Compiler compiler(cx, monitorStub);
-        ICStub* newStub = compiler.getStub(compiler.getStubSpace(script));
-        if (!newStub)
-            return false;
-        stub->addNewStub(newStub);
-
-        *attached = true;
-        return true;
-    }
-
-    return true;
-}
-
-static bool
-TryAttachLengthStub(JSContext* cx, JSScript* script, ICGetProp_Fallback* stub, HandleValue val,
-                    HandleValue res, bool* attached)
-{
-    MOZ_ASSERT(!*attached);
-
-    if (val.isString()) {
-        MOZ_ASSERT(res.isInt32());
-        JitSpew(JitSpew_BaselineIC, "  Generating GetProp(String.length) stub");
-        ICGetProp_StringLength::Compiler compiler(cx);
-        ICStub* newStub = compiler.getStub(compiler.getStubSpace(script));
-        if (!newStub)
-            return false;
-
-        *attached = true;
-        stub->addNewStub(newStub);
-        return true;
-    }
-
-    if (val.isMagic(JS_OPTIMIZED_ARGUMENTS) && res.isInt32()) {
-        JitSpew(JitSpew_BaselineIC, "  Generating GetProp(MagicArgs.length) stub");
-        ICGetProp_ArgumentsLength::Compiler compiler(cx, ICGetProp_ArgumentsLength::Magic);
-        ICStub* newStub = compiler.getStub(compiler.getStubSpace(script));
-        if (!newStub)
-            return false;
-
-        *attached = true;
-        stub->addNewStub(newStub);
-        return true;
-    }
-
-    if (!val.isObject())
-        return true;
-
-    RootedObject obj(cx, &val.toObject());
-
-    if (obj->is<ArrayObject>() && res.isInt32()) {
-        JitSpew(JitSpew_BaselineIC, "  Generating GetProp(Array.length) stub");
-        ICGetProp_ArrayLength::Compiler compiler(cx);
-        ICStub* newStub = compiler.getStub(compiler.getStubSpace(script));
-        if (!newStub)
-            return false;
-
-        *attached = true;
-        stub->addNewStub(newStub);
-        return true;
-    }
-
-    if (obj->is<UnboxedArrayObject>() && res.isInt32()) {
-        JitSpew(JitSpew_BaselineIC, "  Generating GetProp(UnboxedArray.length) stub");
-        ICGetProp_UnboxedArrayLength::Compiler compiler(cx);
-        ICStub* newStub = compiler.getStub(compiler.getStubSpace(script));
-        if (!newStub)
-            return false;
-
-        *attached = true;
-        stub->addNewStub(newStub);
-        return true;
-    }
-
-    if (obj->is<ArgumentsObject>() && res.isInt32()) {
-        JitSpew(JitSpew_BaselineIC, "  Generating GetProp(ArgsObj.length %s) stub",
-                obj->is<MappedArgumentsObject>() ? "Mapped" : "Unmapped");
-        ICGetProp_ArgumentsLength::Which which = ICGetProp_ArgumentsLength::Mapped;
-        if (obj->is<UnmappedArgumentsObject>())
-            which = ICGetProp_ArgumentsLength::Unmapped;
-        ICGetProp_ArgumentsLength::Compiler compiler(cx, which);
-        ICStub* newStub = compiler.getStub(compiler.getStubSpace(script));
-        if (!newStub)
-            return false;
-
-        *attached = true;
-        stub->addNewStub(newStub);
-        return true;
-    }
-
-    return true;
-}
-
-static bool
-UpdateExistingGenerationalDOMProxyStub(ICGetProp_Fallback* stub,
-                                       HandleObject obj)
-{
-    Value expandoSlot = GetProxyExtra(obj, GetDOMProxyExpandoSlot());
-    MOZ_ASSERT(!expandoSlot.isObject() && !expandoSlot.isUndefined());
-    ExpandoAndGeneration* expandoAndGeneration = (ExpandoAndGeneration*)expandoSlot.toPrivate();
-    for (ICStubConstIterator iter = stub->beginChainConst(); !iter.atEnd(); iter++) {
-        if (iter->isGetProp_CallDOMProxyWithGenerationNative()) {
-            ICGetProp_CallDOMProxyWithGenerationNative* updateStub =
-                iter->toGetProp_CallDOMProxyWithGenerationNative();
-            if (updateStub->expandoAndGeneration() == expandoAndGeneration) {
-                // Update generation
-                uint32_t generation = expandoAndGeneration->generation;
-                JitSpew(JitSpew_BaselineIC,
-                        "  Updating existing stub with generation, old value: %i, "
-                        "new value: %i", updateStub->generation(),
-                        generation);
-                updateStub->setGeneration(generation);
-                return true;
-            }
-        }
-    }
-    return false;
-}
-
-// Return whether obj is in some PreliminaryObjectArray and has a structure
-// that might change in the future.
-static bool
-IsPreliminaryObject(JSObject* obj)
-{
-    if (obj->isSingleton())
-        return false;
-
-    TypeNewScript* newScript = obj->group()->newScript();
-    if (newScript && !newScript->analyzed())
-        return true;
-
-    if (obj->group()->maybePreliminaryObjects())
-        return true;
-
-    return false;
-}
-
-static void
-StripPreliminaryObjectStubs(JSContext* cx, ICFallbackStub* stub)
-{
-    // Before the new script properties analysis has been performed on a type,
-    // all instances of that type have the maximum number of fixed slots.
-    // Afterwards, the objects (even the preliminary ones) might be changed
-    // to reduce the number of fixed slots they have. If we generate stubs for
-    // both the old and new number of fixed slots, the stub will look
-    // polymorphic to IonBuilder when it is actually monomorphic. To avoid
-    // this, strip out any stubs for preliminary objects before attaching a new
-    // stub which isn't on a preliminary object.
-
-    for (ICStubIterator iter = stub->beginChain(); !iter.atEnd(); iter++) {
-        if (iter->isGetProp_Native() && iter->toGetProp_Native()->hasPreliminaryObject())
-            iter.unlink(cx);
-        else if (iter->isSetProp_Native() && iter->toSetProp_Native()->hasPreliminaryObject())
-            iter.unlink(cx);
-    }
-}
-
-static bool
-TryAttachNativeGetValuePropStub(JSContext* cx, HandleScript script, jsbytecode* pc,
-                                ICGetProp_Fallback* stub, HandlePropertyName name,
-                                HandleValue val, HandleShape oldShape,
-                                HandleValue res, bool* attached)
-{
-    MOZ_ASSERT(!*attached);
-
-    if (!val.isObject())
-        return true;
-
-    RootedObject obj(cx, &val.toObject());
-
-    if (obj->isNative() && oldShape != obj->as<NativeObject>().lastProperty()) {
-        // No point attaching anything, since we know the shape guard will fail
-        return true;
-    }
-
-    RootedShape shape(cx);
-    RootedObject holder(cx);
-    RootedId id(cx, NameToId(name));
-    if (!EffectlesslyLookupProperty(cx, obj, id, &holder, &shape))
-        return false;
-
-    ICStub* monitorStub = stub->fallbackMonitorStub()->firstMonitorStub();
-    if (IsCacheableGetPropReadSlot(obj, holder, shape)) {
-        bool isFixedSlot;
-        uint32_t offset;
-        GetFixedOrDynamicSlotOffset(shape, &isFixedSlot, &offset);
-
-        // Instantiate this property for singleton holders, for use during Ion compilation.
-        if (IsIonEnabled(cx))
-            EnsureTrackPropertyTypes(cx, holder, NameToId(name));
-
-        ICStub::Kind kind =
-            (obj == holder) ? ICStub::GetProp_Native : ICStub::GetProp_NativePrototype;
-
-        JitSpew(JitSpew_BaselineIC, "  Generating GetProp(Native %s) stub",
-                    (obj == holder) ? "direct" : "prototype");
-        ICGetPropNativeCompiler compiler(cx, kind, monitorStub, obj, holder,
-                                         name, isFixedSlot, offset);
-        ICGetPropNativeStub* newStub = compiler.getStub(compiler.getStubSpace(script));
-        if (!newStub)
-            return false;
-
-        if (IsPreliminaryObject(obj))
-            newStub->notePreliminaryObject();
-        else
-            StripPreliminaryObjectStubs(cx, stub);
-
-        stub->addNewStub(newStub);
-        *attached = true;
-        return true;
-    }
-    return true;
-}
-
-
-static bool
-TryAttachNativeGetAccessorPropStub(JSContext* cx, HandleScript script, jsbytecode* pc,
-                                   ICGetProp_Fallback* stub, HandlePropertyName name,
-                                   HandleValue val, HandleValue res, bool* attached,
-                                   bool* isTemporarilyUnoptimizable)
-{
-    MOZ_ASSERT(!*attached);
-    MOZ_ASSERT(!*isTemporarilyUnoptimizable);
-
-    if (!val.isObject())
-        return true;
-
-    RootedObject obj(cx, &val.toObject());
-
-    bool isDOMProxy;
-    bool domProxyHasGeneration;
-    DOMProxyShadowsResult domProxyShadowsResult;
-    RootedShape shape(cx);
-    RootedObject holder(cx);
-    RootedId id(cx, NameToId(name));
-    if (!EffectlesslyLookupProperty(cx, obj, id, &holder, &shape, &isDOMProxy,
-                                    &domProxyShadowsResult, &domProxyHasGeneration))
-    {
-        return false;
-    }
-
-    ICStub* monitorStub = stub->fallbackMonitorStub()->firstMonitorStub();
-
-    bool isScripted = false;
-    bool cacheableCall = IsCacheableGetPropCall(cx, obj, holder, shape, &isScripted,
-                                                isTemporarilyUnoptimizable);
-
-    // Try handling scripted getters.
-    if (cacheableCall && isScripted && !isDOMProxy) {
-        RootedFunction callee(cx, &shape->getterObject()->as<JSFunction>());
-        MOZ_ASSERT(callee->hasScript());
-
-        if (UpdateExistingGetPropCallStubs(stub, ICStub::GetProp_CallScripted,
-                                           holder.as<NativeObject>(), obj, callee)) {
-            *attached = true;
-            return true;
-        }
-
-        JitSpew(JitSpew_BaselineIC, "  Generating GetProp(NativeObj/ScriptedGetter %s:%" PRIuSIZE ") stub",
-                callee->nonLazyScript()->filename(), callee->nonLazyScript()->lineno());
-
-        ICGetProp_CallScripted::Compiler compiler(cx, monitorStub, obj, holder, callee,
-                                                  script->pcToOffset(pc));
-        ICStub* newStub = compiler.getStub(compiler.getStubSpace(script));
-        if (!newStub)
-            return false;
-
-        stub->addNewStub(newStub);
-        *attached = true;
-        return true;
-    }
-
-    // If it's a shadowed listbase proxy property, attach stub to call Proxy::get instead.
-    if (isDOMProxy && DOMProxyIsShadowing(domProxyShadowsResult)) {
-        MOZ_ASSERT(obj == holder);
-
-        JitSpew(JitSpew_BaselineIC, "  Generating GetProp(DOMProxyProxy) stub");
-        Rooted<ProxyObject*> proxy(cx, &obj->as<ProxyObject>());
-        ICGetProp_DOMProxyShadowed::Compiler compiler(cx, monitorStub, proxy, name,
-                                                      script->pcToOffset(pc));
-        ICStub* newStub = compiler.getStub(compiler.getStubSpace(script));
-        if (!newStub)
-            return false;
-        stub->addNewStub(newStub);
-        *attached = true;
-        return true;
-    }
-
-    const Class* outerClass = nullptr;
-    if (!isDOMProxy && !obj->isNative()) {
-        outerClass = obj->getClass();
-        if (!IsWindowProxy(obj))
-            return true;
-
-        // This must be a WindowProxy for the current Window/global. Else it'd
-        // be a cross-compartment wrapper and IsWindowProxy returns false for
-        // those.
-        MOZ_ASSERT(ToWindowIfWindowProxy(obj) == cx->global());
-        obj = cx->global();
-
-        if (!EffectlesslyLookupProperty(cx, obj, id, &holder, &shape, &isDOMProxy,
-                                        &domProxyShadowsResult, &domProxyHasGeneration))
-        {
-            return false;
-        }
-        cacheableCall = IsCacheableGetPropCall(cx, obj, holder, shape, &isScripted,
-                                               isTemporarilyUnoptimizable, isDOMProxy);
-    }
-
-    // Try handling JSNative getters.
-    if (!cacheableCall || isScripted)
-        return true;
-
-    if (!shape || !shape->hasGetterValue() || !shape->getterValue().isObject() ||
-        !shape->getterObject()->is<JSFunction>())
-    {
-        return true;
-    }
-
-    RootedFunction callee(cx, &shape->getterObject()->as<JSFunction>());
-    MOZ_ASSERT(callee->isNative());
-
-    if (outerClass && (!callee->jitInfo() || callee->jitInfo()->needsOuterizedThisObject()))
-        return true;
-
-    JitSpew(JitSpew_BaselineIC, "  Generating GetProp(%s%s/NativeGetter %p) stub",
-            isDOMProxy ? "DOMProxyObj" : "NativeObj",
-            isDOMProxy && domProxyHasGeneration ? "WithGeneration" : "",
-            callee->native());
-
-    ICStub* newStub = nullptr;
-    if (isDOMProxy) {
-        MOZ_ASSERT(obj != holder);
-        ICStub::Kind kind;
-        if (domProxyHasGeneration) {
-            if (UpdateExistingGenerationalDOMProxyStub(stub, obj)) {
-                *attached = true;
-                return true;
-            }
-            kind = ICStub::GetProp_CallDOMProxyWithGenerationNative;
-        } else {
-            kind = ICStub::GetProp_CallDOMProxyNative;
-        }
-        Rooted<ProxyObject*> proxy(cx, &obj->as<ProxyObject>());
-        ICGetPropCallDOMProxyNativeCompiler compiler(cx, kind, monitorStub, proxy, holder, callee,
-                                                     script->pcToOffset(pc));
-        newStub = compiler.getStub(compiler.getStubSpace(script));
-    } else {
-        if (UpdateExistingGetPropCallStubs(stub, ICStub::GetProp_CallNative,
-                                           holder.as<NativeObject>(), obj, callee))
-        {
-            *attached = true;
-            return true;
-        }
-
-        ICGetPropCallNativeCompiler compiler(cx, ICStub::GetProp_CallNative,
-                                             monitorStub, obj, holder, callee,
-                                             script->pcToOffset(pc), outerClass);
-        newStub = compiler.getStub(compiler.getStubSpace(script));
-    }
-    if (!newStub)
-        return false;
-    stub->addNewStub(newStub);
-    *attached = true;
-    return true;
-}
-
-static bool
-TryAttachUnboxedGetPropStub(JSContext* cx, HandleScript script,
-                            ICGetProp_Fallback* stub, HandlePropertyName name, HandleValue val,
-                            bool* attached)
-{
-    MOZ_ASSERT(!*attached);
-
-    if (!cx->runtime()->jitSupportsFloatingPoint)
-        return true;
-
-    if (!val.isObject() || !val.toObject().is<UnboxedPlainObject>())
-        return true;
-    Rooted<UnboxedPlainObject*> obj(cx, &val.toObject().as<UnboxedPlainObject>());
-
-    const UnboxedLayout::Property* property = obj->layout().lookup(name);
-    if (!property)
-        return true;
-
-    ICStub* monitorStub = stub->fallbackMonitorStub()->firstMonitorStub();
-
-    ICGetProp_Unboxed::Compiler compiler(cx, monitorStub, obj->group(),
-                                         property->offset + UnboxedPlainObject::offsetOfData(),
-                                         property->type);
-    ICStub* newStub = compiler.getStub(compiler.getStubSpace(script));
-    if (!newStub)
-        return false;
-    stub->addNewStub(newStub);
-
-    StripPreliminaryObjectStubs(cx, stub);
-
-    *attached = true;
-    return true;
-}
-
-static bool
-TryAttachUnboxedExpandoGetPropStub(JSContext* cx, HandleScript script, jsbytecode* pc,
-                                   ICGetProp_Fallback* stub, HandlePropertyName name, HandleValue val,
-                                   bool* attached)
-{
-    MOZ_ASSERT(!*attached);
-
-    if (!val.isObject() || !val.toObject().is<UnboxedPlainObject>())
-        return true;
-    Rooted<UnboxedPlainObject*> obj(cx, &val.toObject().as<UnboxedPlainObject>());
-
-    Rooted<UnboxedExpandoObject*> expando(cx, obj->maybeExpando());
-    if (!expando)
-        return true;
-
-    Shape* shape = expando->lookup(cx, name);
-    if (!shape || !shape->hasDefaultGetter() || !shape->hasSlot())
-        return true;
-
-    bool isFixedSlot;
-    uint32_t offset;
-    GetFixedOrDynamicSlotOffset(shape, &isFixedSlot, &offset);
-
-    ICStub* monitorStub = stub->fallbackMonitorStub()->firstMonitorStub();
-
-    ICGetPropNativeCompiler compiler(cx, ICStub::GetProp_Native, monitorStub, obj, obj,
-                                     name, isFixedSlot, offset);
-    ICGetPropNativeStub* newStub = compiler.getStub(compiler.getStubSpace(script));
-    if (!newStub)
-        return false;
-
-    StripPreliminaryObjectStubs(cx, stub);
-
-    stub->addNewStub(newStub);
-    *attached = true;
-    return true;
-}
-
-static bool
-TryAttachTypedObjectGetPropStub(JSContext* cx, HandleScript script,
-                                ICGetProp_Fallback* stub, HandlePropertyName name, HandleValue val,
-                                bool* attached)
-{
-    MOZ_ASSERT(!*attached);
-
-    if (!cx->runtime()->jitSupportsFloatingPoint)
-        return true;
-
-    if (!val.isObject() || !val.toObject().is<TypedObject>())
-        return true;
-    Rooted<TypedObject*> obj(cx, &val.toObject().as<TypedObject>());
-
-    if (!obj->typeDescr().is<StructTypeDescr>())
-        return true;
-    Rooted<StructTypeDescr*> structDescr(cx, &obj->typeDescr().as<StructTypeDescr>());
-
-    size_t fieldIndex;
-    if (!structDescr->fieldIndex(NameToId(name), &fieldIndex))
-        return true;
-
-    Rooted<TypeDescr*> fieldDescr(cx, &structDescr->fieldDescr(fieldIndex));
-    if (!fieldDescr->is<SimpleTypeDescr>())
-        return true;
-
-    uint32_t fieldOffset = structDescr->fieldOffset(fieldIndex);
-    ICStub* monitorStub = stub->fallbackMonitorStub()->firstMonitorStub();
-
-    ICGetProp_TypedObject::Compiler compiler(cx, monitorStub, obj->maybeShape(),
-                                             fieldOffset, &fieldDescr->as<SimpleTypeDescr>());
-    ICStub* newStub = compiler.getStub(compiler.getStubSpace(script));
-    if (!newStub)
-        return false;
-    stub->addNewStub(newStub);
-
-    *attached = true;
-    return true;
-}
-
-static bool
-TryAttachPrimitiveGetPropStub(JSContext* cx, HandleScript script, jsbytecode* pc,
-                              ICGetProp_Fallback* stub, HandlePropertyName name, HandleValue val,
-                              HandleValue res, bool* attached)
-{
-    MOZ_ASSERT(!*attached);
-
-    JSValueType primitiveType;
-    RootedNativeObject proto(cx);
-    Rooted<GlobalObject*> global(cx, &script->global());
-    if (val.isString()) {
-        primitiveType = JSVAL_TYPE_STRING;
-        proto = GlobalObject::getOrCreateStringPrototype(cx, global);
-    } else if (val.isSymbol()) {
-        primitiveType = JSVAL_TYPE_SYMBOL;
-        proto = GlobalObject::getOrCreateSymbolPrototype(cx, global);
-    } else if (val.isNumber()) {
-        primitiveType = JSVAL_TYPE_DOUBLE;
-        proto = GlobalObject::getOrCreateNumberPrototype(cx, global);
-    } else {
-        MOZ_ASSERT(val.isBoolean());
-        primitiveType = JSVAL_TYPE_BOOLEAN;
-        proto = GlobalObject::getOrCreateBooleanPrototype(cx, global);
-    }
-    if (!proto)
-        return false;
-
-    // Instantiate this property, for use during Ion compilation.
-    RootedId id(cx, NameToId(name));
-    if (IsIonEnabled(cx))
-        EnsureTrackPropertyTypes(cx, proto, id);
-
-    // For now, only look for properties directly set on the prototype.
-    RootedShape shape(cx, proto->lookup(cx, id));
-    if (!shape || !shape->hasSlot() || !shape->hasDefaultGetter())
-        return true;
-
-    bool isFixedSlot;
-    uint32_t offset;
-    GetFixedOrDynamicSlotOffset(shape, &isFixedSlot, &offset);
-
-    ICStub* monitorStub = stub->fallbackMonitorStub()->firstMonitorStub();
-
-    JitSpew(JitSpew_BaselineIC, "  Generating GetProp_Primitive stub");
-    ICGetProp_Primitive::Compiler compiler(cx, monitorStub, primitiveType, proto,
-                                           isFixedSlot, offset);
-    ICStub* newStub = compiler.getStub(compiler.getStubSpace(script));
-    if (!newStub)
-        return false;
-
-    stub->addNewStub(newStub);
-    *attached = true;
-    return true;
-}
-
-static bool
-TryAttachNativeGetPropDoesNotExistStub(JSContext* cx, HandleScript script,
-                                       jsbytecode* pc, ICGetProp_Fallback* stub,
-                                       HandlePropertyName name, HandleValue val,
-                                       bool* attached)
-{
-    MOZ_ASSERT(!*attached);
-
-    if (!val.isObject())
-        return true;
-
-    RootedObject obj(cx, &val.toObject());
-
-    // Don't attach stubs for CALLPROP since those need NoSuchMethod handling.
-    if (JSOp(*pc) == JSOP_CALLPROP)
-        return true;
-
-    // Check if does-not-exist can be confirmed on property.
-    RootedObject lastProto(cx);
-    size_t protoChainDepth = SIZE_MAX;
-    if (!CheckHasNoSuchProperty(cx, obj, name, &lastProto, &protoChainDepth))
-        return true;
-    MOZ_ASSERT(protoChainDepth < SIZE_MAX);
-
-    if (protoChainDepth > ICGetProp_NativeDoesNotExist::MAX_PROTO_CHAIN_DEPTH)
-        return true;
-
-    ICStub* monitorStub = stub->fallbackMonitorStub()->firstMonitorStub();
-
-    // Confirmed no-such-property.  Add stub.
-    JitSpew(JitSpew_BaselineIC, "  Generating GetProp_NativeDoesNotExist stub");
-    ICGetPropNativeDoesNotExistCompiler compiler(cx, monitorStub, obj, protoChainDepth);
-    ICStub* newStub = compiler.getStub(compiler.getStubSpace(script));
-    if (!newStub)
-        return false;
-
-    stub->addNewStub(newStub);
-    *attached = true;
-    return true;
-}
-
-static bool
-ComputeGetPropResult(JSContext* cx, BaselineFrame* frame, JSOp op, HandlePropertyName name,
-                     MutableHandleValue val, MutableHandleValue res)
-{
-    // Handle arguments.length and arguments.callee on optimized arguments, as
-    // it is not an object.
-    if (val.isMagic(JS_OPTIMIZED_ARGUMENTS) && IsOptimizedArguments(frame, val)) {
-        if (op == JSOP_LENGTH) {
-            res.setInt32(frame->numActualArgs());
-        } else {
-            MOZ_ASSERT(name == cx->names().callee);
-            MOZ_ASSERT(frame->script()->hasMappedArgsObj());
-            res.setObject(*frame->callee());
-        }
-    } else {
-        if (op == JSOP_GETXPROP) {
-            RootedObject obj(cx, &val.toObject());
-            RootedId id(cx, NameToId(name));
-            if (!GetPropertyForNameLookup(cx, obj, id, res))
-                return false;
-        } else {
-            MOZ_ASSERT(op == JSOP_GETPROP || op == JSOP_CALLPROP || op == JSOP_LENGTH);
-            if (!GetProperty(cx, val, name, res))
-                return false;
-        }
-    }
-
-    return true;
-}
-
-static bool
-DoGetPropFallback(JSContext* cx, BaselineFrame* frame, ICGetProp_Fallback* stub_,
-                  MutableHandleValue val, MutableHandleValue res)
-{
-    // This fallback stub may trigger debug mode toggling.
-    DebugModeOSRVolatileStub<ICGetProp_Fallback*> stub(frame, stub_);
-
-    jsbytecode* pc = stub->icEntry()->pc(frame->script());
-    JSOp op = JSOp(*pc);
-    FallbackICSpew(cx, stub, "GetProp(%s)", js_CodeName[op]);
-
-    MOZ_ASSERT(op == JSOP_GETPROP || op == JSOP_CALLPROP || op == JSOP_LENGTH || op == JSOP_GETXPROP);
-
-    // Grab our old shape before it goes away.
-    RootedShape oldShape(cx);
-    if (val.isObject())
-        oldShape = val.toObject().maybeShape();
-
-    bool attached = false;
-    // There are some reasons we can fail to attach a stub that are temporary.
-    // We want to avoid calling noteUnoptimizableAccess() if the reason we
-    // failed to attach a stub is one of those temporary reasons, since we might
-    // end up attaching a stub for the exact same access later.
-    bool isTemporarilyUnoptimizable = false;
-
-    RootedScript script(cx, frame->script());
-    RootedPropertyName name(cx, frame->script()->getName(pc));
-
-    // After the  Genericstub was added, we should never reach the Fallbackstub again.
-    MOZ_ASSERT(!stub->hasStub(ICStub::GetProp_Generic));
-
-    if (stub->numOptimizedStubs() >= ICGetProp_Fallback::MAX_OPTIMIZED_STUBS) {
-        // Discard all stubs in this IC and replace with generic getprop stub.
-        for(ICStubIterator iter = stub->beginChain(); !iter.atEnd(); iter++)
-            iter.unlink(cx);
-        ICGetProp_Generic::Compiler compiler(cx, stub->fallbackMonitorStub()->firstMonitorStub());
-        ICStub* newStub = compiler.getStub(compiler.getStubSpace(script));
-        if (!newStub)
-            return false;
-        stub->addNewStub(newStub);
-        attached = true;
-    }
-
-    if (!attached && !TryAttachNativeGetAccessorPropStub(cx, script, pc, stub, name, val, res,
-                                                         &attached, &isTemporarilyUnoptimizable))
-    {
-        return false;
-    }
-
-    if (!ComputeGetPropResult(cx, frame, op, name, val, res))
-        return false;
-
-    TypeScript::Monitor(cx, script, pc, res);
-
-    // Check if debug mode toggling made the stub invalid.
-    if (stub.invalid())
-        return true;
-
-    // Add a type monitor stub for the resulting value.
-    if (!stub->addMonitorStubForValue(cx, script, res))
-        return false;
-
-    if (attached)
-        return true;
-
-    if (op == JSOP_LENGTH) {
-        if (!TryAttachLengthStub(cx, script, stub, val, res, &attached))
-            return false;
-        if (attached)
-            return true;
-    }
-
-    if (!TryAttachMagicArgumentsGetPropStub(cx, script, stub, name, val, res, &attached))
-        return false;
-    if (attached)
-        return true;
-
-    if (!TryAttachNativeGetValuePropStub(cx, script, pc, stub, name, val, oldShape,
-                                         res, &attached))
-        return false;
-    if (attached)
-        return true;
-
-    if (!TryAttachUnboxedGetPropStub(cx, script, stub, name, val, &attached))
-        return false;
-    if (attached)
-        return true;
-
-    if (!TryAttachUnboxedExpandoGetPropStub(cx, script, pc, stub, name, val, &attached))
-        return false;
-    if (attached)
-        return true;
-
-    if (!TryAttachTypedObjectGetPropStub(cx, script, stub, name, val, &attached))
-        return false;
-    if (attached)
-        return true;
-
-    if (val.isString() || val.isNumber() || val.isBoolean()) {
-        if (!TryAttachPrimitiveGetPropStub(cx, script, pc, stub, name, val, res, &attached))
-            return false;
-        if (attached)
-            return true;
-    }
-
-    if (res.isUndefined()) {
-        // Try attaching property-not-found optimized stub for undefined results.
-        if (!TryAttachNativeGetPropDoesNotExistStub(cx, script, pc, stub, name, val, &attached))
-            return false;
-        if (attached)
-            return true;
-    }
-
-    MOZ_ASSERT(!attached);
-    if (!isTemporarilyUnoptimizable)
-        stub->noteUnoptimizableAccess();
-
-    return true;
-}
-
-typedef bool (*DoGetPropFallbackFn)(JSContext*, BaselineFrame*, ICGetProp_Fallback*,
-                                    MutableHandleValue, MutableHandleValue);
-static const VMFunction DoGetPropFallbackInfo =
-    FunctionInfo<DoGetPropFallbackFn>(DoGetPropFallback, TailCall, PopValues(1));
-
-bool
-ICGetProp_Fallback::Compiler::generateStubCode(MacroAssembler& masm)
-{
-    MOZ_ASSERT(engine_ == Engine::Baseline);
-    MOZ_ASSERT(R0 == JSReturnOperand);
-
-    EmitRestoreTailCallReg(masm);
-
-    // Ensure stack is fully synced for the expression decompiler.
-    masm.pushValue(R0);
-
-    // Push arguments.
-    masm.pushValue(R0);
-    masm.push(ICStubReg);
-    pushFramePtr(masm, R0.scratchReg());
-
-    if (!tailCallVM(DoGetPropFallbackInfo, masm))
-        return false;
-
-    // What follows is bailout for inlined scripted getters.
-    // The return address pointed to by the baseline stack points here.
-    returnOffset_ = masm.currentOffset();
-
-    // Even though the fallback frame doesn't enter a stub frame, the CallScripted
-    // frame that we are emulating does. Again, we lie.
-    inStubFrame_ = true;
-#ifdef DEBUG
-    entersStubFrame_ = true;
-#endif
-
-    leaveStubFrame(masm, true);
-
-    // When we get here, ICStubReg contains the ICGetProp_Fallback stub,
-    // which we can't use to enter the TypeMonitor IC, because it's a MonitoredFallbackStub
-    // instead of a MonitoredStub. So, we cheat.
-    masm.loadPtr(Address(ICStubReg, ICMonitoredFallbackStub::offsetOfFallbackMonitorStub()),
-                 ICStubReg);
-    EmitEnterTypeMonitorIC(masm, ICTypeMonitor_Fallback::offsetOfFirstMonitorStub());
-
-    return true;
-}
-
-void
-ICGetProp_Fallback::Compiler::postGenerateStubCode(MacroAssembler& masm, Handle<JitCode*> code)
-{
-    cx->compartment()->jitCompartment()->initBaselineGetPropReturnAddr(code->raw() + returnOffset_);
-}
-
-bool
-ICGetProp_ArrayLength::Compiler::generateStubCode(MacroAssembler& masm)
-{
-    MOZ_ASSERT(engine_ == Engine::Baseline);
-
-    Label failure;
-    masm.branchTestObject(Assembler::NotEqual, R0, &failure);
-
-    Register scratch = R1.scratchReg();
-
-    // Unbox R0 and guard it's an array.
-    Register obj = masm.extractObject(R0, ExtractTemp0);
-    masm.branchTestObjClass(Assembler::NotEqual, obj, scratch, &ArrayObject::class_, &failure);
-
-    // Load obj->elements->length.
-    masm.loadPtr(Address(obj, NativeObject::offsetOfElements()), scratch);
-    masm.load32(Address(scratch, ObjectElements::offsetOfLength()), scratch);
-
-    // Guard length fits in an int32.
-    masm.branchTest32(Assembler::Signed, scratch, scratch, &failure);
-
-    masm.tagValue(JSVAL_TYPE_INT32, scratch, R0);
-    EmitReturnFromIC(masm);
-
-    // Failure case - jump to next stub
-    masm.bind(&failure);
-    EmitStubGuardFailure(masm);
-    return true;
-}
-
-bool
-ICGetProp_UnboxedArrayLength::Compiler::generateStubCode(MacroAssembler& masm)
-{
-    MOZ_ASSERT(engine_ == Engine::Baseline);
-
-    Label failure;
-    masm.branchTestObject(Assembler::NotEqual, R0, &failure);
-
-    Register scratch = R1.scratchReg();
-
-    // Unbox R0 and guard it's an unboxed array.
-    Register obj = masm.extractObject(R0, ExtractTemp0);
-    masm.branchTestObjClass(Assembler::NotEqual, obj, scratch, &UnboxedArrayObject::class_, &failure);
-
-    // Load obj->length.
-    masm.load32(Address(obj, UnboxedArrayObject::offsetOfLength()), scratch);
-
-    masm.tagValue(JSVAL_TYPE_INT32, scratch, R0);
-    EmitReturnFromIC(masm);
-
-    // Failure case - jump to next stub
-    masm.bind(&failure);
-    EmitStubGuardFailure(masm);
-    return true;
-}
-
-bool
-ICGetProp_StringLength::Compiler::generateStubCode(MacroAssembler& masm)
-{
-    MOZ_ASSERT(engine_ == Engine::Baseline);
-
-    Label failure;
-    masm.branchTestString(Assembler::NotEqual, R0, &failure);
-
-    // Unbox string and load its length.
-    Register string = masm.extractString(R0, ExtractTemp0);
-    masm.loadStringLength(string, string);
-
-    masm.tagValue(JSVAL_TYPE_INT32, string, R0);
-    EmitReturnFromIC(masm);
-
-    // Failure case - jump to next stub
-    masm.bind(&failure);
-    EmitStubGuardFailure(masm);
-    return true;
-}
-
-bool
-ICGetProp_Primitive::Compiler::generateStubCode(MacroAssembler& masm)
-{
-    MOZ_ASSERT(engine_ == Engine::Baseline);
-
-    Label failure;
-    switch (primitiveType_) {
-      case JSVAL_TYPE_STRING:
-        masm.branchTestString(Assembler::NotEqual, R0, &failure);
-        break;
-      case JSVAL_TYPE_SYMBOL:
-        masm.branchTestSymbol(Assembler::NotEqual, R0, &failure);
-        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");
-    }
-
-    AllocatableGeneralRegisterSet regs(availableGeneralRegs(1));
-    Register holderReg = regs.takeAny();
-    Register scratchReg = regs.takeAny();
-
-    // Verify the shape of the prototype.
-    masm.movePtr(ImmGCPtr(prototype_.get()), holderReg);
-
-    Address shapeAddr(ICStubReg, ICGetProp_Primitive::offsetOfProtoShape());
-    masm.loadPtr(Address(holderReg, JSObject::offsetOfShape()), scratchReg);
-    masm.branchPtr(Assembler::NotEqual, shapeAddr, scratchReg, &failure);
-
-    if (!isFixedSlot_)
-        masm.loadPtr(Address(holderReg, NativeObject::offsetOfSlots()), holderReg);
-
-    masm.load32(Address(ICStubReg, ICGetProp_Primitive::offsetOfOffset()), scratchReg);
-    masm.loadValue(BaseIndex(holderReg, scratchReg, TimesOne), R0);
-
-    // Enter type monitor IC to type-check result.
-    EmitEnterTypeMonitorIC(masm);
-
-    // Failure case - jump to next stub
-    masm.bind(&failure);
-    EmitStubGuardFailure(masm);
-    return true;
-}
-
-ICGetPropNativeStub*
-ICGetPropNativeCompiler::getStub(ICStubSpace* space)
-{
-    ReceiverGuard guard(obj_);
-
-    switch (kind) {
-      case ICStub::GetProp_Native: {
-        MOZ_ASSERT(obj_ == holder_);
-        return newStub<ICGetProp_Native>(space, getStubCode(), firstMonitorStub_, guard, offset_);
-      }
-
-      case ICStub::GetProp_NativePrototype: {
-        MOZ_ASSERT(obj_ != holder_);
-        Shape* holderShape = holder_->as<NativeObject>().lastProperty();
-        return newStub<ICGetProp_NativePrototype>(space, getStubCode(), firstMonitorStub_, guard,
-                                                  offset_, holder_, holderShape);
-      }
-
-      case ICStub::GetName_Global: {
-        MOZ_ASSERT(obj_ != holder_);
-        Shape* holderShape = holder_->as<NativeObject>().lastProperty();
-        Shape* globalShape = obj_->as<ClonedBlockObject>().global().lastProperty();
-        return newStub<ICGetName_Global>(space, getStubCode(), firstMonitorStub_, guard,
-                                         offset_, holder_, holderShape, globalShape);
-      }
-
-      default:
-        MOZ_CRASH("Bad stub kind");
-    }
-}
-
-static void
-GuardGlobalObject(MacroAssembler& masm, HandleObject holder, Register globalLexicalReg,
-                  Register holderReg, Register scratch, size_t globalShapeOffset, Label* failure)
-{
-    if (holder->is<GlobalObject>())
-        return;
-    masm.extractObject(Address(globalLexicalReg, ScopeObject::offsetOfEnclosingScope()),
-                       holderReg);
-    masm.loadPtr(Address(ICStubReg, globalShapeOffset), scratch);
-    masm.branchTestObjShape(Assembler::NotEqual, holderReg, scratch, failure);
-}
-
-bool
-ICGetPropNativeCompiler::generateStubCode(MacroAssembler& masm)
-{
-    MOZ_ASSERT(engine_ == Engine::Baseline);
-
-    Label failure;
-    AllocatableGeneralRegisterSet regs(availableGeneralRegs(0));
-    Register objReg = InvalidReg;
-
-    if (inputDefinitelyObject_) {
-        objReg = R0.scratchReg();
-    } else {
-        regs.take(R0);
-        // Guard input is an object and unbox.
-        masm.branchTestObject(Assembler::NotEqual, R0, &failure);
-        objReg = masm.extractObject(R0, ExtractTemp0);
-    }
-    regs.takeUnchecked(objReg);
-
-    Register scratch = regs.takeAnyExcluding(ICTailCallReg);
-
-    // Shape/group guard.
-    GuardReceiverObject(masm, ReceiverGuard(obj_), objReg, scratch,
-                        ICGetPropNativeStub::offsetOfReceiverGuard(), &failure);
-
-    Register holderReg;
-    if (obj_ == holder_) {
-        MOZ_ASSERT(kind != ICStub::GetName_Global);
-        if (obj_->is<UnboxedPlainObject>()) {
-            // We are loading off the expando object, so use that for the holder.
-            holderReg = regs.takeAny();
-            masm.loadPtr(Address(objReg, UnboxedPlainObject::offsetOfExpando()), holderReg);
-        } else {
-            holderReg = objReg;
-        }
-    } else {
-        holderReg = regs.takeAny();
-
-        // If we are generating a non-lexical GETGNAME stub, we must also
-        // guard on the shape of the GlobalObject.
-        if (kind == ICStub::GetName_Global) {
-            MOZ_ASSERT(obj_->is<ClonedBlockObject>() && obj_->as<ClonedBlockObject>().isGlobal());
-            GuardGlobalObject(masm, holder_, objReg, holderReg, scratch,
-                              ICGetName_Global::offsetOfGlobalShape(), &failure);
-        }
-
-        // Shape guard holder.
-        masm.loadPtr(Address(ICStubReg, ICGetProp_NativePrototype::offsetOfHolder()),
-                     holderReg);
-        masm.loadPtr(Address(ICStubReg, ICGetProp_NativePrototype::offsetOfHolderShape()),
-                     scratch);
-        masm.branchTestObjShape(Assembler::NotEqual, holderReg, scratch, &failure);
-    }
-
-    if (!isFixedSlot_) {
-        // Don't overwrite actual holderReg if we need to load a dynamic slots object.
-        // May need to preserve object for noSuchMethod check later.
-        Register nextHolder = regs.takeAny();
-        masm.loadPtr(Address(holderReg, NativeObject::offsetOfSlots()), nextHolder);
-        holderReg = nextHolder;
-    }
-
-    masm.load32(Address(ICStubReg, ICGetPropNativeStub::offsetOfOffset()), scratch);
-    BaseIndex result(holderReg, scratch, TimesOne);
-
-    masm.loadValue(result, R0);
-
-    // Enter type monitor IC to type-check result.
-    EmitEnterTypeMonitorIC(masm);
-
-    // Failure case - jump to next stub
-    masm.bind(&failure);
-    EmitStubGuardFailure(masm);
-    return true;
-}
-
-ICStub*
-ICGetPropNativeDoesNotExistCompiler::getStub(ICStubSpace* space)
-{
-    Rooted<ShapeVector> shapes(cx, ShapeVector(cx));
-
-    if (!GetProtoShapes(obj_, protoChainDepth_, &shapes))
-        return nullptr;
-
-    JS_STATIC_ASSERT(ICGetProp_NativeDoesNotExist::MAX_PROTO_CHAIN_DEPTH == 8);
-
-    ICStub* 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;
-      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.");
-    }
-    if (!stub)
-        return nullptr;
-    return stub;
-}
-
-bool
-ICGetPropNativeDoesNotExistCompiler::generateStubCode(MacroAssembler& masm)
-{
-    MOZ_ASSERT(engine_ == Engine::Baseline);
-
-    Label failure;
-
-    AllocatableGeneralRegisterSet regs(availableGeneralRegs(1));
-    Register scratch = regs.takeAny();
-
-#ifdef DEBUG
-    // Ensure that protoChainDepth_ matches the protoChainDepth stored on the stub.
-    {
-        Label ok;
-        masm.load16ZeroExtend(Address(ICStubReg, ICStub::offsetOfExtra()), scratch);
-        masm.branch32(Assembler::Equal, scratch, Imm32(protoChainDepth_), &ok);
-        masm.assumeUnreachable("Non-matching proto chain depth on stub.");
-        masm.bind(&ok);
-    }
-#endif // DEBUG
-
-    // Guard input is an object.
-    masm.branchTestObject(Assembler::NotEqual, R0, &failure);
-
-    // Unbox and guard against old shape/group.
-    Register objReg = masm.extractObject(R0, ExtractTemp0);
-    GuardReceiverObject(masm, ReceiverGuard(obj_), objReg, scratch,
-                        ICGetProp_NativeDoesNotExist::offsetOfGuard(), &failure);
-
-    Register protoReg = regs.takeAny();
-    // Check the proto chain.
-    for (size_t i = 0; i < protoChainDepth_; i++) {
-        masm.loadObjProto(i == 0 ? objReg : protoReg, protoReg);
-        masm.branchTestPtr(Assembler::Zero, protoReg, protoReg, &failure);
-        size_t shapeOffset = ICGetProp_NativeDoesNotExistImpl<0>::offsetOfShape(i);
-        masm.loadPtr(Address(ICStubReg, shapeOffset), scratch);
-        masm.branchTestObjShape(Assembler::NotEqual, protoReg, scratch, &failure);
-    }
-
-    // Shape and type checks succeeded, ok to proceed.
-    masm.moveValue(UndefinedValue(), R0);
-
-    // Normally for this op, the result would have to be monitored by TI.
-    // However, since this stub ALWAYS returns UndefinedValue(), and we can be sure
-    // that undefined is already registered with the type-set, this can be avoided.
-    EmitReturnFromIC(masm);
-
-    masm.bind(&failure);
-    EmitStubGuardFailure(masm);
-    return true;
-}
-
-bool
-ICGetProp_CallScripted::Compiler::generateStubCode(MacroAssembler& masm)
-{
-    MOZ_ASSERT(engine_ == Engine::Baseline);
-
-    Label failure;
-    Label failureLeaveStubFrame;
-    AllocatableGeneralRegisterSet regs(availableGeneralRegs(1));
-    Register scratch = regs.takeAnyExcluding(ICTailCallReg);
-
-    // Guard input is an object.
-    masm.branchTestObject(Assembler::NotEqual, R0, &failure);
-
-    // Unbox and shape guard.
-    Register objReg = masm.extractObject(R0, ExtractTemp0);
-    GuardReceiverObject(masm, ReceiverGuard(receiver_), objReg, scratch,
-                        ICGetProp_CallScripted::offsetOfReceiverGuard(), &failure);
-
-    if (receiver_ != holder_) {
-        Register holderReg = regs.takeAny();
-        masm.loadPtr(Address(ICStubReg, ICGetProp_CallScripted::offsetOfHolder()), holderReg);
-        masm.loadPtr(Address(ICStubReg, ICGetProp_CallScripted::offsetOfHolderShape()), scratch);
-        masm.branchTestObjShape(Assembler::NotEqual, holderReg, scratch, &failure);
-        regs.add(holderReg);
-    }
-
-    // Push a stub frame so that we can perform a non-tail call.
-    enterStubFrame(masm, scratch);
-
-    // Load callee function and code.  To ensure that |code| doesn't end up being
-    // ArgumentsRectifierReg, if it's available we assign it to |callee| instead.
-    Register callee;
-    if (regs.has(ArgumentsRectifierReg)) {
-        callee = ArgumentsRectifierReg;
-        regs.take(callee);
-    } else {
-        callee = regs.takeAny();
-    }
-    Register code = regs.takeAny();
-    masm.loadPtr(Address(ICStubReg, ICGetProp_CallScripted::offsetOfGetter()), callee);
-    masm.branchIfFunctionHasNoScript(callee, &failureLeaveStubFrame);
-    masm.loadPtr(Address(callee, JSFunction::offsetOfNativeOrScript()), code);
-    masm.loadBaselineOrIonRaw(code, code, &failureLeaveStubFrame);
-
-    // Align the stack such that the JitFrameLayout is aligned on
-    // JitStackAlignment.
-    masm.alignJitStackBasedOnNArgs(0);
-
-    // Getter is called with 0 arguments, just |obj| as thisv.
-    // Note that we use Push, not push, so that callJit will align the stack
-    // properly on ARM.
-    masm.Push(R0);
-    EmitBaselineCreateStubFrameDescriptor(masm, scratch);
-    masm.Push(Imm32(0));  // ActualArgc is 0
-    masm.Push(callee);
-    masm.Push(scratch);
-
-    // Handle arguments underflow.
-    Label noUnderflow;
-    masm.load16ZeroExtend(Address(callee, JSFunction::offsetOfNargs()), scratch);
-    masm.branch32(Assembler::Equal, scratch, Imm32(0), &noUnderflow);
-    {
-        // Call the arguments rectifier.
-        MOZ_ASSERT(ArgumentsRectifierReg != code);
-
-        JitCode* argumentsRectifier =
-            cx->runtime()->jitRuntime()->getArgumentsRectifier();
-
-        masm.movePtr(ImmGCPtr(argumentsRectifier), code);
-        masm.loadPtr(Address(code, JitCode::offsetOfCode()), code);
-        masm.movePtr(ImmWord(0), ArgumentsRectifierReg);
-    }
-
-    masm.bind(&noUnderflow);
-    masm.callJit(code);
-
-    leaveStubFrame(masm, true);
-
-    // Enter type monitor IC to type-check result.
-    EmitEnterTypeMonitorIC(masm);
-
-    // Leave stub frame and go to next stub.
-    masm.bind(&failureLeaveStubFrame);
-    inStubFrame_ = true;
-    leaveStubFrame(masm, false);
-
-    // Failure case - jump to next stub
-    masm.bind(&failure);
-    EmitStubGuardFailure(masm);
-    return true;
-}
-
-bool
-ICGetPropCallNativeCompiler::generateStubCode(MacroAssembler& masm)
-{
-    MOZ_ASSERT(engine_ == Engine::Baseline);
-
-    Label failure;
-
-    AllocatableGeneralRegisterSet regs(availableGeneralRegs(1));
-    Register objReg = InvalidReg;
-
-    MOZ_ASSERT(!(inputDefinitelyObject_ && outerClass_));
-    if (inputDefinitelyObject_) {
-        objReg = R0.scratchReg();
-    } else {
-        // Guard input is an object and unbox.
-        masm.branchTestObject(Assembler::NotEqual, R0, &failure);
-        objReg = masm.extractObject(R0, ExtractTemp0);
-        if (outerClass_) {
-            Register tmp = regs.takeAny();
-            masm.branchTestObjClass(Assembler::NotEqual, objReg, tmp, outerClass_, &failure);
-            masm.movePtr(ImmGCPtr(cx->global()), objReg);
-            regs.add(tmp);
-        }
-    }
-
-    Register scratch = regs.takeAnyExcluding(ICTailCallReg);
-
-    // Shape guard.
-    GuardReceiverObject(masm, ReceiverGuard(receiver_), objReg, scratch,
-                        ICGetPropCallGetter::offsetOfReceiverGuard(), &failure);
-
-    if (receiver_ != holder_) {
-        Register holderReg = regs.takeAny();
-
-        // If we are generating a non-lexical GETGNAME stub, we must also
-        // guard on the shape of the GlobalObject.
-        if (kind == ICStub::GetProp_CallNativeGlobal) {
-            MOZ_ASSERT(receiver_->is<ClonedBlockObject>() &&
-                       receiver_->as<ClonedBlockObject>().isGlobal());
-            GuardGlobalObject(masm, holder_, objReg, holderReg, scratch,
-                              ICGetProp_CallNativeGlobal::offsetOfGlobalShape(), &failure);
-        }
-
-        masm.loadPtr(Address(ICStubReg, ICGetPropCallGetter::offsetOfHolder()), holderReg);
-        masm.loadPtr(Address(ICStubReg, ICGetPropCallGetter::offsetOfHolderShape()), scratch);
-        masm.branchTestObjShape(Assembler::NotEqual, holderReg, scratch, &failure);
-        regs.add(holderReg);
-    }
-
-    // Box and push obj onto baseline frame stack for decompiler
-    if (inputDefinitelyObject_)
-        masm.tagValue(JSVAL_TYPE_OBJECT, objReg, R0);
-    EmitStowICValues(masm, 1);
-    if (inputDefinitelyObject_)
-        objReg = masm.extractObject(R0, ExtractTemp0);
-
-    // Push a stub frame so that we can perform a non-tail call.
-    enterStubFrame(masm, scratch);
-
-    // Load callee function.
-    Register callee = regs.takeAny();
-    masm.loadPtr(Address(ICStubReg, ICGetPropCallGetter::offsetOfGetter()), callee);
-
-    // If we're calling a getter on the global, inline the logic for the
-    // 'this' hook on the global lexical scope and manually push the global.
-    if (kind == ICStub::GetProp_CallNativeGlobal)
-        masm.extractObject(Address(objReg, ScopeObject::offsetOfEnclosingScope()), objReg);
-
-    // Push args for vm call.
-    masm.push(objReg);
-    masm.push(callee);
-
-    regs.add(R0);
-
-    if (!callVM(DoCallNativeGetterInfo, masm))
-        return false;
-    leaveStubFrame(masm);
-
-    EmitUnstowICValues(masm, 1, /* discard = */true);
-
-    // Enter type monitor IC to type-check result.
-    EmitEnterTypeMonitorIC(masm);
-
-    // Failure case - jump to next stub
-    masm.bind(&failure);
-    EmitStubGuardFailure(masm);
-    return true;
-}
-
-ICStub*
-ICGetPropCallNativeCompiler::getStub(ICStubSpace* space)
-{
-    ReceiverGuard guard(receiver_);
-    Shape* holderShape = holder_->as<NativeObject>().lastProperty();
-
-    switch (kind) {
-      case ICStub::GetProp_CallNative:
-        return newStub<ICGetProp_CallNative>(space, getStubCode(), firstMonitorStub_,
-                                             guard, holder_, holderShape,
-                                             getter_, pcOffset_);
-
-      case ICStub::GetProp_CallNativeGlobal: {
-        Shape* globalShape = receiver_->as<ClonedBlockObject>().global().lastProperty();
-        return newStub<ICGetProp_CallNativeGlobal>(space, getStubCode(), firstMonitorStub_,
-                                                   guard, holder_, holderShape, globalShape,
-                                                   getter_, pcOffset_);
-      }
-
-      default:
-        MOZ_CRASH("Bad stub kind");
-    }
-}
-
-bool
-ICGetPropCallDOMProxyNativeCompiler::generateStubCode(MacroAssembler& masm,
-                                                      Address* expandoAndGenerationAddr,
-                                                      Address* generationAddr)
-{
-    MOZ_ASSERT(engine_ == Engine::Baseline);
-
-    Label failure;
-    AllocatableGeneralRegisterSet regs(availableGeneralRegs(1));
-    Register scratch = regs.takeAnyExcluding(ICTailCallReg);
-
-    // Guard input is an object.
-    masm.branchTestObject(Assembler::NotEqual, R0, &failure);
-
-    // Unbox.
-    Register objReg = masm.extractObject(R0, ExtractTemp0);
-
-    // Shape guard.
-    static const size_t receiverShapeOffset =
-        ICGetProp_CallDOMProxyNative::offsetOfReceiverGuard() +
-        HeapReceiverGuard::offsetOfShape();
-    masm.loadPtr(Address(ICStubReg, receiverShapeOffset), scratch);
-    masm.branchTestObjShape(Assembler::NotEqual, objReg, scratch, &failure);
-
-    // Guard that our expando object hasn't started shadowing this property.
-    {
-        AllocatableGeneralRegisterSet domProxyRegSet(GeneralRegisterSet::All());
-        domProxyRegSet.take(ICStubReg);
-        domProxyRegSet.take(objReg);
-        domProxyRegSet.take(scratch);
-        Address expandoShapeAddr(ICStubReg, ICGetProp_CallDOMProxyNative::offsetOfExpandoShape());
-        CheckDOMProxyExpandoDoesNotShadow(
-                cx, masm, objReg,
-                expandoShapeAddr, expandoAndGenerationAddr, generationAddr,
-                scratch,
-                domProxyRegSet,
-                &failure);
-    }
-
-    Register holderReg = regs.takeAny();
-    masm.loadPtr(Address(ICStubReg, ICGetProp_CallDOMProxyNative::offsetOfHolder()),
-                 holderReg);
-    masm.loadPtr(Address(ICStubReg, ICGetProp_CallDOMProxyNative::offsetOfHolderShape()),
-                 scratch);
-    masm.branchTestObjShape(Assembler::NotEqual, holderReg, scratch, &failure);
-    regs.add(holderReg);
-
-    // Push a stub frame so that we can perform a non-tail call.
-    enterStubFrame(masm, scratch);
-
-    // Load callee function.
-    Register callee = regs.takeAny();
-    masm.loadPtr(Address(ICStubReg, ICGetProp_CallDOMProxyNative::offsetOfGetter()), callee);
-
-    // Push args for vm call.
-    masm.push(objReg);
-    masm.push(callee);
-
-    // Don't have to preserve R0 anymore.
-    regs.add(R0);
-
-    if (!callVM(DoCallNativeGetterInfo, masm))
-        return false;
-    leaveStubFrame(masm);
-
-    // Enter type monitor IC to type-check result.
-    EmitEnterTypeMonitorIC(masm);
-
-    // Failure case - jump to next stub
-    masm.bind(&failure);
-    EmitStubGuardFailure(masm);
-    return true;
-}
-
-bool
-ICGetPropCallDOMProxyNativeCompiler::generateStubCode(MacroAssembler& masm)
-{
-    MOZ_ASSERT(engine_ == Engine::Baseline);
-
-    if (kind == ICStub::GetProp_CallDOMProxyNative)
-        return generateStubCode(masm, nullptr, nullptr);
-
-    Address internalStructAddress(ICStubReg,
-        ICGetProp_CallDOMProxyWithGenerationNative::offsetOfInternalStruct());
-    Address generationAddress(ICStubReg,
-        ICGetProp_CallDOMProxyWithGenerationNative::offsetOfGeneration());
-    return generateStubCode(masm, &internalStructAddress, &generationAddress);
-}
-
-ICStub*
-ICGetPropCallDOMProxyNativeCompiler::getStub(ICStubSpace* space)
-{
-    RootedShape shape(cx, proxy_->maybeShape());
-    RootedShape holderShape(cx, holder_->as<NativeObject>().lastProperty());
-
-    Value expandoSlot = GetProxyExtra(proxy_, GetDOMProxyExpandoSlot());
-    RootedShape expandoShape(cx, nullptr);
-    ExpandoAndGeneration* expandoAndGeneration;
-    int32_t generation;
-    Value expandoVal;
-    if (kind == ICStub::GetProp_CallDOMProxyNative) {
-        expandoVal = expandoSlot;
-        expandoAndGeneration = nullptr;  // initialize to silence GCC warning
-        generation = 0;  // initialize to silence GCC warning
-    } else {
-        MOZ_ASSERT(kind == ICStub::GetProp_CallDOMProxyWithGenerationNative);
-        MOZ_ASSERT(!expandoSlot.isObject() && !expandoSlot.isUndefined());
-        expandoAndGeneration = (ExpandoAndGeneration*)expandoSlot.toPrivate();
-        expandoVal = expandoAndGeneration->expando;
-        generation = expandoAndGeneration->generation;
-    }
-
-    if (expandoVal.isObject())
-        expandoShape = expandoVal.toObject().as<NativeObject>().lastProperty();
-
-    if (kind == ICStub::GetProp_CallDOMProxyNative) {
-        return newStub<ICGetProp_CallDOMProxyNative>(
-            space, getStubCode(), firstMonitorStub_, shape,
-            expandoShape, holder_, holderShape, getter_, pcOffset_);
-    }
-
-    return newStub<ICGetProp_CallDOMProxyWithGenerationNative>(
-        space, getStubCode(), firstMonitorStub_, shape,
-        expandoAndGeneration, generation, expandoShape, holder_, holderShape, getter_,
-        pcOffset_);
-}
-
-ICStub*
-ICGetProp_DOMProxyShadowed::Compiler::getStub(ICStubSpace* space)
-{
-    RootedShape shape(cx, proxy_->maybeShape());
-    return New<ICGetProp_DOMProxyShadowed>(cx, space, getStubCode(), firstMonitorStub_, shape,
-                                           proxy_->handler(), name_, pcOffset_);
-}
-
-static bool
-ProxyGet(JSContext* cx, HandleObject proxy, HandlePropertyName name, MutableHandleValue vp)
-{
-    RootedValue receiver(cx, ObjectValue(*proxy));
-    RootedId id(cx, NameToId(name));
-    return Proxy::get(cx, proxy, receiver, id, vp);
-}
-
-typedef bool (*ProxyGetFn)(JSContext* cx, HandleObject proxy, HandlePropertyName name,
-                           MutableHandleValue vp);
-static const VMFunction ProxyGetInfo = FunctionInfo<ProxyGetFn>(ProxyGet);
-
-bool
-ICGetProp_DOMProxyShadowed::Compiler::generateStubCode(MacroAssembler& masm)
-{
-    MOZ_ASSERT(engine_ == Engine::Baseline);
-
-    Label failure;
-
-    AllocatableGeneralRegisterSet regs(availableGeneralRegs(1));
-    // Need to reserve a scratch register, but the scratch register should not be
-    // ICTailCallReg, because it's used for |enterStubFrame| which needs a
-    // non-ICTailCallReg scratch reg.
-    Register scratch = regs.takeAnyExcluding(ICTailCallReg);
-
-    // Guard input is an object.
-    masm.branchTestObject(Assembler::NotEqual, R0, &failure);
-
-    // Unbox.
-    Register objReg = masm.extractObject(R0, ExtractTemp0);
-
-    // Shape guard.
-    masm.loadPtr(Address(ICStubReg, ICGetProp_DOMProxyShadowed::offsetOfShape()), scratch);
-    masm.branchTestObjShape(Assembler::NotEqual, objReg, scratch, &failure);
-
-    // No need to do any more guards; it's safe to call ProxyGet even
-    // if we've since stopped shadowing.
-
-    // Call ProxyGet(JSContext* cx, HandleObject proxy, HandlePropertyName name, MutableHandleValue vp);
-
-    // Push a stub frame so that we can perform a non-tail call.
-    enterStubFrame(masm, scratch);
-
-    // Push property name and proxy object.
-    masm.loadPtr(Address(ICStubReg, ICGetProp_DOMProxyShadowed::offsetOfName()), scratch);
-    masm.push(scratch);
-    masm.push(objReg);
-
-    // Don't have to preserve R0 anymore.
-    regs.add(R0);
-
-    if (!callVM(ProxyGetInfo, masm))
-        return false;
-    leaveStubFrame(masm);
-
-    // Enter type monitor IC to type-check result.
-    EmitEnterTypeMonitorIC(masm);
-
-    // Failure case - jump to next stub
-    masm.bind(&failure);
-    EmitStubGuardFailure(masm);
-    return true;
-}
-
-bool
-ICGetProp_ArgumentsLength::Compiler::generateStubCode(MacroAssembler& masm)
-{
-    MOZ_ASSERT(engine_ == Engine::Baseline);
-
-    Label failure;
-    if (which_ == ICGetProp_ArgumentsLength::Magic) {
-        // Ensure that this is lazy arguments.
-        masm.branchTestMagicValue(Assembler::NotEqual, R0, JS_OPTIMIZED_ARGUMENTS, &failure);
-
-        // Ensure that frame has not loaded different arguments object since.
-        masm.branchTest32(Assembler::NonZero,
-                          Address(BaselineFrameReg, BaselineFrame::reverseOffsetOfFlags()),
-                          Imm32(BaselineFrame::HAS_ARGS_OBJ),
-                          &failure);
-
-        Address actualArgs(BaselineFrameReg, BaselineFrame::offsetOfNumActualArgs());
-        masm.loadPtr(actualArgs, R0.scratchReg());
-        masm.tagValue(JSVAL_TYPE_INT32, R0.scratchReg(), R0);
-        EmitReturnFromIC(masm);
-
-        masm.bind(&failure);
-        EmitStubGuardFailure(masm);
-        return true;
-    }
-    MOZ_ASSERT(which_ == ICGetProp_ArgumentsLength::Mapped ||
-               which_ == ICGetProp_ArgumentsLength::Unmapped);
-
-    const Class* clasp = (which_ == ICGetProp_ArgumentsLength::Mapped)
-                         ? &MappedArgumentsObject::class_
-                         : &UnmappedArgumentsObject::class_;
-
-    Register scratchReg = R1.scratchReg();
-
-    // Guard on input being an arguments object.
-    masm.branchTestObject(Assembler::NotEqual, R0, &failure);
-    Register objReg = masm.extractObject(R0, ExtractTemp0);
-    masm.branchTestObjClass(Assembler::NotEqual, objReg, scratchReg, clasp, &failure);
-
-    // Get initial length value.
-    masm.unboxInt32(Address(objReg, ArgumentsObject::getInitialLengthSlotOffset()), scratchReg);
-
-    // Test if length has been overridden.
-    masm.branchTest32(Assembler::NonZero,
-                      scratchReg,
-                      Imm32(ArgumentsObject::LENGTH_OVERRIDDEN_BIT),
-                      &failure);
-
-    // Nope, shift out arguments length and return it.
-    // No need to type monitor because this stub always returns Int32.
-    masm.rshiftPtr(Imm32(ArgumentsObject::PACKED_BITS_COUNT), scratchReg);
-    masm.tagValue(JSVAL_TYPE_INT32, scratchReg, R0);
-    EmitReturnFromIC(masm);
-
-    masm.bind(&failure);
-    EmitStubGuardFailure(masm);
-    return true;
-}
-
-ICGetProp_ArgumentsCallee::ICGetProp_ArgumentsCallee(JitCode* stubCode, ICStub* firstMonitorStub)
-  : ICMonitoredStub(GetProp_ArgumentsCallee, stubCode, firstMonitorStub)
-{ }
-
-bool
-ICGetProp_ArgumentsCallee::Compiler::generateStubCode(MacroAssembler& masm)
-{
-    MOZ_ASSERT(engine_ == Engine::Baseline);
-
-    Label failure;
-
-    // Ensure that this is lazy arguments.
-    masm.branchTestMagicValue(Assembler::NotEqual, R0, JS_OPTIMIZED_ARGUMENTS, &failure);
-
-    // Ensure that frame has not loaded different arguments object since.
-    masm.branchTest32(Assembler::NonZero,
-                      Address(BaselineFrameReg, BaselineFrame::reverseOffsetOfFlags()),
-                      Imm32(BaselineFrame::HAS_ARGS_OBJ),
-                      &failure);
-
-    Address callee(BaselineFrameReg, BaselineFrame::offsetOfCalleeToken());
-    masm.loadFunctionFromCalleeToken(callee, R0.scratchReg());
-    masm.tagValue(JSVAL_TYPE_OBJECT, R0.scratchReg(), R0);
-
-    EmitEnterTypeMonitorIC(masm);
-
-    masm.bind(&failure);
-    EmitStubGuardFailure(masm);
-    return true;
-}
-
-/* static */ ICGetProp_Generic*
-ICGetProp_Generic::Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitorStub,
-                         ICGetProp_Generic& other)
-{
-    return New<ICGetProp_Generic>(cx, space, other.jitCode(), firstMonitorStub);
-}
-
-static bool
-DoGetPropGeneric(JSContext* cx, BaselineFrame* frame, ICGetProp_Generic* stub, MutableHandleValue val, MutableHandleValue res)
-{
-    jsbytecode* pc = stub->getChainFallback()->icEntry()->pc(frame->script());
-    JSOp op = JSOp(*pc);
-    RootedPropertyName name(cx, frame->script()->getName(pc));
-    return ComputeGetPropResult(cx, frame, op, name, val, res);
-}
-
-typedef bool (*DoGetPropGenericFn)(JSContext*, BaselineFrame*, ICGetProp_Generic*, MutableHandleValue, MutableHandleValue);
-static const VMFunction DoGetPropGenericInfo = FunctionInfo<DoGetPropGenericFn>(DoGetPropGeneric);
-
-bool
-ICGetProp_Generic::Compiler::generateStubCode(MacroAssembler& masm)
-{
-    MOZ_ASSERT(engine_ == Engine::Baseline);
-
-    AllocatableGeneralRegisterSet regs(availableGeneralRegs(1));
-
-    Register scratch = regs.takeAnyExcluding(ICTailCallReg);
-
-    // Sync for the decompiler.
-    EmitStowICValues(masm, 1);
-
-    enterStubFrame(masm, scratch);
-
-    // Push arguments.
-    masm.pushValue(R0);
-    masm.push(ICStubReg);
-    pushFramePtr(masm, R0.scratchReg());
-
-    if(!callVM(DoGetPropGenericInfo, masm))
-        return false;
-
-    leaveStubFrame(masm);
-    EmitUnstowICValues(masm, 1, /* discard = */ true);
-    EmitEnterTypeMonitorIC(masm);
-    return true;
-}
-
-bool
-ICGetProp_Unboxed::Compiler::generateStubCode(MacroAssembler& masm)
-{
-    MOZ_ASSERT(engine_ == Engine::Baseline);
-
-    Label failure;
-
-    AllocatableGeneralRegisterSet regs(availableGeneralRegs(1));
-
-    Register scratch = regs.takeAnyExcluding(ICTailCallReg);
-
-    // Object and group guard.
-    masm.branchTestObject(Assembler::NotEqual, R0, &failure);
-    Register object = masm.extractObject(R0, ExtractTemp0);
-    masm.loadPtr(Address(ICStubReg, ICGetProp_Unboxed::offsetOfGroup()), scratch);
-    masm.branchPtr(Assembler::NotEqual, Address(object, JSObject::offsetOfGroup()), scratch,
-                   &failure);
-
-    // Get the address being read from.
-    masm.load32(Address(ICStubReg, ICGetProp_Unboxed::offsetOfFieldOffset()), scratch);
-
-    masm.loadUnboxedProperty(BaseIndex(object, scratch, TimesOne), fieldType_, TypedOrValueRegister(R0));
-
-    // Only monitor the result if its type might change.
-    if (fieldType_ == JSVAL_TYPE_OBJECT)
-        EmitEnterTypeMonitorIC(masm);
-    else
-        EmitReturnFromIC(masm);
-
-    masm.bind(&failure);
-    EmitStubGuardFailure(masm);
-
-    return true;
-}
-
-bool
-ICGetProp_TypedObject::Compiler::generateStubCode(MacroAssembler& masm)
-{
-    MOZ_ASSERT(engine_ == Engine::Baseline);
-
-    Label failure;
-
-    CheckForNeuteredTypedObject(cx, masm, &failure);
-
-    AllocatableGeneralRegisterSet regs(availableGeneralRegs(1));
-
-    Register scratch1 = regs.takeAnyExcluding(ICTailCallReg);
-    Register scratch2 = regs.takeAnyExcluding(ICTailCallReg);
-
-    // Object and shape guard.
-    masm.branchTestObject(Assembler::NotEqual, R0, &failure);
-    Register object = masm.extractObject(R0, ExtractTemp0);
-    masm.loadPtr(Address(ICStubReg, ICGetProp_TypedObject::offsetOfShape()), scratch1);
-    masm.branchTestObjShape(Assembler::NotEqual, object, scratch1, &failure);
-
-    // Get the object's data pointer.
-    LoadTypedThingData(masm, layout_, object, scratch1);
-
-    // Get the address being written to.
-    masm.load32(Address(ICStubReg, ICGetProp_TypedObject::offsetOfFieldOffset()), scratch2);
-    masm.addPtr(scratch2, scratch1);
-
-    // Only monitor the result if the type produced by this stub might vary.
-    bool monitorLoad;
-
-    if (fieldDescr_->is<ScalarTypeDescr>()) {
-        Scalar::Type type = fieldDescr_->as<ScalarTypeDescr>().type();
-        monitorLoad = type == Scalar::Uint32;
-
-        masm.loadFromTypedArray(type, Address(scratch1, 0), R0, /* allowDouble = */ true,
-                                scratch2, nullptr);
-    } else {
-        ReferenceTypeDescr::Type type = fieldDescr_->as<ReferenceTypeDescr>().type();
-        monitorLoad = type != ReferenceTypeDescr::TYPE_STRING;
-
-        switch (type) {
-          case ReferenceTypeDescr::TYPE_ANY:
-            masm.loadValue(Address(scratch1, 0), R0);
-            break;
-
-          case ReferenceTypeDescr::TYPE_OBJECT: {
-            Label notNull, done;
-            masm.loadPtr(Address(scratch1, 0), scratch1);
-            masm.branchTestPtr(Assembler::NonZero, scratch1, scratch1, &notNull);
-            masm.moveValue(NullValue(), R0);
-            masm.jump(&done);
-            masm.bind(&notNull);
-            masm.tagValue(JSVAL_TYPE_OBJECT, scratch1, R0);
-            masm.bind(&done);
-            break;
-          }
-
-          case ReferenceTypeDescr::TYPE_STRING:
-            masm.loadPtr(Address(scratch1, 0), scratch1);
-            masm.tagValue(JSVAL_TYPE_STRING, scratch1, R0);
-            break;
-
-          default:
-            MOZ_CRASH();
-        }
-    }
-
-    if (monitorLoad)
-        EmitEnterTypeMonitorIC(masm);
-    else
-        EmitReturnFromIC(masm);
-
-    masm.bind(&failure);
-    EmitStubGuardFailure(masm);
-
-    return true;
-}
-
-void
-BaselineScript::noteAccessedGetter(uint32_t pcOffset)
-{
-    ICEntry& entry = icEntryFromPCOffset(pcOffset);
-    ICFallbackStub* stub = entry.fallbackStub();
-
-    if (stub->isGetProp_Fallback())
-        stub->toGetProp_Fallback()->noteAccessedGetter();
-}
-
-//
 // SetProp_Fallback
 //
 
 // Attach an optimized property set stub for a SETPROP/SETGNAME/SETNAME op on a
 // value property.
 static bool
 TryAttachSetValuePropStub(JSContext* cx, HandleScript script, jsbytecode* pc, ICSetProp_Fallback* stub,
                           HandleObject obj, HandleShape oldShape, HandleObjectGroup oldGroup,
@@ -11142,61 +8920,16 @@ ICGetName_Scope<NumHops>::ICGetName_Scop
 ICGetIntrinsic_Constant::ICGetIntrinsic_Constant(JitCode* stubCode, const Value& value)
   : ICStub(GetIntrinsic_Constant, stubCode),
     value_(value)
 { }
 
 ICGetIntrinsic_Constant::~ICGetIntrinsic_Constant()
 { }
 
-ICGetProp_Primitive::ICGetProp_Primitive(JitCode* stubCode, ICStub* firstMonitorStub,
-                                         JSValueType primitiveType, Shape* protoShape,
-                                         uint32_t offset)
-  : ICMonitoredStub(GetProp_Primitive, stubCode, firstMonitorStub),
-    protoShape_(protoShape),
-    offset_(offset)
-{
-    extra_ = uint16_t(primitiveType);
-    MOZ_ASSERT(JSValueType(extra_) == primitiveType);
-}
-
-ICGetPropNativeStub::ICGetPropNativeStub(ICStub::Kind kind, JitCode* stubCode,
-                                         ICStub* firstMonitorStub,
-                                         ReceiverGuard guard, uint32_t offset)
-  : ICMonitoredStub(kind, stubCode, firstMonitorStub),
-    receiverGuard_(guard),
-    offset_(offset)
-{ }
-
-/* static */ ICGetProp_Native*
-ICGetProp_Native::Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitorStub,
-                        ICGetProp_Native& other)
-{
-    return New<ICGetProp_Native>(cx, space, other.jitCode(), firstMonitorStub,
-                                 other.receiverGuard(), other.offset());
-}
-
-ICGetPropNativePrototypeStub::ICGetPropNativePrototypeStub(ICStub::Kind kind, JitCode* stubCode,
-                                                           ICStub* firstMonitorStub,
-                                                           ReceiverGuard guard, uint32_t offset,
-                                                           JSObject* holder, Shape* holderShape)
-  : ICGetPropNativeStub(kind, stubCode, firstMonitorStub, guard, offset),
-    holder_(holder),
-    holderShape_(holderShape)
-{ }
-
-/* static */ ICGetProp_NativePrototype*
-ICGetProp_NativePrototype::Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitorStub,
-                                 ICGetProp_NativePrototype& other)
-{
-    return New<ICGetProp_NativePrototype>(cx, space, other.jitCode(), firstMonitorStub,
-                                          other.receiverGuard(), other.offset(),
-                                          other.holder(), other.holderShape());
-}
-
 ICGetName_Global::ICGetName_Global(JitCode* stubCode, ICStub* firstMonitorStub,
                                    ReceiverGuard guard, uint32_t offset,
                                    JSObject* holder, Shape* holderShape, Shape* globalShape)
   : ICGetPropNativePrototypeStub(GetName_Global, stubCode, firstMonitorStub, guard, offset,
                                  holder, holderShape),
     globalShape_(globalShape)
 { }
 
@@ -11204,113 +8937,24 @@ ICGetName_Global::ICGetName_Global(JitCo
 ICGetName_Global::Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitorStub,
                         ICGetName_Global& other)
 {
     return New<ICGetName_Global>(cx, space, other.jitCode(), firstMonitorStub,
                                  other.receiverGuard(), other.offset(),
                                  other.holder(), other.holderShape(), other.globalShape());
 }
 
-ICGetProp_NativeDoesNotExist::ICGetProp_NativeDoesNotExist(
-    JitCode* stubCode, ICStub* firstMonitorStub, ReceiverGuard guard,
-    size_t protoChainDepth)
-  : ICMonitoredStub(GetProp_NativeDoesNotExist, stubCode, firstMonitorStub),
-    guard_(guard)
-{
-    MOZ_ASSERT(protoChainDepth <= MAX_PROTO_CHAIN_DEPTH);
-    extra_ = protoChainDepth;
-}
-
-/* static */ size_t
-ICGetProp_NativeDoesNotExist::offsetOfShape(size_t idx)
-{
-    MOZ_ASSERT(ICGetProp_NativeDoesNotExistImpl<0>::offsetOfShape(idx) ==
-               ICGetProp_NativeDoesNotExistImpl<
-                    ICGetProp_NativeDoesNotExist::MAX_PROTO_CHAIN_DEPTH>::offsetOfShape(idx));
-    return ICGetProp_NativeDoesNotExistImpl<0>::offsetOfShape(idx);
-}
-
-template <size_t ProtoChainDepth>
-ICGetProp_NativeDoesNotExistImpl<ProtoChainDepth>::ICGetProp_NativeDoesNotExistImpl(
-        JitCode* stubCode, ICStub* firstMonitorStub, ReceiverGuard guard,
-        Handle<ShapeVector> shapes)
-  : ICGetProp_NativeDoesNotExist(stubCode, firstMonitorStub, guard, ProtoChainDepth)
-{
-    MOZ_ASSERT(shapes.length() == NumShapes);
-
-    // Note: using int32_t here to avoid gcc warning.
-    for (int32_t i = 0; i < int32_t(NumShapes); i++)
-        shapes_[i].init(shapes[i]);
-}
-
-ICGetPropNativeDoesNotExistCompiler::ICGetPropNativeDoesNotExistCompiler(
-        JSContext* cx, ICStub* firstMonitorStub, HandleObject obj, size_t protoChainDepth)
-  : ICStubCompiler(cx, ICStub::GetProp_NativeDoesNotExist, Engine::Baseline),
-    firstMonitorStub_(firstMonitorStub),
-    obj_(cx, obj),
-    protoChainDepth_(protoChainDepth)
-{
-    MOZ_ASSERT(protoChainDepth_ <= ICGetProp_NativeDoesNotExist::MAX_PROTO_CHAIN_DEPTH);
-}
-
-ICGetPropCallGetter::ICGetPropCallGetter(Kind kind, JitCode* stubCode, ICStub* firstMonitorStub,
-                                         ReceiverGuard receiverGuard, JSObject* holder,
-                                         Shape* holderShape, JSFunction* getter,
-                                         uint32_t pcOffset)
-  : ICMonitoredStub(kind, stubCode, firstMonitorStub),
-    receiverGuard_(receiverGuard),
-    holder_(holder),
-    holderShape_(holderShape),
-    getter_(getter),
-    pcOffset_(pcOffset)
-{
-    MOZ_ASSERT(kind == ICStub::GetProp_CallScripted  ||
-               kind == ICStub::GetProp_CallNative    ||
-               kind == ICStub::GetProp_CallNativeGlobal ||
-               kind == ICStub::GetProp_CallDOMProxyNative ||
-               kind == ICStub::GetProp_CallDOMProxyWithGenerationNative);
-}
-
 ICInstanceOf_Function::ICInstanceOf_Function(JitCode* stubCode, Shape* shape,
                                              JSObject* prototypeObj, uint32_t slot)
   : ICStub(InstanceOf_Function, stubCode),
     shape_(shape),
     prototypeObj_(prototypeObj),
     slot_(slot)
 { }
 
-/* static */ ICGetProp_CallScripted*
-ICGetProp_CallScripted::Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitorStub,
-                              ICGetProp_CallScripted& other)
-{
-    return New<ICGetProp_CallScripted>(cx, space, other.jitCode(), firstMonitorStub,
-                                       other.receiverGuard(),
-                                       other.holder_, other.holderShape_,
-                                       other.getter_, other.pcOffset_);
-}
-
-/* static */ ICGetProp_CallNative*
-ICGetProp_CallNative::Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitorStub,
-                            ICGetProp_CallNative& other)
-{
-    return New<ICGetProp_CallNative>(cx, space, other.jitCode(), firstMonitorStub,
-                                     other.receiverGuard(), other.holder_,
-                                     other.holderShape_, other.getter_, other.pcOffset_);
-}
-
-/* static */ ICGetProp_CallNativeGlobal*
-ICGetProp_CallNativeGlobal::Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitorStub,
-                            ICGetProp_CallNativeGlobal& other)
-{
-    return New<ICGetProp_CallNativeGlobal>(cx, space, other.jitCode(), firstMonitorStub,
-                                           other.receiverGuard(), other.holder_,
-                                           other.holderShape_, other.globalShape_,
-                                           other.getter_, other.pcOffset_);
-}
-
 ICSetProp_Native::ICSetProp_Native(JitCode* stubCode, ObjectGroup* group, Shape* shape,
                                    uint32_t offset)
   : ICUpdatedStub(SetProp_Native, stubCode),
     group_(group),
     shape_(shape),
     offset_(offset)
 { }
 
@@ -11503,96 +9147,16 @@ ICCall_ScriptedApplyArguments::Clone(JSC
 /* static */ ICCall_ScriptedFunCall*
 ICCall_ScriptedFunCall::Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitorStub,
                               ICCall_ScriptedFunCall& other)
 {
     return New<ICCall_ScriptedFunCall>(cx, space, other.jitCode(), firstMonitorStub,
                                        other.pcOffset_);
 }
 
-ICGetPropCallDOMProxyNativeStub::ICGetPropCallDOMProxyNativeStub(Kind kind, JitCode* stubCode,
-                                                                 ICStub* firstMonitorStub,
-                                                                 Shape* shape,
-                                                                 Shape* expandoShape,
-                                                                 JSObject* holder,
-                                                                 Shape* holderShape,
-                                                                 JSFunction* getter,
-                                                                 uint32_t pcOffset)
-  : ICGetPropCallGetter(kind, stubCode, firstMonitorStub, ReceiverGuard(nullptr, shape),
-                        holder, holderShape, getter, pcOffset),
-    expandoShape_(expandoShape)
-{ }
-
-ICGetPropCallDOMProxyNativeCompiler::ICGetPropCallDOMProxyNativeCompiler(JSContext* cx,
-                                                                         ICStub::Kind kind,
-                                                                         ICStub* firstMonitorStub,
-                                                                         Handle<ProxyObject*> proxy,
-                                                                         HandleObject holder,
-                                                                         HandleFunction getter,
-                                                                         uint32_t pcOffset)
-  : ICStubCompiler(cx, kind, Engine::Baseline),
-    firstMonitorStub_(firstMonitorStub),
-    proxy_(cx, proxy),
-    holder_(cx, holder),
-    getter_(cx, getter),
-    pcOffset_(pcOffset)
-{
-    MOZ_ASSERT(kind == ICStub::GetProp_CallDOMProxyNative ||
-               kind == ICStub::GetProp_CallDOMProxyWithGenerationNative);
-    MOZ_ASSERT(proxy_->handler()->family() == GetDOMProxyHandlerFamily());
-}
-
-/* static */ ICGetProp_CallDOMProxyNative*
-ICGetProp_CallDOMProxyNative::Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitorStub,
-                                    ICGetProp_CallDOMProxyNative& other)
-{
-    return New<ICGetProp_CallDOMProxyNative>(cx, space, other.jitCode(), firstMonitorStub,
-                                             other.receiverGuard_.shape(), other.expandoShape_,
-                                             other.holder_, other.holderShape_, other.getter_,
-                                             other.pcOffset_);
-}
-
-/* static */ ICGetProp_CallDOMProxyWithGenerationNative*
-ICGetProp_CallDOMProxyWithGenerationNative::Clone(JSContext* cx,
-                                                  ICStubSpace* space,
-                                                  ICStub* firstMonitorStub,
-                                                  ICGetProp_CallDOMProxyWithGenerationNative& other)
-{
-    return New<ICGetProp_CallDOMProxyWithGenerationNative>(cx, space, other.jitCode(),
-                                                           firstMonitorStub,
-                                                           other.receiverGuard_.shape(),
-                                                           other.expandoAndGeneration_,
-                                                           other.generation_,
-                                                           other.expandoShape_, other.holder_,
-                                                           other.holderShape_, other.getter_,
-                                                           other.pcOffset_);
-}
-
-ICGetProp_DOMProxyShadowed::ICGetProp_DOMProxyShadowed(JitCode* stubCode,
-                                                       ICStub* firstMonitorStub,
-                                                       Shape* shape,
-                                                       const BaseProxyHandler* proxyHandler,
-                                                       PropertyName* name,
-                                                       uint32_t pcOffset)
-  : ICMonitoredStub(ICStub::GetProp_DOMProxyShadowed, stubCode, firstMonitorStub),
-    shape_(shape),
-    proxyHandler_(proxyHandler),
-    name_(name),
-    pcOffset_(pcOffset)
-{ }
-
-/* static */ ICGetProp_DOMProxyShadowed*
-ICGetProp_DOMProxyShadowed::Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitorStub,
-                                  ICGetProp_DOMProxyShadowed& other)
-{
-    return New<ICGetProp_DOMProxyShadowed>(cx, space, other.jitCode(), firstMonitorStub,
-                                           other.shape_, other.proxyHandler_, other.name_,
-                                           other.pcOffset_);
-}
-
 //
 // Rest_Fallback
 //
 
 static bool DoRestFallback(JSContext* cx, BaselineFrame* frame, ICRest_Fallback* stub,
                            MutableHandleValue res)
 {
     unsigned numFormals = frame->numFormalArgs() - 1;
--- a/js/src/jit/BaselineIC.h
+++ b/js/src/jit/BaselineIC.h
@@ -16,18 +16,16 @@
 
 #include "builtin/TypedObject.h"
 #include "jit/BaselineICList.h"
 #include "jit/BaselineJIT.h"
 #include "jit/SharedIC.h"
 #include "jit/SharedICRegisters.h"
 #include "js/TraceableVector.h"
 #include "vm/ArrayObject.h"
-#include "vm/ReceiverGuard.h"
-#include "vm/TypedArrayCommon.h"
 #include "vm/UnboxedObject.h"
 
 namespace js {
 namespace jit {
 
 // WarmUpCounter_Fallback
 
 // A WarmUpCounter IC chain has only the fallback stub.
@@ -1401,35 +1399,16 @@ class ICGetElem_UnboxedArray : public IC
         {}
 
         ICStub* getStub(ICStubSpace* space) {
             return newStub<ICGetElem_UnboxedArray>(space, getStubCode(), firstMonitorStub_, group_);
         }
     };
 };
 
-// Enum for stubs handling a combination of typed arrays and typed objects.
-enum TypedThingLayout {
-    Layout_TypedArray,
-    Layout_OutlineTypedObject,
-    Layout_InlineTypedObject
-};
-
-static inline TypedThingLayout
-GetTypedThingLayout(const Class* clasp)
-{
-    if (IsAnyTypedArrayClass(clasp))
-        return Layout_TypedArray;
-    if (IsOutlineTypedObjectClass(clasp))
-        return Layout_OutlineTypedObject;
-    if (IsInlineTypedObjectClass(clasp))
-        return Layout_InlineTypedObject;
-    MOZ_CRASH("Bad object class");
-}
-
 // Accesses scalar elements of a typed array or typed object.
 class ICGetElem_TypedArray : public ICStub
 {
     friend class ICStubSpace;
 
   protected: // Protected to silence Clang warning.
     HeapPtrShape shape_;
 
@@ -2266,1072 +2245,16 @@ class ICGetIntrinsic_Constant : public I
         {}
 
         ICStub* getStub(ICStubSpace* space) {
             return newStub<ICGetIntrinsic_Constant>(space, getStubCode(), value_);
         }
     };
 };
 
-class ICGetProp_Fallback : public ICMonitoredFallbackStub
-{
-    friend class ICStubSpace;
-
-    explicit ICGetProp_Fallback(JitCode* stubCode)
-      : ICMonitoredFallbackStub(ICStub::GetProp_Fallback, stubCode)
-    { }
-
-  public:
-    static const uint32_t MAX_OPTIMIZED_STUBS = 16;
-    static const size_t UNOPTIMIZABLE_ACCESS_BIT = 0;
-    static const size_t ACCESSED_GETTER_BIT = 1;
-
-    void noteUnoptimizableAccess() {
-        extra_ |= (1u << UNOPTIMIZABLE_ACCESS_BIT);
-    }
-    bool hadUnoptimizableAccess() const {
-        return extra_ & (1u << UNOPTIMIZABLE_ACCESS_BIT);
-    }
-
-    void noteAccessedGetter() {
-        extra_ |= (1u << ACCESSED_GETTER_BIT);
-    }
-    bool hasAccessedGetter() const {
-        return extra_ & (1u << ACCESSED_GETTER_BIT);
-    }
-
-    class Compiler : public ICStubCompiler {
-      public:
-        static const int32_t BASELINE_KEY =
-            (static_cast<int32_t>(Engine::Baseline)) |
-            (static_cast<int32_t>(ICStub::GetProp_Fallback) << 1);
-
-      protected:
-        uint32_t returnOffset_;
-        bool generateStubCode(MacroAssembler& masm);
-        void postGenerateStubCode(MacroAssembler& masm, Handle<JitCode*> code);
-
-      public:
-        explicit Compiler(JSContext* cx)
-          : ICStubCompiler(cx, ICStub::GetProp_Fallback, Engine::Baseline)
-        { }
-
-        ICStub* getStub(ICStubSpace* space) {
-            ICGetProp_Fallback* stub = newStub<ICGetProp_Fallback>(space, getStubCode());
-            if (!stub || !stub->initMonitoringChain(cx, space))
-                return nullptr;
-            return stub;
-        }
-    };
-};
-
-// Stub for sites, which are too polymorphic (i.e. MAX_OPTIMIZED_STUBS was reached)
-class ICGetProp_Generic : public ICMonitoredStub
-{
-    friend class ICStubSpace;
-
-  protected:
-    explicit ICGetProp_Generic(JitCode* stubCode, ICStub* firstMonitorStub)
-      : ICMonitoredStub(ICStub::GetProp_Generic, stubCode, firstMonitorStub) {}
-
-  public:
-    static ICGetProp_Generic* Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitorStub,
-                                    ICGetProp_Generic& other);
-
-    class Compiler : public ICStubCompiler {
-      protected:
-        bool generateStubCode(MacroAssembler& masm);
-        ICStub* firstMonitorStub_;
-      public:
-        explicit Compiler(JSContext* cx, ICStub* firstMonitorStub)
-          : ICStubCompiler(cx, ICStub::GetProp_Generic, Engine::Baseline),
-            firstMonitorStub_(firstMonitorStub)
-        {}
-
-        ICStub* getStub(ICStubSpace* space) {
-            return newStub<ICGetProp_Generic>(space, getStubCode(), firstMonitorStub_);
-        }
-    };
-};
-
-// Stub for accessing a dense array's length.
-class ICGetProp_ArrayLength : public ICStub
-{
-    friend class ICStubSpace;
-
-    explicit ICGetProp_ArrayLength(JitCode* stubCode)
-      : ICStub(GetProp_ArrayLength, stubCode)
-    {}
-
-  public:
-    class Compiler : public ICStubCompiler {
-        bool generateStubCode(MacroAssembler& masm);
-
-      public:
-        explicit Compiler(JSContext* cx)
-          : ICStubCompiler(cx, ICStub::GetProp_ArrayLength, Engine::Baseline)
-        {}
-
-        ICStub* getStub(ICStubSpace* space) {
-            return newStub<ICGetProp_ArrayLength>(space, getStubCode());
-        }
-    };
-};
-
-// Stub for accessing an unboxed array's length.
-class ICGetProp_UnboxedArrayLength : public ICStub
-{
-    friend class ICStubSpace;
-
-    explicit ICGetProp_UnboxedArrayLength(JitCode* stubCode)
-      : ICStub(GetProp_UnboxedArrayLength, stubCode)
-    {}
-
-  public:
-    class Compiler : public ICStubCompiler {
-        bool generateStubCode(MacroAssembler& masm);
-
-      public:
-        explicit Compiler(JSContext* cx)
-          : ICStubCompiler(cx, ICStub::GetProp_UnboxedArrayLength, Engine::Baseline)
-        {}
-
-        ICStub* getStub(ICStubSpace* space) {
-            return newStub<ICGetProp_UnboxedArrayLength>(space, getStubCode());
-        }
-    };
-};
-
-// Stub for accessing a property on a primitive's prototype.
-class ICGetProp_Primitive : public ICMonitoredStub
-{
-    friend class ICStubSpace;
-
-  protected: // Protected to silence Clang warning.
-    // Shape of String.prototype/Number.prototype to check for.
-    HeapPtrShape protoShape_;
-
-    // Fixed or dynamic slot offset.
-    uint32_t offset_;
-
-    ICGetProp_Primitive(JitCode* stubCode, ICStub* firstMonitorStub, JSValueType primitiveType,
-                        Shape* protoShape, uint32_t offset);
-
-  public:
-    HeapPtrShape& protoShape() {
-        return protoShape_;
-    }
-    JSValueType primitiveType() const {
-        return JSValueType(extra_);
-    }
-
-    static size_t offsetOfProtoShape() {
-        return offsetof(ICGetProp_Primitive, protoShape_);
-    }
-
-    static size_t offsetOfOffset() {
-        return offsetof(ICGetProp_Primitive, offset_);
-    }
-
-    class Compiler : public ICStubCompiler {
-        ICStub* firstMonitorStub_;
-        JSValueType primitiveType_;
-        RootedObject prototype_;
-        bool isFixedSlot_;
-        uint32_t offset_;
-
-        bool generateStubCode(MacroAssembler& masm);
-
-      protected:
-        virtual int32_t getKey() const {
-            static_assert(sizeof(JSValueType) == 1, "JSValueType should fit in one byte");
-            return static_cast<int32_t>(engine_) |
-                  (static_cast<int32_t>(kind) << 1) |
-                  (static_cast<int32_t>(isFixedSlot_) << 17) |
-                  (static_cast<int32_t>(primitiveType_) << 25);
-        }
-
-      public:
-        Compiler(JSContext* cx, ICStub* firstMonitorStub, JSValueType primitiveType,
-                 HandleObject prototype, bool isFixedSlot, uint32_t offset)
-          : ICStubCompiler(cx, ICStub::GetProp_Primitive, Engine::Baseline),
-            firstMonitorStub_(firstMonitorStub),
-            primitiveType_(primitiveType),
-            prototype_(cx, prototype),
-            isFixedSlot_(isFixedSlot),
-            offset_(offset)
-        {}
-
-        ICStub* getStub(ICStubSpace* space) {
-            RootedShape protoShape(cx, prototype_->as<NativeObject>().lastProperty());
-            return newStub<ICGetProp_Primitive>(space, getStubCode(), firstMonitorStub_,
-                                                primitiveType_, protoShape, offset_);
-        }
-    };
-};
-
-// Stub for accessing a string's length.
-class ICGetProp_StringLength : public ICStub
-{
-    friend class ICStubSpace;
-
-    explicit ICGetProp_StringLength(JitCode* stubCode)
-      : ICStub(GetProp_StringLength, stubCode)
-    {}
-
-  public:
-    class Compiler : public ICStubCompiler {
-        bool generateStubCode(MacroAssembler& masm);
-
-      public:
-        explicit Compiler(JSContext* cx)
-          : ICStubCompiler(cx, ICStub::GetProp_StringLength, Engine::Baseline)
-        {}
-
-        ICStub* getStub(ICStubSpace* space) {
-            return newStub<ICGetProp_StringLength>(space, getStubCode());
-        }
-    };
-};
-
-// Base class for native GetProp stubs.
-class ICGetPropNativeStub : public ICMonitoredStub
-{
-    // Object shape/group.
-    HeapReceiverGuard receiverGuard_;
-
-    // Fixed or dynamic slot offset.
-    uint32_t offset_;
-
-  protected:
-    ICGetPropNativeStub(ICStub::Kind kind, JitCode* stubCode, ICStub* firstMonitorStub,
-                        ReceiverGuard guard, uint32_t offset);
-
-  public:
-    HeapReceiverGuard& receiverGuard() {
-        return receiverGuard_;
-    }
-    uint32_t offset() const {
-        return offset_;
-    }
-
-    void notePreliminaryObject() {
-        extra_ = 1;
-    }
-    bool hasPreliminaryObject() const {
-        return extra_;
-    }
-
-    static size_t offsetOfReceiverGuard() {
-        return offsetof(ICGetPropNativeStub, receiverGuard_);
-    }
-    static size_t offsetOfOffset() {
-        return offsetof(ICGetPropNativeStub, offset_);
-    }
-};
-
-// Stub for accessing an own property on a native object.
-class ICGetProp_Native : public ICGetPropNativeStub
-{
-    friend class ICStubSpace;
-
-    ICGetProp_Native(JitCode* stubCode, ICStub* firstMonitorStub, ReceiverGuard guard,
-                     uint32_t offset)
-      : ICGetPropNativeStub(GetProp_Native, stubCode, firstMonitorStub, guard, offset)
-    {}
-
-  public:
-    static ICGetProp_Native* Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitorStub,
-                                   ICGetProp_Native& other);
-};
-
-class ICGetPropNativePrototypeStub : public ICGetPropNativeStub
-{
-    // Holder and its shape.
-    HeapPtrObject holder_;
-    HeapPtrShape holderShape_;
-
-  protected:
-    ICGetPropNativePrototypeStub(ICStub::Kind kind, JitCode* stubCode, ICStub* firstMonitorStub,
-                                 ReceiverGuard guard, uint32_t offset, JSObject* holder,
-                                 Shape* holderShape);
-
-  public:
-    HeapPtrObject& holder() {
-        return holder_;
-    }
-    HeapPtrShape& holderShape() {
-        return holderShape_;
-    }
-    static size_t offsetOfHolder() {
-        return offsetof(ICGetPropNativePrototypeStub, holder_);
-    }
-    static size_t offsetOfHolderShape() {
-        return offsetof(ICGetPropNativePrototypeStub, holderShape_);
-    }
-};
-
-// Stub for accessing a property on the native prototype of a native or unboxed
-// object. Note that due to the shape teleporting optimization, we only have to
-// guard on the object's shape/group and the holder's shape.
-class ICGetProp_NativePrototype : public ICGetPropNativePrototypeStub
-{
-    friend class ICStubSpace;
-
-  protected:
-    ICGetProp_NativePrototype(JitCode* stubCode, ICStub* firstMonitorStub, ReceiverGuard guard,
-                              uint32_t offset, JSObject* holder, Shape* holderShape)
-      : ICGetPropNativePrototypeStub(GetProp_NativePrototype, stubCode, firstMonitorStub, guard,
-                                     offset, holder, holderShape)
-    { }
-
-  public:
-    static ICGetProp_NativePrototype* Clone(JSContext* cx,
-                                            ICStubSpace* space,
-                                            ICStub* firstMonitorStub,
-                                            ICGetProp_NativePrototype& other);
-};
-
-// Stub for accessing a non-lexical global name. Semantically, it is really a
-// getprop: the name is either on the GlobalObject or its prototype chain. We
-// teleport to the object that has the name, but we also need to guard on the
-// shape of the global object.
-//
-// The receiver object is the global lexical scope.
-class ICGetName_Global : public ICGetPropNativePrototypeStub
-{
-    friend class ICStubSpace;
-
-  protected:
-    HeapPtrShape globalShape_;
-
-    ICGetName_Global(JitCode* stubCode, ICStub* firstMonitorStub, ReceiverGuard guard,
-                     uint32_t slot, JSObject* holder, Shape* holderShape, Shape* globalShape);
-
-  public:
-    static ICGetName_Global* Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitorStub,
-                                   ICGetName_Global& other);
-
-    HeapPtrShape& globalShape() {
-        return globalShape_;
-    }
-    static size_t offsetOfGlobalShape() {
-        return offsetof(ICGetName_Global, globalShape_);
-    }
-};
-
-// Compiler for native GetProp stubs.
-class ICGetPropNativeCompiler : public ICStubCompiler
-{
-    ICStub* firstMonitorStub_;
-    HandleObject obj_;
-    HandleObject holder_;
-    HandlePropertyName propName_;
-    bool isFixedSlot_;
-    uint32_t offset_;
-    bool inputDefinitelyObject_;
-
-    bool generateStubCode(MacroAssembler& masm);
-
-  protected:
-    virtual int32_t getKey() const {
-        return static_cast<int32_t>(engine_) |
-              (static_cast<int32_t>(kind) << 1) |
-              (static_cast<int32_t>(isFixedSlot_) << 17) |
-              (static_cast<int32_t>(inputDefinitelyObject_) << 18) |
-              (HeapReceiverGuard::keyBits(obj_) << 19);
-    }
-
-  public:
-    ICGetPropNativeCompiler(JSContext* cx, ICStub::Kind kind,
-                            ICStub* firstMonitorStub, HandleObject obj, HandleObject holder,
-                            HandlePropertyName propName, bool isFixedSlot, uint32_t offset,
-                            bool inputDefinitelyObject = false)
-      : ICStubCompiler(cx, kind, Engine::Baseline),
-        firstMonitorStub_(firstMonitorStub),
-        obj_(obj),
-        holder_(holder),
-        propName_(propName),
-        isFixedSlot_(isFixedSlot),
-        offset_(offset),
-        inputDefinitelyObject_(inputDefinitelyObject)
-    {}
-
-    ICGetPropNativeStub* getStub(ICStubSpace* space);
-};
-
-template <size_t ProtoChainDepth> class ICGetProp_NativeDoesNotExistImpl;
-
-class ICGetProp_NativeDoesNotExist : public ICMonitoredStub
-{
-    friend class ICStubSpace;
-  public:
-    HeapReceiverGuard guard_;
-
-    static const size_t MAX_PROTO_CHAIN_DEPTH = 8;
-
-  protected:
-    ICGetProp_NativeDoesNotExist(JitCode* stubCode, ICStub* firstMonitorStub,
-                                 ReceiverGuard guard,
-                                 size_t protoChainDepth);
-
-  public:
-    size_t protoChainDepth() const {
-        MOZ_ASSERT(extra_ <= MAX_PROTO_CHAIN_DEPTH);
-        return extra_;
-    }
-
-    template <size_t ProtoChainDepth>
-    ICGetProp_NativeDoesNotExistImpl<ProtoChainDepth>* toImpl() {
-        MOZ_ASSERT(ProtoChainDepth == protoChainDepth());
-        return static_cast<ICGetProp_NativeDoesNotExistImpl<ProtoChainDepth>*>(this);
-    }
-
-    HeapReceiverGuard& guard() {
-        return guard_;
-    }
-
-    static size_t offsetOfGuard() {
-        return offsetof(ICGetProp_NativeDoesNotExist, guard_);
-    }
-
-    static size_t offsetOfShape(size_t idx);
-};
-
-template <size_t ProtoChainDepth>
-class ICGetProp_NativeDoesNotExistImpl : public ICGetProp_NativeDoesNotExist
-{
-    friend class ICStubSpace;
-  public:
-    static const size_t MAX_PROTO_CHAIN_DEPTH = 8;
-    static const size_t NumShapes = ProtoChainDepth;
-
-  private:
-    mozilla::Array<HeapPtrShape, NumShapes> shapes_;
-
-    ICGetProp_NativeDoesNotExistImpl(JitCode* stubCode, ICStub* firstMonitorStub,
-                                     ReceiverGuard guard,
-                                     Handle<ShapeVector> shapes);
-
-  public:
-    void traceShapes(JSTracer* trc) {
-        // Note: using int32_t here to avoid gcc warning.
-        for (int32_t i = 0; i < int32_t(NumShapes); i++)
-            TraceEdge(trc, &shapes_[i], "baseline-getpropnativedoesnotexist-stub-shape");
-    }
-
-    static size_t offsetOfShape(size_t idx) {
-        return offsetof(ICGetProp_NativeDoesNotExistImpl, shapes_) + (idx * sizeof(HeapPtrShape));
-    }
-};
-
-class ICGetPropNativeDoesNotExistCompiler : public ICStubCompiler
-{
-    ICStub* firstMonitorStub_;
-    RootedObject obj_;
-    size_t protoChainDepth_;
-
-  protected:
-    virtual int32_t getKey() const {
-        return static_cast<int32_t>(engine_) |
-              (static_cast<int32_t>(kind) << 1) |
-              (HeapReceiverGuard::keyBits(obj_) << 17) |
-              (static_cast<int32_t>(protoChainDepth_) << 19);
-    }
-
-    bool generateStubCode(MacroAssembler& masm);
-
-  public:
-    ICGetPropNativeDoesNotExistCompiler(JSContext* cx, ICStub* firstMonitorStub,
-                                        HandleObject obj, size_t protoChainDepth);
-
-    template <size_t ProtoChainDepth>
-    ICStub* getStubSpecific(ICStubSpace* space, Handle<ShapeVector> shapes) {
-        ReceiverGuard guard(obj_);
-        return newStub<ICGetProp_NativeDoesNotExistImpl<ProtoChainDepth>>
-            (space, getStubCode(), firstMonitorStub_, guard, shapes);
-    }
-
-    ICStub* getStub(ICStubSpace* space);
-};
-
-class ICGetProp_Unboxed : public ICMonitoredStub
-{
-    friend class ICStubSpace;
-
-    HeapPtrObjectGroup group_;
-    uint32_t fieldOffset_;
-
-    ICGetProp_Unboxed(JitCode* stubCode, ICStub* firstMonitorStub, ObjectGroup* group,
-                      uint32_t fieldOffset)
-      : ICMonitoredStub(ICStub::GetProp_Unboxed, stubCode, firstMonitorStub),
-        group_(group), fieldOffset_(fieldOffset)
-    {
-        (void) fieldOffset_; // Silence clang warning
-    }
-
-  public:
-    HeapPtrObjectGroup& group() {
-        return group_;
-    }
-
-    static size_t offsetOfGroup() {
-        return offsetof(ICGetProp_Unboxed, group_);
-    }
-    static size_t offsetOfFieldOffset() {
-        return offsetof(ICGetProp_Unboxed, fieldOffset_);
-    }
-
-    class Compiler : public ICStubCompiler {
-      protected:
-        ICStub* firstMonitorStub_;
-        RootedObjectGroup group_;
-        uint32_t fieldOffset_;
-        JSValueType fieldType_;
-
-        bool generateStubCode(MacroAssembler& masm);
-
-        virtual int32_t getKey() const {
-            return static_cast<int32_t>(engine_) |
-                  (static_cast<int32_t>(kind) << 1) |
-                  (static_cast<int32_t>(fieldType_) << 17);
-        }
-
-      public:
-        Compiler(JSContext* cx, ICStub* firstMonitorStub,
-                 ObjectGroup* group, uint32_t fieldOffset, JSValueType fieldType)
-          : ICStubCompiler(cx, ICStub::GetProp_Unboxed, Engine::Baseline),
-            firstMonitorStub_(firstMonitorStub),
-            group_(cx, group),
-            fieldOffset_(fieldOffset),
-            fieldType_(fieldType)
-        {}
-
-        ICStub* getStub(ICStubSpace* space) {
-            return newStub<ICGetProp_Unboxed>(space, getStubCode(), firstMonitorStub_, group_,
-                                              fieldOffset_);
-        }
-    };
-};
-
-static uint32_t
-SimpleTypeDescrKey(SimpleTypeDescr* descr)
-{
-    if (descr->is<ScalarTypeDescr>())
-        return uint32_t(descr->as<ScalarTypeDescr>().type()) << 1;
-    return (uint32_t(descr->as<ReferenceTypeDescr>().type()) << 1) | 1;
-}
-
-class ICGetProp_TypedObject : public ICMonitoredStub
-{
-    friend class ICStubSpace;
-
-    HeapPtrShape shape_;
-    uint32_t fieldOffset_;
-
-    ICGetProp_TypedObject(JitCode* stubCode, ICStub* firstMonitorStub, Shape* shape,
-                          uint32_t fieldOffset)
-      : ICMonitoredStub(ICStub::GetProp_TypedObject, stubCode, firstMonitorStub),
-        shape_(shape), fieldOffset_(fieldOffset)
-    {
-        (void) fieldOffset_; // Silence clang warning
-    }
-
-  public:
-    HeapPtrShape& shape() {
-        return shape_;
-    }
-
-    static size_t offsetOfShape() {
-        return offsetof(ICGetProp_TypedObject, shape_);
-    }
-    static size_t offsetOfFieldOffset() {
-        return offsetof(ICGetProp_TypedObject, fieldOffset_);
-    }
-
-    class Compiler : public ICStubCompiler {
-      protected:
-        ICStub* firstMonitorStub_;
-        RootedShape shape_;
-        uint32_t fieldOffset_;
-        TypedThingLayout layout_;
-        Rooted<SimpleTypeDescr*> fieldDescr_;
-
-        bool generateStubCode(MacroAssembler& masm);
-
-        virtual int32_t getKey() const {
-            return static_cast<int32_t>(engine_) |
-                  (static_cast<int32_t>(kind) << 1) |
-                  (static_cast<int32_t>(SimpleTypeDescrKey(fieldDescr_)) << 17) |
-                  (static_cast<int32_t>(layout_) << 25);
-        }
-
-      public:
-        Compiler(JSContext* cx, ICStub* firstMonitorStub,
-                 Shape* shape, uint32_t fieldOffset, SimpleTypeDescr* fieldDescr)
-          : ICStubCompiler(cx, ICStub::GetProp_TypedObject, Engine::Baseline),
-            firstMonitorStub_(firstMonitorStub),
-            shape_(cx, shape),
-            fieldOffset_(fieldOffset),
-            layout_(GetTypedThingLayout(shape->getObjectClass())),
-            fieldDescr_(cx, fieldDescr)
-        {}
-
-        ICStub* getStub(ICStubSpace* space) {
-            return newStub<ICGetProp_TypedObject>(space, getStubCode(), firstMonitorStub_, shape_,
-                                                  fieldOffset_);
-        }
-    };
-};
-
-class ICGetPropCallGetter : public ICMonitoredStub
-{
-    friend class ICStubSpace;
-
-  protected:
-    // Shape/group of receiver object. Used for both own and proto getters.
-    // In the GetPropCallDOMProxyNative case, the receiver guard enforces
-    // the proxy handler, because Shape implies Class.
-    HeapReceiverGuard receiverGuard_;
-
-    // Holder and holder shape. For own getters, guarding on receiverGuard_ is
-    // sufficient, although Ion may use holder_ and holderShape_ even for own
-    // getters. In this case holderShape_ == receiverGuard_.shape_ (isOwnGetter
-    // below relies on this).
-    HeapPtrObject holder_;
-
-    HeapPtrShape holderShape_;
-
-    // Function to call.
-    HeapPtrFunction getter_;
-
-    // PC offset of call
-    uint32_t pcOffset_;
-
-    ICGetPropCallGetter(Kind kind, JitCode* stubCode, ICStub* firstMonitorStub,
-                        ReceiverGuard receiverGuard, JSObject* holder,
-                        Shape* holderShape, JSFunction* getter, uint32_t pcOffset);
-
-  public:
-    HeapPtrObject& holder() {
-        return holder_;
-    }
-    HeapPtrShape& holderShape() {
-        return holderShape_;
-    }
-    HeapPtrFunction& getter() {
-        return getter_;
-    }
-    HeapReceiverGuard& receiverGuard() {
-        return receiverGuard_;
-    }
-
-    bool isOwnGetter() const {
-        MOZ_ASSERT(holder_->isNative());
-        MOZ_ASSERT(holderShape_);
-        return receiverGuard_.shape() == holderShape_;
-    }
-
-    static size_t offsetOfHolder() {
-        return offsetof(ICGetPropCallGetter, holder_);
-    }
-    static size_t offsetOfHolderShape() {
-        return offsetof(ICGetPropCallGetter, holderShape_);
-    }
-    static size_t offsetOfGetter() {
-        return offsetof(ICGetPropCallGetter, getter_);
-    }
-    static size_t offsetOfPCOffset() {
-        return offsetof(ICGetPropCallGetter, pcOffset_);
-    }
-    static size_t offsetOfReceiverGuard() {
-        return offsetof(ICGetPropCallGetter, receiverGuard_);
-    }
-
-    class Compiler : public ICStubCompiler {
-      protected:
-        ICStub* firstMonitorStub_;
-        RootedObject receiver_;
-        RootedObject holder_;
-        RootedFunction getter_;
-        uint32_t pcOffset_;
-        const Class* outerClass_;
-
-        virtual int32_t getKey() const {
-            // ICGetPropCallNativeCompiler::getKey adds more bits to our
-            // return value, so be careful when making changes here.
-            return static_cast<int32_t>(engine_) |
-                  (static_cast<int32_t>(kind) << 1) |
-                  (HeapReceiverGuard::keyBits(receiver_) << 17) |
-                  (static_cast<int32_t>(!!outerClass_) << 19) |
-                  (static_cast<int32_t>(receiver_ != holder_) << 20);
-        }
-
-      public:
-        Compiler(JSContext* cx, ICStub::Kind kind, ICStub* firstMonitorStub,
-                 HandleObject receiver, HandleObject holder, HandleFunction getter,
-                 uint32_t pcOffset, const Class* outerClass)
-          : ICStubCompiler(cx, kind, Engine::Baseline),
-            firstMonitorStub_(firstMonitorStub),
-            receiver_(cx, receiver),
-            holder_(cx, holder),
-            getter_(cx, getter),
-            pcOffset_(pcOffset),
-            outerClass_(outerClass)
-        {
-            MOZ_ASSERT(kind == ICStub::GetProp_CallScripted ||
-                       kind == ICStub::GetProp_CallNative ||
-                       kind == ICStub::GetProp_CallNativeGlobal);
-        }
-    };
-};
-
-// Stub for calling a scripted getter on a native object when the getter is kept on the
-// proto-chain.
-class ICGetProp_CallScripted : public ICGetPropCallGetter
-{
-    friend class ICStubSpace;
-
-  protected:
-    ICGetProp_CallScripted(JitCode* stubCode, ICStub* firstMonitorStub,
-                           ReceiverGuard receiverGuard,
-                           JSObject* holder, Shape* holderShape,
-                           JSFunction* getter, uint32_t pcOffset)
-      : ICGetPropCallGetter(GetProp_CallScripted, stubCode, firstMonitorStub,
-                            receiverGuard, holder, holderShape, getter, pcOffset)
-    {}
-
-  public:
-    static ICGetProp_CallScripted* Clone(JSContext* cx, ICStubSpace* space,
-                                         ICStub* firstMonitorStub, ICGetProp_CallScripted& other);
-
-    class Compiler : public ICGetPropCallGetter::Compiler {
-      protected:
-        bool generateStubCode(MacroAssembler& masm);
-
-      public:
-        Compiler(JSContext* cx, ICStub* firstMonitorStub, HandleObject obj,
-                 HandleObject holder, HandleFunction getter, uint32_t pcOffset)
-          : ICGetPropCallGetter::Compiler(cx, ICStub::GetProp_CallScripted,
-                                          firstMonitorStub, obj, holder,
-                                          getter, pcOffset, /* outerClass = */ nullptr)
-        {}
-
-        ICStub* getStub(ICStubSpace* space) {
-            ReceiverGuard guard(receiver_);
-            Shape* holderShape = holder_->as<NativeObject>().lastProperty();
-            return newStub<ICGetProp_CallScripted>(space, getStubCode(), firstMonitorStub_,
-                                                       guard, holder_, holderShape, getter_,
-                                                       pcOffset_);
-        }
-    };
-};
-
-// Stub for calling a native getter on a native object.
-class ICGetProp_CallNative : public ICGetPropCallGetter
-{
-    friend class ICStubSpace;
-
-  protected:
-
-    ICGetProp_CallNative(JitCode* stubCode, ICStub* firstMonitorStub,
-                         ReceiverGuard receiverGuard,
-                         JSObject* holder, Shape* holderShape,
-                         JSFunction* getter, uint32_t pcOffset)
-      : ICGetPropCallGetter(GetProp_CallNative, stubCode, firstMonitorStub,
-                            receiverGuard, holder, holderShape, getter, pcOffset)
-    {}
-
-  public:
-    static ICGetProp_CallNative* Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitorStub,
-                                       ICGetProp_CallNative& other);
-
-};
-
-// Stub for calling a native getter on the GlobalObject.
-class ICGetProp_CallNativeGlobal : public ICGetPropCallGetter
-{
-    friend class ICStubSpace;
-
-  protected:
-    HeapPtrShape globalShape_;
-
-    ICGetProp_CallNativeGlobal(JitCode* stubCode, ICStub* firstMonitorStub,
-                               ReceiverGuard receiverGuard,
-                               JSObject* holder, Shape* holderShape, Shape* globalShape,
-                               JSFunction* getter, uint32_t pcOffset)
-      : ICGetPropCallGetter(GetProp_CallNativeGlobal, stubCode, firstMonitorStub,
-                            receiverGuard, holder, holderShape, getter, pcOffset),
-        globalShape_(globalShape)
-    { }
-
-  public:
-    static ICGetProp_CallNativeGlobal* Clone(JSContext* cx, ICStubSpace* space,
-                                             ICStub* firstMonitorStub,
-                                             ICGetProp_CallNativeGlobal& other);
-
-    HeapPtrShape& globalShape() {
-        return globalShape_;
-    }
-    static size_t offsetOfGlobalShape() {
-        return offsetof(ICGetProp_CallNativeGlobal, globalShape_);
-    }
-};
-
-class ICGetPropCallNativeCompiler : public ICGetPropCallGetter::Compiler
-{
-    bool inputDefinitelyObject_;
-  protected:
-    bool generateStubCode(MacroAssembler& masm);
-
-    virtual int32_t getKey() const {
-        int32_t baseKey = ICGetPropCallGetter::Compiler::getKey();
-        MOZ_ASSERT((baseKey >> 21) == 0);
-        return baseKey | (static_cast<int32_t>(inputDefinitelyObject_) << 21);
-    }
-
-  public:
-    ICGetPropCallNativeCompiler(JSContext* cx, ICStub::Kind kind, ICStub* firstMonitorStub,
-                                HandleObject receiver, HandleObject holder, HandleFunction getter,
-                                uint32_t pcOffset, const Class* outerClass,
-                                bool inputDefinitelyObject = false)
-      : ICGetPropCallGetter::Compiler(cx, kind, firstMonitorStub, receiver, holder,
-                                      getter, pcOffset, outerClass),
-        inputDefinitelyObject_(inputDefinitelyObject)
-    {}
-
-    ICStub* getStub(ICStubSpace* space);
-};
-
-class ICGetPropCallDOMProxyNativeStub : public ICGetPropCallGetter
-{
-  friend class ICStubSpace;
-  protected:
-    // Object shape of expected expando object. (nullptr if no expando object should be there)
-    HeapPtrShape expandoShape_;
-
-    ICGetPropCallDOMProxyNativeStub(ICStub::Kind kind, JitCode* stubCode,
-                                    ICStub* firstMonitorStub, Shape* shape,
-                                    Shape* expandoShape,
-                                    JSObject* holder, Shape* holderShape,
-                                    JSFunction* getter, uint32_t pcOffset);
-
-  public:
-    HeapPtrShape& expandoShape() {
-        return expandoShape_;
-    }
-    static size_t offsetOfExpandoShape() {
-        return offsetof(ICGetPropCallDOMProxyNativeStub, expandoShape_);
-    }
-};
-
-class ICGetProp_CallDOMProxyNative : public ICGetPropCallDOMProxyNativeStub
-{
-    friend class ICStubSpace;
-    ICGetProp_CallDOMProxyNative(JitCode* stubCode, ICStub* firstMonitorStub, Shape* shape,
-                                 Shape* expandoShape,
-                                 JSObject* holder, Shape* holderShape,
-                                 JSFunction* getter, uint32_t pcOffset)
-      : ICGetPropCallDOMProxyNativeStub(ICStub::GetProp_CallDOMProxyNative, stubCode,
-                                        firstMonitorStub, shape, expandoShape,
-                                        holder, holderShape, getter, pcOffset)
-    {}
-
-  public:
-    static ICGetProp_CallDOMProxyNative* Clone(JSContext* cx,
-                                               ICStubSpace* space,
-                                               ICStub* firstMonitorStub,
-                                               ICGetProp_CallDOMProxyNative& other);
-};
-
-class ICGetProp_CallDOMProxyWithGenerationNative : public ICGetPropCallDOMProxyNativeStub
-{
-  protected:
-    ExpandoAndGeneration* expandoAndGeneration_;
-    uint32_t generation_;
-
-  public:
-    ICGetProp_CallDOMProxyWithGenerationNative(JitCode* stubCode, ICStub* firstMonitorStub,
-                                               Shape* shape,
-                                               ExpandoAndGeneration* expandoAndGeneration,
-                                               uint32_t generation, Shape* expandoShape,
-                                               JSObject* holder, Shape* holderShape,
-                                               JSFunction* getter, uint32_t pcOffset)
-      : ICGetPropCallDOMProxyNativeStub(ICStub::GetProp_CallDOMProxyWithGenerationNative,
-                                        stubCode, firstMonitorStub, shape,
-                                        expandoShape, holder, holderShape, getter, pcOffset),
-        expandoAndGeneration_(expandoAndGeneration),
-        generation_(generation)
-    {
-    }
-
-    static ICGetProp_CallDOMProxyWithGenerationNative*
-    Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitorStub,
-          ICGetProp_CallDOMProxyWithGenerationNative& other);
-
-    void* expandoAndGeneration() const {
-        return expandoAndGeneration_;
-    }
-    uint32_t generation() const {
-        return generation_;
-    }
-
-    void setGeneration(uint32_t value) {
-        generation_ = value;
-    }
-
-    static size_t offsetOfInternalStruct() {
-        return offsetof(ICGetProp_CallDOMProxyWithGenerationNative, expandoAndGeneration_);
-    }
-    static size_t offsetOfGeneration() {
-        return offsetof(ICGetProp_CallDOMProxyWithGenerationNative, generation_);
-    }
-};
-
-class ICGetPropCallDOMProxyNativeCompiler : public ICStubCompiler {
-    ICStub* firstMonitorStub_;
-    Rooted<ProxyObject*> proxy_;
-    RootedObject holder_;
-    RootedFunction getter_;
-    uint32_t pcOffset_;
-
-    bool generateStubCode(MacroAssembler& masm, Address* internalStructAddr,
-                          Address* generationAddr);
-    bool generateStubCode(MacroAssembler& masm);
-
-  public:
-    ICGetPropCallDOMProxyNativeCompiler(JSContext* cx, ICStub::Kind kind,
-                                        ICStub* firstMonitorStub, Handle<ProxyObject*> proxy,
-                                        HandleObject holder, HandleFunction getter,
-                                        uint32_t pcOffset);
-
-    ICStub* getStub(ICStubSpace* space);
-};
-
-class ICGetProp_DOMProxyShadowed : public ICMonitoredStub
-{
-  friend class ICStubSpace;
-  protected:
-    HeapPtrShape shape_;
-    const BaseProxyHandler* proxyHandler_;
-    HeapPtrPropertyName name_;
-    uint32_t pcOffset_;
-
-    ICGetProp_DOMProxyShadowed(JitCode* stubCode, ICStub* firstMonitorStub, Shape* shape,
-                               const BaseProxyHandler* proxyHandler, PropertyName* name,
-                               uint32_t pcOffset);
-
-  public:
-    static ICGetProp_DOMProxyShadowed* Clone(JSContext* cx, ICStubSpace* space,
-                                             ICStub* firstMonitorStub,
-                                             ICGetProp_DOMProxyShadowed& other);
-
-    HeapPtrShape& shape() {
-        return shape_;
-    }
-    HeapPtrPropertyName& name() {
-        return name_;
-    }
-
-    static size_t offsetOfShape() {
-        return offsetof(ICGetProp_DOMProxyShadowed, shape_);
-    }
-    static size_t offsetOfProxyHandler() {
-        return offsetof(ICGetProp_DOMProxyShadowed, proxyHandler_);
-    }
-    static size_t offsetOfName() {
-        return offsetof(ICGetProp_DOMProxyShadowed, name_);
-    }
-    static size_t offsetOfPCOffset() {
-        return offsetof(ICGetProp_DOMProxyShadowed, pcOffset_);
-    }
-
-    class Compiler : public ICStubCompiler {
-        ICStub* firstMonitorStub_;
-        Rooted<ProxyObject*> proxy_;
-        RootedPropertyName name_;
-        uint32_t pcOffset_;
-
-        bool generateStubCode(MacroAssembler& masm);
-
-      public:
-        Compiler(JSContext* cx, ICStub* firstMonitorStub, Handle<ProxyObject*> proxy,
-                 HandlePropertyName name, uint32_t pcOffset)
-          : ICStubCompiler(cx, ICStub::GetProp_CallNative, Engine::Baseline),
-            firstMonitorStub_(firstMonitorStub),
-            proxy_(cx, proxy),
-            name_(cx, name),
-            pcOffset_(pcOffset)
-        {}
-
-        ICStub* getStub(ICStubSpace* space);
-    };
-};
-
-class ICGetProp_ArgumentsLength : public ICStub
-{
-  friend class ICStubSpace;
-  public:
-    enum Which { Mapped, Unmapped, Magic };
-
-  protected:
-    explicit ICGetProp_ArgumentsLength(JitCode* stubCode)
-      : ICStub(ICStub::GetProp_ArgumentsLength, stubCode)
-    { }
-
-  public:
-    class Compiler : public ICStubCompiler {
-      protected:
-        Which which_;
-
-        bool generateStubCode(MacroAssembler& masm);
-
-        virtual int32_t getKey() const {
-            return static_cast<int32_t>(engine_) |
-                  (static_cast<int32_t>(kind) << 1) |
-                  (static_cast<int32_t>(which_) << 17);
-        }
-
-      public:
-        Compiler(JSContext* cx, Which which)
-          : ICStubCompiler(cx, ICStub::GetProp_ArgumentsLength, Engine::Baseline),
-            which_(which)
-        {}
-
-        ICStub* getStub(ICStubSpace* space) {
-            return newStub<ICGetProp_ArgumentsLength>(space, getStubCode());
-        }
-    };
-};
-
-class ICGetProp_ArgumentsCallee : public ICMonitoredStub
-{
-    friend class ICStubSpace;
-
-  protected:
-    ICGetProp_ArgumentsCallee(JitCode* stubCode, ICStub* firstMonitorStub);
-
-  public:
-    class Compiler : public ICStubCompiler {
-      protected:
-        ICStub* firstMonitorStub_;
-        bool generateStubCode(MacroAssembler& masm);
-
-      public:
-        Compiler(JSContext* cx, ICStub* firstMonitorStub)
-          : ICStubCompiler(cx, ICStub::GetProp_ArgumentsCallee, Engine::Baseline),
-            firstMonitorStub_(firstMonitorStub)
-        {}
-
-        ICStub* getStub(ICStubSpace* space) {
-            return newStub<ICGetProp_ArgumentsCallee>(space, getStubCode(), firstMonitorStub_);
-        }
-    };
-};
-
 // SetProp
 //     JSOP_SETPROP
 //     JSOP_SETNAME
 //     JSOP_SETGNAME
 //     JSOP_INITPROP
 
 class ICSetProp_Fallback : public ICFallbackStub
 {
--- a/js/src/jit/BaselineICList.h
+++ b/js/src/jit/BaselineICList.h
@@ -88,36 +88,16 @@ namespace jit {
     _(GetName_Scope5)                            \
     _(GetName_Scope6)                            \
                                                  \
     _(BindName_Fallback)                         \
                                                  \
     _(GetIntrinsic_Fallback)                     \
     _(GetIntrinsic_Constant)                     \
                                                  \
-    _(GetProp_Fallback)                          \
-    _(GetProp_ArrayLength)                       \
-    _(GetProp_UnboxedArrayLength)                \
-    _(GetProp_Primitive)                         \
-    _(GetProp_StringLength)                      \
-    _(GetProp_Native)                            \
-    _(GetProp_NativeDoesNotExist)                \
-    _(GetProp_NativePrototype)                   \
-    _(GetProp_Unboxed)                           \
-    _(GetProp_TypedObject)                       \
-    _(GetProp_CallScripted)                      \
-    _(GetProp_CallNative)                        \
-    _(GetProp_CallNativeGlobal)                  \
-    _(GetProp_CallDOMProxyNative)                \
-    _(GetProp_CallDOMProxyWithGenerationNative)  \
-    _(GetProp_DOMProxyShadowed)                  \
-    _(GetProp_ArgumentsLength)                   \
-    _(GetProp_ArgumentsCallee)                   \
-    _(GetProp_Generic)                           \
-                                                 \
     _(SetProp_Fallback)                          \
     _(SetProp_Native)                            \
     _(SetProp_NativeAdd)                         \
     _(SetProp_Unboxed)                           \
     _(SetProp_TypedObject)                       \
     _(SetProp_CallScripted)                      \
     _(SetProp_CallNative)                        \
                                                  \
--- a/js/src/jit/SharedIC.cpp
+++ b/js/src/jit/SharedIC.cpp
@@ -2,16 +2,17 @@
  * 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 "jit/SharedIC.h"
 
 #include "mozilla/Casting.h"
+#include "mozilla/DebugOnly.h"
 #include "mozilla/SizePrintfMacros.h"
 
 #include "jslibmath.h"
 #include "jstypes.h"
 
 #include "jit/BaselineDebugModeOSR.h"
 #include "jit/BaselineIC.h"
 #include "jit/JitSpewer.h"
@@ -22,16 +23,17 @@
 #endif
 #include "jit/VMFunctions.h"
 #include "vm/Interpreter.h"
 
 #include "jit/MacroAssembler-inl.h"
 #include "vm/Interpreter-inl.h"
 
 using mozilla::BitwiseCast;
+using mozilla::DebugOnly;
 
 namespace js {
 namespace jit {
 
 #ifdef JS_JITSPEW
 void
 FallbackICSpew(JSContext* cx, ICFallbackStub* stub, const char* fmt, ...)
 {
@@ -2026,10 +2028,2451 @@ ICCompare_Int32WithBoolean::Compiler::ge
     }
 
     // Failure case - jump to next stub
     masm.bind(&failure);
     EmitStubGuardFailure(masm);
     return true;
 }
 
+//
+// GetProp_Fallback
+//
+
+static bool
+TryAttachMagicArgumentsGetPropStub(JSContext* cx, JSScript* script, ICGetProp_Fallback* stub,
+                                   HandlePropertyName name, HandleValue val, HandleValue res,
+                                   bool* attached)
+{
+    MOZ_ASSERT(!*attached);
+
+    if (!val.isMagic(JS_OPTIMIZED_ARGUMENTS))
+        return true;
+
+    // Try handling arguments.callee on optimized arguments.
+    if (name == cx->names().callee) {
+        MOZ_ASSERT(script->hasMappedArgsObj());
+
+        JitSpew(JitSpew_BaselineIC, "  Generating GetProp(MagicArgs.callee) stub");
+
+        // Unlike ICGetProp_ArgumentsLength, only magic argument stubs are
+        // supported at the moment.
+        ICStub* monitorStub = stub->fallbackMonitorStub()->firstMonitorStub();
+        ICGetProp_ArgumentsCallee::Compiler compiler(cx, monitorStub);
+        ICStub* newStub = compiler.getStub(compiler.getStubSpace(script));
+        if (!newStub)
+            return false;
+        stub->addNewStub(newStub);
+
+        *attached = true;
+        return true;
+    }
+
+    return true;
+}
+
+static bool
+TryAttachLengthStub(JSContext* cx, JSScript* script, ICGetProp_Fallback* stub, HandleValue val,
+                    HandleValue res, bool* attached)
+{
+    MOZ_ASSERT(!*attached);
+
+    if (val.isString()) {
+        MOZ_ASSERT(res.isInt32());
+        JitSpew(JitSpew_BaselineIC, "  Generating GetProp(String.length) stub");
+        ICGetProp_StringLength::Compiler compiler(cx);
+        ICStub* newStub = compiler.getStub(compiler.getStubSpace(script));
+        if (!newStub)
+            return false;
+
+        *attached = true;
+        stub->addNewStub(newStub);
+        return true;
+    }
+
+    if (val.isMagic(JS_OPTIMIZED_ARGUMENTS) && res.isInt32()) {
+        JitSpew(JitSpew_BaselineIC, "  Generating GetProp(MagicArgs.length) stub");
+        ICGetProp_ArgumentsLength::Compiler compiler(cx, ICGetProp_ArgumentsLength::Magic);
+        ICStub* newStub = compiler.getStub(compiler.getStubSpace(script));
+        if (!newStub)
+            return false;
+
+        *attached = true;
+        stub->addNewStub(newStub);
+        return true;
+    }
+
+    if (!val.isObject())
+        return true;
+
+    RootedObject obj(cx, &val.toObject());
+
+    if (obj->is<ArrayObject>() && res.isInt32()) {
+        JitSpew(JitSpew_BaselineIC, "  Generating GetProp(Array.length) stub");
+        ICGetProp_ArrayLength::Compiler compiler(cx);
+        ICStub* newStub = compiler.getStub(compiler.getStubSpace(script));
+        if (!newStub)
+            return false;
+
+        *attached = true;
+        stub->addNewStub(newStub);
+        return true;
+    }
+
+    if (obj->is<UnboxedArrayObject>() && res.isInt32()) {
+        JitSpew(JitSpew_BaselineIC, "  Generating GetProp(UnboxedArray.length) stub");
+        ICGetProp_UnboxedArrayLength::Compiler compiler(cx);
+        ICStub* newStub = compiler.getStub(compiler.getStubSpace(script));
+        if (!newStub)
+            return false;
+
+        *attached = true;
+        stub->addNewStub(newStub);
+        return true;
+    }
+
+    if (obj->is<ArgumentsObject>() && res.isInt32()) {
+        JitSpew(JitSpew_BaselineIC, "  Generating GetProp(ArgsObj.length %s) stub",
+                obj->is<MappedArgumentsObject>() ? "Mapped" : "Unmapped");
+        ICGetProp_ArgumentsLength::Which which = ICGetProp_ArgumentsLength::Mapped;
+        if (obj->is<UnmappedArgumentsObject>())
+            which = ICGetProp_ArgumentsLength::Unmapped;
+        ICGetProp_ArgumentsLength::Compiler compiler(cx, which);
+        ICStub* newStub = compiler.getStub(compiler.getStubSpace(script));
+        if (!newStub)
+            return false;
+
+        *attached = true;
+        stub->addNewStub(newStub);
+        return true;
+    }
+
+    return true;
+}
+
+static bool
+UpdateExistingGenerationalDOMProxyStub(ICGetProp_Fallback* stub,
+                                       HandleObject obj)
+{
+    Value expandoSlot = GetProxyExtra(obj, GetDOMProxyExpandoSlot());
+    MOZ_ASSERT(!expandoSlot.isObject() && !expandoSlot.isUndefined());
+    ExpandoAndGeneration* expandoAndGeneration = (ExpandoAndGeneration*)expandoSlot.toPrivate();
+    for (ICStubConstIterator iter = stub->beginChainConst(); !iter.atEnd(); iter++) {
+        if (iter->isGetProp_CallDOMProxyWithGenerationNative()) {
+            ICGetProp_CallDOMProxyWithGenerationNative* updateStub =
+                iter->toGetProp_CallDOMProxyWithGenerationNative();
+            if (updateStub->expandoAndGeneration() == expandoAndGeneration) {
+                // Update generation
+                uint32_t generation = expandoAndGeneration->generation;
+                JitSpew(JitSpew_BaselineIC,
+                        "  Updating existing stub with generation, old value: %i, "
+                        "new value: %i", updateStub->generation(),
+                        generation);
+                updateStub->setGeneration(generation);
+                return true;
+            }
+        }
+    }
+    return false;
+}
+
+// Return whether obj is in some PreliminaryObjectArray and has a structure
+// that might change in the future.
+bool
+IsPreliminaryObject(JSObject* obj)
+{
+    if (obj->isSingleton())
+        return false;
+
+    TypeNewScript* newScript = obj->group()->newScript();
+    if (newScript && !newScript->analyzed())
+        return true;
+
+    if (obj->group()->maybePreliminaryObjects())
+        return true;
+
+    return false;
+}
+
+void
+StripPreliminaryObjectStubs(JSContext* cx, ICFallbackStub* stub)
+{
+    // Before the new script properties analysis has been performed on a type,
+    // all instances of that type have the maximum number of fixed slots.
+    // Afterwards, the objects (even the preliminary ones) might be changed
+    // to reduce the number of fixed slots they have. If we generate stubs for
+    // both the old and new number of fixed slots, the stub will look
+    // polymorphic to IonBuilder when it is actually monomorphic. To avoid
+    // this, strip out any stubs for preliminary objects before attaching a new
+    // stub which isn't on a preliminary object.
+
+    for (ICStubIterator iter = stub->beginChain(); !iter.atEnd(); iter++) {
+        if (iter->isGetProp_Native() && iter->toGetProp_Native()->hasPreliminaryObject())
+            iter.unlink(cx);
+        else if (iter->isSetProp_Native() && iter->toSetProp_Native()->hasPreliminaryObject())
+            iter.unlink(cx);
+    }
+}
+
+JSObject*
+GetDOMProxyProto(JSObject* obj)
+{
+    MOZ_ASSERT(IsCacheableDOMProxy(obj));
+    return obj->getTaggedProto().toObjectOrNull();
+}
+
+// Look up a property's shape on an object, being careful never to do any effectful
+// operations.  This procedure not yielding a shape should not be taken as a lack of
+// existence of the property on the object.
+bool
+EffectlesslyLookupProperty(JSContext* cx, HandleObject obj, HandleId id,
+                           MutableHandleObject holder, MutableHandleShape shape,
+                           bool* checkDOMProxy,
+                           DOMProxyShadowsResult* shadowsResult,
+                           bool* domProxyHasGeneration)
+{
+    shape.set(nullptr);
+    holder.set(nullptr);
+
+    if (checkDOMProxy) {
+        *checkDOMProxy = false;
+        *shadowsResult = ShadowCheckFailed;
+    }
+
+    // Check for list base if asked to.
+    RootedObject checkObj(cx, obj);
+    if (checkDOMProxy && IsCacheableDOMProxy(obj)) {
+        MOZ_ASSERT(domProxyHasGeneration);
+        MOZ_ASSERT(shadowsResult);
+
+        *checkDOMProxy = true;
+        if (obj->hasUncacheableProto())
+            return true;
+
+        *shadowsResult = GetDOMProxyShadowsCheck()(cx, obj, id);
+        if (*shadowsResult == ShadowCheckFailed)
+            return false;
+
+        if (DOMProxyIsShadowing(*shadowsResult)) {
+            holder.set(obj);
+            return true;
+        }
+
+        *domProxyHasGeneration = (*shadowsResult == DoesntShadowUnique);
+
+        checkObj = GetDOMProxyProto(obj);
+        if (!checkObj)
+            return true;
+    }
+
+    if (LookupPropertyPure(cx, checkObj, id, holder.address(), shape.address()))
+        return true;
+
+    holder.set(nullptr);
+    shape.set(nullptr);
+    return true;
+}
+
+bool
+IsCacheableProtoChain(JSObject* obj, JSObject* holder, bool isDOMProxy)
+{
+    MOZ_ASSERT_IF(isDOMProxy, IsCacheableDOMProxy(obj));
+
+    if (!isDOMProxy && !obj->isNative()) {
+        if (obj == holder)
+            return false;
+        if (!obj->is<UnboxedPlainObject>() &&
+            !obj->is<UnboxedArrayObject>() &&
+            !obj->is<TypedObject>())
+        {
+            return false;
+        }
+    }
+
+    // Don't handle objects which require a prototype guard. This should
+    // be uncommon so handling it is likely not worth the complexity.
+    if (obj->hasUncacheableProto())
+        return false;
+
+    JSObject* cur = obj;
+    while (cur != holder) {
+        // We cannot assume that we find the holder object on the prototype
+        // chain and must check for null proto. The prototype chain can be
+        // altered during the lookupProperty call.
+        JSObject* proto;
+        if (isDOMProxy && cur == obj)
+            proto = cur->getTaggedProto().toObjectOrNull();
+        else
+            proto = cur->getProto();
+
+        if (!proto || !proto->isNative())
+            return false;
+
+        if (proto->hasUncacheableProto())
+            return false;
+
+        cur = proto;
+    }
+    return true;
+}
+
+bool
+IsCacheableGetPropReadSlot(JSObject* obj, JSObject* holder, Shape* shape, bool isDOMProxy)
+{
+    if (!shape || !IsCacheableProtoChain(obj, holder, isDOMProxy))
+        return false;
+
+    if (!shape->hasSlot() || !shape->hasDefaultGetter())
+        return false;
+
+    return true;
+}
+
+void
+GetFixedOrDynamicSlotOffset(Shape* shape, bool* isFixed, uint32_t* offset)
+{
+    MOZ_ASSERT(isFixed);
+    MOZ_ASSERT(offset);
+    *isFixed = shape->slot() < shape->numFixedSlots();
+    *offset = *isFixed ? NativeObject::getFixedSlotOffset(shape->slot())
+                       : (shape->slot() - shape->numFixedSlots()) * sizeof(Value);
+}
+
+
+static bool
+TryAttachNativeGetValuePropStub(JSContext* cx, HandleScript script, jsbytecode* pc,
+                                ICGetProp_Fallback* stub, HandlePropertyName name,
+                                HandleValue val, HandleShape oldShape,
+                                HandleValue res, bool* attached)
+{
+    MOZ_ASSERT(!*attached);
+
+    if (!val.isObject())
+        return true;
+
+    RootedObject obj(cx, &val.toObject());
+
+    if (obj->isNative() && oldShape != obj->as<NativeObject>().lastProperty()) {
+        // No point attaching anything, since we know the shape guard will fail
+        return true;
+    }
+
+    RootedShape shape(cx);
+    RootedObject holder(cx);
+    RootedId id(cx, NameToId(name));
+    if (!EffectlesslyLookupProperty(cx, obj, id, &holder, &shape))
+        return false;
+
+    ICStub* monitorStub = stub->fallbackMonitorStub()->firstMonitorStub();
+    if (IsCacheableGetPropReadSlot(obj, holder, shape)) {
+        bool isFixedSlot;
+        uint32_t offset;
+        GetFixedOrDynamicSlotOffset(shape, &isFixedSlot, &offset);
+
+        // Instantiate this property for singleton holders, for use during Ion compilation.
+        if (IsIonEnabled(cx))
+            EnsureTrackPropertyTypes(cx, holder, NameToId(name));
+
+        ICStub::Kind kind =
+            (obj == holder) ? ICStub::GetProp_Native : ICStub::GetProp_NativePrototype;
+
+        JitSpew(JitSpew_BaselineIC, "  Generating GetProp(Native %s) stub",
+                    (obj == holder) ? "direct" : "prototype");
+        ICGetPropNativeCompiler compiler(cx, kind, monitorStub, obj, holder,
+                                         name, isFixedSlot, offset);
+        ICGetPropNativeStub* newStub = compiler.getStub(compiler.getStubSpace(script));
+        if (!newStub)
+            return false;
+
+        if (IsPreliminaryObject(obj))
+            newStub->notePreliminaryObject();
+        else
+            StripPreliminaryObjectStubs(cx, stub);
+
+        stub->addNewStub(newStub);
+        *attached = true;
+        return true;
+    }
+    return true;
+}
+
+bool
+IsCacheableGetPropCall(JSContext* cx, JSObject* obj, JSObject* holder, Shape* shape,
+                       bool* isScripted, bool* isTemporarilyUnoptimizable, bool isDOMProxy)
+{
+    MOZ_ASSERT(isScripted);
+
+    if (!shape || !IsCacheableProtoChain(obj, holder, isDOMProxy))
+        return false;
+
+    if (shape->hasSlot() || shape->hasDefaultGetter())
+        return false;
+
+    if (!shape->hasGetterValue())
+        return false;
+
+    if (!shape->getterValue().isObject() || !shape->getterObject()->is<JSFunction>())
+        return false;
+
+    JSFunction* func = &shape->getterObject()->as<JSFunction>();
+    if (func->isNative()) {
+        *isScripted = false;
+        return true;
+    }
+
+    if (!func->hasJITCode()) {
+        *isTemporarilyUnoptimizable = true;
+        return false;
+    }
+
+    *isScripted = true;
+    return true;
+}
+
+// Try to update all existing GetProp/GetName getter call stubs that match the
+// given holder in place with a new shape and getter.  fallbackStub can be
+// either an ICGetProp_Fallback or an ICGetName_Fallback.
+//
+// If 'getter' is an own property, holder == receiver must be true.
+bool
+UpdateExistingGetPropCallStubs(ICFallbackStub* fallbackStub,
+                               ICStub::Kind kind,
+                               HandleNativeObject holder,
+                               HandleObject receiver,
+                               HandleFunction getter)
+{
+    MOZ_ASSERT(kind == ICStub::GetProp_CallScripted ||
+               kind == ICStub::GetProp_CallNative ||
+               kind == ICStub::GetProp_CallNativeGlobal);
+    MOZ_ASSERT(fallbackStub->isGetName_Fallback() ||
+               fallbackStub->isGetProp_Fallback());
+    MOZ_ASSERT(holder);
+    MOZ_ASSERT(receiver);
+
+    bool isOwnGetter = (holder == receiver);
+    bool foundMatchingStub = false;
+    ReceiverGuard receiverGuard(receiver);
+    for (ICStubConstIterator iter = fallbackStub->beginChainConst(); !iter.atEnd(); iter++) {
+        if (iter->kind() == kind) {
+            ICGetPropCallGetter* getPropStub = static_cast<ICGetPropCallGetter*>(*iter);
+            if (getPropStub->holder() == holder && getPropStub->isOwnGetter() == isOwnGetter) {
+                // If this is an own getter, update the receiver guard as well,
+                // since that's the shape we'll be guarding on. Furthermore,
+                // isOwnGetter() relies on holderShape_ and receiverGuard_ being
+                // the same shape.
+                if (isOwnGetter)
+                    getPropStub->receiverGuard().update(receiverGuard);
+
+                MOZ_ASSERT(getPropStub->holderShape() != holder->lastProperty() ||
+                           !getPropStub->receiverGuard().matches(receiverGuard) ||
+                           getPropStub->toGetProp_CallNativeGlobal()->globalShape() !=
+                           receiver->as<ClonedBlockObject>().global().lastProperty(),
+                           "Why didn't we end up using this stub?");
+
+                // We want to update the holder shape to match the new one no
+                // matter what, even if the receiver shape is different.
+                getPropStub->holderShape() = holder->lastProperty();
+
+                // Make sure to update the getter, since a shape change might
+                // have changed which getter we want to use.
+                getPropStub->getter() = getter;
+
+                if (getPropStub->isGetProp_CallNativeGlobal()) {
+                    ICGetProp_CallNativeGlobal* globalStub =
+                        getPropStub->toGetProp_CallNativeGlobal();
+                    globalStub->globalShape() =
+                        receiver->as<ClonedBlockObject>().global().lastProperty();
+                }
+
+                if (getPropStub->receiverGuard().matches(receiverGuard))
+                    foundMatchingStub = true;
+            }
+        }
+    }
+
+    return foundMatchingStub;
+}
+
+static bool
+TryAttachNativeGetAccessorPropStub(JSContext* cx, HandleScript script, jsbytecode* pc,
+                                   ICGetProp_Fallback* stub, HandlePropertyName name,
+                                   HandleValue val, HandleValue res, bool* attached,
+                                   bool* isTemporarilyUnoptimizable)
+{
+    MOZ_ASSERT(!*attached);
+    MOZ_ASSERT(!*isTemporarilyUnoptimizable);
+
+    if (!val.isObject())
+        return true;
+
+    RootedObject obj(cx, &val.toObject());
+
+    bool isDOMProxy;
+    bool domProxyHasGeneration;
+    DOMProxyShadowsResult domProxyShadowsResult;
+    RootedShape shape(cx);
+    RootedObject holder(cx);
+    RootedId id(cx, NameToId(name));
+    if (!EffectlesslyLookupProperty(cx, obj, id, &holder, &shape, &isDOMProxy,
+                                    &domProxyShadowsResult, &domProxyHasGeneration))
+    {
+        return false;
+    }
+
+    ICStub* monitorStub = stub->fallbackMonitorStub()->firstMonitorStub();
+
+    bool isScripted = false;
+    bool cacheableCall = IsCacheableGetPropCall(cx, obj, holder, shape, &isScripted,
+                                                isTemporarilyUnoptimizable);
+
+    // Try handling scripted getters.
+    if (cacheableCall && isScripted && !isDOMProxy) {
+        RootedFunction callee(cx, &shape->getterObject()->as<JSFunction>());
+        MOZ_ASSERT(callee->hasScript());
+
+        if (UpdateExistingGetPropCallStubs(stub, ICStub::GetProp_CallScripted,
+                                           holder.as<NativeObject>(), obj, callee)) {
+            *attached = true;
+            return true;
+        }
+
+        JitSpew(JitSpew_BaselineIC, "  Generating GetProp(NativeObj/ScriptedGetter %s:%" PRIuSIZE ") stub",
+                callee->nonLazyScript()->filename(), callee->nonLazyScript()->lineno());
+
+        ICGetProp_CallScripted::Compiler compiler(cx, monitorStub, obj, holder, callee,
+                                                  script->pcToOffset(pc));
+        ICStub* newStub = compiler.getStub(compiler.getStubSpace(script));
+        if (!newStub)
+            return false;
+
+        stub->addNewStub(newStub);
+        *attached = true;
+        return true;
+    }
+
+    // If it's a shadowed listbase proxy property, attach stub to call Proxy::get instead.
+    if (isDOMProxy && DOMProxyIsShadowing(domProxyShadowsResult)) {
+        MOZ_ASSERT(obj == holder);
+
+        JitSpew(JitSpew_BaselineIC, "  Generating GetProp(DOMProxyProxy) stub");
+        Rooted<ProxyObject*> proxy(cx, &obj->as<ProxyObject>());
+        ICGetProp_DOMProxyShadowed::Compiler compiler(cx, monitorStub, proxy, name,
+                                                      script->pcToOffset(pc));
+        ICStub* newStub = compiler.getStub(compiler.getStubSpace(script));
+        if (!newStub)
+            return false;
+        stub->addNewStub(newStub);
+        *attached = true;
+        return true;
+    }
+
+    const Class* outerClass = nullptr;
+    if (!isDOMProxy && !obj->isNative()) {
+        outerClass = obj->getClass();
+        if (!IsWindowProxy(obj))
+            return true;
+
+        // This must be a WindowProxy for the current Window/global. Else it'd
+        // be a cross-compartment wrapper and IsWindowProxy returns false for
+        // those.
+        MOZ_ASSERT(ToWindowIfWindowProxy(obj) == cx->global());
+        obj = cx->global();
+
+        if (!EffectlesslyLookupProperty(cx, obj, id, &holder, &shape, &isDOMProxy,
+                                        &domProxyShadowsResult, &domProxyHasGeneration))
+        {
+            return false;
+        }
+        cacheableCall = IsCacheableGetPropCall(cx, obj, holder, shape, &isScripted,
+                                               isTemporarilyUnoptimizable, isDOMProxy);
+    }
+
+    // Try handling JSNative getters.
+    if (!cacheableCall || isScripted)
+        return true;
+
+    if (!shape || !shape->hasGetterValue() || !shape->getterValue().isObject() ||
+        !shape->getterObject()->is<JSFunction>())
+    {
+        return true;
+    }
+
+    RootedFunction callee(cx, &shape->getterObject()->as<JSFunction>());
+    MOZ_ASSERT(callee->isNative());
+
+    if (outerClass && (!callee->jitInfo() || callee->jitInfo()->needsOuterizedThisObject()))
+        return true;
+
+    JitSpew(JitSpew_BaselineIC, "  Generating GetProp(%s%s/NativeGetter %p) stub",
+            isDOMProxy ? "DOMProxyObj" : "NativeObj",
+            isDOMProxy && domProxyHasGeneration ? "WithGeneration" : "",
+            callee->native());
+
+    ICStub* newStub = nullptr;
+    if (isDOMProxy) {
+        MOZ_ASSERT(obj != holder);
+        ICStub::Kind kind;
+        if (domProxyHasGeneration) {
+            if (UpdateExistingGenerationalDOMProxyStub(stub, obj)) {
+                *attached = true;
+                return true;
+            }
+            kind = ICStub::GetProp_CallDOMProxyWithGenerationNative;
+        } else {
+            kind = ICStub::GetProp_CallDOMProxyNative;
+        }
+        Rooted<ProxyObject*> proxy(cx, &obj->as<ProxyObject>());
+        ICGetPropCallDOMProxyNativeCompiler compiler(cx, kind, monitorStub, proxy, holder, callee,
+                                                     script->pcToOffset(pc));
+        newStub = compiler.getStub(compiler.getStubSpace(script));
+    } else {
+        if (UpdateExistingGetPropCallStubs(stub, ICStub::GetProp_CallNative,
+                                           holder.as<NativeObject>(), obj, callee))
+        {
+            *attached = true;
+            return true;
+        }
+
+        ICGetPropCallNativeCompiler compiler(cx, ICStub::GetProp_CallNative,
+                                             monitorStub, obj, holder, callee,
+                                             script->pcToOffset(pc), outerClass);
+        newStub = compiler.getStub(compiler.getStubSpace(script));
+    }
+    if (!newStub)
+        return false;
+    stub->addNewStub(newStub);
+    *attached = true;
+    return true;
+}
+
+static bool
+TryAttachUnboxedGetPropStub(JSContext* cx, HandleScript script,
+                            ICGetProp_Fallback* stub, HandlePropertyName name, HandleValue val,
+                            bool* attached)
+{
+    MOZ_ASSERT(!*attached);
+
+    if (!cx->runtime()->jitSupportsFloatingPoint)
+        return true;
+
+    if (!val.isObject() || !val.toObject().is<UnboxedPlainObject>())
+        return true;
+    Rooted<UnboxedPlainObject*> obj(cx, &val.toObject().as<UnboxedPlainObject>());
+
+    const UnboxedLayout::Property* property = obj->layout().lookup(name);
+    if (!property)
+        return true;
+
+    ICStub* monitorStub = stub->fallbackMonitorStub()->firstMonitorStub();
+
+    ICGetProp_Unboxed::Compiler compiler(cx, monitorStub, obj->group(),
+                                         property->offset + UnboxedPlainObject::offsetOfData(),
+                                         property->type);
+    ICStub* newStub = compiler.getStub(compiler.getStubSpace(script));
+    if (!newStub)
+        return false;
+    stub->addNewStub(newStub);
+
+    StripPreliminaryObjectStubs(cx, stub);
+
+    *attached = true;
+    return true;
+}
+
+static bool
+TryAttachUnboxedExpandoGetPropStub(JSContext* cx, HandleScript script, jsbytecode* pc,
+                                   ICGetProp_Fallback* stub, HandlePropertyName name, HandleValue val,
+                                   bool* attached)
+{
+    MOZ_ASSERT(!*attached);
+
+    if (!val.isObject() || !val.toObject().is<UnboxedPlainObject>())
+        return true;
+    Rooted<UnboxedPlainObject*> obj(cx, &val.toObject().as<UnboxedPlainObject>());
+
+    Rooted<UnboxedExpandoObject*> expando(cx, obj->maybeExpando());
+    if (!expando)
+        return true;
+
+    Shape* shape = expando->lookup(cx, name);
+    if (!shape || !shape->hasDefaultGetter() || !shape->hasSlot())
+        return true;
+
+    bool isFixedSlot;
+    uint32_t offset;
+    GetFixedOrDynamicSlotOffset(shape, &isFixedSlot, &offset);
+
+    ICStub* monitorStub = stub->fallbackMonitorStub()->firstMonitorStub();
+
+    ICGetPropNativeCompiler compiler(cx, ICStub::GetProp_Native, monitorStub, obj, obj,
+                                     name, isFixedSlot, offset);
+    ICGetPropNativeStub* newStub = compiler.getStub(compiler.getStubSpace(script));
+    if (!newStub)
+        return false;
+
+    StripPreliminaryObjectStubs(cx, stub);
+
+    stub->addNewStub(newStub);
+    *attached = true;
+    return true;
+}
+
+static bool
+TryAttachTypedObjectGetPropStub(JSContext* cx, HandleScript script,
+                                ICGetProp_Fallback* stub, HandlePropertyName name, HandleValue val,
+                                bool* attached)
+{
+    MOZ_ASSERT(!*attached);
+
+    if (!cx->runtime()->jitSupportsFloatingPoint)
+        return true;
+
+    if (!val.isObject() || !val.toObject().is<TypedObject>())
+        return true;
+    Rooted<TypedObject*> obj(cx, &val.toObject().as<TypedObject>());
+
+    if (!obj->typeDescr().is<StructTypeDescr>())
+        return true;
+    Rooted<StructTypeDescr*> structDescr(cx, &obj->typeDescr().as<StructTypeDescr>());
+
+    size_t fieldIndex;
+    if (!structDescr->fieldIndex(NameToId(name), &fieldIndex))
+        return true;
+
+    Rooted<TypeDescr*> fieldDescr(cx, &structDescr->fieldDescr(fieldIndex));
+    if (!fieldDescr->is<SimpleTypeDescr>())
+        return true;
+
+    uint32_t fieldOffset = structDescr->fieldOffset(fieldIndex);
+    ICStub* monitorStub = stub->fallbackMonitorStub()->firstMonitorStub();
+
+    ICGetProp_TypedObject::Compiler compiler(cx, monitorStub, obj->maybeShape(),
+                                             fieldOffset, &fieldDescr->as<SimpleTypeDescr>());
+    ICStub* newStub = compiler.getStub(compiler.getStubSpace(script));
+    if (!newStub)
+        return false;
+    stub->addNewStub(newStub);
+
+    *attached = true;
+    return true;
+}
+
+static bool
+TryAttachPrimitiveGetPropStub(JSContext* cx, HandleScript script, jsbytecode* pc,
+                              ICGetProp_Fallback* stub, HandlePropertyName name, HandleValue val,
+                              HandleValue res, bool* attached)
+{
+    MOZ_ASSERT(!*attached);
+
+    JSValueType primitiveType;
+    RootedNativeObject proto(cx);
+    Rooted<GlobalObject*> global(cx, &script->global());
+    if (val.isString()) {
+        primitiveType = JSVAL_TYPE_STRING;
+        proto = GlobalObject::getOrCreateStringPrototype(cx, global);
+    } else if (val.isSymbol()) {
+        primitiveType = JSVAL_TYPE_SYMBOL;
+        proto = GlobalObject::getOrCreateSymbolPrototype(cx, global);
+    } else if (val.isNumber()) {
+        primitiveType = JSVAL_TYPE_DOUBLE;
+        proto = GlobalObject::getOrCreateNumberPrototype(cx, global);
+    } else {
+        MOZ_ASSERT(val.isBoolean());
+        primitiveType = JSVAL_TYPE_BOOLEAN;
+        proto = GlobalObject::getOrCreateBooleanPrototype(cx, global);
+    }
+    if (!proto)
+        return false;
+
+    // Instantiate this property, for use during Ion compilation.
+    RootedId id(cx, NameToId(name));
+    if (IsIonEnabled(cx))
+        EnsureTrackPropertyTypes(cx, proto, id);
+
+    // For now, only look for properties directly set on the prototype.
+    RootedShape shape(cx, proto->lookup(cx, id));
+    if (!shape || !shape->hasSlot() || !shape->hasDefaultGetter())
+        return true;
+
+    bool isFixedSlot;
+    uint32_t offset;
+    GetFixedOrDynamicSlotOffset(shape, &isFixedSlot, &offset);
+
+    ICStub* monitorStub = stub->fallbackMonitorStub()->firstMonitorStub();
+
+    JitSpew(JitSpew_BaselineIC, "  Generating GetProp_Primitive stub");
+    ICGetProp_Primitive::Compiler compiler(cx, monitorStub, primitiveType, proto,
+                                           isFixedSlot, offset);
+    ICStub* newStub = compiler.getStub(compiler.getStubSpace(script));
+    if (!newStub)
+        return false;
+
+    stub->addNewStub(newStub);
+    *attached = true;
+    return true;
+}
+
+bool
+CheckHasNoSuchProperty(JSContext* cx, HandleObject obj, HandlePropertyName name,
+                       MutableHandleObject lastProto, size_t* protoChainDepthOut)
+{
+    MOZ_ASSERT(protoChainDepthOut != nullptr);
+
+    size_t depth = 0;
+    RootedObject curObj(cx, obj);
+    while (curObj) {
+        if (curObj->isNative()) {
+            // Don't handle proto chains with resolve hooks.
+            if (ClassMayResolveId(cx->names(), curObj->getClass(), NameToId(name), curObj))
+                return false;
+            if (curObj->as<NativeObject>().contains(cx, NameToId(name)))
+                return false;
+        } else if (curObj != obj) {
+            // Non-native objects are only handled as the original receiver.
+            return false;
+        } else if (curObj->is<UnboxedPlainObject>()) {
+            if (curObj->as<UnboxedPlainObject>().containsUnboxedOrExpandoProperty(cx, NameToId(name)))
+                return false;
+        } else if (curObj->is<UnboxedArrayObject>()) {
+            if (name == cx->names().length)
+                return false;
+        } else if (curObj->is<TypedObject>()) {
+            if (curObj->as<TypedObject>().typeDescr().hasProperty(cx->names(), NameToId(name)))
+                return false;
+        } else {
+            return false;
+        }
+
+        JSObject* proto = curObj->getTaggedProto().toObjectOrNull();
+        if (!proto)
+            break;
+
+        curObj = proto;
+        depth++;
+    }
+
+    lastProto.set(curObj);
+    *protoChainDepthOut = depth;
+    return true;
+}
+
+static bool
+TryAttachNativeGetPropDoesNotExistStub(JSContext* cx, HandleScript script,
+                                       jsbytecode* pc, ICGetProp_Fallback* stub,
+                                       HandlePropertyName name, HandleValue val,
+                                       bool* attached)
+{
+    MOZ_ASSERT(!*attached);
+
+    if (!val.isObject())
+        return true;
+
+    RootedObject obj(cx, &val.toObject());
+
+    // Don't attach stubs for CALLPROP since those need NoSuchMethod handling.
+    if (JSOp(*pc) == JSOP_CALLPROP)
+        return true;
+
+    // Check if does-not-exist can be confirmed on property.
+    RootedObject lastProto(cx);
+    size_t protoChainDepth = SIZE_MAX;
+    if (!CheckHasNoSuchProperty(cx, obj, name, &lastProto, &protoChainDepth))
+        return true;
+    MOZ_ASSERT(protoChainDepth < SIZE_MAX);
+
+    if (protoChainDepth > ICGetProp_NativeDoesNotExist::MAX_PROTO_CHAIN_DEPTH)
+        return true;
+
+    ICStub* monitorStub = stub->fallbackMonitorStub()->firstMonitorStub();
+
+    // Confirmed no-such-property.  Add stub.
+    JitSpew(JitSpew_BaselineIC, "  Generating GetProp_NativeDoesNotExist stub");
+    ICGetPropNativeDoesNotExistCompiler compiler(cx, monitorStub, obj, protoChainDepth);
+    ICStub* newStub = compiler.getStub(compiler.getStubSpace(script));
+    if (!newStub)
+        return false;
+
+    stub->addNewStub(newStub);
+    *attached = true;
+    return true;
+}
+
+static bool
+ComputeGetPropResult(JSContext* cx, BaselineFrame* frame, JSOp op, HandlePropertyName name,
+                     MutableHandleValue val, MutableHandleValue res)
+{
+    // Handle arguments.length and arguments.callee on optimized arguments, as
+    // it is not an object.
+    if (val.isMagic(JS_OPTIMIZED_ARGUMENTS) && IsOptimizedArguments(frame, val)) {
+        if (op == JSOP_LENGTH) {
+            res.setInt32(frame->numActualArgs());
+        } else {
+            MOZ_ASSERT(name == cx->names().callee);
+            MOZ_ASSERT(frame->script()->hasMappedArgsObj());
+            res.setObject(*frame->callee());
+        }
+    } else {
+        if (op == JSOP_GETXPROP) {
+            RootedObject obj(cx, &val.toObject());
+            RootedId id(cx, NameToId(name));
+            if (!GetPropertyForNameLookup(cx, obj, id, res))
+                return false;
+        } else {
+            MOZ_ASSERT(op == JSOP_GETPROP || op == JSOP_CALLPROP || op == JSOP_LENGTH);
+            if (!GetProperty(cx, val, name, res))
+                return false;
+        }
+    }
+
+    return true;
+}
+
+static bool
+DoGetPropFallback(JSContext* cx, BaselineFrame* frame, ICGetProp_Fallback* stub_,
+                  MutableHandleValue val, MutableHandleValue res)
+{
+    // This fallback stub may trigger debug mode toggling.
+    DebugModeOSRVolatileStub<ICGetProp_Fallback*> stub(frame, stub_);
+
+    jsbytecode* pc = stub->icEntry()->pc(frame->script());
+    JSOp op = JSOp(*pc);
+    FallbackICSpew(cx, stub, "GetProp(%s)", js_CodeName[op]);
+
+    MOZ_ASSERT(op == JSOP_GETPROP || op == JSOP_CALLPROP || op == JSOP_LENGTH || op == JSOP_GETXPROP);
+
+    // Grab our old shape before it goes away.
+    RootedShape oldShape(cx);
+    if (val.isObject())
+        oldShape = val.toObject().maybeShape();
+
+    bool attached = false;
+    // There are some reasons we can fail to attach a stub that are temporary.
+    // We want to avoid calling noteUnoptimizableAccess() if the reason we
+    // failed to attach a stub is one of those temporary reasons, since we might
+    // end up attaching a stub for the exact same access later.
+    bool isTemporarilyUnoptimizable = false;
+
+    RootedScript script(cx, frame->script());
+    RootedPropertyName name(cx, frame->script()->getName(pc));
+
+    // After the  Genericstub was added, we should never reach the Fallbackstub again.
+    MOZ_ASSERT(!stub->hasStub(ICStub::GetProp_Generic));
+
+    if (stub->numOptimizedStubs() >= ICGetProp_Fallback::MAX_OPTIMIZED_STUBS) {
+        // Discard all stubs in this IC and replace with generic getprop stub.
+        for(ICStubIterator iter = stub->beginChain(); !iter.atEnd(); iter++)
+            iter.unlink(cx);
+        ICGetProp_Generic::Compiler compiler(cx, stub->fallbackMonitorStub()->firstMonitorStub());
+        ICStub* newStub = compiler.getStub(compiler.getStubSpace(script));
+        if (!newStub)
+            return false;
+        stub->addNewStub(newStub);
+        attached = true;
+    }
+
+    if (!attached && !TryAttachNativeGetAccessorPropStub(cx, script, pc, stub, name, val, res,
+                                                         &attached, &isTemporarilyUnoptimizable))
+    {
+        return false;
+    }
+
+    if (!ComputeGetPropResult(cx, frame, op, name, val, res))
+        return false;
+
+    TypeScript::Monitor(cx, script, pc, res);
+
+    // Check if debug mode toggling made the stub invalid.
+    if (stub.invalid())
+        return true;
+
+    // Add a type monitor stub for the resulting value.
+    if (!stub->addMonitorStubForValue(cx, script, res))
+        return false;
+
+    if (attached)
+        return true;
+
+    if (op == JSOP_LENGTH) {
+        if (!TryAttachLengthStub(cx, script, stub, val, res, &attached))
+            return false;
+        if (attached)
+            return true;
+    }
+
+    if (!TryAttachMagicArgumentsGetPropStub(cx, script, stub, name, val, res, &attached))
+        return false;
+    if (attached)
+        return true;
+
+    if (!TryAttachNativeGetValuePropStub(cx, script, pc, stub, name, val, oldShape,
+                                         res, &attached))
+        return false;
+    if (attached)
+        return true;
+
+    if (!TryAttachUnboxedGetPropStub(cx, script, stub, name, val, &attached))
+        return false;
+    if (attached)
+        return true;
+
+    if (!TryAttachUnboxedExpandoGetPropStub(cx, script, pc, stub, name, val, &attached))
+        return false;
+    if (attached)
+        return true;
+
+    if (!TryAttachTypedObjectGetPropStub(cx, script, stub, name, val, &attached))
+        return false;
+    if (attached)
+        return true;
+
+    if (val.isString() || val.isNumber() || val.isBoolean()) {
+        if (!TryAttachPrimitiveGetPropStub(cx, script, pc, stub, name, val, res, &attached))
+            return false;
+        if (attached)
+            return true;
+    }
+
+    if (res.isUndefined()) {
+        // Try attaching property-not-found optimized stub for undefined results.
+        if (!TryAttachNativeGetPropDoesNotExistStub(cx, script, pc, stub, name, val, &attached))
+            return false;
+        if (attached)
+            return true;
+    }
+
+    MOZ_ASSERT(!attached);
+    if (!isTemporarilyUnoptimizable)
+        stub->noteUnoptimizableAccess();
+
+    return true;
+}
+
+typedef bool (*DoGetPropFallbackFn)(JSContext*, BaselineFrame*, ICGetProp_Fallback*,
+                                    MutableHandleValue, MutableHandleValue);
+static const VMFunction DoGetPropFallbackInfo =
+    FunctionInfo<DoGetPropFallbackFn>(DoGetPropFallback, TailCall, PopValues(1));
+
+bool
+ICGetProp_Fallback::Compiler::generateStubCode(MacroAssembler& masm)
+{
+    MOZ_ASSERT(engine_ == Engine::Baseline);
+    MOZ_ASSERT(R0 == JSReturnOperand);
+
+    EmitRestoreTailCallReg(masm);
+
+    // Ensure stack is fully synced for the expression decompiler.
+    masm.pushValue(R0);
+
+    // Push arguments.
+    masm.pushValue(R0);
+    masm.push(ICStubReg);
+    pushFramePtr(masm, R0.scratchReg());
+
+    if (!tailCallVM(DoGetPropFallbackInfo, masm))
+        return false;
+
+    // What follows is bailout for inlined scripted getters.
+    // The return address pointed to by the baseline stack points here.
+    returnOffset_ = masm.currentOffset();
+
+    // Even though the fallback frame doesn't enter a stub frame, the CallScripted
+    // frame that we are emulating does. Again, we lie.
+    inStubFrame_ = true;
+#ifdef DEBUG
+    entersStubFrame_ = true;
+#endif
+
+    leaveStubFrame(masm, true);
+
+    // When we get here, ICStubReg contains the ICGetProp_Fallback stub,
+    // which we can't use to enter the TypeMonitor IC, because it's a MonitoredFallbackStub
+    // instead of a MonitoredStub. So, we cheat.
+    masm.loadPtr(Address(ICStubReg, ICMonitoredFallbackStub::offsetOfFallbackMonitorStub()),
+                 ICStubReg);
+    EmitEnterTypeMonitorIC(masm, ICTypeMonitor_Fallback::offsetOfFirstMonitorStub());
+
+    return true;
+}
+
+void
+ICGetProp_Fallback::Compiler::postGenerateStubCode(MacroAssembler& masm, Handle<JitCode*> code)
+{
+    cx->compartment()->jitCompartment()->initBaselineGetPropReturnAddr(code->raw() + returnOffset_);
+}
+
+bool
+ICGetProp_ArrayLength::Compiler::generateStubCode(MacroAssembler& masm)
+{
+    MOZ_ASSERT(engine_ == Engine::Baseline);
+
+    Label failure;
+    masm.branchTestObject(Assembler::NotEqual, R0, &failure);
+
+    Register scratch = R1.scratchReg();
+
+    // Unbox R0 and guard it's an array.
+    Register obj = masm.extractObject(R0, ExtractTemp0);
+    masm.branchTestObjClass(Assembler::NotEqual, obj, scratch, &ArrayObject::class_, &failure);
+
+    // Load obj->elements->length.
+    masm.loadPtr(Address(obj, NativeObject::offsetOfElements()), scratch);
+    masm.load32(Address(scratch, ObjectElements::offsetOfLength()), scratch);
+
+    // Guard length fits in an int32.
+    masm.branchTest32(Assembler::Signed, scratch, scratch, &failure);
+
+    masm.tagValue(JSVAL_TYPE_INT32, scratch, R0);
+    EmitReturnFromIC(masm);
+
+    // Failure case - jump to next stub
+    masm.bind(&failure);
+    EmitStubGuardFailure(masm);
+    return true;
+}
+
+bool
+ICGetProp_UnboxedArrayLength::Compiler::generateStubCode(MacroAssembler& masm)
+{
+    MOZ_ASSERT(engine_ == Engine::Baseline);
+
+    Label failure;
+    masm.branchTestObject(Assembler::NotEqual, R0, &failure);
+
+    Register scratch = R1.scratchReg();
+
+    // Unbox R0 and guard it's an unboxed array.
+    Register obj = masm.extractObject(R0, ExtractTemp0);
+    masm.branchTestObjClass(Assembler::NotEqual, obj, scratch, &UnboxedArrayObject::class_, &failure);
+
+    // Load obj->length.
+    masm.load32(Address(obj, UnboxedArrayObject::offsetOfLength()), scratch);
+
+    masm.tagValue(JSVAL_TYPE_INT32, scratch, R0);
+    EmitReturnFromIC(masm);
+
+    // Failure case - jump to next stub
+    masm.bind(&failure);
+    EmitStubGuardFailure(masm);
+    return true;
+}
+
+bool
+ICGetProp_StringLength::Compiler::generateStubCode(MacroAssembler& masm)
+{
+    MOZ_ASSERT(engine_ == Engine::Baseline);
+
+    Label failure;
+    masm.branchTestString(Assembler::NotEqual, R0, &failure);
+
+    // Unbox string and load its length.
+    Register string = masm.extractString(R0, ExtractTemp0);
+    masm.loadStringLength(string, string);
+
+    masm.tagValue(JSVAL_TYPE_INT32, string, R0);
+    EmitReturnFromIC(masm);
+
+    // Failure case - jump to next stub
+    masm.bind(&failure);
+    EmitStubGuardFailure(masm);
+    return true;
+}
+
+bool
+ICGetProp_Primitive::Compiler::generateStubCode(MacroAssembler& masm)
+{
+    MOZ_ASSERT(engine_ == Engine::Baseline);
+
+    Label failure;
+    switch (primitiveType_) {
+      case JSVAL_TYPE_STRING:
+        masm.branchTestString(Assembler::NotEqual, R0, &failure);
+        break;
+      case JSVAL_TYPE_SYMBOL:
+        masm.branchTestSymbol(Assembler::NotEqual, R0, &failure);
+        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");
+    }
+
+    AllocatableGeneralRegisterSet regs(availableGeneralRegs(1));
+    Register holderReg = regs.takeAny();
+    Register scratchReg = regs.takeAny();
+
+    // Verify the shape of the prototype.
+    masm.movePtr(ImmGCPtr(prototype_.get()), holderReg);
+
+    Address shapeAddr(ICStubReg, ICGetProp_Primitive::offsetOfProtoShape());
+    masm.loadPtr(Address(holderReg, JSObject::offsetOfShape()), scratchReg);
+    masm.branchPtr(Assembler::NotEqual, shapeAddr, scratchReg, &failure);
+
+    if (!isFixedSlot_)
+        masm.loadPtr(Address(holderReg, NativeObject::offsetOfSlots()), holderReg);
+
+    masm.load32(Address(ICStubReg, ICGetProp_Primitive::offsetOfOffset()), scratchReg);
+    masm.loadValue(BaseIndex(holderReg, scratchReg, TimesOne), R0);
+
+    // Enter type monitor IC to type-check result.
+    EmitEnterTypeMonitorIC(masm);
+
+    // Failure case - jump to next stub
+    masm.bind(&failure);
+    EmitStubGuardFailure(masm);
+    return true;
+}
+
+ICGetPropNativeStub*
+ICGetPropNativeCompiler::getStub(ICStubSpace* space)
+{
+    ReceiverGuard guard(obj_);
+
+    switch (kind) {
+      case ICStub::GetProp_Native: {
+        MOZ_ASSERT(obj_ == holder_);
+        return newStub<ICGetProp_Native>(space, getStubCode(), firstMonitorStub_, guard, offset_);
+      }
+
+      case ICStub::GetProp_NativePrototype: {
+        MOZ_ASSERT(obj_ != holder_);
+        Shape* holderShape = holder_->as<NativeObject>().lastProperty();
+        return newStub<ICGetProp_NativePrototype>(space, getStubCode(), firstMonitorStub_, guard,
+                                                  offset_, holder_, holderShape);
+      }
+
+      case ICStub::GetName_Global: {
+        MOZ_ASSERT(obj_ != holder_);
+        Shape* holderShape = holder_->as<NativeObject>().lastProperty();
+        Shape* globalShape = obj_->as<ClonedBlockObject>().global().lastProperty();
+        return newStub<ICGetName_Global>(space, getStubCode(), firstMonitorStub_, guard,
+                                         offset_, holder_, holderShape, globalShape);
+      }
+
+      default:
+        MOZ_CRASH("Bad stub kind");
+    }
+}
+
+void
+GuardReceiverObject(MacroAssembler& masm, ReceiverGuard guard,
+                    Register object, Register scratch,
+                    size_t receiverGuardOffset, Label* failure)
+{
+    Address groupAddress(ICStubReg, receiverGuardOffset + HeapReceiverGuard::offsetOfGroup());
+    Address shapeAddress(ICStubReg, receiverGuardOffset + HeapReceiverGuard::offsetOfShape());
+    Address expandoAddress(object, UnboxedPlainObject::offsetOfExpando());
+
+    if (guard.group) {
+        masm.loadPtr(groupAddress, scratch);
+        masm.branchTestObjGroup(Assembler::NotEqual, object, scratch, failure);
+
+        if (guard.group->clasp() == &UnboxedPlainObject::class_ && !guard.shape) {
+            // Guard the unboxed object has no expando object.
+            masm.branchPtr(Assembler::NotEqual, expandoAddress, ImmWord(0), failure);
+        }
+    }
+
+    if (guard.shape) {
+        masm.loadPtr(shapeAddress, scratch);
+        if (guard.group && guard.group->clasp() == &UnboxedPlainObject::class_) {
+            // Guard the unboxed object has a matching expando object.
+            masm.branchPtr(Assembler::Equal, expandoAddress, ImmWord(0), failure);
+            Label done;
+            masm.push(object);
+            masm.loadPtr(expandoAddress, object);
+            masm.branchTestObjShape(Assembler::Equal, object, scratch, &done);
+            masm.pop(object);
+            masm.jump(failure);
+            masm.bind(&done);
+            masm.pop(object);
+        } else {
+            masm.branchTestObjShape(Assembler::NotEqual, object, scratch, failure);
+        }
+    }
+}
+
+static void
+GuardGlobalObject(MacroAssembler& masm, HandleObject holder, Register globalLexicalReg,
+                  Register holderReg, Register scratch, size_t globalShapeOffset, Label* failure)
+{
+    if (holder->is<GlobalObject>())
+        return;
+    masm.extractObject(Address(globalLexicalReg, ScopeObject::offsetOfEnclosingScope()),
+                       holderReg);
+    masm.loadPtr(Address(ICStubReg, globalShapeOffset), scratch);
+    masm.branchTestObjShape(Assembler::NotEqual, holderReg, scratch, failure);
+}
+
+bool
+ICGetPropNativeCompiler::generateStubCode(MacroAssembler& masm)
+{
+    MOZ_ASSERT(engine_ == Engine::Baseline);
+
+    Label failure;
+    AllocatableGeneralRegisterSet regs(availableGeneralRegs(0));
+    Register objReg = InvalidReg;
+
+    if (inputDefinitelyObject_) {
+        objReg = R0.scratchReg();
+    } else {
+        regs.take(R0);
+        // Guard input is an object and unbox.
+        masm.branchTestObject(Assembler::NotEqual, R0, &failure);
+        objReg = masm.extractObject(R0, ExtractTemp0);
+    }
+    regs.takeUnchecked(objReg);
+
+    Register scratch = regs.takeAnyExcluding(ICTailCallReg);
+
+    // Shape/group guard.
+    GuardReceiverObject(masm, ReceiverGuard(obj_), objReg, scratch,
+                        ICGetPropNativeStub::offsetOfReceiverGuard(), &failure);
+
+    Register holderReg;
+    if (obj_ == holder_) {
+        MOZ_ASSERT(kind != ICStub::GetName_Global);
+        if (obj_->is<UnboxedPlainObject>()) {
+            // We are loading off the expando object, so use that for the holder.
+            holderReg = regs.takeAny();
+            masm.loadPtr(Address(objReg, UnboxedPlainObject::offsetOfExpando()), holderReg);
+        } else {
+            holderReg = objReg;
+        }
+    } else {
+        holderReg = regs.takeAny();
+
+        // If we are generating a non-lexical GETGNAME stub, we must also
+        // guard on the shape of the GlobalObject.
+        if (kind == ICStub::GetName_Global) {
+            MOZ_ASSERT(obj_->is<ClonedBlockObject>() && obj_->as<ClonedBlockObject>().isGlobal());
+            GuardGlobalObject(masm, holder_, objReg, holderReg, scratch,
+                              ICGetName_Global::offsetOfGlobalShape(), &failure);
+        }
+
+        // Shape guard holder.
+        masm.loadPtr(Address(ICStubReg, ICGetProp_NativePrototype::offsetOfHolder()),
+                     holderReg);
+        masm.loadPtr(Address(ICStubReg, ICGetProp_NativePrototype::offsetOfHolderShape()),
+                     scratch);
+        masm.branchTestObjShape(Assembler::NotEqual, holderReg, scratch, &failure);
+    }
+
+    if (!isFixedSlot_) {
+        // Don't overwrite actual holderReg if we need to load a dynamic slots object.
+        // May need to preserve object for noSuchMethod check later.
+        Register nextHolder = regs.takeAny();
+        masm.loadPtr(Address(holderReg, NativeObject::offsetOfSlots()), nextHolder);
+        holderReg = nextHolder;
+    }
+
+    masm.load32(Address(ICStubReg, ICGetPropNativeStub::offsetOfOffset()), scratch);
+    BaseIndex result(holderReg, scratch, TimesOne);
+
+    masm.loadValue(result, R0);
+
+    // Enter type monitor IC to type-check result.
+    EmitEnterTypeMonitorIC(masm);
+
+    // Failure case - jump to next stub
+    masm.bind(&failure);
+    EmitStubGuardFailure(masm);
+    return true;
+}
+
+bool
+GetProtoShapes(JSObject* obj, size_t protoChainDepth, MutableHandle<ShapeVector> shapes)
+{
+    JSObject* curProto = obj->getProto();
+    for (size_t i = 0; i < protoChainDepth; i++) {
+        if (!shapes.append(curProto->as<NativeObject>().lastProperty()))
+            return false;
+        curProto = curProto->getProto();
+    }
+    MOZ_ASSERT(!curProto);
+    return true;
+}
+
+ICStub*
+ICGetPropNativeDoesNotExistCompiler::getStub(ICStubSpace* space)
+{
+    Rooted<ShapeVector> shapes(cx, ShapeVector(cx));
+
+    if (!GetProtoShapes(obj_, protoChainDepth_, &shapes))
+        return nullptr;
+
+    JS_STATIC_ASSERT(ICGetProp_NativeDoesNotExist::MAX_PROTO_CHAIN_DEPTH == 8);
+
+    ICStub* 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;
+      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.");
+    }
+    if (!stub)
+        return nullptr;
+    return stub;
+}
+
+bool
+ICGetPropNativeDoesNotExistCompiler::generateStubCode(MacroAssembler& masm)
+{
+    MOZ_ASSERT(engine_ == Engine::Baseline);
+
+    Label failure;
+
+    AllocatableGeneralRegisterSet regs(availableGeneralRegs(1));
+    Register scratch = regs.takeAny();
+
+#ifdef DEBUG
+    // Ensure that protoChainDepth_ matches the protoChainDepth stored on the stub.
+    {
+        Label ok;
+        masm.load16ZeroExtend(Address(ICStubReg, ICStub::offsetOfExtra()), scratch);
+        masm.branch32(Assembler::Equal, scratch, Imm32(protoChainDepth_), &ok);
+        masm.assumeUnreachable("Non-matching proto chain depth on stub.");
+        masm.bind(&ok);
+    }
+#endif // DEBUG
+
+    // Guard input is an object.
+    masm.branchTestObject(Assembler::NotEqual, R0, &failure);
+
+    // Unbox and guard against old shape/group.
+    Register objReg = masm.extractObject(R0, ExtractTemp0);
+    GuardReceiverObject(masm, ReceiverGuard(obj_), objReg, scratch,
+                        ICGetProp_NativeDoesNotExist::offsetOfGuard(), &failure);
+
+    Register protoReg = regs.takeAny();
+    // Check the proto chain.
+    for (size_t i = 0; i < protoChainDepth_; i++) {
+        masm.loadObjProto(i == 0 ? objReg : protoReg, protoReg);
+        masm.branchTestPtr(Assembler::Zero, protoReg, protoReg, &failure);
+        size_t shapeOffset = ICGetProp_NativeDoesNotExistImpl<0>::offsetOfShape(i);
+        masm.loadPtr(Address(ICStubReg, shapeOffset), scratch);
+        masm.branchTestObjShape(Assembler::NotEqual, protoReg, scratch, &failure);
+    }
+
+    // Shape and type checks succeeded, ok to proceed.
+    masm.moveValue(UndefinedValue(), R0);
+
+    // Normally for this op, the result would have to be monitored by TI.
+    // However, since this stub ALWAYS returns UndefinedValue(), and we can be sure
+    // that undefined is already registered with the type-set, this can be avoided.
+    EmitReturnFromIC(masm);
+
+    masm.bind(&failure);
+    EmitStubGuardFailure(masm);
+    return true;
+}
+
+bool
+ICGetProp_CallScripted::Compiler::generateStubCode(MacroAssembler& masm)
+{
+    MOZ_ASSERT(engine_ == Engine::Baseline);
+
+    Label failure;
+    Label failureLeaveStubFrame;
+    AllocatableGeneralRegisterSet regs(availableGeneralRegs(1));
+    Register scratch = regs.takeAnyExcluding(ICTailCallReg);
+
+    // Guard input is an object.
+    masm.branchTestObject(Assembler::NotEqual, R0, &failure);
+
+    // Unbox and shape guard.
+    Register objReg = masm.extractObject(R0, ExtractTemp0);
+    GuardReceiverObject(masm, ReceiverGuard(receiver_), objReg, scratch,
+                        ICGetProp_CallScripted::offsetOfReceiverGuard(), &failure);
+
+    if (receiver_ != holder_) {
+        Register holderReg = regs.takeAny();
+        masm.loadPtr(Address(ICStubReg, ICGetProp_CallScripted::offsetOfHolder()), holderReg);
+        masm.loadPtr(Address(ICStubReg, ICGetProp_CallScripted::offsetOfHolderShape()), scratch);
+        masm.branchTestObjShape(Assembler::NotEqual, holderReg, scratch, &failure);
+        regs.add(holderReg);
+    }
+
+    // Push a stub frame so that we can perform a non-tail call.
+    enterStubFrame(masm, scratch);
+
+    // Load callee function and code.  To ensure that |code| doesn't end up being
+    // ArgumentsRectifierReg, if it's available we assign it to |callee| instead.
+    Register callee;
+    if (regs.has(ArgumentsRectifierReg)) {
+        callee = ArgumentsRectifierReg;
+        regs.take(callee);
+    } else {
+        callee = regs.takeAny();
+    }
+    Register code = regs.takeAny();
+    masm.loadPtr(Address(ICStubReg, ICGetProp_CallScripted::offsetOfGetter()), callee);
+    masm.branchIfFunctionHasNoScript(callee, &failureLeaveStubFrame);
+    masm.loadPtr(Address(callee, JSFunction::offsetOfNativeOrScript()), code);
+    masm.loadBaselineOrIonRaw(code, code, &failureLeaveStubFrame);
+
+    // Align the stack such that the JitFrameLayout is aligned on
+    // JitStackAlignment.
+    masm.alignJitStackBasedOnNArgs(0);
+
+    // Getter is called with 0 arguments, just |obj| as thisv.
+    // Note that we use Push, not push, so that callJit will align the stack
+    // properly on ARM.
+    masm.Push(R0);
+    EmitBaselineCreateStubFrameDescriptor(masm, scratch);
+    masm.Push(Imm32(0));  // ActualArgc is 0
+    masm.Push(callee);
+    masm.Push(scratch);
+
+    // Handle arguments underflow.
+    Label noUnderflow;
+    masm.load16ZeroExtend(Address(callee, JSFunction::offsetOfNargs()), scratch);
+    masm.branch32(Assembler::Equal, scratch, Imm32(0), &noUnderflow);
+    {
+        // Call the arguments rectifier.
+        MOZ_ASSERT(ArgumentsRectifierReg != code);
+
+        JitCode* argumentsRectifier =
+            cx->runtime()->jitRuntime()->getArgumentsRectifier();
+
+        masm.movePtr(ImmGCPtr(argumentsRectifier), code);
+        masm.loadPtr(Address(code, JitCode::offsetOfCode()), code);
+        masm.movePtr(ImmWord(0), ArgumentsRectifierReg);
+    }
+
+    masm.bind(&noUnderflow);
+    masm.callJit(code);
+
+    leaveStubFrame(masm, true);
+
+    // Enter type monitor IC to type-check result.
+    EmitEnterTypeMonitorIC(masm);
+
+    // Leave stub frame and go to next stub.
+    masm.bind(&failureLeaveStubFrame);
+    inStubFrame_ = true;
+    leaveStubFrame(masm, false);
+
+    // Failure case - jump to next stub
+    masm.bind(&failure);
+    EmitStubGuardFailure(masm);
+    return true;
+}
+
+//
+// VM function to help call native getters.
+//
+
+bool
+DoCallNativeGetter(JSContext* cx, HandleFunction callee, HandleObject obj,
+                   MutableHandleValue result)
+{
+    MOZ_ASSERT(callee->isNative());
+    JSNative natfun = callee->native();
+
+    JS::AutoValueArray<2> vp(cx);
+    vp[0].setObject(*callee.get());
+    vp[1].setObject(*obj.get());
+
+    if (!natfun(cx, 0, vp.begin()))
+        return false;
+
+    result.set(vp[0]);
+    return true;
+}
+
+typedef bool (*DoCallNativeGetterFn)(JSContext*, HandleFunction, HandleObject, MutableHandleValue);
+static const VMFunction DoCallNativeGetterInfo =
+    FunctionInfo<DoCallNativeGetterFn>(DoCallNativeGetter);
+
+bool
+ICGetPropCallNativeCompiler::generateStubCode(MacroAssembler& masm)
+{
+    MOZ_ASSERT(engine_ == Engine::Baseline);
+
+    Label failure;
+
+    AllocatableGeneralRegisterSet regs(availableGeneralRegs(1));
+    Register objReg = InvalidReg;
+
+    MOZ_ASSERT(!(inputDefinitelyObject_ && outerClass_));
+    if (inputDefinitelyObject_) {
+        objReg = R0.scratchReg();
+    } else {
+        // Guard input is an object and unbox.
+        masm.branchTestObject(Assembler::NotEqual, R0, &failure);
+        objReg = masm.extractObject(R0, ExtractTemp0);
+        if (outerClass_) {
+            Register tmp = regs.takeAny();
+            masm.branchTestObjClass(Assembler::NotEqual, objReg, tmp, outerClass_, &failure);
+            masm.movePtr(ImmGCPtr(cx->global()), objReg);
+            regs.add(tmp);
+        }
+    }
+
+    Register scratch = regs.takeAnyExcluding(ICTailCallReg);
+
+    // Shape guard.
+    GuardReceiverObject(masm, ReceiverGuard(receiver_), objReg, scratch,
+                        ICGetPropCallGetter::offsetOfReceiverGuard(), &failure);
+
+    if (receiver_ != holder_) {
+        Register holderReg = regs.takeAny();
+
+        // If we are generating a non-lexical GETGNAME stub, we must also
+        // guard on the shape of the GlobalObject.
+        if (kind == ICStub::GetProp_CallNativeGlobal) {
+            MOZ_ASSERT(receiver_->is<ClonedBlockObject>() &&
+                       receiver_->as<ClonedBlockObject>().isGlobal());
+            GuardGlobalObject(masm, holder_, objReg, holderReg, scratch,
+                              ICGetProp_CallNativeGlobal::offsetOfGlobalShape(), &failure);
+        }
+
+        masm.loadPtr(Address(ICStubReg, ICGetPropCallGetter::offsetOfHolder()), holderReg);
+        masm.loadPtr(Address(ICStubReg, ICGetPropCallGetter::offsetOfHolderShape()), scratch);
+        masm.branchTestObjShape(Assembler::NotEqual, holderReg, scratch, &failure);
+        regs.add(holderReg);
+    }
+
+    // Box and push obj onto baseline frame stack for decompiler
+    if (inputDefinitelyObject_)
+        masm.tagValue(JSVAL_TYPE_OBJECT, objReg, R0);
+    EmitStowICValues(masm, 1);
+    if (inputDefinitelyObject_)
+        objReg = masm.extractObject(R0, ExtractTemp0);
+
+    // Push a stub frame so that we can perform a non-tail call.
+    enterStubFrame(masm, scratch);
+
+    // Load callee function.
+    Register callee = regs.takeAny();
+    masm.loadPtr(Address(ICStubReg, ICGetPropCallGetter::offsetOfGetter()), callee);
+
+    // If we're calling a getter on the global, inline the logic for the
+    // 'this' hook on the global lexical scope and manually push the global.
+    if (kind == ICStub::GetProp_CallNativeGlobal)
+        masm.extractObject(Address(objReg, ScopeObject::offsetOfEnclosingScope()), objReg);
+
+    // Push args for vm call.
+    masm.push(objReg);
+    masm.push(callee);
+
+    regs.add(R0);
+
+    if (!callVM(DoCallNativeGetterInfo, masm))
+        return false;
+    leaveStubFrame(masm);
+
+    EmitUnstowICValues(masm, 1, /* discard = */true);
+
+    // Enter type monitor IC to type-check result.
+    EmitEnterTypeMonitorIC(masm);
+
+    // Failure case - jump to next stub
+    masm.bind(&failure);
+    EmitStubGuardFailure(masm);
+    return true;
+}
+
+ICStub*
+ICGetPropCallNativeCompiler::getStub(ICStubSpace* space)
+{
+    ReceiverGuard guard(receiver_);
+    Shape* holderShape = holder_->as<NativeObject>().lastProperty();
+
+    switch (kind) {
+      case ICStub::GetProp_CallNative:
+        return newStub<ICGetProp_CallNative>(space, getStubCode(), firstMonitorStub_,
+                                             guard, holder_, holderShape,
+                                             getter_, pcOffset_);
+
+      case ICStub::GetProp_CallNativeGlobal: {
+        Shape* globalShape = receiver_->as<ClonedBlockObject>().global().lastProperty();
+        return newStub<ICGetProp_CallNativeGlobal>(space, getStubCode(), firstMonitorStub_,
+                                                   guard, holder_, holderShape, globalShape,
+                                                   getter_, pcOffset_);
+      }
+
+      default:
+        MOZ_CRASH("Bad stub kind");
+    }
+}
+
+// Callers are expected to have already guarded on the shape of the
+// object, which guarantees the object is a DOM proxy.
+void
+CheckDOMProxyExpandoDoesNotShadow(JSContext* cx, MacroAssembler& masm, Register object,
+                                  const Address& checkExpandoShapeAddr,
+                                  Address* expandoAndGenerationAddr,
+                                  Address* generationAddr,
+                                  Register scratch,
+                                  AllocatableGeneralRegisterSet& domProxyRegSet,
+                                  Label* checkFailed)
+{
+    // Guard that the object does not have expando properties, or has an expando
+    // which is known to not have the desired property.
+
+    // For the remaining code, we need to reserve some registers to load a value.
+    // This is ugly, but unavoidable.
+    ValueOperand tempVal = domProxyRegSet.takeAnyValue();
+    masm.pushValue(tempVal);
+
+    Label failDOMProxyCheck;
+    Label domProxyOk;
+
+    masm.loadPtr(Address(object, ProxyObject::offsetOfValues()), scratch);
+    Address expandoAddr(scratch, ProxyObject::offsetOfExtraSlotInValues(GetDOMProxyExpandoSlot()));
+
+    if (expandoAndGenerationAddr) {
+        MOZ_ASSERT(generationAddr);
+
+        masm.loadPtr(*expandoAndGenerationAddr, tempVal.scratchReg());
+        masm.branchPrivatePtr(Assembler::NotEqual, expandoAddr, tempVal.scratchReg(),
+                              &failDOMProxyCheck);
+
+        masm.load32(*generationAddr, scratch);
+        masm.branch32(Assembler::NotEqual,
+                      Address(tempVal.scratchReg(), offsetof(ExpandoAndGeneration, generation)),
+                      scratch, &failDOMProxyCheck);
+
+        masm.loadValue(Address(tempVal.scratchReg(), 0), tempVal);
+    } else {
+        masm.loadValue(expandoAddr, tempVal);
+    }
+
+    // If the incoming object does not have an expando object then we're sure we're not
+    // shadowing.
+    masm.branchTestUndefined(Assembler::Equal, tempVal, &domProxyOk);
+
+    // The reference object used to generate this check may not have had an
+    // expando object at all, in which case the presence of a non-undefined
+    // expando value in the incoming object is automatically a failure.
+    masm.loadPtr(checkExpandoShapeAddr, scratch);
+    masm.branchPtr(Assembler::Equal, scratch, ImmPtr(nullptr), &failDOMProxyCheck);
+
+    // Otherwise, ensure that the incoming object has an object for its expando value and that
+    // the shape matches.
+    masm.branchTestObject(Assembler::NotEqual, tempVal, &failDOMProxyCheck);
+    Register objReg = masm.extractObject(tempVal, tempVal.scratchReg());
+    masm.branchTestObjShape(Assembler::Equal, objReg, scratch, &domProxyOk);
+
+    // Failure case: restore the tempVal registers and jump to failures.
+    masm.bind(&failDOMProxyCheck);
+    masm.popValue(tempVal);
+    masm.jump(checkFailed);
+
+    // Success case: restore the tempval and proceed.
+    masm.bind(&domProxyOk);
+    masm.popValue(tempVal);
+}
+
+bool
+ICGetPropCallDOMProxyNativeCompiler::generateStubCode(MacroAssembler& masm,
+                                                      Address* expandoAndGenerationAddr,
+                                                      Address* generationAddr)
+{
+    MOZ_ASSERT(engine_ == Engine::Baseline);
+
+    Label failure;
+    AllocatableGeneralRegisterSet regs(availableGeneralRegs(1));
+    Register scratch = regs.takeAnyExcluding(ICTailCallReg);
+
+    // Guard input is an object.
+    masm.branchTestObject(Assembler::NotEqual, R0, &failure);
+
+    // Unbox.
+    Register objReg = masm.extractObject(R0, ExtractTemp0);
+
+    // Shape guard.
+    static const size_t receiverShapeOffset =
+        ICGetProp_CallDOMProxyNative::offsetOfReceiverGuard() +
+        HeapReceiverGuard::offsetOfShape();
+    masm.loadPtr(Address(ICStubReg, receiverShapeOffset), scratch);
+    masm.branchTestObjShape(Assembler::NotEqual, objReg, scratch, &failure);
+
+    // Guard that our expando object hasn't started shadowing this property.
+    {
+        AllocatableGeneralRegisterSet domProxyRegSet(GeneralRegisterSet::All());
+        domProxyRegSet.take(ICStubReg);
+        domProxyRegSet.take(objReg);
+        domProxyRegSet.take(scratch);
+        Address expandoShapeAddr(ICStubReg, ICGetProp_CallDOMProxyNative::offsetOfExpandoShape());
+        CheckDOMProxyExpandoDoesNotShadow(
+                cx, masm, objReg,
+                expandoShapeAddr, expandoAndGenerationAddr, generationAddr,
+                scratch,
+                domProxyRegSet,
+                &failure);
+    }
+
+    Register holderReg = regs.takeAny();
+    masm.loadPtr(Address(ICStubReg, ICGetProp_CallDOMProxyNative::offsetOfHolder()),
+                 holderReg);
+    masm.loadPtr(Address(ICStubReg, ICGetProp_CallDOMProxyNative::offsetOfHolderShape()),
+                 scratch);
+    masm.branchTestObjShape(Assembler::NotEqual, holderReg, scratch, &failure);
+    regs.add(holderReg);
+
+    // Push a stub frame so that we can perform a non-tail call.
+    enterStubFrame(masm, scratch);
+
+    // Load callee function.
+    Register callee = regs.takeAny();
+    masm.loadPtr(Address(ICStubReg, ICGetProp_CallDOMProxyNative::offsetOfGetter()), callee);
+
+    // Push args for vm call.
+    masm.push(objReg);
+    masm.push(callee);
+
+    // Don't have to preserve R0 anymore.
+    regs.add(R0);
+
+    if (!callVM(DoCallNativeGetterInfo, masm))
+        return false;
+    leaveStubFrame(masm);
+
+    // Enter type monitor IC to type-check result.
+    EmitEnterTypeMonitorIC(masm);
+
+    // Failure case - jump to next stub
+    masm.bind(&failure);
+    EmitStubGuardFailure(masm);
+    return true;
+}
+
+bool
+ICGetPropCallDOMProxyNativeCompiler::generateStubCode(MacroAssembler& masm)
+{
+    MOZ_ASSERT(engine_ == Engine::Baseline);
+
+    if (kind == ICStub::GetProp_CallDOMProxyNative)
+        return generateStubCode(masm, nullptr, nullptr);
+
+    Address internalStructAddress(ICStubReg,
+        ICGetProp_CallDOMProxyWithGenerationNative::offsetOfInternalStruct());
+    Address generationAddress(ICStubReg,
+        ICGetProp_CallDOMProxyWithGenerationNative::offsetOfGeneration());
+    return generateStubCode(masm, &internalStructAddress, &generationAddress);
+}
+
+ICStub*
+ICGetPropCallDOMProxyNativeCompiler::getStub(ICStubSpace* space)
+{
+    RootedShape shape(cx, proxy_->maybeShape());
+    RootedShape holderShape(cx, holder_->as<NativeObject>().lastProperty());
+
+    Value expandoSlot = GetProxyExtra(proxy_, GetDOMProxyExpandoSlot());
+    RootedShape expandoShape(cx, nullptr);
+    ExpandoAndGeneration* expandoAndGeneration;
+    int32_t generation;
+    Value expandoVal;
+    if (kind == ICStub::GetProp_CallDOMProxyNative) {
+        expandoVal = expandoSlot;
+        expandoAndGeneration = nullptr;  // initialize to silence GCC warning
+        generation = 0;  // initialize to silence GCC warning
+    } else {
+        MOZ_ASSERT(kind == ICStub::GetProp_CallDOMProxyWithGenerationNative);
+        MOZ_ASSERT(!expandoSlot.isObject() && !expandoSlot.isUndefined());
+        expandoAndGeneration = (ExpandoAndGeneration*)expandoSlot.toPrivate();
+        expandoVal = expandoAndGeneration->expando;
+        generation = expandoAndGeneration->generation;
+    }
+
+    if (expandoVal.isObject())
+        expandoShape = expandoVal.toObject().as<NativeObject>().lastProperty();
+
+    if (kind == ICStub::GetProp_CallDOMProxyNative) {
+        return newStub<ICGetProp_CallDOMProxyNative>(
+            space, getStubCode(), firstMonitorStub_, shape,
+            expandoShape, holder_, holderShape, getter_, pcOffset_);
+    }
+
+    return newStub<ICGetProp_CallDOMProxyWithGenerationNative>(
+        space, getStubCode(), firstMonitorStub_, shape,
+        expandoAndGeneration, generation, expandoShape, holder_, holderShape, getter_,
+        pcOffset_);
+}
+
+ICStub*
+ICGetProp_DOMProxyShadowed::Compiler::getStub(ICStubSpace* space)
+{
+    RootedShape shape(cx, proxy_->maybeShape());
+    return New<ICGetProp_DOMProxyShadowed>(cx, space, getStubCode(), firstMonitorStub_, shape,
+                                           proxy_->handler(), name_, pcOffset_);
+}
+
+static bool
+ProxyGet(JSContext* cx, HandleObject proxy, HandlePropertyName name, MutableHandleValue vp)
+{
+    RootedValue receiver(cx, ObjectValue(*proxy));
+    RootedId id(cx, NameToId(name));
+    return Proxy::get(cx, proxy, receiver, id, vp);
+}
+
+typedef bool (*ProxyGetFn)(JSContext* cx, HandleObject proxy, HandlePropertyName name,
+                           MutableHandleValue vp);
+static const VMFunction ProxyGetInfo = FunctionInfo<ProxyGetFn>(ProxyGet);
+
+bool
+ICGetProp_DOMProxyShadowed::Compiler::generateStubCode(MacroAssembler& masm)
+{
+    MOZ_ASSERT(engine_ == Engine::Baseline);
+
+    Label failure;
+
+    AllocatableGeneralRegisterSet regs(availableGeneralRegs(1));
+    // Need to reserve a scratch register, but the scratch register should not be
+    // ICTailCallReg, because it's used for |enterStubFrame| which needs a
+    // non-ICTailCallReg scratch reg.
+    Register scratch = regs.takeAnyExcluding(ICTailCallReg);
+
+    // Guard input is an object.
+    masm.branchTestObject(Assembler::NotEqual, R0, &failure);
+
+    // Unbox.
+    Register objReg = masm.extractObject(R0, ExtractTemp0);
+
+    // Shape guard.
+    masm.loadPtr(Address(ICStubReg, ICGetProp_DOMProxyShadowed::offsetOfShape()), scratch);
+    masm.branchTestObjShape(Assembler::NotEqual, objReg, scratch, &failure);
+
+    // No need to do any more guards; it's safe to call ProxyGet even
+    // if we've since stopped shadowing.
+
+    // Call ProxyGet(JSContext* cx, HandleObject proxy, HandlePropertyName name, MutableHandleValue vp);
+
+    // Push a stub frame so that we can perform a non-tail call.
+    enterStubFrame(masm, scratch);
+
+    // Push property name and proxy object.
+    masm.loadPtr(Address(ICStubReg, ICGetProp_DOMProxyShadowed::offsetOfName()), scratch);
+    masm.push(scratch);
+    masm.push(objReg);
+
+    // Don't have to preserve R0 anymore.
+    regs.add(R0);
+
+    if (!callVM(ProxyGetInfo, masm))
+        return false;
+    leaveStubFrame(masm);
+
+    // Enter type monitor IC to type-check result.
+    EmitEnterTypeMonitorIC(masm);
+
+    // Failure case - jump to next stub
+    masm.bind(&failure);
+    EmitStubGuardFailure(masm);
+    return true;
+}
+
+bool
+ICGetProp_ArgumentsLength::Compiler::generateStubCode(MacroAssembler& masm)
+{
+    MOZ_ASSERT(engine_ == Engine::Baseline);
+
+    Label failure;
+    if (which_ == ICGetProp_ArgumentsLength::Magic) {
+        // Ensure that this is lazy arguments.
+        masm.branchTestMagicValue(Assembler::NotEqual, R0, JS_OPTIMIZED_ARGUMENTS, &failure);
+
+        // Ensure that frame has not loaded different arguments object since.
+        masm.branchTest32(Assembler::NonZero,
+                          Address(BaselineFrameReg, BaselineFrame::reverseOffsetOfFlags()),
+                          Imm32(BaselineFrame::HAS_ARGS_OBJ),
+                          &failure);
+
+        Address actualArgs(BaselineFrameReg, BaselineFrame::offsetOfNumActualArgs());
+        masm.loadPtr(actualArgs, R0.scratchReg());
+        masm.tagValue(JSVAL_TYPE_INT32, R0.scratchReg(), R0);
+        EmitReturnFromIC(masm);
+
+        masm.bind(&failure);
+        EmitStubGuardFailure(masm);
+        return true;
+    }
+    MOZ_ASSERT(which_ == ICGetProp_ArgumentsLength::Mapped ||
+               which_ == ICGetProp_ArgumentsLength::Unmapped);
+
+    const Class* clasp = (which_ == ICGetProp_ArgumentsLength::Mapped)
+                         ? &MappedArgumentsObject::class_
+                         : &UnmappedArgumentsObject::class_;
+
+    Register scratchReg = R1.scratchReg();
+
+    // Guard on input being an arguments object.
+    masm.branchTestObject(Assembler::NotEqual, R0, &failure);
+    Register objReg = masm.extractObject(R0, ExtractTemp0);
+    masm.branchTestObjClass(Assembler::NotEqual, objReg, scratchReg, clasp, &failure);
+
+    // Get initial length value.
+    masm.unboxInt32(Address(objReg, ArgumentsObject::getInitialLengthSlotOffset()), scratchReg);
+
+    // Test if length has been overridden.
+    masm.branchTest32(Assembler::NonZero,
+                      scratchReg,
+                      Imm32(ArgumentsObject::LENGTH_OVERRIDDEN_BIT),
+                      &failure);
+
+    // Nope, shift out arguments length and return it.
+    // No need to type monitor because this stub always returns Int32.
+    masm.rshiftPtr(Imm32(ArgumentsObject::PACKED_BITS_COUNT), scratchReg);
+    masm.tagValue(JSVAL_TYPE_INT32, scratchReg, R0);
+    EmitReturnFromIC(masm);
+
+    masm.bind(&failure);
+    EmitStubGuardFailure(masm);
+    return true;
+}
+
+ICGetProp_ArgumentsCallee::ICGetProp_ArgumentsCallee(JitCode* stubCode, ICStub* firstMonitorStub)
+  : ICMonitoredStub(GetProp_ArgumentsCallee, stubCode, firstMonitorStub)
+{ }
+
+bool
+ICGetProp_ArgumentsCallee::Compiler::generateStubCode(MacroAssembler& masm)
+{
+    MOZ_ASSERT(engine_ == Engine::Baseline);
+
+    Label failure;
+
+    // Ensure that this is lazy arguments.
+    masm.branchTestMagicValue(Assembler::NotEqual, R0, JS_OPTIMIZED_ARGUMENTS, &failure);
+
+    // Ensure that frame has not loaded different arguments object since.
+    masm.branchTest32(Assembler::NonZero,
+                      Address(BaselineFrameReg, BaselineFrame::reverseOffsetOfFlags()),
+                      Imm32(BaselineFrame::HAS_ARGS_OBJ),
+                      &failure);
+
+    Address callee(BaselineFrameReg, BaselineFrame::offsetOfCalleeToken());
+    masm.loadFunctionFromCalleeToken(callee, R0.scratchReg());
+    masm.tagValue(JSVAL_TYPE_OBJECT, R0.scratchReg(), R0);
+
+    EmitEnterTypeMonitorIC(masm);
+
+    masm.bind(&failure);
+    EmitStubGuardFailure(masm);
+    return true;
+}
+
+/* static */ ICGetProp_Generic*
+ICGetProp_Generic::Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitorStub,
+                         ICGetProp_Generic& other)
+{
+    return New<ICGetProp_Generic>(cx, space, other.jitCode(), firstMonitorStub);
+}
+
+static bool
+DoGetPropGeneric(JSContext* cx, BaselineFrame* frame, ICGetProp_Generic* stub, MutableHandleValue val, MutableHandleValue res)
+{
+    jsbytecode* pc = stub->getChainFallback()->icEntry()->pc(frame->script());
+    JSOp op = JSOp(*pc);
+    RootedPropertyName name(cx, frame->script()->getName(pc));
+    return ComputeGetPropResult(cx, frame, op, name, val, res);
+}
+
+typedef bool (*DoGetPropGenericFn)(JSContext*, BaselineFrame*, ICGetProp_Generic*, MutableHandleValue, MutableHandleValue);
+static const VMFunction DoGetPropGenericInfo = FunctionInfo<DoGetPropGenericFn>(DoGetPropGeneric);
+
+bool
+ICGetProp_Generic::Compiler::generateStubCode(MacroAssembler& masm)
+{
+    MOZ_ASSERT(engine_ == Engine::Baseline);
+
+    AllocatableGeneralRegisterSet regs(availableGeneralRegs(1));
+
+    Register scratch = regs.takeAnyExcluding(ICTailCallReg);
+
+    // Sync for the decompiler.
+    EmitStowICValues(masm, 1);
+
+    enterStubFrame(masm, scratch);
+
+    // Push arguments.
+    masm.pushValue(R0);
+    masm.push(ICStubReg);
+    pushFramePtr(masm, R0.scratchReg());
+
+    if(!callVM(DoGetPropGenericInfo, masm))
+        return false;
+
+    leaveStubFrame(masm);
+    EmitUnstowICValues(masm, 1, /* discard = */ true);
+    EmitEnterTypeMonitorIC(masm);
+    return true;
+}
+
+bool
+ICGetProp_Unboxed::Compiler::generateStubCode(MacroAssembler& masm)
+{
+    MOZ_ASSERT(engine_ == Engine::Baseline);
+
+    Label failure;
+
+    AllocatableGeneralRegisterSet regs(availableGeneralRegs(1));
+
+    Register scratch = regs.takeAnyExcluding(ICTailCallReg);
+
+    // Object and group guard.
+    masm.branchTestObject(Assembler::NotEqual, R0, &failure);
+    Register object = masm.extractObject(R0, ExtractTemp0);
+    masm.loadPtr(Address(ICStubReg, ICGetProp_Unboxed::offsetOfGroup()), scratch);
+    masm.branchPtr(Assembler::NotEqual, Address(object, JSObject::offsetOfGroup()), scratch,
+                   &failure);
+
+    // Get the address being read from.
+    masm.load32(Address(ICStubReg, ICGetProp_Unboxed::offsetOfFieldOffset()), scratch);
+
+    masm.loadUnboxedProperty(BaseIndex(object, scratch, TimesOne), fieldType_, TypedOrValueRegister(R0));
+
+    // Only monitor the result if its type might change.
+    if (fieldType_ == JSVAL_TYPE_OBJECT)
+        EmitEnterTypeMonitorIC(masm);
+    else
+        EmitReturnFromIC(masm);
+
+    masm.bind(&failure);
+    EmitStubGuardFailure(masm);
+
+    return true;
+}
+
+void
+CheckForNeuteredTypedObject(JSContext* cx, MacroAssembler& masm, Label* failure)
+{
+    // All stubs which manipulate typed objects need to check the compartment
+    // wide flag indicating whether the objects are neutered, and bail out in
+    // this case.
+    int32_t* address = &cx->compartment()->neuteredTypedObjects;
+    masm.branch32(Assembler::NotEqual, AbsoluteAddress(address), Imm32(0), failure);
+}
+
+void
+LoadTypedThingData(MacroAssembler& masm, TypedThingLayout layout, Register obj, Register result)
+{
+    switch (layout) {
+      case Layout_TypedArray:
+        masm.loadPtr(Address(obj, TypedArrayLayout::dataOffset()), result);
+        break;
+      case Layout_OutlineTypedObject:
+        masm.loadPtr(Address(obj, OutlineTypedObject::offsetOfData()), result);
+        break;
+      case Layout_InlineTypedObject:
+        masm.computeEffectiveAddress(Address(obj, InlineTypedObject::offsetOfDataStart()), result);
+        break;
+      default:
+        MOZ_CRASH();
+    }
+}
+
+bool
+ICGetProp_TypedObject::Compiler::generateStubCode(MacroAssembler& masm)
+{
+    MOZ_ASSERT(engine_ == Engine::Baseline);
+
+    Label failure;
+
+    CheckForNeuteredTypedObject(cx, masm, &failure);
+
+    AllocatableGeneralRegisterSet regs(availableGeneralRegs(1));
+
+    Register scratch1 = regs.takeAnyExcluding(ICTailCallReg);
+    Register scratch2 = regs.takeAnyExcluding(ICTailCallReg);
+
+    // Object and shape guard.
+    masm.branchTestObject(Assembler::NotEqual, R0, &failure);
+    Register object = masm.extractObject(R0, ExtractTemp0);
+    masm.loadPtr(Address(ICStubReg, ICGetProp_TypedObject::offsetOfShape()), scratch1);
+    masm.branchTestObjShape(Assembler::NotEqual, object, scratch1, &failure);
+
+    // Get the object's data pointer.
+    LoadTypedThingData(masm, layout_, object, scratch1);
+
+    // Get the address being written to.
+    masm.load32(Address(ICStubReg, ICGetProp_TypedObject::offsetOfFieldOffset()), scratch2);
+    masm.addPtr(scratch2, scratch1);
+
+    // Only monitor the result if the type produced by this stub might vary.
+    bool monitorLoad;
+
+    if (fieldDescr_->is<ScalarTypeDescr>()) {
+        Scalar::Type type = fieldDescr_->as<ScalarTypeDescr>().type();
+        monitorLoad = type == Scalar::Uint32;
+
+        masm.loadFromTypedArray(type, Address(scratch1, 0), R0, /* allowDouble = */ true,
+                                scratch2, nullptr);
+    } else {
+        ReferenceTypeDescr::Type type = fieldDescr_->as<ReferenceTypeDescr>().type();
+        monitorLoad = type != ReferenceTypeDescr::TYPE_STRING;
+
+        switch (type) {
+          case ReferenceTypeDescr::TYPE_ANY:
+            masm.loadValue(Address(scratch1, 0), R0);
+            break;
+
+          case ReferenceTypeDescr::TYPE_OBJECT: {
+            Label notNull, done;
+            masm.loadPtr(Address(scratch1, 0), scratch1);
+            masm.branchTestPtr(Assembler::NonZero, scratch1, scratch1, &notNull);
+            masm.moveValue(NullValue(), R0);
+            masm.jump(&done);
+            masm.bind(&notNull);
+            masm.tagValue(JSVAL_TYPE_OBJECT, scratch1, R0);
+            masm.bind(&done);
+            break;
+          }
+
+          case ReferenceTypeDescr::TYPE_STRING:
+            masm.loadPtr(Address(scratch1, 0), scratch1);
+            masm.tagValue(JSVAL_TYPE_STRING, scratch1, R0);
+            break;
+
+          default:
+            MOZ_CRASH();
+        }
+    }
+
+    if (monitorLoad)
+        EmitEnterTypeMonitorIC(masm);
+    else
+        EmitReturnFromIC(masm);
+
+    masm.bind(&failure);
+    EmitStubGuardFailure(masm);
+
+    return true;
+}
+
+void
+BaselineScript::noteAccessedGetter(uint32_t pcOffset)
+{
+    ICEntry& entry = icEntryFromPCOffset(pcOffset);
+    ICFallbackStub* stub = entry.fallbackStub();
+
+    if (stub->isGetProp_Fallback())
+        stub->toGetProp_Fallback()->noteAccessedGetter();
+}
+
+ICGetProp_Primitive::ICGetProp_Primitive(JitCode* stubCode, ICStub* firstMonitorStub,
+                                         JSValueType primitiveType, Shape* protoShape,
+                                         uint32_t offset)
+  : ICMonitoredStub(GetProp_Primitive, stubCode, firstMonitorStub),
+    protoShape_(protoShape),
+    offset_(offset)
+{
+    extra_ = uint16_t(primitiveType);
+    MOZ_ASSERT(JSValueType(extra_) == primitiveType);
+}
+
+ICGetPropNativeStub::ICGetPropNativeStub(ICStub::Kind kind, JitCode* stubCode,
+                                         ICStub* firstMonitorStub,
+                                         ReceiverGuard guard, uint32_t offset)
+  : ICMonitoredStub(kind, stubCode, firstMonitorStub),
+    receiverGuard_(guard),
+    offset_(offset)
+{ }
+
+/* static */ ICGetProp_Native*
+ICGetProp_Native::Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitorStub,
+                        ICGetProp_Native& other)
+{
+    return New<ICGetProp_Native>(cx, space, other.jitCode(), firstMonitorStub,
+                                 other.receiverGuard(), other.offset());
+}
+
+ICGetPropNativePrototypeStub::ICGetPropNativePrototypeStub(ICStub::Kind kind, JitCode* stubCode,
+                                                           ICStub* firstMonitorStub,
+                                                           ReceiverGuard guard, uint32_t offset,
+                                                           JSObject* holder, Shape* holderShape)
+  : ICGetPropNativeStub(kind, stubCode, firstMonitorStub, guard, offset),
+    holder_(holder),
+    holderShape_(holderShape)
+{ }
+
+/* static */ ICGetProp_NativePrototype*
+ICGetProp_NativePrototype::Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitorStub,
+                                 ICGetProp_NativePrototype& other)
+{
+    return New<ICGetProp_NativePrototype>(cx, space, other.jitCode(), firstMonitorStub,
+                                          other.receiverGuard(), other.offset(),
+                                          other.holder(), other.holderShape());
+}
+
+ICGetProp_NativeDoesNotExist::ICGetProp_NativeDoesNotExist(
+    JitCode* stubCode, ICStub* firstMonitorStub, ReceiverGuard guard,
+    size_t protoChainDepth)
+  : ICMonitoredStub(GetProp_NativeDoesNotExist, stubCode, firstMonitorStub),
+    guard_(guard)
+{
+    MOZ_ASSERT(protoChainDepth <= MAX_PROTO_CHAIN_DEPTH);
+    extra_ = protoChainDepth;
+}
+
+/* static */ size_t
+ICGetProp_NativeDoesNotExist::offsetOfShape(size_t idx)
+{
+    MOZ_ASSERT(ICGetProp_NativeDoesNotExistImpl<0>::offsetOfShape(idx) ==
+               ICGetProp_NativeDoesNotExistImpl<
+                    ICGetProp_NativeDoesNotExist::MAX_PROTO_CHAIN_DEPTH>::offsetOfShape(idx));
+    return ICGetProp_NativeDoesNotExistImpl<0>::offsetOfShape(idx);
+}
+
+template <size_t ProtoChainDepth>
+ICGetProp_NativeDoesNotExistImpl<ProtoChainDepth>::ICGetProp_NativeDoesNotExistImpl(
+        JitCode* stubCode, ICStub* firstMonitorStub, ReceiverGuard guard,
+        Handle<ShapeVector> shapes)
+  : ICGetProp_NativeDoesNotExist(stubCode, firstMonitorStub, guard, ProtoChainDepth)
+{
+    MOZ_ASSERT(shapes.length() == NumShapes);
+
+    // Note: using int32_t here to avoid gcc warning.
+    for (int32_t i = 0; i < int32_t(NumShapes); i++)
+        shapes_[i].init(shapes[i]);
+}
+
+ICGetPropNativeDoesNotExistCompiler::ICGetPropNativeDoesNotExistCompiler(
+        JSContext* cx, ICStub* firstMonitorStub, HandleObject obj, size_t protoChainDepth)
+  : ICStubCompiler(cx, ICStub::GetProp_NativeDoesNotExist, Engine::Baseline),
+    firstMonitorStub_(firstMonitorStub),
+    obj_(cx, obj),
+    protoChainDepth_(protoChainDepth)
+{
+    MOZ_ASSERT(protoChainDepth_ <= ICGetProp_NativeDoesNotExist::MAX_PROTO_CHAIN_DEPTH);
+}
+
+ICGetPropCallGetter::ICGetPropCallGetter(Kind kind, JitCode* stubCode, ICStub* firstMonitorStub,
+                                         ReceiverGuard receiverGuard, JSObject* holder,
+                                         Shape* holderShape, JSFunction* getter,
+                                         uint32_t pcOffset)
+  : ICMonitoredStub(kind, stubCode, firstMonitorStub),
+    receiverGuard_(receiverGuard),
+    holder_(holder),
+    holderShape_(holderShape),
+    getter_(getter),
+    pcOffset_(pcOffset)
+{
+    MOZ_ASSERT(kind == ICStub::GetProp_CallScripted  ||
+               kind == ICStub::GetProp_CallNative    ||
+               kind == ICStub::GetProp_CallNativeGlobal ||
+               kind == ICStub::GetProp_CallDOMProxyNative ||
+               kind == ICStub::GetProp_CallDOMProxyWithGenerationNative);
+}
+
+/* static */ ICGetProp_CallScripted*
+ICGetProp_CallScripted::Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitorStub,
+                              ICGetProp_CallScripted& other)
+{
+    return New<ICGetProp_CallScripted>(cx, space, other.jitCode(), firstMonitorStub,
+                                       other.receiverGuard(),
+                                       other.holder_, other.holderShape_,
+                                       other.getter_, other.pcOffset_);
+}
+
+/* static */ ICGetProp_CallNative*
+ICGetProp_CallNative::Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitorStub,
+                            ICGetProp_CallNative& other)
+{
+    return New<ICGetProp_CallNative>(cx, space, other.jitCode(), firstMonitorStub,
+                                     other.receiverGuard(), other.holder_,
+                                     other.holderShape_, other.getter_, other.pcOffset_);
+}
+
+/* static */ ICGetProp_CallNativeGlobal*
+ICGetProp_CallNativeGlobal::Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitorStub,
+                            ICGetProp_CallNativeGlobal& other)
+{
+    return New<ICGetProp_CallNativeGlobal>(cx, space, other.jitCode(), firstMonitorStub,
+                                           other.receiverGuard(), other.holder_,
+                                           other.holderShape_, other.globalShape_,
+                                           other.getter_, other.pcOffset_);
+}
+
+ICGetPropCallDOMProxyNativeStub::ICGetPropCallDOMProxyNativeStub(Kind kind, JitCode* stubCode,
+                                                                 ICStub* firstMonitorStub,
+                                                                 Shape* shape,
+                                                                 Shape* expandoShape,
+                                                                 JSObject* holder,
+                                                                 Shape* holderShape,
+                                                                 JSFunction* getter,
+                                                                 uint32_t pcOffset)
+  : ICGetPropCallGetter(kind, stubCode, firstMonitorStub, ReceiverGuard(nullptr, shape),
+                        holder, holderShape, getter, pcOffset),
+    expandoShape_(expandoShape)
+{ }
+
+ICGetPropCallDOMProxyNativeCompiler::ICGetPropCallDOMProxyNativeCompiler(JSContext* cx,
+                                                                         ICStub::Kind kind,
+                                                                         ICStub* firstMonitorStub,
+                                                                         Handle<ProxyObject*> proxy,
+                                                                         HandleObject holder,
+                                                                         HandleFunction getter,
+                                                                         uint32_t pcOffset)
+  : ICStubCompiler(cx, kind, Engine::Baseline),
+    firstMonitorStub_(firstMonitorStub),
+    proxy_(cx, proxy),
+    holder_(cx, holder),
+    getter_(cx, getter),
+    pcOffset_(pcOffset)
+{
+    MOZ_ASSERT(kind == ICStub::GetProp_CallDOMProxyNative ||
+               kind == ICStub::GetProp_CallDOMProxyWithGenerationNative);
+    MOZ_ASSERT(proxy_->handler()->family() == GetDOMProxyHandlerFamily());
+}
+
+/* static */ ICGetProp_CallDOMProxyNative*
+ICGetProp_CallDOMProxyNative::Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitorStub,
+                                    ICGetProp_CallDOMProxyNative& other)
+{
+    return New<ICGetProp_CallDOMProxyNative>(cx, space, other.jitCode(), firstMonitorStub,
+                                             other.receiverGuard_.shape(), other.expandoShape_,
+                                             other.holder_, other.holderShape_, other.getter_,
+                                             other.pcOffset_);
+}
+
+/* static */ ICGetProp_CallDOMProxyWithGenerationNative*
+ICGetProp_CallDOMProxyWithGenerationNative::Clone(JSContext* cx,
+                                                  ICStubSpace* space,
+                                                  ICStub* firstMonitorStub,
+                                                  ICGetProp_CallDOMProxyWithGenerationNative& other)
+{
+    return New<ICGetProp_CallDOMProxyWithGenerationNative>(cx, space, other.jitCode(),
+                                                           firstMonitorStub,
+                                                           other.receiverGuard_.shape(),
+                                                           other.expandoAndGeneration_,
+                                                           other.generation_,
+                                                           other.expandoShape_, other.holder_,
+                                                           other.holderShape_, other.getter_,
+                                                           other.pcOffset_);
+}
+
+ICGetProp_DOMProxyShadowed::ICGetProp_DOMProxyShadowed(JitCode* stubCode,
+                                                       ICStub* firstMonitorStub,
+                                                       Shape* shape,
+                                                       const BaseProxyHandler* proxyHandler,
+                                                       PropertyName* name,
+                                                       uint32_t pcOffset)
+  : ICMonitoredStub(ICStub::GetProp_DOMProxyShadowed, stubCode, firstMonitorStub),
+    shape_(shape),
+    proxyHandler_(proxyHandler),
+    name_(name),
+    pcOffset_(pcOffset)
+{ }
+
+/* static */ ICGetProp_DOMProxyShadowed*
+ICGetProp_DOMProxyShadowed::Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitorStub,
+                                  ICGetProp_DOMProxyShadowed& other)
+{
+    return New<ICGetProp_DOMProxyShadowed>(cx, space, other.jitCode(), firstMonitorStub,
+                                           other.shape_, other.proxyHandler_, other.name_,
+                                           other.pcOffset_);
+}
+
 } // namespace jit
 } // namespace js
--- a/js/src/jit/SharedIC.h
+++ b/js/src/jit/SharedIC.h
@@ -11,20 +11,24 @@
 #include "jscompartment.h"
 #include "jsgc.h"
 
 #include "jit/BaselineICList.h"
 #include "jit/BaselineJIT.h"
 #include "jit/MacroAssembler.h"
 #include "jit/SharedICList.h"
 #include "jit/SharedICRegisters.h"
+#include "vm/ReceiverGuard.h"
+#include "vm/TypedArrayCommon.h"
 
 namespace js {
 namespace jit {
 
+class AutoShapeVector;
+
 //
 // Baseline Inline Caches are polymorphic caches that aggressively
 // share their stub code.
 //
 // Every polymorphic site contains a linked list of stubs which are
 // specific to that site.  These stubs are composed of a |StubData|
 // structure that stores parametrization information (e.g.
 // the shape pointer for a shape-check-and-property-get stub), any
@@ -1741,12 +1745,1153 @@ class ICCompare_Int32WithBoolean : publi
         {}
 
         ICStub* getStub(ICStubSpace* space) {
             return newStub<ICCompare_Int32WithBoolean>(space, getStubCode(), lhsIsInt32_);
         }
     };
 };
 
+// Enum for stubs handling a combination of typed arrays and typed objects.
+enum TypedThingLayout {
+    Layout_TypedArray,
+    Layout_OutlineTypedObject,
+    Layout_InlineTypedObject
+};
+
+static inline TypedThingLayout
+GetTypedThingLayout(const Class* clasp)
+{
+    if (IsAnyTypedArrayClass(clasp))
+        return Layout_TypedArray;
+    if (IsOutlineTypedObjectClass(clasp))
+        return Layout_OutlineTypedObject;
+    if (IsInlineTypedObjectClass(clasp))
+        return Layout_InlineTypedObject;
+    MOZ_CRASH("Bad object class");
+}
+
+bool
+IsPreliminaryObject(JSObject* obj);
+
+void
+StripPreliminaryObjectStubs(JSContext* cx, ICFallbackStub* stub);
+
+bool
+EffectlesslyLookupProperty(JSContext* cx, HandleObject obj, HandleId name,
+                           MutableHandleObject holder, MutableHandleShape shape,
+                           bool* checkDOMProxy=nullptr,
+                           DOMProxyShadowsResult* shadowsResult=nullptr,
+                           bool* domProxyHasGeneration=nullptr);
+
+JSObject*
+GetDOMProxyProto(JSObject* obj);
+
+bool
+IsCacheableProtoChain(JSObject* obj, JSObject* holder, bool isDOMProxy=false);
+
+bool
+IsCacheableGetPropReadSlot(JSObject* obj, JSObject* holder, Shape* shape, bool isDOMProxy=false);
+
+void
+GetFixedOrDynamicSlotOffset(Shape* shape, bool* isFixed, uint32_t* offset);
+
+bool
+IsCacheableGetPropCall(JSContext* cx, JSObject* obj, JSObject* holder, Shape* shape,
+                       bool* isScripted, bool* isTemporarilyUnoptimizable, bool isDOMProxy=false);
+
+bool
+UpdateExistingGetPropCallStubs(ICFallbackStub* fallbackStub,
+                               ICStub::Kind kind,
+                               HandleNativeObject holder,
+                               HandleObject receiver,
+                               HandleFunction getter);
+bool
+CheckHasNoSuchProperty(JSContext* cx, HandleObject obj, HandlePropertyName name,
+                       MutableHandleObject lastProto, size_t* protoChainDepthOut);
+
+void
+GuardReceiverObject(MacroAssembler& masm, ReceiverGuard guard,
+                    Register object, Register scratch,
+                    size_t receiverGuardOffset, Label* failure);
+
+bool
+GetProtoShapes(JSObject* obj, size_t protoChainDepth, MutableHandle<ShapeVector> shapes);
+
+void
+CheckDOMProxyExpandoDoesNotShadow(JSContext* cx, MacroAssembler& masm, Register object,
+                                  const Address& checkExpandoShapeAddr,
+                                  Address* expandoAndGenerationAddr,
+                                  Address* generationAddr,
+                                  Register scratch,
+                                  AllocatableGeneralRegisterSet& domProxyRegSet,
+                                  Label* checkFailed);
+
+void
+CheckForNeuteredTypedObject(JSContext* cx, MacroAssembler& masm, Label* failure);
+
+bool
+DoCallNativeGetter(JSContext* cx, HandleFunction callee, HandleObject obj,
+                   MutableHandleValue result);
+
+void
+LoadTypedThingData(MacroAssembler& masm, TypedThingLayout layout, Register obj, Register result);
+
+class ICGetProp_Fallback : public ICMonitoredFallbackStub
+{
+    friend class ICStubSpace;
+
+    explicit ICGetProp_Fallback(JitCode* stubCode)
+      : ICMonitoredFallbackStub(ICStub::GetProp_Fallback, stubCode)
+    { }
+
+  public:
+    static const uint32_t MAX_OPTIMIZED_STUBS = 16;
+    static const size_t UNOPTIMIZABLE_ACCESS_BIT = 0;
+    static const size_t ACCESSED_GETTER_BIT = 1;
+
+    void noteUnoptimizableAccess() {
+        extra_ |= (1u << UNOPTIMIZABLE_ACCESS_BIT);
+    }
+    bool hadUnoptimizableAccess() const {
+        return extra_ & (1u << UNOPTIMIZABLE_ACCESS_BIT);
+    }
+
+    void noteAccessedGetter() {
+        extra_ |= (1u << ACCESSED_GETTER_BIT);
+    }
+    bool hasAccessedGetter() const {
+        return extra_ & (1u << ACCESSED_GETTER_BIT);
+    }
+
+    class Compiler : public ICStubCompiler {
+      public:
+        static const int32_t BASELINE_KEY =
+            (static_cast<int32_t>(Engine::Baseline)) |
+            (static_cast<int32_t>(ICStub::GetProp_Fallback) << 1);
+
+      protected:
+        uint32_t returnOffset_;
+        bool generateStubCode(MacroAssembler& masm);
+        void postGenerateStubCode(MacroAssembler& masm, Handle<JitCode*> code);
+
+      public:
+        explicit Compiler(JSContext* cx)
+          : ICStubCompiler(cx, ICStub::GetProp_Fallback, Engine::Baseline)
+        { }
+
+        ICStub* getStub(ICStubSpace* space) {
+            ICGetProp_Fallback* stub = newStub<ICGetProp_Fallback>(space, getStubCode());
+            if (!stub || !stub->initMonitoringChain(cx, space))
+                return nullptr;
+            return stub;
+        }
+    };
+};
+
+// Stub for sites, which are too polymorphic (i.e. MAX_OPTIMIZED_STUBS was reached)
+class ICGetProp_Generic : public ICMonitoredStub
+{
+    friend class ICStubSpace;
+
+  protected:
+    explicit ICGetProp_Generic(JitCode* stubCode, ICStub* firstMonitorStub)
+      : ICMonitoredStub(ICStub::GetProp_Generic, stubCode, firstMonitorStub) {}
+
+  public:
+    static ICGetProp_Generic* Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitorStub,
+                                    ICGetProp_Generic& other);
+
+    class Compiler : public ICStubCompiler {
+      protected:
+        bool generateStubCode(MacroAssembler& masm);
+        ICStub* firstMonitorStub_;
+      public:
+        explicit Compiler(JSContext* cx, ICStub* firstMonitorStub)
+          : ICStubCompiler(cx, ICStub::GetProp_Generic, Engine::Baseline),
+            firstMonitorStub_(firstMonitorStub)
+        {}
+
+        ICStub* getStub(ICStubSpace* space) {
+            return newStub<ICGetProp_Generic>(space, getStubCode(), firstMonitorStub_);
+        }
+    };
+};
+
+// Stub for accessing a dense array's length.
+class ICGetProp_ArrayLength : public ICStub
+{
+    friend class ICStubSpace;
+
+    explicit ICGetProp_ArrayLength(JitCode* stubCode)
+      : ICStub(GetProp_ArrayLength, stubCode)
+    {}
+
+  public:
+    class Compiler : public ICStubCompiler {
+        bool generateStubCode(MacroAssembler& masm);
+
+      public:
+        explicit Compiler(JSContext* cx)
+          : ICStubCompiler(cx, ICStub::GetProp_ArrayLength, Engine::Baseline)
+        {}
+
+        ICStub* getStub(ICStubSpace* space) {
+            return newStub<ICGetProp_ArrayLength>(space, getStubCode());
+        }
+    };
+};
+
+// Stub for accessing an unboxed array's length.
+class ICGetProp_UnboxedArrayLength : public ICStub
+{
+    friend class ICStubSpace;
+
+    explicit ICGetProp_UnboxedArrayLength(JitCode* stubCode)
+      : ICStub(GetProp_UnboxedArrayLength, stubCode)
+    {}
+
+  public:
+    class Compiler : public ICStubCompiler {
+        bool generateStubCode(MacroAssembler& masm);
+
+      public:
+        explicit Compiler(JSContext* cx)
+          : ICStubCompiler(cx, ICStub::GetProp_UnboxedArrayLength, Engine::Baseline)
+        {}
+
+        ICStub* getStub(ICStubSpace* space) {
+            return newStub<ICGetProp_UnboxedArrayLength>(space, getStubCode());
+        }
+    };
+};
+
+// Stub for accessing a property on a primitive's prototype.
+class ICGetProp_Primitive : public ICMonitoredStub
+{
+    friend class ICStubSpace;
+
+  protected: // Protected to silence Clang warning.
+    // Shape of String.prototype/Number.prototype to check for.
+    HeapPtrShape protoShape_;
+
+    // Fixed or dynamic slot offset.
+    uint32_t offset_;
+
+    ICGetProp_Primitive(JitCode* stubCode, ICStub* firstMonitorStub, JSValueType primitiveType,
+                        Shape* protoShape, uint32_t offset);
+
+  public:
+    HeapPtrShape& protoShape() {
+        return protoShape_;
+    }
+    JSValueType primitiveType() const {
+        return JSValueType(extra_);
+    }
+
+    static size_t offsetOfProtoShape() {
+        return offsetof(ICGetProp_Primitive, protoShape_);
+    }
+
+    static size_t offsetOfOffset() {
+        return offsetof(ICGetProp_Primitive, offset_);
+    }
+
+    class Compiler : public ICStubCompiler {
+        ICStub* firstMonitorStub_;
+        JSValueType primitiveType_;
+        RootedObject prototype_;
+        bool isFixedSlot_;
+        uint32_t offset_;
+
+        bool generateStubCode(MacroAssembler& masm);
+
+      protected:
+        virtual int32_t getKey() const {
+            static_assert(sizeof(JSValueType) == 1, "JSValueType should fit in one byte");
+            return static_cast<int32_t>(engine_) |
+                  (static_cast<int32_t>(kind) << 1) |
+                  (static_cast<int32_t>(isFixedSlot_) << 17) |
+                  (static_cast<int32_t>(primitiveType_) << 25);
+        }
+
+      public:
+        Compiler(JSContext* cx, ICStub* firstMonitorStub, JSValueType primitiveType,
+                 HandleObject prototype, bool isFixedSlot, uint32_t offset)
+          : ICStubCompiler(cx, ICStub::GetProp_Primitive, Engine::Baseline),
+            firstMonitorStub_(firstMonitorStub),
+            primitiveType_(primitiveType),
+            prototype_(cx, prototype),
+            isFixedSlot_(isFixedSlot),
+            offset_(offset)
+        {}
+
+        ICStub* getStub(ICStubSpace* space) {
+            RootedShape protoShape(cx, prototype_->as<NativeObject>().lastProperty());
+            return newStub<ICGetProp_Primitive>(space, getStubCode(), firstMonitorStub_,
+                                                primitiveType_, protoShape, offset_);
+        }
+    };
+};
+
+// Stub for accessing a string's length.
+class ICGetProp_StringLength : public ICStub
+{
+    friend class ICStubSpace;
+
+    explicit ICGetProp_StringLength(JitCode* stubCode)
+      : ICStub(GetProp_StringLength, stubCode)
+    {}
+
+  public:
+    class Compiler : public ICStubCompiler {
+        bool generateStubCode(MacroAssembler& masm);
+
+      public:
+        explicit Compiler(JSContext* cx)
+          : ICStubCompiler(cx, ICStub::GetProp_StringLength, Engine::Baseline)
+        {}
+
+        ICStub* getStub(ICStubSpace* space) {
+            return newStub<ICGetProp_StringLength>(space, getStubCode());
+        }
+    };
+};
+
+// Base class for native GetProp stubs.
+class ICGetPropNativeStub : public ICMonitoredStub
+{
+    // Object shape/group.
+    HeapReceiverGuard receiverGuard_;
+
+    // Fixed or dynamic slot offset.
+    uint32_t offset_;
+
+  protected:
+    ICGetPropNativeStub(ICStub::Kind kind, JitCode* stubCode, ICStub* firstMonitorStub,
+                        ReceiverGuard guard, uint32_t offset);
+
+  public:
+    HeapReceiverGuard& receiverGuard() {
+        return receiverGuard_;
+    }
+    uint32_t offset() const {
+        return offset_;
+    }
+
+    void notePreliminaryObject() {
+        extra_ = 1;
+    }
+    bool hasPreliminaryObject() const {
+        return extra_;
+    }
+
+    static size_t offsetOfReceiverGuard() {
+        return offsetof(ICGetPropNativeStub, receiverGuard_);
+    }
+    static size_t offsetOfOffset() {
+        return offsetof(ICGetPropNativeStub, offset_);
+    }
+};
+
+// Stub for accessing an own property on a native object.
+class ICGetProp_Native : public ICGetPropNativeStub
+{
+    friend class ICStubSpace;
+
+    ICGetProp_Native(JitCode* stubCode, ICStub* firstMonitorStub, ReceiverGuard guard,
+                     uint32_t offset)
+      : ICGetPropNativeStub(GetProp_Native, stubCode, firstMonitorStub, guard, offset)
+    {}
+
+  public:
+    static ICGetProp_Native* Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitorStub,
+                                   ICGetProp_Native& other);
+};
+
+class ICGetPropNativePrototypeStub : public ICGetPropNativeStub
+{
+    // Holder and its shape.
+    HeapPtrObject holder_;
+    HeapPtrShape holderShape_;
+
+  protected:
+    ICGetPropNativePrototypeStub(ICStub::Kind kind, JitCode* stubCode, ICStub* firstMonitorStub,
+                                 ReceiverGuard guard, uint32_t offset, JSObject* holder,
+                                 Shape* holderShape);
+
+  public:
+    HeapPtrObject& holder() {
+        return holder_;
+    }
+    HeapPtrShape& holderShape() {
+        return holderShape_;
+    }
+    static size_t offsetOfHolder() {
+        return offsetof(ICGetPropNativePrototypeStub, holder_);
+    }
+    static size_t offsetOfHolderShape() {
+        return offsetof(ICGetPropNativePrototypeStub, holderShape_);
+    }
+};
+
+// Stub for accessing a property on the native prototype of a native or unboxed
+// object. Note that due to the shape teleporting optimization, we only have to
+// guard on the object's shape/group and the holder's shape.
+class ICGetProp_NativePrototype : public ICGetPropNativePrototypeStub
+{
+    friend class ICStubSpace;
+
+  protected:
+    ICGetProp_NativePrototype(JitCode* stubCode, ICStub* firstMonitorStub, ReceiverGuard guard,
+                              uint32_t offset, JSObject* holder, Shape* holderShape)
+      : ICGetPropNativePrototypeStub(GetProp_NativePrototype, stubCode, firstMonitorStub, guard,
+                                     offset, holder, holderShape)
+    { }
+
+  public:
+    static ICGetProp_NativePrototype* Clone(JSContext* cx,
+                                            ICStubSpace* space,
+                                            ICStub* firstMonitorStub,
+                                            ICGetProp_NativePrototype& other);
+};
+
+// Stub for accessing a non-lexical global name. Semantically, it is really a
+// getprop: the name is either on the GlobalObject or its prototype chain. We
+// teleport to the object that has the name, but we also need to guard on the
+// shape of the global object.
+//
+// The receiver object is the global lexical scope.
+class ICGetName_Global : public ICGetPropNativePrototypeStub
+{
+    friend class ICStubSpace;
+
+  protected:
+    HeapPtrShape globalShape_;
+
+    ICGetName_Global(JitCode* stubCode, ICStub* firstMonitorStub, ReceiverGuard guard,
+                     uint32_t slot, JSObject* holder, Shape* holderShape, Shape* globalShape);
+
+  public:
+    static ICGetName_Global* Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitorStub,
+                                   ICGetName_Global& other);
+
+    HeapPtrShape& globalShape() {
+        return globalShape_;
+    }
+    static size_t offsetOfGlobalShape() {
+        return offsetof(ICGetName_Global, globalShape_);
+    }
+};
+
+// Compiler for native GetProp stubs.
+class ICGetPropNativeCompiler : public ICStubCompiler
+{
+    ICStub* firstMonitorStub_;
+    HandleObject obj_;
+    HandleObject holder_;
+    HandlePropertyName propName_;
+    bool isFixedSlot_;
+    uint32_t offset_;
+    bool inputDefinitelyObject_;
+
+    bool generateStubCode(MacroAssembler& masm);
+
+  protected:
+    virtual int32_t getKey() const {
+        return static_cast<int32_t>(engine_) |
+              (static_cast<int32_t>(kind) << 1) |
+              (static_cast<int32_t>(isFixedSlot_) << 17) |
+              (static_cast<int32_t>(inputDefinitelyObject_) << 18) |
+              (HeapReceiverGuard::keyBits(obj_) << 19);
+    }
+
+  public:
+    ICGetPropNativeCompiler(JSContext* cx, ICStub::Kind kind,
+                            ICStub* firstMonitorStub, HandleObject obj, HandleObject holder,
+                            HandlePropertyName propName, bool isFixedSlot, uint32_t offset,
+                            bool inputDefinitelyObject = false)
+      : ICStubCompiler(cx, kind, Engine::Baseline),
+        firstMonitorStub_(firstMonitorStub),
+        obj_(obj),
+        holder_(holder),
+        propName_(propName),
+        isFixedSlot_(isFixedSlot),
+        offset_(offset),
+        inputDefinitelyObject_(inputDefinitelyObject)
+    {}
+
+    ICGetPropNativeStub* getStub(ICStubSpace* space);
+};
+
+template <size_t ProtoChainDepth> class ICGetProp_NativeDoesNotExistImpl;
+
+class ICGetProp_NativeDoesNotExist : public ICMonitoredStub
+{
+    friend class ICStubSpace;
+  public:
+    HeapReceiverGuard guard_;
+
+    static const size_t MAX_PROTO_CHAIN_DEPTH = 8;
+
+  protected:
+    ICGetProp_NativeDoesNotExist(JitCode* stubCode, ICStub* firstMonitorStub,
+                                 ReceiverGuard guard,
+                                 size_t protoChainDepth);
+
+  public:
+    size_t protoChainDepth() const {
+        MOZ_ASSERT(extra_ <= MAX_PROTO_CHAIN_DEPTH);
+        return extra_;
+    }
+
+    template <size_t ProtoChainDepth>
+    ICGetProp_NativeDoesNotExistImpl<ProtoChainDepth>* toImpl() {
+        MOZ_ASSERT(ProtoChainDepth == protoChainDepth());
+        return static_cast<ICGetProp_NativeDoesNotExistImpl<ProtoChainDepth>*>(this);
+    }
+
+    HeapReceiverGuard& guard() {
+        return guard_;
+    }
+
+    static size_t offsetOfGuard() {
+        return offsetof(ICGetProp_NativeDoesNotExist, guard_);
+    }
+
+    static size_t offsetOfShape(size_t idx);
+};
+
+template <size_t ProtoChainDepth>
+class ICGetProp_NativeDoesNotExistImpl : public ICGetProp_NativeDoesNotExist
+{
+    friend class ICStubSpace;
+  public:
+    static const size_t MAX_PROTO_CHAIN_DEPTH = 8;
+    static const size_t NumShapes = ProtoChainDepth;
+
+  private:
+    mozilla::Array<HeapPtrShape, NumShapes> shapes_;
+
+    ICGetProp_NativeDoesNotExistImpl(JitCode* stubCode, ICStub* firstMonitorStub,
+                                     ReceiverGuard guard,
+                                     Handle<ShapeVector> shapes);
+
+  public:
+    void traceShapes(JSTracer* trc) {
+        // Note: using int32_t here to avoid gcc warning.
+        for (int32_t i = 0; i < int32_t(NumShapes); i++)
+            TraceEdge(trc, &shapes_[i], "baseline-getpropnativedoesnotexist-stub-shape");
+    }
+
+    static size_t offsetOfShape(size_t idx) {
+        return offsetof(ICGetProp_NativeDoesNotExistImpl, shapes_) + (idx * sizeof(HeapPtrShape));
+    }
+};
+
+class ICGetPropNativeDoesNotExistCompiler : public ICStubCompiler
+{
+    ICStub* firstMonitorStub_;
+    RootedObject obj_;
+    size_t protoChainDepth_;
+
+  protected:
+    virtual int32_t getKey() const {
+        return static_cast<int32_t>(engine_) |
+              (static_cast<int32_t>(kind) << 1) |
+              (HeapReceiverGuard::keyBits(obj_) << 17) |
+              (static_cast<int32_t>(protoChainDepth_) << 19);
+    }
+
+    bool generateStubCode(MacroAssembler& masm);
+
+  public:
+    ICGetPropNativeDoesNotExistCompiler(JSContext* cx, ICStub* firstMonitorStub,
+                                        HandleObject obj, size_t protoChainDepth);
+
+    template <size_t ProtoChainDepth>
+    ICStub* getStubSpecific(ICStubSpace* space, Handle<ShapeVector> shapes) {
+        ReceiverGuard guard(obj_);
+        return newStub<ICGetProp_NativeDoesNotExistImpl<ProtoChainDepth>>
+            (space, getStubCode(), firstMonitorStub_, guard, shapes);
+    }
+
+    ICStub* getStub(ICStubSpace* space);
+};
+
+class ICGetProp_Unboxed : public ICMonitoredStub
+{
+    friend class ICStubSpace;
+
+    HeapPtrObjectGroup group_;
+    uint32_t fieldOffset_;
+
+    ICGetProp_Unboxed(JitCode* stubCode, ICStub* firstMonitorStub, ObjectGroup* group,
+                      uint32_t fieldOffset)
+      : ICMonitoredStub(ICStub::GetProp_Unboxed, stubCode, firstMonitorStub),
+        group_(group), fieldOffset_(fieldOffset)
+    {
+        (void) fieldOffset_; // Silence clang warning
+    }
+
+  public:
+    HeapPtrObjectGroup& group() {
+        return group_;
+    }
+
+    static size_t offsetOfGroup() {
+        return offsetof(ICGetProp_Unboxed, group_);
+    }
+    static size_t offsetOfFieldOffset() {
+        return offsetof(ICGetProp_Unboxed, fieldOffset_);
+    }
+
+    class Compiler : public ICStubCompiler {
+      protected:
+        ICStub* firstMonitorStub_;
+        RootedObjectGroup group_;
+        uint32_t fieldOffset_;
+        JSValueType fieldType_;
+
+        bool generateStubCode(MacroAssembler& masm);
+
+        virtual int32_t getKey() const {
+            return static_cast<int32_t>(engine_) |
+                  (static_cast<int32_t>(kind) << 1) |
+                  (static_cast<int32_t>(fieldType_) << 17);
+        }
+
+      public:
+        Compiler(JSContext* cx, ICStub* firstMonitorStub,
+                 ObjectGroup* group, uint32_t fieldOffset, JSValueType fieldType)
+          : ICStubCompiler(cx, ICStub::GetProp_Unboxed, Engine::Baseline),
+            firstMonitorStub_(firstMonitorStub),
+            group_(cx, group),
+            fieldOffset_(fieldOffset),
+            fieldType_(fieldType)
+        {}
+
+        ICStub* getStub(ICStubSpace* space) {
+            return newStub<ICGetProp_Unboxed>(space, getStubCode(), firstMonitorStub_, group_,
+                                              fieldOffset_);
+        }
+    };
+};
+
+static uint32_t
+SimpleTypeDescrKey(SimpleTypeDescr* descr)
+{
+    if (descr->is<ScalarTypeDescr>())
+        return uint32_t(descr->as<ScalarTypeDescr>().type()) << 1;
+    return (uint32_t(descr->as<ReferenceTypeDescr>().type()) << 1) | 1;
+}
+
+class ICGetProp_TypedObject : public ICMonitoredStub
+{
+    friend class ICStubSpace;
+
+    HeapPtrShape shape_;
+    uint32_t fieldOffset_;
+
+    ICGetProp_TypedObject(JitCode* stubCode, ICStub* firstMonitorStub, Shape* shape,
+                          uint32_t fieldOffset)
+      : ICMonitoredStub(ICStub::GetProp_TypedObject, stubCode, firstMonitorStub),
+        shape_(shape), fieldOffset_(fieldOffset)
+    {
+        (void) fieldOffset_; // Silence clang warning
+    }
+
+  public:
+    HeapPtrShape& shape() {
+        return shape_;
+    }
+
+    static size_t offsetOfShape() {
+        return offsetof(ICGetProp_TypedObject, shape_);
+    }
+    static size_t offsetOfFieldOffset() {
+        return offsetof(ICGetProp_TypedObject, fieldOffset_);
+    }
+
+    class Compiler : public ICStubCompiler {
+      protected:
+        ICStub* firstMonitorStub_;
+        RootedShape shape_;
+        uint32_t fieldOffset_;
+        TypedThingLayout layout_;
+        Rooted<SimpleTypeDescr*> fieldDescr_;
+
+        bool generateStubCode(MacroAssembler& masm);
+
+        virtual int32_t getKey() const {
+            return static_cast<int32_t>(engine_) |
+                  (static_cast<int32_t>(kind) << 1) |
+                  (static_cast<int32_t>(SimpleTypeDescrKey(fieldDescr_)) << 17) |
+                  (static_cast<int32_t>(layout_) << 25);
+        }
+
+      public:
+        Compiler(JSContext* cx, ICStub* firstMonitorStub,
+                 Shape* shape, uint32_t fieldOffset, SimpleTypeDescr* fieldDescr)
+          : ICStubCompiler(cx, ICStub::GetProp_TypedObject, Engine::Baseline),
+            firstMonitorStub_(firstMonitorStub),
+            shape_(cx, shape),
+            fieldOffset_(fieldOffset),
+            layout_(GetTypedThingLayout(shape->getObjectClass())),
+            fieldDescr_(cx, fieldDescr)
+        {}
+
+        ICStub* getStub(ICStubSpace* space) {
+            return newStub<ICGetProp_TypedObject>(space, getStubCode(), firstMonitorStub_, shape_,
+                                                  fieldOffset_);
+        }
+    };
+};
+
+class ICGetPropCallGetter : public ICMonitoredStub
+{
+    friend class ICStubSpace;
+
+  protected:
+    // Shape/group of receiver object. Used for both own and proto getters.
+    // In the GetPropCallDOMProxyNative case, the receiver guard enforces
+    // the proxy handler, because Shape implies Class.
+    HeapReceiverGuard receiverGuard_;
+
+    // Holder and holder shape. For own getters, guarding on receiverGuard_ is
+    // sufficient, although Ion may use holder_ and holderShape_ even for own
+    // getters. In this case holderShape_ == receiverGuard_.shape_ (isOwnGetter
+    // below relies on this).
+    HeapPtrObject holder_;
+
+    HeapPtrShape holderShape_;
+
+    // Function to call.
+    HeapPtrFunction getter_;
+
+    // PC offset of call
+    uint32_t pcOffset_;
+
+    ICGetPropCallGetter(Kind kind, JitCode* stubCode, ICStub* firstMonitorStub,
+                        ReceiverGuard receiverGuard, JSObject* holder,
+                        Shape* holderShape, JSFunction* getter, uint32_t pcOffset);
+
+  public:
+    HeapPtrObject& holder() {
+        return holder_;
+    }
+    HeapPtrShape& holderShape() {
+        return holderShape_;
+    }
+    HeapPtrFunction& getter() {
+        return getter_;
+    }
+    HeapReceiverGuard& receiverGuard() {
+        return receiverGuard_;
+    }
+
+    bool isOwnGetter() const {
+        MOZ_ASSERT(holder_->isNative());
+        MOZ_ASSERT(holderShape_);
+        return receiverGuard_.shape() == holderShape_;
+    }
+
+    static size_t offsetOfHolder() {
+        return offsetof(ICGetPropCallGetter, holder_);
+    }
+    static size_t offsetOfHolderShape() {
+        return offsetof(ICGetPropCallGetter, holderShape_);
+    }
+    static size_t offsetOfGetter() {
+        return offsetof(ICGetPropCallGetter, getter_);
+    }
+    static size_t offsetOfPCOffset() {
+        return offsetof(ICGetPropCallGetter, pcOffset_);
+    }
+    static size_t offsetOfReceiverGuard() {
+        return offsetof(ICGetPropCallGetter, receiverGuard_);
+    }
+
+    class Compiler : public ICStubCompiler {
+      protected:
+        ICStub* firstMonitorStub_;
+        RootedObject receiver_;
+        RootedObject holder_;
+        RootedFunction getter_;
+        uint32_t pcOffset_;
+        const Class* outerClass_;
+
+        virtual int32_t getKey() const {
+            // ICGetPropCallNativeCompiler::getKey adds more bits to our
+            // return value, so be careful when making changes here.
+            return static_cast<int32_t>(engine_) |
+                  (static_cast<int32_t>(kind) << 1) |
+                  (HeapReceiverGuard::keyBits(receiver_) << 17) |
+                  (static_cast<int32_t>(!!outerClass_) << 19) |
+                  (static_cast<int32_t>(receiver_ != holder_) << 20);
+        }
+
+      public:
+        Compiler(JSContext* cx, ICStub::Kind kind, ICStub* firstMonitorStub,
+                 HandleObject receiver, HandleObject holder, HandleFunction getter,
+                 uint32_t pcOffset, const Class* outerClass)
+          : ICStubCompiler(cx, kind, Engine::Baseline),
+            firstMonitorStub_(firstMonitorStub),
+            receiver_(cx, receiver),
+            holder_(cx, holder),
+            getter_(cx, getter),
+            pcOffset_(pcOffset),
+            outerClass_(outerClass)
+        {
+            MOZ_ASSERT(kind == ICStub::GetProp_CallScripted ||
+                       kind == ICStub::GetProp_CallNative ||
+                       kind == ICStub::GetProp_CallNativeGlobal);
+        }
+    };
+};
+
+// Stub for calling a scripted getter on a native object when the getter is kept on the
+// proto-chain.
+class ICGetProp_CallScripted : public ICGetPropCallGetter
+{
+    friend class ICStubSpace;
+
+  protected:
+    ICGetProp_CallScripted(JitCode* stubCode, ICStub* firstMonitorStub,
+                           ReceiverGuard receiverGuard,
+                           JSObject* holder, Shape* holderShape,
+                           JSFunction* getter, uint32_t pcOffset)
+      : ICGetPropCallGetter(GetProp_CallScripted, stubCode, firstMonitorStub,
+                            receiverGuard, holder, holderShape, getter, pcOffset)
+    {}
+
+  public:
+    static ICGetProp_CallScripted* Clone(JSContext* cx, ICStubSpace* space,
+                                         ICStub* firstMonitorStub, ICGetProp_CallScripted& other);
+
+    class Compiler : public ICGetPropCallGetter::Compiler {
+      protected:
+        bool generateStubCode(MacroAssembler& masm);
+
+      public:
+        Compiler(JSContext* cx, ICStub* firstMonitorStub, HandleObject obj,
+                 HandleObject holder, HandleFunction getter, uint32_t pcOffset)
+          : ICGetPropCallGetter::Compiler(cx, ICStub::GetProp_CallScripted,
+                                          firstMonitorStub, obj, holder,
+                                          getter, pcOffset, /* outerClass = */ nullptr)
+        {}
+
+        ICStub* getStub(ICStubSpace* space) {
+            ReceiverGuard guard(receiver_);
+            Shape* holderShape = holder_->as<NativeObject>().lastProperty();
+            return newStub<ICGetProp_CallScripted>(space, getStubCode(), firstMonitorStub_,
+                                                       guard, holder_, holderShape, getter_,
+                                                       pcOffset_);
+        }
+    };
+};
+
+// Stub for calling a native getter on a native object.
+class ICGetProp_CallNative : public ICGetPropCallGetter
+{
+    friend class ICStubSpace;
+
+  protected:
+
+    ICGetProp_CallNative(JitCode* stubCode, ICStub* firstMonitorStub,
+                         ReceiverGuard receiverGuard,
+                         JSObject* holder, Shape* holderShape,
+                         JSFunction* getter, uint32_t pcOffset)
+      : ICGetPropCallGetter(GetProp_CallNative, stubCode, firstMonitorStub,
+                            receiverGuard, holder, holderShape, getter, pcOffset)
+    {}
+
+  public:
+    static ICGetProp_CallNative* Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitorStub,
+                                       ICGetProp_CallNative& other);
+
+};
+
+// Stub for calling a native getter on the GlobalObject.
+class ICGetProp_CallNativeGlobal : public ICGetPropCallGetter
+{
+    friend class ICStubSpace;
+
+  protected:
+    HeapPtrShape globalShape_;
+
+    ICGetProp_CallNativeGlobal(JitCode* stubCode, ICStub* firstMonitorStub,
+                               ReceiverGuard receiverGuard,
+                               JSObject* holder, Shape* holderShape, Shape* globalShape,
+                               JSFunction* getter, uint32_t pcOffset)
+      : ICGetPropCallGetter(GetProp_CallNativeGlobal, stubCode, firstMonitorStub,
+                            receiverGuard, holder, holderShape, getter, pcOffset),
+        globalShape_(globalShape)
+    { }
+
+  public:
+    static ICGetProp_CallNativeGlobal* Clone(JSContext* cx, ICStubSpace* space,
+                                             ICStub* firstMonitorStub,
+                                             ICGetProp_CallNativeGlobal& other);
+
+    HeapPtrShape& globalShape() {
+        return globalShape_;
+    }
+    static size_t offsetOfGlobalShape() {
+        return offsetof(ICGetProp_CallNativeGlobal, globalShape_);
+    }
+};
+
+class ICGetPropCallNativeCompiler : public ICGetPropCallGetter::Compiler
+{
+    bool inputDefinitelyObject_;
+  protected:
+    bool generateStubCode(MacroAssembler& masm);
+
+    virtual int32_t getKey() const {
+        int32_t baseKey = ICGetPropCallGetter::Compiler::getKey();
+        MOZ_ASSERT((baseKey >> 21) == 0);
+        return baseKey | (static_cast<int32_t>(inputDefinitelyObject_) << 21);
+    }
+
+  public:
+    ICGetPropCallNativeCompiler(JSContext* cx, ICStub::Kind kind, ICStub* firstMonitorStub,
+                                HandleObject receiver, HandleObject holder, HandleFunction getter,
+                                uint32_t pcOffset, const Class* outerClass,
+                                bool inputDefinitelyObject = false)
+      : ICGetPropCallGetter::Compiler(cx, kind, firstMonitorStub, receiver, holder,
+                                      getter, pcOffset, outerClass),
+        inputDefinitelyObject_(inputDefinitelyObject)
+    {}
+
+    ICStub* getStub(ICStubSpace* space);
+};
+
+class ICGetPropCallDOMProxyNativeStub : public ICGetPropCallGetter
+{
+  friend class ICStubSpace;
+  protected:
+    // Object shape of expected expando object. (nullptr if no expando object should be there)
+    HeapPtrShape expandoShape_;
+
+    ICGetPropCallDOMProxyNativeStub(ICStub::Kind kind, JitCode* stubCode,
+                                    ICStub* firstMonitorStub, Shape* shape,
+                                    Shape* expandoShape,
+                                    JSObject* holder, Shape* holderShape,
+                                    JSFunction* getter, uint32_t pcOffset);
+
+  public:
+    HeapPtrShape& expandoShape() {
+        return expandoShape_;
+    }
+    static size_t offsetOfExpandoShape() {
+        return offsetof(ICGetPropCallDOMProxyNativeStub, expandoShape_);
+    }
+};
+
+class ICGetProp_CallDOMProxyNative : public ICGetPropCallDOMProxyNativeStub
+{
+    friend class ICStubSpace;
+    ICGetProp_CallDOMProxyNative(JitCode* stubCode, ICStub* firstMonitorStub, Shape* shape,
+                                 Shape* expandoShape,
+                                 JSObject* holder, Shape* holderShape,
+                                 JSFunction* getter, uint32_t pcOffset)
+      : ICGetPropCallDOMProxyNativeStub(ICStub::GetProp_CallDOMProxyNative, stubCode,
+                                        firstMonitorStub, shape, expandoShape,
+                                        holder, holderShape, getter, pcOffset)
+    {}
+
+  public:
+    static ICGetProp_CallDOMProxyNative* Clone(JSContext* cx,
+                                               ICStubSpace* space,
+                                               ICStub* firstMonitorStub,
+                                               ICGetProp_CallDOMProxyNative& other);
+};
+
+class ICGetProp_CallDOMProxyWithGenerationNative : public ICGetPropCallDOMProxyNativeStub
+{
+  protected:
+    ExpandoAndGeneration* expandoAndGeneration_;
+    uint32_t generation_;
+
+  public:
+    ICGetProp_CallDOMProxyWithGenerationNative(JitCode* stubCode, ICStub* firstMonitorStub,
+                                               Shape* shape,
+                                               ExpandoAndGeneration* expandoAndGeneration,
+                                               uint32_t generation, Shape* expandoShape,
+                                               JSObject* holder, Shape* holderShape,
+                                               JSFunction* getter, uint32_t pcOffset)
+      : ICGetPropCallDOMProxyNativeStub(ICStub::GetProp_CallDOMProxyWithGenerationNative,
+                                        stubCode, firstMonitorStub, shape,
+                                        expandoShape, holder, holderShape, getter, pcOffset),
+        expandoAndGeneration_(expandoAndGeneration),
+        generation_(generation)
+    {
+    }
+
+    static ICGetProp_CallDOMProxyWithGenerationNative*
+    Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitorStub,
+          ICGetProp_CallDOMProxyWithGenerationNative& other);
+
+    void* expandoAndGeneration() const {
+        return expandoAndGeneration_;
+    }
+    uint32_t generation() const {
+        return generation_;
+    }
+
+    void setGeneration(uint32_t value) {
+        generation_ = value;
+    }
+
+    static size_t offsetOfInternalStruct() {
+        return offsetof(ICGetProp_CallDOMProxyWithGenerationNative, expandoAndGeneration_);
+    }
+    static size_t offsetOfGeneration() {
+        return offsetof(ICGetProp_CallDOMProxyWithGenerationNative, generation_);
+    }
+};
+
+class ICGetPropCallDOMProxyNativeCompiler : public ICStubCompiler {
+    ICStub* firstMonitorStub_;
+    Rooted<ProxyObject*> proxy_;
+    RootedObject holder_;
+    RootedFunction getter_;
+    uint32_t pcOffset_;
+
+    bool generateStubCode(MacroAssembler& masm, Address* internalStructAddr,
+                          Address* generationAddr);
+    bool generateStubCode(MacroAssembler& masm);
+
+  public:
+    ICGetPropCallDOMProxyNativeCompiler(JSContext* cx, ICStub::Kind kind,
+                                        ICStub* firstMonitorStub, Handle<ProxyObject*> proxy,
+                                        HandleObject holder, HandleFunction getter,
+                                        uint32_t pcOffset);
+
+    ICStub* getStub(ICStubSpace* space);
+};
+
+class ICGetProp_DOMProxyShadowed : public ICMonitoredStub
+{
+  friend class ICStubSpace;
+  protected:
+    HeapPtrShape shape_;
+    const BaseProxyHandler* proxyHandler_;
+    HeapPtrPropertyName name_;
+    uint32_t pcOffset_;
+
+    ICGetProp_DOMProxyShadowed(JitCode* stubCode, ICStub* firstMonitorStub, Shape* shape,
+                               const BaseProxyHandler* proxyHandler, PropertyName* name,
+                               uint32_t pcOffset);
+
+  public:
+    static ICGetProp_DOMProxyShadowed* Clone(JSContext* cx, ICStubSpace* space,
+                                             ICStub* firstMonitorStub,
+                                             ICGetProp_DOMProxyShadowed& other);
+
+    HeapPtrShape& shape() {
+        return shape_;
+    }
+    HeapPtrPropertyName& name() {
+        return name_;
+    }
+
+    static size_t offsetOfShape() {
+        return offsetof(ICGetProp_DOMProxyShadowed, shape_);
+    }
+    static size_t offsetOfProxyHandler() {
+        return offsetof(ICGetProp_DOMProxyShadowed, proxyHandler_);
+    }
+    static size_t offsetOfName() {
+        return offsetof(ICGetProp_DOMProxyShadowed, name_);
+    }
+    static size_t offsetOfPCOffset() {
+        return offsetof(ICGetProp_DOMProxyShadowed, pcOffset_);
+    }
+
+    class Compiler : public ICStubCompiler {
+        ICStub* firstMonitorStub_;
+        Rooted<ProxyObject*> proxy_;
+        RootedPropertyName name_;
+        uint32_t pcOffset_;
+
+        bool generateStubCode(MacroAssembler& masm);
+
+      public:
+        Compiler(JSContext* cx, ICStub* firstMonitorStub, Handle<ProxyObject*> proxy,
+                 HandlePropertyName name, uint32_t pcOffset)
+          : ICStubCompiler(cx, ICStub::GetProp_CallNative, Engine::Baseline),
+            firstMonitorStub_(firstMonitorStub),
+            proxy_(cx, proxy),
+            name_(cx, name),
+            pcOffset_(pcOffset)
+        {}
+
+        ICStub* getStub(ICStubSpace* space);
+    };
+};
+
+class ICGetProp_ArgumentsLength : public ICStub
+{
+  friend class ICStubSpace;
+  public:
+    enum Which { Mapped, Unmapped, Magic };
+
+  protected:
+    explicit ICGetProp_ArgumentsLength(JitCode* stubCode)
+      : ICStub(ICStub::GetProp_ArgumentsLength, stubCode)
+    { }
+
+  public:
+    class Compiler : public ICStubCompiler {
+      protected:
+        Which which_;
+
+        bool generateStubCode(MacroAssembler& masm);
+
+        virtual int32_t getKey() const {
+            return static_cast<int32_t>(engine_) |
+                  (static_cast<int32_t>(kind) << 1) |
+                  (static_cast<int32_t>(which_) << 17);
+        }
+
+      public:
+        Compiler(JSContext* cx, Which which)
+          : ICStubCompiler(cx, ICStub::GetProp_ArgumentsLength, Engine::Baseline),
+            which_(which)
+        {}
+
+        ICStub* getStub(ICStubSpace* space) {
+            return newStub<ICGetProp_ArgumentsLength>(space, getStubCode());
+        }
+    };
+};
+
+class ICGetProp_ArgumentsCallee : public ICMonitoredStub
+{
+    friend class ICStubSpace;
+
+  protected:
+    ICGetProp_ArgumentsCallee(JitCode* stubCode, ICStub* firstMonitorStub);
+
+  public:
+    class Compiler : public ICStubCompiler {
+      protected:
+        ICStub* firstMonitorStub_;
+        bool generateStubCode(MacroAssembler& masm);
+
+      public:
+        Compiler(JSContext* cx, ICStub* firstMonitorStub)
+          : ICStubCompiler(cx, ICStub::GetProp_ArgumentsCallee, Engine::Baseline),
+            firstMonitorStub_(firstMonitorStub)
+        {}
+
+        ICStub* getStub(ICStubSpace* space) {
+            return newStub<ICGetProp_ArgumentsCallee>(space, getStubCode(), firstMonitorStub_);
+        }
+    };
+};
+
 } // namespace jit
 } // namespace js
 
 #endif /* jit_SharedIC_h */
--- a/js/src/jit/SharedICList.h
+++ b/js/src/jit/SharedICList.h
@@ -29,13 +29,33 @@ namespace jit {
     _(Compare_Double)                            \
     _(Compare_NumberWithUndefined)               \
     _(Compare_String)                            \
     _(Compare_Boolean)                           \
     _(Compare_Object)                            \
     _(Compare_ObjectWithUndefined)               \
     _(Compare_Int32WithBoolean)                  \
                                                  \
+    _(GetProp_Fallback)                          \
+    _(GetProp_ArrayLength)                       \
+    _(GetProp_UnboxedArrayLength)                \
+    _(GetProp_Primitive)                         \
+    _(GetProp_StringLength)                      \
+    _(GetProp_Native)                            \
+    _(GetProp_NativeDoesNotExist)                \
+    _(GetProp_NativePrototype)                   \
+    _(GetProp_Unboxed)                           \
+    _(GetProp_TypedObject)                       \
+    _(GetProp_CallScripted)                      \
+    _(GetProp_CallNative)                        \
+    _(GetProp_CallNativeGlobal)                  \
+    _(GetProp_CallDOMProxyNative)                \
+    _(GetProp_CallDOMProxyWithGenerationNative)  \
+    _(GetProp_DOMProxyShadowed)                  \
+    _(GetProp_ArgumentsLength)                   \
+    _(GetProp_ArgumentsCallee)                   \
+    _(GetProp_Generic)                           \
+                                                 \
 
 } // namespace jit
 } // namespace js
 
 #endif /* jit_SharedICList_h */