author | Jan de Mooij <jdemooij@mozilla.com> |
Wed, 26 Aug 2020 20:00:45 +0000 | |
changeset 546400 | fc681a8e552e530a2d8af0870ca3d91550e6a1e2 |
parent 546399 | 44ee384376ce8b20ef64db6e4fef50af983c2088 |
child 546401 | d01415c7707edaaf119e5e4c76f6b4e3c6a30e13 |
push id | 37735 |
push user | abutkovits@mozilla.com |
push date | Thu, 27 Aug 2020 21:29:40 +0000 |
treeherder | mozilla-central@109f3a4de567 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | iain |
bugs | 1661211 |
milestone | 82.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
|
--- a/js/src/jit/BaselineCacheIRCompiler.cpp +++ b/js/src/jit/BaselineCacheIRCompiler.cpp @@ -491,18 +491,21 @@ bool BaselineCacheIRCompiler::emitGuardH masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, ObjectHasGetterSetterPure)); masm.mov(ReturnReg, scratch1); masm.PopRegsInMask(volatileRegs); masm.branchIfFalseBool(scratch1, failure->label()); return true; } -bool BaselineCacheIRCompiler::emitCallScriptedGetterResultShared( - TypedOrValueRegister receiver, uint32_t getterOffset, bool sameRealm) { +bool BaselineCacheIRCompiler::emitCallScriptedGetterResult( + ValOperandId receiverId, uint32_t getterOffset, bool sameRealm) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + + ValueOperand receiver = allocator.useValueRegister(masm, receiverId); Address getterAddr(stubAddress(getterOffset)); AutoScratchRegister code(allocator, masm); AutoScratchRegister callee(allocator, masm); AutoScratchRegister scratch(allocator, masm); // First, retrieve jitCodeRaw for getter. masm.loadPtr(getterAddr, callee); @@ -549,82 +552,44 @@ bool BaselineCacheIRCompiler::emitCallSc if (!sameRealm) { masm.switchToBaselineFrameRealm(R1.scratchReg()); } return true; } -bool BaselineCacheIRCompiler::emitCallScriptedGetterResult( - ObjOperandId objId, uint32_t getterOffset, bool sameRealm) { +bool BaselineCacheIRCompiler::emitCallNativeGetterResult( + ValOperandId receiverId, uint32_t getterOffset) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); - Register obj = allocator.useRegister(masm, objId); - - return emitCallScriptedGetterResultShared( - TypedOrValueRegister(MIRType::Object, AnyRegister(obj)), getterOffset, - sameRealm); -} - -bool BaselineCacheIRCompiler::emitCallScriptedGetterByValueResult( - ValOperandId valId, uint32_t getterOffset, bool sameRealm) { - JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); - ValueOperand val = allocator.useValueRegister(masm, valId); - - return emitCallScriptedGetterResultShared(val, getterOffset, sameRealm); -} - -template <typename T, typename CallVM> -bool BaselineCacheIRCompiler::emitCallNativeGetterResultShared( - T receiver, uint32_t getterOffset, const CallVM& emitCallVM) { + + ValueOperand receiver = allocator.useValueRegister(masm, receiverId); Address getterAddr(stubAddress(getterOffset)); AutoScratchRegister scratch(allocator, masm); allocator.discardStack(masm); AutoStubFrame stubFrame(*this); stubFrame.enter(masm, scratch); // Load the callee in the scratch register. masm.loadPtr(getterAddr, scratch); masm.Push(receiver); masm.Push(scratch); - emitCallVM(); + using Fn = + bool (*)(JSContext*, HandleFunction, HandleValue, MutableHandleValue); + callVM<Fn, CallNativeGetter>(masm); stubFrame.leave(masm); return true; } -bool BaselineCacheIRCompiler::emitCallNativeGetterResult( - ObjOperandId objId, uint32_t getterOffset) { - JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); - Register obj = allocator.useRegister(masm, objId); - - return emitCallNativeGetterResultShared(obj, getterOffset, [this]() { - using Fn = - bool (*)(JSContext*, HandleFunction, HandleObject, MutableHandleValue); - callVM<Fn, CallNativeGetter>(masm); - }); -} - -bool BaselineCacheIRCompiler::emitCallNativeGetterByValueResult( - ValOperandId valId, uint32_t getterOffset) { - JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); - ValueOperand val = allocator.useValueRegister(masm, valId); - - return emitCallNativeGetterResultShared(val, getterOffset, [this]() { - using Fn = - bool (*)(JSContext*, HandleFunction, HandleValue, MutableHandleValue); - callVM<Fn, CallNativeGetterByValue>(masm); - }); -} - bool BaselineCacheIRCompiler::emitProxyGetResult(ObjOperandId objId, uint32_t idOffset) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); Register obj = allocator.useRegister(masm, objId); Address idAddr(stubAddress(idOffset)); AutoScratchRegister scratch(allocator, masm);
--- a/js/src/jit/BaselineCacheIRCompiler.h +++ b/js/src/jit/BaselineCacheIRCompiler.h @@ -69,24 +69,16 @@ class MOZ_RAII BaselineCacheIRCompiler : void updateReturnValue(); enum class NativeCallType { Native, ClassHook }; bool emitCallNativeShared(NativeCallType callType, ObjOperandId calleeId, Int32OperandId argcId, CallFlags flags, mozilla::Maybe<bool> ignoresReturnValue, mozilla::Maybe<uint32_t> targetOffset); - MOZ_MUST_USE bool emitCallScriptedGetterResultShared( - TypedOrValueRegister receiver, uint32_t getterOffset, bool sameRealm); - - template <typename T, typename CallVM> - MOZ_MUST_USE bool emitCallNativeGetterResultShared(T receiver, - uint32_t getterOffset, - const CallVM& emitCallVM); - enum class StringCode { CodeUnit, CodePoint }; bool emitStringFromCodeResult(Int32OperandId codeId, StringCode stringCode); public: friend class AutoStubFrame; BaselineCacheIRCompiler(JSContext* cx, const CacheIRWriter& writer, uint32_t stubDataOffset,
--- a/js/src/jit/CacheIR.cpp +++ b/js/src/jit/CacheIR.cpp @@ -314,23 +314,16 @@ static bool ValueToNameOrSymbolId(JSCont } AttachDecision GetPropIRGenerator::tryAttachStub() { // Idempotent ICs should call tryAttachIdempotentStub instead. MOZ_ASSERT(!idempotent()); AutoAssertNoPendingException aanpe(cx_); - // Non-object receivers are a degenerate case, so don't try to attach - // stubs. The stubs we do emit will still perform runtime checks and - // fallback as needed. - if (isSuper() && !receiver_.isObject()) { - return AttachDecision::NoAction; - } - ValOperandId valId(writer.setInputOperandId(0)); if (cacheKind_ != CacheKind::GetProp) { MOZ_ASSERT_IF(cacheKind_ == CacheKind::GetPropSuper, getSuperReceiverValueId().id() == 1); MOZ_ASSERT_IF(cacheKind_ != CacheKind::GetPropSuper, getElemKeyValueId().id() == 1); writer.setInputOperandId(1); } @@ -341,30 +334,35 @@ AttachDecision GetPropIRGenerator::tryAt RootedId id(cx_); bool nameOrSymbol; if (!ValueToNameOrSymbolId(cx_, idVal_, &id, &nameOrSymbol)) { cx_->clearPendingException(); return AttachDecision::NoAction; } + // |super.prop| getter calls use a |this| value that differs from lookup + // object. + ValOperandId receiverId = isSuper() ? getSuperReceiverValueId() : valId; + if (val_.isObject()) { RootedObject obj(cx_, &val_.toObject()); ObjOperandId objId = writer.guardToObject(valId); if (nameOrSymbol) { TRY_ATTACH(tryAttachObjectLength(obj, objId, id)); TRY_ATTACH(tryAttachTypedArrayLength(obj, objId, id)); - TRY_ATTACH(tryAttachNative(obj, objId, id)); + TRY_ATTACH(tryAttachNative(obj, objId, id, receiverId)); TRY_ATTACH(tryAttachTypedObject(obj, objId, id)); TRY_ATTACH(tryAttachModuleNamespace(obj, objId, id)); TRY_ATTACH(tryAttachWindowProxy(obj, objId, id)); TRY_ATTACH(tryAttachCrossCompartmentWrapper(obj, objId, id)); - TRY_ATTACH(tryAttachXrayCrossCompartmentWrapper(obj, objId, id)); + TRY_ATTACH( + tryAttachXrayCrossCompartmentWrapper(obj, objId, id, receiverId)); TRY_ATTACH(tryAttachFunction(obj, objId, id)); - TRY_ATTACH(tryAttachProxy(obj, objId, id)); + TRY_ATTACH(tryAttachProxy(obj, objId, id, receiverId)); trackAttached(IRGenerator::NotAttached); return AttachDecision::NoAction; } MOZ_ASSERT(cacheKind_ == CacheKind::GetElem || cacheKind_ == CacheKind::GetElemSuper); @@ -420,24 +418,25 @@ AttachDecision GetPropIRGenerator::tryAt MOZ_ASSERT(idempotent()); RootedObject obj(cx_, &val_.toObject()); RootedId id(cx_, NameToId(idVal_.toString()->asAtom().asPropertyName())); ValOperandId valId(writer.setInputOperandId(0)); ObjOperandId objId = writer.guardToObject(valId); - TRY_ATTACH(tryAttachNative(obj, objId, id)); + ValOperandId receiverId = valId; + TRY_ATTACH(tryAttachNative(obj, objId, id, receiverId)); // Object lengths are supported only if int32 results are allowed. TRY_ATTACH(tryAttachObjectLength(obj, objId, id)); // Also support native data properties on DOMProxy prototypes. if (GetProxyStubType(cx_, obj, id) == ProxyStubType::DOMUnshadowed) { - return tryAttachDOMProxyUnshadowed(obj, objId, id); + return tryAttachDOMProxyUnshadowed(obj, objId, id, receiverId); } return AttachDecision::NoAction; } static bool IsCacheableProtoChain(JSObject* obj, JSObject* holder) { while (obj != holder) { /* @@ -997,17 +996,17 @@ static void EmitReadSlotReturn(CacheIRWr // avoided. writer.returnFromIC(); } } static void EmitCallGetterResultNoGuards(JSContext* cx, CacheIRWriter& writer, JSObject* obj, JSObject* holder, Shape* shape, - ObjOperandId receiverId) { + ValOperandId receiverId) { switch (IsCacheableGetPropCall(obj, holder, shape)) { case CanAttachNativeGetter: { JSFunction* target = &shape->getterValue().toObject().as<JSFunction>(); MOZ_ASSERT(target->isNativeWithoutJitEntry()); writer.callNativeGetterResult(receiverId, target); writer.typeMonitorResult(); break; } @@ -1045,59 +1044,22 @@ static void EmitCallGetterResultGuards(C } } else { writer.guardHasGetterSetter(objId, shape); } } static void EmitCallGetterResult(JSContext* cx, CacheIRWriter& writer, JSObject* obj, JSObject* holder, Shape* shape, - ObjOperandId objId, ObjOperandId receiverId, + ObjOperandId objId, ValOperandId receiverId, ICState::Mode mode) { EmitCallGetterResultGuards(writer, obj, holder, shape, objId, mode); EmitCallGetterResultNoGuards(cx, writer, obj, holder, shape, receiverId); } -static void EmitCallGetterResult(JSContext* cx, CacheIRWriter& writer, - JSObject* obj, JSObject* holder, Shape* shape, - ObjOperandId objId, ICState::Mode mode) { - EmitCallGetterResult(cx, writer, obj, holder, shape, objId, objId, mode); -} - -static void EmitCallGetterByValueResult(JSContext* cx, CacheIRWriter& writer, - JSObject* obj, JSObject* holder, - Shape* shape, ObjOperandId objId, - ValOperandId receiverId, - ICState::Mode mode) { - EmitCallGetterResultGuards(writer, obj, holder, shape, objId, mode); - - switch (IsCacheableGetPropCall(obj, holder, shape)) { - case CanAttachNativeGetter: { - JSFunction* target = &shape->getterValue().toObject().as<JSFunction>(); - MOZ_ASSERT(target->isNativeWithoutJitEntry()); - writer.callNativeGetterByValueResult(receiverId, target); - writer.typeMonitorResult(); - break; - } - case CanAttachScriptedGetter: { - JSFunction* target = &shape->getterValue().toObject().as<JSFunction>(); - MOZ_ASSERT(target->hasJitEntry()); - bool sameRealm = cx->realm() == target->realm(); - writer.callScriptedGetterByValueResult(receiverId, target, sameRealm); - writer.typeMonitorResult(); - break; - } - default: - // CanAttachNativeGetProp guarantees that the getter is either a native or - // a scripted function. - MOZ_ASSERT_UNREACHABLE("Can't attach getter"); - break; - } -} - void GetPropIRGenerator::attachMegamorphicNativeSlot(ObjOperandId objId, jsid id, bool handleMissing) { MOZ_ASSERT(mode_ == ICState::Mode::Megamorphic); // The stub handles the missing-properties case only if we're seeing one // now, to make sure Ion ICs correctly monitor the undefined type. Without // TI we don't use type monitoring so always allow |undefined|. @@ -1118,17 +1080,18 @@ void GetPropIRGenerator::attachMegamorph writer.typeMonitorResult(); trackAttached(handleMissing ? "MegamorphicMissingNativeSlot" : "MegamorphicNativeSlot"); } AttachDecision GetPropIRGenerator::tryAttachNative(HandleObject obj, ObjOperandId objId, - HandleId id) { + HandleId id, + ValOperandId receiverId) { RootedShape shape(cx_); RootedNativeObject holder(cx_); NativeGetPropCacheability type = CanAttachNativeGetProp(cx_, obj, id, &holder, &shape, pc_, resultFlags_); switch (type) { case CanAttachNone: return AttachDecision::NoAction; @@ -1150,21 +1113,17 @@ AttachDecision GetPropIRGenerator::tryAt } EmitReadSlotResult(writer, obj, holder, shape, objId); EmitReadSlotReturn(writer, obj, holder, shape); trackAttached("NativeSlot"); return AttachDecision::Attach; case CanAttachScriptedGetter: case CanAttachNativeGetter: { - // |super.prop| accesses use a |this| value that differs from lookup - // object MOZ_ASSERT(!idempotent()); - ObjOperandId receiverId = - isSuper() ? writer.guardToObject(getSuperReceiverValueId()) : objId; maybeEmitIdGuard(id); EmitCallGetterResult(cx_, writer, obj, holder, shape, objId, receiverId, mode_); trackAttached("NativeGetter"); return AttachDecision::Attach; } } @@ -1263,18 +1222,19 @@ AttachDecision GetPropIRGenerator::tryAt return AttachDecision::NoAction; } // Guard the incoming object is a WindowProxy and inline a getter call // based on the Window object. maybeEmitIdGuard(id); ObjOperandId windowObjId = GuardAndLoadWindowProxyWindow(writer, objId, windowObj); + ValOperandId receiverId = writer.boxObject(windowObjId); EmitCallGetterResult(cx_, writer, windowObj, holder, shape, windowObjId, - mode_); + receiverId, mode_); trackAttached("WindowProxyGetter"); return AttachDecision::Attach; } case CanAttachScriptedGetter: MOZ_ASSERT_UNREACHABLE("Not possible for window proxies"); } @@ -1385,17 +1345,18 @@ static bool GetXrayExpandoShapeWrapper(J return wrapper != nullptr; } } wrapper.set(nullptr); return true; } AttachDecision GetPropIRGenerator::tryAttachXrayCrossCompartmentWrapper( - HandleObject obj, ObjOperandId objId, HandleId id) { + HandleObject obj, ObjOperandId objId, HandleId id, + ValOperandId receiverId) { if (!IsProxy(obj)) { return AttachDecision::NoAction; } XrayJitInfo* info = GetXrayJitInfo(); if (!info || !info->isCrossCompartmentXray(GetProxyHandler(obj))) { return AttachDecision::NoAction; } @@ -1483,17 +1444,17 @@ AttachDecision GetPropIRGenerator::tryAt ObjOperandId protoId = writer.loadObject(proto); if (JSObject* protoShapeWrapper = prototypeExpandoShapeWrappers[i]) { writer.guardXrayExpandoShapeAndDefaultProto(protoId, protoShapeWrapper); } else { writer.guardXrayNoExpando(protoId); } } - writer.callNativeGetterResult(objId, &getter->as<JSFunction>()); + writer.callNativeGetterResult(receiverId, &getter->as<JSFunction>()); writer.typeMonitorResult(); trackAttached("XrayGetter"); return AttachDecision::Attach; } AttachDecision GetPropIRGenerator::tryAttachGenericProxy( HandleObject obj, ObjOperandId objId, HandleId id, bool handleDOMProxies) { @@ -1541,19 +1502,19 @@ ObjOperandId IRGenerator::guardDOMProxyE } // Guard the expando is an object and shape guard. ObjOperandId expandoObjId = writer.guardToObject(expandoValId); TestMatchingHolder(writer, expandoObj, expandoObjId); return expandoObjId; } -AttachDecision GetPropIRGenerator::tryAttachDOMProxyExpando(HandleObject obj, - ObjOperandId objId, - HandleId id) { +AttachDecision GetPropIRGenerator::tryAttachDOMProxyExpando( + HandleObject obj, ObjOperandId objId, HandleId id, + ValOperandId receiverId) { MOZ_ASSERT(IsCacheableDOMProxy(obj)); RootedValue expandoVal(cx_, GetProxyPrivate(obj)); RootedObject expandoObj(cx_); if (expandoVal.isObject()) { expandoObj = &expandoVal.toObject(); } else { MOZ_ASSERT(!expandoVal.isUndefined(), @@ -1588,17 +1549,17 @@ AttachDecision GetPropIRGenerator::tryAt propShape); writer.typeMonitorResult(); } else { // Call the getter. Note that we pass objId, the DOM proxy, as |this| // and not the expando object. MOZ_ASSERT(canCache == CanAttachNativeGetter || canCache == CanAttachScriptedGetter); EmitCallGetterResultNoGuards(cx_, writer, expandoObj, expandoObj, propShape, - objId); + receiverId); } trackAttached("DOMProxyExpando"); return AttachDecision::Attach; } AttachDecision GetPropIRGenerator::tryAttachDOMProxyShadowed(HandleObject obj, ObjOperandId objId, @@ -1647,17 +1608,18 @@ static void CheckDOMProxyExpandoDoesNotS writer.guardDOMExpandoMissingOrGuardShape(expandoId, expandoObj.lastProperty()); } else { MOZ_CRASH("Invalid expando value"); } } AttachDecision GetPropIRGenerator::tryAttachDOMProxyUnshadowed( - HandleObject obj, ObjOperandId objId, HandleId id) { + HandleObject obj, ObjOperandId objId, HandleId id, + ValOperandId receiverId) { MOZ_ASSERT(IsCacheableDOMProxy(obj)); RootedObject checkObj(cx_, obj->staticPrototype()); if (!checkObj) { return AttachDecision::NoAction; } RootedNativeObject holder(cx_); @@ -1689,33 +1651,35 @@ AttachDecision GetPropIRGenerator::tryAt } else { // EmitCallGetterResultNoGuards expects |obj| to be the object the // property is on to do some checks. Since we actually looked at // checkObj, and no extra guards will be generated, we can just // pass that instead. MOZ_ASSERT(canCache == CanAttachNativeGetter || canCache == CanAttachScriptedGetter); MOZ_ASSERT(!isSuper()); - EmitCallGetterResultNoGuards(cx_, writer, checkObj, holder, shape, objId); + EmitCallGetterResultNoGuards(cx_, writer, checkObj, holder, shape, + receiverId); } } else { // Property was not found on the prototype chain. Deoptimize down to // proxy get call. MOZ_ASSERT(!isSuper()); writer.proxyGetResult(objId, id); writer.typeMonitorResult(); } trackAttached("DOMProxyUnshadowed"); return AttachDecision::Attach; } AttachDecision GetPropIRGenerator::tryAttachProxy(HandleObject obj, ObjOperandId objId, - HandleId id) { + HandleId id, + ValOperandId receiverId) { ProxyStubType type = GetProxyStubType(cx_, obj, id); if (type == ProxyStubType::None) { return AttachDecision::NoAction; } // The proxy stubs don't currently support |super| access. if (isSuper()) { return AttachDecision::NoAction; @@ -1724,22 +1688,22 @@ AttachDecision GetPropIRGenerator::tryAt if (mode_ == ICState::Mode::Megamorphic) { return tryAttachGenericProxy(obj, objId, id, /* handleDOMProxies = */ true); } switch (type) { case ProxyStubType::None: break; case ProxyStubType::DOMExpando: - TRY_ATTACH(tryAttachDOMProxyExpando(obj, objId, id)); + TRY_ATTACH(tryAttachDOMProxyExpando(obj, objId, id, receiverId)); [[fallthrough]]; // Fall through to the generic shadowed case. case ProxyStubType::DOMShadowed: return tryAttachDOMProxyShadowed(obj, objId, id); case ProxyStubType::DOMUnshadowed: - TRY_ATTACH(tryAttachDOMProxyUnshadowed(obj, objId, id)); + TRY_ATTACH(tryAttachDOMProxyUnshadowed(obj, objId, id, receiverId)); return tryAttachGenericProxy(obj, objId, id, /* handleDOMProxies = */ true); case ProxyStubType::Generic: return tryAttachGenericProxy(obj, objId, id, /* handleDOMProxies = */ false); } MOZ_CRASH("Unexpected ProxyStubType"); @@ -2055,18 +2019,18 @@ AttachDecision GetPropIRGenerator::tryAt if (val_.isNumber()) { writer.guardIsNumber(valId); } else { writer.guardNonDoubleType(valId, val_.type()); } maybeEmitIdGuard(id); ObjOperandId protoId = writer.loadObject(proto); - EmitCallGetterByValueResult(cx_, writer, proto, holder, shape, protoId, - valId, mode_); + EmitCallGetterResult(cx_, writer, proto, holder, shape, protoId, valId, + mode_); trackAttached("PrimitiveGetter"); return AttachDecision::Attach; } } MOZ_CRASH("Bad NativeGetPropCacheability"); } @@ -2745,18 +2709,19 @@ AttachDecision GetNameIRGenerator::tryAt writer.guardShape(globalId, globalLexical->global().lastProperty()); if (holder != &globalLexical->global()) { // Shape guard holder. ObjOperandId holderId = writer.loadObject(holder); writer.guardShape(holderId, holder->lastProperty()); } + ValOperandId receiverId = writer.boxObject(globalId); EmitCallGetterResultNoGuards(cx_, writer, &globalLexical->global(), holder, - shape, globalId); + shape, receiverId); trackAttached("GlobalNameGetter"); return AttachDecision::Attach; } static bool NeedEnvironmentShapeGuard(JSObject* envObj) { if (!envObj->is<CallObject>()) { return true;
--- a/js/src/jit/CacheIR.h +++ b/js/src/jit/CacheIR.h @@ -761,16 +761,20 @@ class MOZ_RAII CacheIRWriter : public JS return Int32OperandId(input.id()); } NumberOperandId guardIsNumber(ValOperandId input) { guardIsNumber_(input); return NumberOperandId(input.id()); } + ValOperandId boxObject(ObjOperandId input) { + return ValOperandId(input.id()); + } + void guardShapeForClass(ObjOperandId obj, Shape* shape) { // Guard shape to ensure that object class is unchanged. This is true // for all shapes. guardShape(obj, shape); } void guardShapeForOwnProperties(ObjOperandId obj, Shape* shape) { // Guard shape to detect changes to (non-dense) own properties. This @@ -1174,17 +1178,17 @@ class MOZ_RAII GetPropIRGenerator : publ HandleValue idVal_; HandleValue receiver_; GetPropertyResultFlags resultFlags_; enum class PreliminaryObjectAction { None, Unlink, NotePreliminary }; PreliminaryObjectAction preliminaryObjectAction_; AttachDecision tryAttachNative(HandleObject obj, ObjOperandId objId, - HandleId id); + HandleId id, ValOperandId receiverId); AttachDecision tryAttachUnboxed(HandleObject obj, ObjOperandId objId, HandleId id); AttachDecision tryAttachUnboxedExpando(HandleObject obj, ObjOperandId objId, HandleId id); AttachDecision tryAttachTypedObject(HandleObject obj, ObjOperandId objId, HandleId id); AttachDecision tryAttachObjectLength(HandleObject obj, ObjOperandId objId, HandleId id); @@ -1194,30 +1198,32 @@ class MOZ_RAII GetPropIRGenerator : publ HandleId id); AttachDecision tryAttachWindowProxy(HandleObject obj, ObjOperandId objId, HandleId id); AttachDecision tryAttachCrossCompartmentWrapper(HandleObject obj, ObjOperandId objId, HandleId id); AttachDecision tryAttachXrayCrossCompartmentWrapper(HandleObject obj, ObjOperandId objId, - HandleId id); + HandleId id, + ValOperandId receiverId); AttachDecision tryAttachFunction(HandleObject obj, ObjOperandId objId, HandleId id); AttachDecision tryAttachGenericProxy(HandleObject obj, ObjOperandId objId, HandleId id, bool handleDOMProxies); AttachDecision tryAttachDOMProxyExpando(HandleObject obj, ObjOperandId objId, - HandleId id); + HandleId id, ValOperandId receiverId); AttachDecision tryAttachDOMProxyShadowed(HandleObject obj, ObjOperandId objId, HandleId id); AttachDecision tryAttachDOMProxyUnshadowed(HandleObject obj, - ObjOperandId objId, HandleId id); + ObjOperandId objId, HandleId id, + ValOperandId receiverId); AttachDecision tryAttachProxy(HandleObject obj, ObjOperandId objId, - HandleId id); + HandleId id, ValOperandId receiverId); AttachDecision tryAttachPrimitive(ValOperandId valId, HandleId id); AttachDecision tryAttachStringChar(ValOperandId valId, ValOperandId indexId); AttachDecision tryAttachStringLength(ValOperandId valId, HandleId id); AttachDecision tryAttachMagicArgumentsName(ValOperandId valId, HandleId id); AttachDecision tryAttachMagicArgument(ValOperandId valId, ValOperandId indexId);
--- a/js/src/jit/CacheIROps.yaml +++ b/js/src/jit/CacheIROps.yaml @@ -1813,43 +1813,26 @@ args: val: BigIntId - name: CallScriptedGetterResult shared: false transpile: false cost_estimate: 5 args: - obj: ObjId - getter: ObjectField - sameRealm: BoolImm - -- name: CallScriptedGetterByValueResult - shared: false - transpile: false - cost_estimate: 5 - args: - val: ValId + receiver: ValId getter: ObjectField sameRealm: BoolImm - name: CallNativeGetterResult shared: false transpile: false cost_estimate: 5 args: - obj: ObjId - getter: ObjectField - -- name: CallNativeGetterByValueResult - shared: false - transpile: false - cost_estimate: 5 - args: - val: ValId + receiver: ValId getter: ObjectField - name: ProxyGetResult shared: false transpile: true cost_estimate: 5 args: obj: ObjId
--- a/js/src/jit/IonCacheIRCompiler.cpp +++ b/js/src/jit/IonCacheIRCompiler.cpp @@ -897,19 +897,25 @@ bool IonCacheIRCompiler::emitGuardHasGet masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, ObjectHasGetterSetterPure)); masm.mov(ReturnReg, scratch1); masm.PopRegsInMask(volatileRegs); masm.branchIfFalseBool(scratch1, failure->label()); return true; } -bool IonCacheIRCompiler::emitCallScriptedGetterResultShared( - TypedOrValueRegister receiver, uint32_t getterOffset, bool sameRealm, - TypedOrValueRegister output) { +bool IonCacheIRCompiler::emitCallScriptedGetterResult(ValOperandId receiverId, + uint32_t getterOffset, + bool sameRealm) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + AutoSaveLiveRegisters save(*this); + AutoOutputRegister output(*this); + + ValueOperand receiver = allocator.useValueRegister(masm, receiverId); + JSFunction* target = &objectStubField(getterOffset)->as<JSFunction>(); AutoScratchRegister scratch(allocator, masm); MOZ_ASSERT(sameRealm == (cx_->realm() == target->realm())); allocator.discardStack(masm); uint32_t framePushedBefore = masm.framePushed(); @@ -962,45 +968,24 @@ bool IonCacheIRCompiler::emitCallScripte masm.switchToRealm(cx_->realm(), ReturnReg); } masm.storeCallResultValue(output); masm.freeStack(masm.framePushed() - framePushedBefore); return true; } -bool IonCacheIRCompiler::emitCallScriptedGetterResult(ObjOperandId objId, - uint32_t getterOffset, - bool sameRealm) { +bool IonCacheIRCompiler::emitCallNativeGetterResult(ValOperandId receiverId, + uint32_t getterOffset) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); AutoSaveLiveRegisters save(*this); AutoOutputRegister output(*this); - Register obj = allocator.useRegister(masm, objId); - - return emitCallScriptedGetterResultShared( - TypedOrValueRegister(MIRType::Object, AnyRegister(obj)), getterOffset, - sameRealm, output); -} - -bool IonCacheIRCompiler::emitCallScriptedGetterByValueResult( - ValOperandId valId, uint32_t getterOffset, bool sameRealm) { - JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); - AutoSaveLiveRegisters save(*this); - AutoOutputRegister output(*this); - - ValueOperand val = allocator.useValueRegister(masm, valId); - - return emitCallScriptedGetterResultShared(val, getterOffset, sameRealm, - output); -} - -bool IonCacheIRCompiler::emitCallNativeGetterResultShared( - TypedOrValueRegister receiver, uint32_t getterOffset, - const AutoOutputRegister& output, AutoSaveLiveRegisters& save) { + ValueOperand receiver = allocator.useValueRegister(masm, receiverId); + JSFunction* target = &objectStubField(getterOffset)->as<JSFunction>(); MOZ_ASSERT(target->isNative()); AutoScratchRegisterMaybeOutput argJSContext(allocator, masm, output); AutoScratchRegister argUintN(allocator, masm); AutoScratchRegister argVp(allocator, masm); AutoScratchRegister scratch(allocator, masm); @@ -1059,40 +1044,16 @@ bool IonCacheIRCompiler::emitCallNativeG if (JitOptions.spectreJitToCxxCalls) { masm.speculationBarrier(); } masm.adjustStack(IonOOLNativeExitFrameLayout::Size(0)); return true; } -bool IonCacheIRCompiler::emitCallNativeGetterResult(ObjOperandId objId, - uint32_t getterOffset) { - JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); - AutoSaveLiveRegisters save(*this); - AutoOutputRegister output(*this); - - Register obj = allocator.useRegister(masm, objId); - - return emitCallNativeGetterResultShared( - TypedOrValueRegister(MIRType::Object, AnyRegister(obj)), getterOffset, - output, save); -} - -bool IonCacheIRCompiler::emitCallNativeGetterByValueResult( - ValOperandId valId, uint32_t getterOffset) { - JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); - AutoSaveLiveRegisters save(*this); - AutoOutputRegister output(*this); - - ValueOperand val = allocator.useValueRegister(masm, valId); - - return emitCallNativeGetterResultShared(val, getterOffset, output, save); -} - bool IonCacheIRCompiler::emitProxyGetResult(ObjOperandId objId, uint32_t idOffset) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); AutoSaveLiveRegisters save(*this); AutoOutputRegister output(*this); Register obj = allocator.useRegister(masm, objId); jsid id = idStubField(idOffset);
--- a/js/src/jit/IonCacheIRCompiler.h +++ b/js/src/jit/IonCacheIRCompiler.h @@ -64,22 +64,16 @@ class MOZ_RAII IonCacheIRCompiler : publ template <typename Fn, Fn fn> void callVM(MacroAssembler& masm); MOZ_MUST_USE bool emitAddAndStoreSlotShared( CacheOp op, ObjOperandId objId, uint32_t offsetOffset, ValOperandId rhsId, bool changeGroup, uint32_t newGroupOffset, uint32_t newShapeOffset, mozilla::Maybe<uint32_t> numNewSlotsOffset); - MOZ_MUST_USE bool emitCallScriptedGetterResultShared( - TypedOrValueRegister receiver, uint32_t getterOffset, bool sameRealm, - TypedOrValueRegister output); - MOZ_MUST_USE bool emitCallNativeGetterResultShared( - TypedOrValueRegister receiver, uint32_t getterOffset, - const AutoOutputRegister& output, AutoSaveLiveRegisters& save); bool needsPostBarrier() const; void pushStubCodePointer(); CACHE_IR_COMPILER_UNSHARED_GENERATED };
--- a/js/src/jit/VMFunctionList-inl.h +++ b/js/src/jit/VMFunctionList-inl.h @@ -71,17 +71,16 @@ namespace jit { _(BigIntStringNotEqual, \ js::jit::BigIntStringEqual<js::jit::EqualityKind::NotEqual>) \ _(BigIntSub, JS::BigInt::sub) \ _(BindVarOperation, js::BindVarOperation) \ _(BoxBoxableValue, js::wasm::BoxBoxableValue) \ _(BoxNonStrictThis, js::BoxNonStrictThis) \ _(BuiltinObjectOperation, js::BuiltinObjectOperation) \ _(CallNativeGetter, js::jit::CallNativeGetter) \ - _(CallNativeGetterByValue, js::jit::CallNativeGetterByValue) \ _(CallNativeSetter, js::jit::CallNativeSetter) \ _(CharCodeAt, js::jit::CharCodeAt) \ _(CheckClassHeritageOperation, js::CheckClassHeritageOperation) \ _(CheckGlobalOrEvalDeclarationConflicts, \ js::CheckGlobalOrEvalDeclarationConflicts) \ _(CheckOverRecursed, js::jit::CheckOverRecursed) \ _(CheckOverRecursedBaseline, js::jit::CheckOverRecursedBaseline) \ _(CheckPrivateFieldOperation, js::CheckPrivateFieldOperation) \
--- a/js/src/jit/VMFunctions.cpp +++ b/js/src/jit/VMFunctions.cpp @@ -1474,37 +1474,18 @@ bool ThrowBadDerivedReturnOrUninitialize return ThrowBadDerivedReturn(cx, v); } bool BaselineGetFunctionThis(JSContext* cx, BaselineFrame* frame, MutableHandleValue res) { return GetFunctionThis(cx, frame, res); } -bool CallNativeGetter(JSContext* cx, HandleFunction callee, HandleObject obj, - MutableHandleValue result) { - AutoRealm ar(cx, callee); - - MOZ_ASSERT(callee->isNative()); - JSNative natfun = callee->native(); - - JS::RootedValueArray<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; -} - -bool CallNativeGetterByValue(JSContext* cx, HandleFunction callee, - HandleValue receiver, MutableHandleValue result) { +bool CallNativeGetter(JSContext* cx, HandleFunction callee, + HandleValue receiver, MutableHandleValue result) { AutoRealm ar(cx, callee); MOZ_ASSERT(callee->isNative()); JSNative natfun = callee->native(); JS::RootedValueArray<2> vp(cx); vp[0].setObject(*callee.get()); vp[1].set(receiver);
--- a/js/src/jit/VMFunctions.h +++ b/js/src/jit/VMFunctions.h @@ -1070,21 +1070,18 @@ MOZ_MUST_USE bool ThrowBadDerivedReturn( MOZ_MUST_USE bool ThrowBadDerivedReturnOrUninitializedThis(JSContext* cx, HandleValue v); MOZ_MUST_USE bool BaselineGetFunctionThis(JSContext* cx, BaselineFrame* frame, MutableHandleValue res); MOZ_MUST_USE bool CallNativeGetter(JSContext* cx, HandleFunction callee, - HandleObject obj, MutableHandleValue result); - -MOZ_MUST_USE bool CallNativeGetterByValue(JSContext* cx, HandleFunction callee, - HandleValue receiver, - MutableHandleValue result); + HandleValue receiver, + MutableHandleValue result); MOZ_MUST_USE bool CallNativeSetter(JSContext* cx, HandleFunction callee, HandleObject obj, HandleValue rhs); MOZ_MUST_USE bool EqualStringsHelperPure(JSString* str1, JSString* str2); void HandleCodeCoverageAtPC(BaselineFrame* frame, jsbytecode* pc); void HandleCodeCoverageAtPrologue(BaselineFrame* frame);