From 7730277de2856dde7e4c764a1b4384bc2b25bad0 Mon Sep 17 00:00:00 2001 From: Phil Ringnalda Date: Thu, 11 Sep 2014 23:27:39 -0700 Subject: [PATCH] Back out 74728e99dc47 (bug 1049290) for causing the same hazard build timeouts it caused on Try CLOSED TREE --- js/src/jit/BaselineIC.cpp | 472 ++++---------------------------------- js/src/jit/BaselineIC.h | 257 --------------------- 2 files changed, 44 insertions(+), 685 deletions(-) diff --git a/js/src/jit/BaselineIC.cpp b/js/src/jit/BaselineIC.cpp index 6a823d192a2..e55c379a91e 100644 --- a/js/src/jit/BaselineIC.cpp +++ b/js/src/jit/BaselineIC.cpp @@ -287,43 +287,6 @@ ICStub::trace(JSTracer *trc) MarkScript(trc, &pushFunStub->script(), "baseline-profilerpushfunction-stub-script"); break; } - case ICStub::In_Native: { - ICIn_Native *inStub = toIn_Native(); - MarkShape(trc, &inStub->shape(), "baseline-innative-stub-shape"); - MarkString(trc, &inStub->name(), "baseline-innative-stub-name"); - break; - } - case ICStub::In_NativePrototype: { - ICIn_NativePrototype *inStub = toIn_NativePrototype(); - MarkShape(trc, &inStub->shape(), "baseline-innativeproto-stub-shape"); - MarkString(trc, &inStub->name(), "baseline-innativeproto-stub-name"); - MarkObject(trc, &inStub->holder(), "baseline-innativeproto-stub-holder"); - MarkShape(trc, &inStub->holderShape(), "baseline-innativeproto-stub-holdershape"); - break; - } - case ICStub::In_NativeDoesNotExist: { - ICIn_NativeDoesNotExist *inStub = toIn_NativeDoesNotExist(); - MarkString(trc, &inStub->name(), "baseline-innativedoesnotexist-stub-name"); - JS_STATIC_ASSERT(ICIn_NativeDoesNotExist::MAX_PROTO_CHAIN_DEPTH == 8); - switch (inStub->protoChainDepth()) { - case 0: inStub->toImpl<0>()->traceShapes(trc); break; - case 1: inStub->toImpl<1>()->traceShapes(trc); break; - case 2: inStub->toImpl<2>()->traceShapes(trc); break; - case 3: inStub->toImpl<3>()->traceShapes(trc); break; - case 4: inStub->toImpl<4>()->traceShapes(trc); break; - case 5: inStub->toImpl<5>()->traceShapes(trc); break; - case 6: inStub->toImpl<6>()->traceShapes(trc); break; - case 7: inStub->toImpl<7>()->traceShapes(trc); break; - case 8: inStub->toImpl<8>()->traceShapes(trc); break; - default: MOZ_ASSUME_UNREACHABLE("Invalid proto stub."); - } - break; - } - case ICStub::In_Dense: { - ICIn_Dense *inStub = toIn_Dense(); - MarkShape(trc, &inStub->shape(), "baseline-in-dense-shape"); - break; - } case ICStub::GetName_Global: { ICGetName_Global *globalStub = toGetName_Global(); MarkShape(trc, &globalStub->shape(), "baseline-global-stub-shape"); @@ -3774,29 +3737,22 @@ ArgumentsGetElemStubExists(ICGetElem_Fallback *stub, ICGetElem_Arguments::Which return false; } -static bool -IsOptimizableElementPropertyName(JSContext *cx, HandleValue key, MutableHandleId idp) -{ - if (!key.isString()) - return false; - - // Convert to interned property name. - if (!ValueToId(cx, key, idp)) - return false; - - uint32_t dummy; - if (!JSID_IS_ATOM(idp) || JSID_TO_ATOM(idp)->isIndex(&dummy)) - return false; - - return true; -} static bool TryAttachNativeGetElemStub(JSContext *cx, HandleScript script, jsbytecode *pc, ICGetElem_Fallback *stub, HandleObject obj, HandleValue key) { + // Native-object GetElem stubs can't deal with non-string keys. + if (!key.isString()) + return true; + + // Convert to interned property name. RootedId id(cx); - if (!IsOptimizableElementPropertyName(cx, key, &id)) + if (!ValueToId(cx, key, &id)) + return false; + + uint32_t dummy; + if (!JSID_IS_ATOM(id) || JSID_TO_ATOM(id)->isIndex(&dummy)) return true; RootedPropertyName propName(cx, JSID_TO_ATOM(id)->asPropertyName()); @@ -3910,14 +3866,6 @@ TypedArrayRequiresFloatingPoint(TypedArrayObject *tarr) type == Scalar::Float64; } -static bool -IsNativeDenseElementAccess(HandleObject obj, HandleValue key) -{ - if (obj->isNative() && key.isInt32() && key.toInt32() >= 0 && !obj->is()) - return true; - return false; -} - static bool TryAttachGetElemStub(JSContext *cx, JSScript *script, jsbytecode *pc, ICGetElem_Fallback *stub, HandleValue lhs, HandleValue rhs, HandleValue res) @@ -3981,25 +3929,27 @@ TryAttachGetElemStub(JSContext *cx, JSScript *script, jsbytecode *pc, ICGetElem_ } } - // Check for NativeObject[int] dense accesses. - if (IsNativeDenseElementAccess(obj, rhs)) { - JitSpew(JitSpew_BaselineIC, " Generating GetElem(Native[Int32] dense) stub"); - ICGetElem_Dense::Compiler compiler(cx, stub->fallbackMonitorStub()->firstMonitorStub(), - obj->lastProperty(), isCallElem); - ICStub *denseStub = compiler.getStub(compiler.getStubSpace(script)); - if (!denseStub) - return false; + if (obj->isNative()) { + // Check for NativeObject[int] dense accesses. + if (rhs.isInt32() && rhs.toInt32() >= 0 && !obj->is()) { + JitSpew(JitSpew_BaselineIC, " Generating GetElem(Native[Int32] dense) stub"); + ICGetElem_Dense::Compiler compiler(cx, stub->fallbackMonitorStub()->firstMonitorStub(), + obj->lastProperty(), isCallElem); + ICStub *denseStub = compiler.getStub(compiler.getStubSpace(script)); + if (!denseStub) + return false; - stub->addNewStub(denseStub); - return true; - } + stub->addNewStub(denseStub); + return true; + } - // Check for NativeObject[id] shape-optimizable accesses. - if (obj->isNative() && rhs.isString()) { - RootedScript rootedScript(cx, script); - if (!TryAttachNativeGetElemStub(cx, rootedScript, pc, stub, obj, rhs)) - return false; - script = rootedScript; + // Check for NativeObject[id] shape-optimizable accesses. + if (rhs.isString()) { + RootedScript rootedScript(cx, script); + if (!TryAttachNativeGetElemStub(cx, rootedScript, pc, stub, obj, rhs)) + return false; + script = rootedScript; + } } // Check for TypedArray[int] => Number accesses. @@ -5075,7 +5025,10 @@ DoSetElemFallback(JSContext *cx, BaselineFrame *frame, ICSetElem_Fallback *stub_ } // Try to generate new stubs. - if (IsNativeDenseElementAccess(obj, index) && !rhs.isMagic(JS_ELEMENTS_HOLE)) + if (obj->isNative() && + !obj->is() && + index.isInt32() && index.toInt32() >= 0 && + !rhs.isMagic(JS_ELEMENTS_HOLE)) { bool addingCase; size_t protoDepth; @@ -5659,96 +5612,8 @@ ICSetElem_TypedArray::Compiler::generateStubCode(MacroAssembler &masm) // static bool -TryAttachDenseInStub(JSContext *cx, HandleScript script, ICIn_Fallback *stub, - HandleValue key, HandleObject obj, bool *attached) -{ - MOZ_ASSERT(!*attached); - - if (!IsNativeDenseElementAccess(obj, key)) - return true; - - JitSpew(JitSpew_BaselineIC, " Generating In(Native[Int32] dense) stub"); - ICIn_Dense::Compiler compiler(cx, obj->lastProperty()); - ICStub *denseStub = compiler.getStub(compiler.getStubSpace(script)); - if (!denseStub) - return false; - - *attached = true; - stub->addNewStub(denseStub); - return true; -} - -static bool -TryAttachNativeInStub(JSContext *cx, HandleScript script, ICIn_Fallback *stub, - HandleValue key, HandleObject obj, bool *attached) -{ - MOZ_ASSERT(!*attached); - - RootedId id(cx); - if (!IsOptimizableElementPropertyName(cx, key, &id)) - return true; - - RootedPropertyName name(cx, JSID_TO_ATOM(id)->asPropertyName()); - RootedShape shape(cx); - RootedObject holder(cx); - if (!EffectlesslyLookupProperty(cx, obj, name, &holder, &shape)) - return false; - - if (IsCacheableGetPropReadSlot(obj, holder, shape)) { - ICStub::Kind kind = (obj == holder) ? ICStub::In_Native - : ICStub::In_NativePrototype; - JitSpew(JitSpew_BaselineIC, " Generating In(Native %s) stub", - (obj == holder) ? "direct" : "prototype"); - ICInNativeCompiler compiler(cx, kind, obj, holder, name); - ICStub *newStub = compiler.getStub(compiler.getStubSpace(script)); - if (!newStub) - return false; - - *attached = true; - stub->addNewStub(newStub); - return true; - } - - return true; -} - -static bool -TryAttachNativeInDoesNotExistStub(JSContext *cx, HandleScript script, - ICIn_Fallback *stub, HandleValue key, - HandleObject obj, bool *attached) -{ - MOZ_ASSERT(!*attached); - - RootedId id(cx); - if (!IsOptimizableElementPropertyName(cx, key, &id)) - return true; - - // Check if does-not-exist can be confirmed on property. - RootedPropertyName name(cx, JSID_TO_ATOM(id)->asPropertyName()); - RootedObject lastProto(cx); - size_t protoChainDepth = SIZE_MAX; - if (!CheckHasNoSuchProperty(cx, obj, name, &lastProto, &protoChainDepth)) - return true; - MOZ_ASSERT(protoChainDepth < SIZE_MAX); - - if (protoChainDepth > ICIn_NativeDoesNotExist::MAX_PROTO_CHAIN_DEPTH) - return true; - - // Confirmed no-such-property. Add stub. - JitSpew(JitSpew_BaselineIC, " Generating In_NativeDoesNotExist stub"); - ICInNativeDoesNotExistCompiler compiler(cx, obj, name, protoChainDepth); - ICStub *newStub = compiler.getStub(compiler.getStubSpace(script)); - if (!newStub) - return false; - - *attached = true; - stub->addNewStub(newStub); - return true; -} - -static bool -DoInFallback(JSContext *cx, BaselineFrame *frame, ICIn_Fallback *stub, - HandleValue key, HandleValue objValue, MutableHandleValue res) +DoInFallback(JSContext *cx, ICIn_Fallback *stub, HandleValue key, HandleValue objValue, + MutableHandleValue res) { FallbackICSpew(cx, stub, "In"); @@ -5762,33 +5627,13 @@ DoInFallback(JSContext *cx, BaselineFrame *frame, ICIn_Fallback *stub, bool cond = false; if (!OperatorIn(cx, key, obj, &cond)) return false; + res.setBoolean(cond); - - if (obj->isNative()) { - RootedScript script(cx, frame->script()); - bool attached = false; - if (cond) { - if (!TryAttachDenseInStub(cx, script, stub, key, obj, &attached)) - return false; - if (attached) - return true; - if (!TryAttachNativeInStub(cx, script, stub, key, obj, &attached)) - return false; - if (attached) - return true; - } else { - if (!TryAttachNativeInDoesNotExistStub(cx, script, stub, key, obj, &attached)) - return false; - if (attached) - return true; - } - } - return true; } -typedef bool (*DoInFallbackFn)(JSContext *, BaselineFrame *, ICIn_Fallback *, HandleValue, - HandleValue, MutableHandleValue); +typedef bool (*DoInFallbackFn)(JSContext *, ICIn_Fallback *, HandleValue, HandleValue, + MutableHandleValue); static const VMFunction DoInFallbackInfo = FunctionInfo(DoInFallback, PopValues(2)); @@ -5805,182 +5650,10 @@ ICIn_Fallback::Compiler::generateStubCode(MacroAssembler &masm) masm.pushValue(R1); masm.pushValue(R0); masm.push(BaselineStubReg); - masm.pushBaselineFramePtr(BaselineFrameReg, R0.scratchReg()); return tailCallVM(DoInFallbackInfo, masm); } -bool -ICInNativeCompiler::generateStubCode(MacroAssembler &masm) -{ - Label failure, failurePopR0Scratch; - - masm.branchTestString(Assembler::NotEqual, R0, &failure); - masm.branchTestObject(Assembler::NotEqual, R1, &failure); - - GeneralRegisterSet regs(availableGeneralRegs(2)); - Register scratch = regs.takeAny(); - - // Check key identity. - Register strExtract = masm.extractString(R0, ExtractTemp0); - masm.loadPtr(Address(BaselineStubReg, ICInNativeStub::offsetOfName()), scratch); - masm.branchPtr(Assembler::NotEqual, strExtract, scratch, &failure); - - // Unbox and shape guard object. - Register objReg = masm.extractObject(R1, ExtractTemp0); - masm.loadPtr(Address(BaselineStubReg, ICInNativeStub::offsetOfShape()), scratch); - masm.branchTestObjShape(Assembler::NotEqual, objReg, scratch, &failure); - - if (kind == ICStub::In_NativePrototype) { - // Shape guard holder. Use R0 scrachReg since on x86 there're not enough registers. - Register holderReg = R0.scratchReg(); - masm.push(R0.scratchReg()); - masm.loadPtr(Address(BaselineStubReg, ICIn_NativePrototype::offsetOfHolder()), - holderReg); - masm.loadPtr(Address(BaselineStubReg, ICIn_NativePrototype::offsetOfHolderShape()), - scratch); - masm.branchTestObjShape(Assembler::NotEqual, holderReg, scratch, &failurePopR0Scratch); - masm.addPtr(Imm32(sizeof(size_t)), StackPointer); - } - - masm.moveValue(BooleanValue(true), R0); - - EmitReturnFromIC(masm); - - // Failure case - jump to next stub - masm.bind(&failurePopR0Scratch); - masm.pop(R0.scratchReg()); - masm.bind(&failure); - EmitStubGuardFailure(masm); - return true; -} - -ICStub * -ICInNativeDoesNotExistCompiler::getStub(ICStubSpace *space) -{ - AutoShapeVector shapes(cx); - if (!shapes.append(obj_->lastProperty())) - return nullptr; - - if (!GetProtoShapes(obj_, protoChainDepth_, &shapes)) - return nullptr; - - JS_STATIC_ASSERT(ICIn_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_ASSUME_UNREACHABLE("ProtoChainDepth too high."); - } - if (!stub) - return nullptr; - return stub; -} - -bool -ICInNativeDoesNotExistCompiler::generateStubCode(MacroAssembler &masm) -{ - Label failure, failurePopR0Scratch; - - masm.branchTestString(Assembler::NotEqual, R0, &failure); - masm.branchTestObject(Assembler::NotEqual, R1, &failure); - - GeneralRegisterSet regs(availableGeneralRegs(2)); - Register scratch = regs.takeAny(); - -#ifdef DEBUG - // Ensure that protoChainDepth_ matches the protoChainDepth stored on the stub. - { - Label ok; - masm.load16ZeroExtend(Address(BaselineStubReg, 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 - - // Check key identity. - Register strExtract = masm.extractString(R0, ExtractTemp0); - masm.loadPtr(Address(BaselineStubReg, ICIn_NativeDoesNotExist::offsetOfName()), scratch); - masm.branchPtr(Assembler::NotEqual, strExtract, scratch, &failure); - - // Unbox and guard against old shape. - Register objReg = masm.extractObject(R1, ExtractTemp0); - masm.loadPtr(Address(BaselineStubReg, ICIn_NativeDoesNotExist::offsetOfShape(0)), - scratch); - masm.branchTestObjShape(Assembler::NotEqual, objReg, scratch, &failure); - - // Check the proto chain. - Register protoReg = R0.scratchReg(); - masm.push(R0.scratchReg()); - 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 = ICIn_NativeDoesNotExistImpl<0>::offsetOfShape(i + 1); - masm.loadPtr(Address(BaselineStubReg, shapeOffset), scratch); - masm.branchTestObjShape(Assembler::NotEqual, protoReg, scratch, &failurePopR0Scratch); - } - masm.addPtr(Imm32(sizeof(size_t)), StackPointer); - - // Shape and type checks succeeded, ok to proceed. - masm.moveValue(BooleanValue(false), R0); - - EmitReturnFromIC(masm); - - masm.bind(&failurePopR0Scratch); - masm.pop(R0.scratchReg()); - masm.bind(&failure); - EmitStubGuardFailure(masm); - return true; -} - -bool -ICIn_Dense::Compiler::generateStubCode(MacroAssembler &masm) -{ - Label failure; - - masm.branchTestInt32(Assembler::NotEqual, R0, &failure); - masm.branchTestObject(Assembler::NotEqual, R1, &failure); - - GeneralRegisterSet regs(availableGeneralRegs(2)); - Register scratch = regs.takeAny(); - - // Unbox and shape guard object. - Register obj = masm.extractObject(R1, ExtractTemp0); - masm.loadPtr(Address(BaselineStubReg, ICIn_Dense::offsetOfShape()), scratch); - masm.branchTestObjShape(Assembler::NotEqual, obj, scratch, &failure); - - // Load obj->elements. - masm.loadPtr(Address(obj, JSObject::offsetOfElements()), scratch); - - // Unbox key and bounds check. - Address initLength(scratch, ObjectElements::offsetOfInitializedLength()); - Register key = masm.extractInt32(R0, ExtractTemp0); - masm.branch32(Assembler::BelowOrEqual, initLength, key, &failure); - - // Hole check. - JS_STATIC_ASSERT(sizeof(Value) == 8); - BaseIndex element(scratch, key, TimesEight); - masm.branchTestMagic(Assembler::Equal, element, &failure); - - masm.moveValue(BooleanValue(true), R0); - - EmitReturnFromIC(masm); - - // Failure case - jump to next stub - masm.bind(&failure); - EmitStubGuardFailure(masm); - return true; -} - // Attach an optimized stub for a GETGNAME/CALLGNAME op. static bool TryAttachGlobalNameStub(JSContext *cx, HandleScript script, jsbytecode *pc, @@ -6780,10 +6453,9 @@ TryAttachPrimitiveGetPropStub(JSContext *cx, HandleScript script, jsbytecode *pc } static bool -TryAttachNativeGetPropDoesNotExistStub(JSContext *cx, HandleScript script, - jsbytecode *pc, ICGetProp_Fallback *stub, - HandlePropertyName name, HandleValue val, - bool *attached) +TryAttachNativeDoesNotExistStub(JSContext *cx, HandleScript script, jsbytecode *pc, + ICGetProp_Fallback *stub, HandlePropertyName name, + HandleValue val, bool *attached) { MOZ_ASSERT(!*attached); @@ -6807,6 +6479,8 @@ TryAttachNativeGetPropDoesNotExistStub(JSContext *cx, HandleScript script, return true; ICStub *monitorStub = stub->fallbackMonitorStub()->firstMonitorStub(); + RootedShape objShape(cx, obj->lastProperty()); + RootedShape lastShape(cx, lastProto->lastProperty()); // Confirmed no-such-property. Add stub. JitSpew(JitSpew_BaselineIC, " Generating GetProp_NativeDoesNotExist stub"); @@ -6928,7 +6602,7 @@ DoGetPropFallback(JSContext *cx, BaselineFrame *frame, ICGetProp_Fallback *stub_ if (res.isUndefined()) { // Try attaching property-not-found optimized stub for undefined results. - if (!TryAttachNativeGetPropDoesNotExistStub(cx, script, pc, stub, name, val, &attached)) + if (!TryAttachNativeDoesNotExistStub(cx, script, pc, stub, name, val, &attached)) return false; if (attached) return true; @@ -10771,64 +10445,6 @@ ICSetElem_TypedArray::ICSetElem_TypedArray(JitCode *stubCode, HandleShape shape, extra_ |= (static_cast(expectOutOfBounds) << 8); } -ICInNativeStub::ICInNativeStub(ICStub::Kind kind, JitCode *stubCode, HandleShape shape, - HandlePropertyName name) - : ICStub(kind, stubCode), - shape_(shape), - name_(name) -{ } - -ICIn_NativePrototype::ICIn_NativePrototype(JitCode *stubCode, HandleShape shape, - HandlePropertyName name, HandleObject holder, - HandleShape holderShape) - : ICInNativeStub(In_NativePrototype, stubCode, shape, name), - holder_(holder), - holderShape_(holderShape) -{ } - -ICIn_NativeDoesNotExist::ICIn_NativeDoesNotExist(JitCode *stubCode, size_t protoChainDepth, - HandlePropertyName name) - : ICStub(In_NativeDoesNotExist, stubCode), - name_(name) -{ - MOZ_ASSERT(protoChainDepth <= MAX_PROTO_CHAIN_DEPTH); - extra_ = protoChainDepth; -} - -/* static */ size_t -ICIn_NativeDoesNotExist::offsetOfShape(size_t idx) -{ - MOZ_ASSERT(ICIn_NativeDoesNotExistImpl<0>::offsetOfShape(idx) == - ICIn_NativeDoesNotExistImpl< - ICIn_NativeDoesNotExist::MAX_PROTO_CHAIN_DEPTH>::offsetOfShape(idx)); - return ICIn_NativeDoesNotExistImpl<0>::offsetOfShape(idx); -} - -template -ICIn_NativeDoesNotExistImpl::ICIn_NativeDoesNotExistImpl( - JitCode *stubCode, const AutoShapeVector *shapes, HandlePropertyName name) - : ICIn_NativeDoesNotExist(stubCode, ProtoChainDepth, name) -{ - MOZ_ASSERT(shapes->length() == NumShapes); - for (size_t i = 0; i < NumShapes; i++) - shapes_[i].init((*shapes)[i]); -} - -ICInNativeDoesNotExistCompiler::ICInNativeDoesNotExistCompiler( - JSContext *cx, HandleObject obj, HandlePropertyName name, size_t protoChainDepth) - : ICStubCompiler(cx, ICStub::In_NativeDoesNotExist), - obj_(cx, obj), - name_(cx, name), - protoChainDepth_(protoChainDepth) -{ - MOZ_ASSERT(protoChainDepth_ <= ICIn_NativeDoesNotExist::MAX_PROTO_CHAIN_DEPTH); -} - -ICIn_Dense::ICIn_Dense(JitCode *stubCode, HandleShape shape) - : ICStub(In_Dense, stubCode), - shape_(shape) -{ } - ICGetName_Global::ICGetName_Global(JitCode *stubCode, ICStub *firstMonitorStub, HandleShape shape, uint32_t slot) : ICMonitoredStub(GetName_Global, stubCode, firstMonitorStub), diff --git a/js/src/jit/BaselineIC.h b/js/src/jit/BaselineIC.h index 011bc7b6f24..088994887b3 100644 --- a/js/src/jit/BaselineIC.h +++ b/js/src/jit/BaselineIC.h @@ -391,10 +391,6 @@ class ICEntry _(SetElem_TypedArray) \ \ _(In_Fallback) \ - _(In_Native) \ - _(In_NativePrototype) \ - _(In_NativeDoesNotExist) \ - _(In_Dense) \ \ _(GetName_Fallback) \ _(GetName_Global) \ @@ -3814,259 +3810,6 @@ class ICIn_Fallback : public ICFallbackStub }; }; -// Base class for In_Native and In_NativePrototype stubs. -class ICInNativeStub : public ICStub -{ - HeapPtrShape shape_; - HeapPtrPropertyName name_; - - protected: - ICInNativeStub(ICStub::Kind kind, JitCode *stubCode, HandleShape shape, - HandlePropertyName name); - - public: - HeapPtrShape &shape() { - return shape_; - } - static size_t offsetOfShape() { - return offsetof(ICInNativeStub, shape_); - } - - HeapPtrPropertyName &name() { - return name_; - } - static size_t offsetOfName() { - return offsetof(ICInNativeStub, name_); - } -}; - -// Stub for confirming an own property on a native object. -class ICIn_Native : public ICInNativeStub -{ - friend class ICStubSpace; - - ICIn_Native(JitCode *stubCode, HandleShape shape, HandlePropertyName name) - : ICInNativeStub(In_Native, stubCode, shape, name) - {} - - public: - static inline ICIn_Native *New(ICStubSpace *space, JitCode *code, HandleShape shape, - HandlePropertyName name) - { - if (!code) - return nullptr; - return space->allocate(code, shape, name); - } -}; - -// Stub for confirming a property on a native object's prototype. Note that due to -// the shape teleporting optimization, we only have to guard on the object's shape -// and the holder's shape. -class ICIn_NativePrototype : public ICInNativeStub -{ - friend class ICStubSpace; - - HeapPtrObject holder_; - HeapPtrShape holderShape_; - - ICIn_NativePrototype(JitCode *stubCode, HandleShape shape, HandlePropertyName name, - HandleObject holder, HandleShape holderShape); - - public: - static inline ICIn_NativePrototype *New(ICStubSpace *space, JitCode *code, - HandleShape shape, HandlePropertyName name, - HandleObject holder, HandleShape holderShape) - { - if (!code) - return nullptr; - return space->allocate(code, shape, name, holder, holderShape); - } - - HeapPtrObject &holder() { - return holder_; - } - HeapPtrShape &holderShape() { - return holderShape_; - } - static size_t offsetOfHolder() { - return offsetof(ICIn_NativePrototype, holder_); - } - static size_t offsetOfHolderShape() { - return offsetof(ICIn_NativePrototype, holderShape_); - } -}; - -// Compiler for In_Native and In_NativePrototype stubs. -class ICInNativeCompiler : public ICStubCompiler -{ - RootedObject obj_; - RootedObject holder_; - RootedPropertyName name_; - - bool generateStubCode(MacroAssembler &masm); - - public: - ICInNativeCompiler(JSContext *cx, ICStub::Kind kind, HandleObject obj, HandleObject holder, - HandlePropertyName name) - : ICStubCompiler(cx, kind), - obj_(cx, obj), - holder_(cx, holder), - name_(cx, name) - {} - - ICStub *getStub(ICStubSpace *space) { - RootedShape shape(cx, obj_->lastProperty()); - if (kind == ICStub::In_Native) { - JS_ASSERT(obj_ == holder_); - return ICIn_Native::New(space, getStubCode(), shape, name_); - } - - JS_ASSERT(obj_ != holder_); - JS_ASSERT(kind == ICStub::In_NativePrototype); - RootedShape holderShape(cx, holder_->lastProperty()); - return ICIn_NativePrototype::New(space, getStubCode(), shape, name_, holder_, holderShape); - } -}; - -template class ICIn_NativeDoesNotExistImpl; - -class ICIn_NativeDoesNotExist : public ICStub -{ - friend class ICStubSpace; - - HeapPtrPropertyName name_; - - public: - static const size_t MAX_PROTO_CHAIN_DEPTH = 8; - - protected: - ICIn_NativeDoesNotExist(JitCode *stubCode, size_t protoChainDepth, - HandlePropertyName name); - - public: - size_t protoChainDepth() const { - MOZ_ASSERT(extra_ <= MAX_PROTO_CHAIN_DEPTH); - return extra_; - } - HeapPtrPropertyName &name() { - return name_; - } - - template - ICIn_NativeDoesNotExistImpl *toImpl() { - MOZ_ASSERT(ProtoChainDepth == protoChainDepth()); - return static_cast *>(this); - } - - static size_t offsetOfShape(size_t idx); - static size_t offsetOfName() { - return offsetof(ICIn_NativeDoesNotExist, name_); - } -}; - -template -class ICIn_NativeDoesNotExistImpl : public ICIn_NativeDoesNotExist -{ - friend class ICStubSpace; - - public: - static const size_t MAX_PROTO_CHAIN_DEPTH = 8; - static const size_t NumShapes = ProtoChainDepth + 1; - - private: - mozilla::Array shapes_; - - ICIn_NativeDoesNotExistImpl(JitCode *stubCode, const AutoShapeVector *shapes, - HandlePropertyName name); - - public: - static inline ICIn_NativeDoesNotExistImpl *New( - ICStubSpace *space, JitCode *code, const AutoShapeVector *shapes, - HandlePropertyName name) - { - if (!code) - return nullptr; - return space->allocate>( - code, shapes, name); - } - - void traceShapes(JSTracer *trc) { - for (size_t i = 0; i < NumShapes; i++) - MarkShape(trc, &shapes_[i], "baseline-innativedoesnotexist-stub-shape"); - } - - static size_t offsetOfShape(size_t idx) { - return offsetof(ICIn_NativeDoesNotExistImpl, shapes_) + (idx * sizeof(HeapPtrShape)); - } -}; - -class ICInNativeDoesNotExistCompiler : public ICStubCompiler -{ - RootedObject obj_; - RootedPropertyName name_; - size_t protoChainDepth_; - - protected: - virtual int32_t getKey() const { - return static_cast(kind) | (static_cast(protoChainDepth_) << 16); - } - - bool generateStubCode(MacroAssembler &masm); - - public: - ICInNativeDoesNotExistCompiler(JSContext *cx, HandleObject obj, HandlePropertyName name, - size_t protoChainDepth); - - template - ICStub *getStubSpecific(ICStubSpace *space, const AutoShapeVector *shapes) { - return ICIn_NativeDoesNotExistImpl::New(space, getStubCode(), - shapes, name_); - } - - ICStub *getStub(ICStubSpace *space); -}; - -class ICIn_Dense : public ICStub -{ - friend class ICStubSpace; - - HeapPtrShape shape_; - - ICIn_Dense(JitCode *stubCode, HandleShape shape); - - public: - static inline ICIn_Dense *New(ICStubSpace *space, JitCode *code, HandleShape shape) - { - if (!code) - return nullptr; - return space->allocate(code, shape); - } - - HeapPtrShape &shape() { - return shape_; - } - static size_t offsetOfShape() { - return offsetof(ICIn_Dense, shape_); - } - - class Compiler : public ICStubCompiler { - RootedShape shape_; - - protected: - bool generateStubCode(MacroAssembler &masm); - - public: - Compiler(JSContext *cx, Shape *shape) - : ICStubCompiler(cx, ICStub::In_Dense), - shape_(cx, shape) - {} - - ICStub *getStub(ICStubSpace *space) { - return ICIn_Dense::New(space, getStubCode(), shape_); - } - }; -}; - // GetName // JSOP_NAME // JSOP_GETGNAME