From c3b56668cbd942444783caaaf32e1f019126ec97 Mon Sep 17 00:00:00 2001 From: Caroline Cullen Date: Thu, 10 Jun 2021 21:00:31 +0000 Subject: [PATCH] Bug 1699271 - Part 11: Add autogeneration for MIR ops that take arguments. r=iain Differential Revision: https://phabricator.services.mozilla.com/D116775 --- js/src/jit/GenerateMIRFiles.py | 45 +- js/src/jit/Lowering.cpp | 8 +- js/src/jit/MIR.cpp | 210 +++++ js/src/jit/MIR.h | 1148 -------------------------- js/src/jit/MIROps.yaml | 453 ++++++++-- js/src/jit/ScalarReplacement.cpp | 4 +- js/src/jit/WarpBuilder.cpp | 4 +- js/src/jit/WarpCacheIRTranspiler.cpp | 14 +- 8 files changed, 671 insertions(+), 1215 deletions(-) diff --git a/js/src/jit/GenerateMIRFiles.py b/js/src/jit/GenerateMIRFiles.py index d7141127b278..6e7d8da59aea 100644 --- a/js/src/jit/GenerateMIRFiles.py +++ b/js/src/jit/GenerateMIRFiles.py @@ -98,9 +98,25 @@ mir_base_class = [ ] +gc_pointer_types = [ + "JSObject*", + "NativeObject*", + "JSFunction*", + "BaseScript*", + "PropertyName*", + "Shape*", + "GetterSetter*", + "JSAtom*", + "ClassBodyScope*", + "NamedLambdaObject*", + "RegExpObject*", +] + + def gen_mir_class( name, operands, + arguments, no_type_policy, result, guard, @@ -169,12 +185,28 @@ def gen_mir_class( assert type_policy type_policy = ", " + type_policy code = "class {} : public {}{} {{\\\n".format(class_name, base_class, type_policy) + + # Arguments to class constructor that require accessors. + mir_args = [] + if arguments: + for arg_name in arguments: + arg_type_sig = arguments[arg_name] + mir_args.append(arg_type_sig + " " + arg_name) + if arg_type_sig in gc_pointer_types: + code += " CompilerGCPointer<" + arg_type_sig + ">" + else: + code += " " + arg_type_sig + code += " " + arg_name + "_;\\\n" + code += " explicit {}({}) : {}(classOpcode{})".format( class_name, - ", ".join(mir_operands), + ", ".join(mir_operands + mir_args), base_class, "".join(mir_base_class_operands), ) + if arguments: + for arg_name in arguments: + code += ", " + arg_name + "_(" + arg_name + ")" code += " {\\\n" if guard: code += " setGuard();\\\n" @@ -182,7 +214,12 @@ def gen_mir_class( code += " setMovable();\\\n" if result: code += " setResultType(MIRType::{});\\\n".format(result) - code += " }}\\\n public:\\\n INSTRUCTION_HEADER({})\\\n".format(name) + code += " }\\\n public:\\\n" + if arguments: + for arg_name in arguments: + code += " " + arguments[arg_name] + " " + arg_name + "() const { " + code += "return " + arg_name + "_; }\\\n" + code += " INSTRUCTION_HEADER({})\\\n".format(name) code += " TRIVIAL_NEW_WRAPPERS\\\n" if named_operands: code += " NAMED_OPERANDS({})\\\n".format(", ".join(named_operands)) @@ -251,6 +288,9 @@ def generate_mir_header(c_out, yaml_path): operands = op.get("operands", None) assert operands is None or isinstance(operands, OrderedDict) + arguments = op.get("arguments", None) + assert arguments is None or isinstance(arguments, OrderedDict) + no_type_policy = op.get("type_policy", None) assert no_type_policy is None or no_type_policy == "none" @@ -291,6 +331,7 @@ def generate_mir_header(c_out, yaml_path): code = gen_mir_class( name, operands, + arguments, no_type_policy, result, guard, diff --git a/js/src/jit/Lowering.cpp b/js/src/jit/Lowering.cpp index 9a18e5ce7980..cf0d99c09592 100644 --- a/js/src/jit/Lowering.cpp +++ b/js/src/jit/Lowering.cpp @@ -343,16 +343,16 @@ void LIRGenerator::visitGetInlinedArgument(MGetInlinedArgument* ins) { } void LIRGenerator::visitGetArgumentsObjectArg(MGetArgumentsObjectArg* ins) { - LAllocation argsObj = useRegister(ins->getArgsObject()); + LAllocation argsObj = useRegister(ins->argsObject()); LGetArgumentsObjectArg* lir = new (alloc()) LGetArgumentsObjectArg(argsObj, temp()); defineBox(lir, ins); } void LIRGenerator::visitSetArgumentsObjectArg(MSetArgumentsObjectArg* ins) { - LAllocation argsObj = useRegister(ins->getArgsObject()); + LAllocation argsObj = useRegister(ins->argsObject()); LSetArgumentsObjectArg* lir = new (alloc()) - LSetArgumentsObjectArg(argsObj, useBox(ins->getValue()), temp()); + LSetArgumentsObjectArg(argsObj, useBox(ins->value()), temp()); add(lir, ins); } @@ -380,7 +380,7 @@ void LIRGenerator::visitArgumentsObjectLength(MArgumentsObjectLength* ins) { void LIRGenerator::visitGuardArgumentsObjectFlags( MGuardArgumentsObjectFlags* ins) { - MDefinition* argsObj = ins->getArgsObject(); + MDefinition* argsObj = ins->argsObject(); MOZ_ASSERT(argsObj->type() == MIRType::Object); auto* lir = diff --git a/js/src/jit/MIR.cpp b/js/src/jit/MIR.cpp index 28f36db30827..bb3fa2cbf28e 100644 --- a/js/src/jit/MIR.cpp +++ b/js/src/jit/MIR.cpp @@ -634,6 +634,14 @@ AliasSet MThrow::getAliasSet() const { return AliasSet::Store(AliasSet::ExceptionState); } +AliasSet MNewArrayDynamicLength::getAliasSet() const { + return AliasSet::Store(AliasSet::ExceptionState); +} + +AliasSet MNewTypedArrayDynamicLength::getAliasSet() const { + return AliasSet::Store(AliasSet::ExceptionState); +} + #ifdef JS_JITSPEW void MDefinition::printOpcode(GenericPrinter& out) const { PrintOpcodeName(out, op()); @@ -3114,6 +3122,19 @@ AliasSet MArgumentsObjectLength::getAliasSet() const { AliasSet::DynamicSlot); } +bool MGuardArgumentsObjectFlags::congruentTo(const MDefinition* ins) const { + if (!ins->isGuardArgumentsObjectFlags() || + ins->toGuardArgumentsObjectFlags()->flags() != flags()) { + return false; + } + return congruentIfOperandsEqual(ins); +} + +AliasSet MGuardArgumentsObjectFlags::getAliasSet() const { + // The flags are packed with the length in a fixed private slot. + return AliasSet::Load(AliasSet::FixedSlot); +} + MDefinition* MReturnFromCtor::foldsTo(TempAllocator& alloc) { MDefinition* rval = value(); if (rval->isBox()) { @@ -4108,6 +4129,24 @@ AliasSet MCreateThis::getAliasSet() const { return AliasSet::Load(AliasSet::Any); } +bool MGetArgumentsObjectArg::congruentTo(const MDefinition* ins) const { + if (!ins->isGetArgumentsObjectArg()) { + return false; + } + if (ins->toGetArgumentsObjectArg()->argno() != argno()) { + return false; + } + return congruentIfOperandsEqual(ins); +} + +AliasSet MGetArgumentsObjectArg::getAliasSet() const { + return AliasSet::Load(AliasSet::Any); +} + +AliasSet MSetArgumentsObjectArg::getAliasSet() const { + return AliasSet::Store(AliasSet::Any); +} + MObjectState::MObjectState(MObjectState* state) : MVariadicInstruction(classOpcode), numSlots_(state->numSlots_), @@ -5098,6 +5137,10 @@ MDefinition* MGetFirstDollarIndex::foldsTo(TempAllocator& alloc) { return MConstant::New(alloc, Int32Value(index)); } +AliasSet MThrowRuntimeLexicalError::getAliasSet() const { + return AliasSet::Store(AliasSet::ExceptionState); +} + AliasSet MSlots::getAliasSet() const { return AliasSet::Load(AliasSet::ObjectFields); } @@ -5408,6 +5451,20 @@ bool MCallBindVar::congruentTo(const MDefinition* ins) const { return congruentIfOperandsEqual(ins); } +bool MGuardShape::congruentTo(const MDefinition* ins) const { + if (!ins->isGuardShape()) { + return false; + } + if (shape() != ins->toGuardShape()->shape()) { + return false; + } + return congruentIfOperandsEqual(ins); +} + +AliasSet MGuardShape::getAliasSet() const { + return AliasSet::Load(AliasSet::ObjectFields); +} + MDefinition* MGuardIsNotProxy::foldsTo(TempAllocator& alloc) { KnownClass known = GetObjectKnownClass(object()); if (known == KnownClass::None) { @@ -5424,10 +5481,107 @@ AliasSet MMegamorphicLoadSlotByValue::getAliasSet() const { AliasSet::DynamicSlot); } +bool MMegamorphicLoadSlot::congruentTo(const MDefinition* ins) const { + if (!ins->isMegamorphicLoadSlot()) { + return false; + } + if (ins->toMegamorphicLoadSlot()->name() != name()) { + return false; + } + return congruentIfOperandsEqual(ins); +} + +AliasSet MMegamorphicLoadSlot::getAliasSet() const { + return AliasSet::Load(AliasSet::ObjectFields | AliasSet::FixedSlot | + AliasSet::DynamicSlot); +} + +bool MMegamorphicStoreSlot::congruentTo(const MDefinition* ins) const { + if (!ins->isMegamorphicStoreSlot()) { + return false; + } + if (ins->toMegamorphicStoreSlot()->name() != name()) { + return false; + } + return congruentIfOperandsEqual(ins); +} + +AliasSet MMegamorphicStoreSlot::getAliasSet() const { + return AliasSet::Store(AliasSet::ObjectFields | AliasSet::FixedSlot | + AliasSet::DynamicSlot); +} + +bool MMegamorphicHasProp::congruentTo(const MDefinition* ins) const { + if (!ins->isMegamorphicHasProp()) { + return false; + } + if (ins->toMegamorphicHasProp()->hasOwn() != hasOwn()) { + return false; + } + return congruentIfOperandsEqual(ins); +} + +AliasSet MMegamorphicHasProp::getAliasSet() const { + return AliasSet::Load(AliasSet::ObjectFields | AliasSet::FixedSlot | + AliasSet::DynamicSlot); +} + +bool MNurseryObject::congruentTo(const MDefinition* ins) const { + if (!ins->isNurseryObject()) { + return false; + } + return nurseryIndex() == ins->toNurseryObject()->nurseryIndex(); +} + AliasSet MGuardFunctionIsNonBuiltinCtor::getAliasSet() const { return AliasSet::Load(AliasSet::ObjectFields); } +bool MGuardFunctionKind::congruentTo(const MDefinition* ins) const { + if (!ins->isGuardFunctionKind()) { + return false; + } + if (expected() != ins->toGuardFunctionKind()->expected()) { + return false; + } + if (bailOnEquality() != ins->toGuardFunctionKind()->bailOnEquality()) { + return false; + } + return congruentIfOperandsEqual(ins); +} + +AliasSet MGuardFunctionKind::getAliasSet() const { + return AliasSet::Load(AliasSet::ObjectFields); +} + +bool MGuardFunctionScript::congruentTo(const MDefinition* ins) const { + if (!ins->isGuardFunctionScript()) { + return false; + } + if (expected() != ins->toGuardFunctionScript()->expected()) { + return false; + } + return congruentIfOperandsEqual(ins); +} + +AliasSet MGuardFunctionScript::getAliasSet() const { + // A JSFunction's BaseScript pointer is immutable. Relazification of + // self-hosted functions is an exception to this, but we don't use this + // guard for self-hosted functions. + MOZ_ASSERT(!flags_.isSelfHostedOrIntrinsic()); + return AliasSet::None(); +} + +bool MGuardSpecificAtom::congruentTo(const MDefinition* ins) const { + if (!ins->isGuardSpecificAtom()) { + return false; + } + if (atom() != ins->toGuardSpecificAtom()->atom()) { + return false; + } + return congruentIfOperandsEqual(ins); +} + MDefinition* MGuardStringToIndex::foldsTo(TempAllocator& alloc) { if (!string()->isConstant()) { return this; @@ -5480,6 +5634,15 @@ AliasSet MGuardNoDenseElements::getAliasSet() const { return AliasSet::Load(AliasSet::ObjectFields); } +AliasSet MCopyLexicalEnvironmentObject::getAliasSet() const { + return AliasSet::Load(AliasSet::ObjectFields | AliasSet::FixedSlot | + AliasSet::DynamicSlot); +} + +AliasSet MAllocateAndStoreSlot::getAliasSet() const { + return AliasSet::Store(AliasSet::ObjectFields | AliasSet::DynamicSlot); +} + AliasSet MLoadDOMExpandoValue::getAliasSet() const { return AliasSet::Load(AliasSet::DOMProxyExpando); } @@ -5488,6 +5651,21 @@ AliasSet MLoadDOMExpandoValueIgnoreGeneration::getAliasSet() const { return AliasSet::Load(AliasSet::DOMProxyExpando); } +bool MGuardDOMExpandoMissingOrGuardShape::congruentTo( + const MDefinition* ins) const { + if (!ins->isGuardDOMExpandoMissingOrGuardShape()) { + return false; + } + if (shape() != ins->toGuardDOMExpandoMissingOrGuardShape()->shape()) { + return false; + } + return congruentIfOperandsEqual(ins); +} + +AliasSet MGuardDOMExpandoMissingOrGuardShape::getAliasSet() const { + return AliasSet::Load(AliasSet::ObjectFields); +} + MDefinition* MGuardToClass::foldsTo(TempAllocator& alloc) { const JSClass* clasp = GetObjectKnownJSClass(object()); if (!clasp || getClass() != clasp) { @@ -5640,6 +5818,23 @@ AliasSet MLoadWrapperTarget::getAliasSet() const { return AliasSet::Load(AliasSet::Any); } +AliasSet MGuardHasGetterSetter::getAliasSet() const { + return AliasSet::Load(AliasSet::ObjectFields); +} + +bool MGuardHasGetterSetter::congruentTo(const MDefinition* ins) const { + if (!ins->isGuardHasGetterSetter()) { + return false; + } + if (ins->toGuardHasGetterSetter()->propId() != propId()) { + return false; + } + if (ins->toGuardHasGetterSetter()->getterSetter() != getterSetter()) { + return false; + } + return congruentIfOperandsEqual(ins); +} + AliasSet MGuardIsExtensible::getAliasSet() const { return AliasSet::Load(AliasSet::ObjectFields); } @@ -5754,3 +5949,18 @@ MDefinition* MGetInlinedArgument::foldsTo(TempAllocator& alloc) { return arg; } + +bool MWasmShiftSimd128::congruentTo(const MDefinition* ins) const { + return ins->toWasmShiftSimd128()->simdOp() == simdOp_ && + congruentIfOperandsEqual(ins); +} + +bool MWasmShuffleSimd128::congruentTo(const MDefinition* ins) const { + return ins->toWasmShuffleSimd128()->control().bitwiseEqual(control_) && + congruentIfOperandsEqual(ins); +} + +bool MWasmUnarySimd128::congruentTo(const MDefinition* ins) const { + return ins->toWasmUnarySimd128()->simdOp() == simdOp_ && + congruentIfOperandsEqual(ins); +} diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h index ab77b0fd46a2..f9207cbe8f55 100644 --- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -1833,34 +1833,6 @@ class MNewArray : public MUnaryInstruction, public NoTypePolicy::Data { } }; -class MNewArrayDynamicLength : public MUnaryInstruction, - public UnboxedInt32Policy<0>::Data { - CompilerObject templateObject_; - gc::InitialHeap initialHeap_; - - MNewArrayDynamicLength(TempAllocator& alloc, JSObject* templateObject, - gc::InitialHeap initialHeap, MDefinition* length) - : MUnaryInstruction(classOpcode, length), - templateObject_(templateObject), - initialHeap_(initialHeap) { - setGuard(); // Need to throw if length is negative. - setResultType(MIRType::Object); - } - - public: - INSTRUCTION_HEADER(NewArrayDynamicLength) - TRIVIAL_NEW_WRAPPERS_WITH_ALLOC - NAMED_OPERANDS((0, length)) - - JSObject* templateObject() const { return templateObject_; } - gc::InitialHeap initialHeap() const { return initialHeap_; } - - AliasSet getAliasSet() const override { - // Throws if length is negative. - return AliasSet::Store(AliasSet::ExceptionState); - } -}; - class MNewTypedArray : public MUnaryInstruction, public NoTypePolicy::Data { gc::InitialHeap initialHeap_; @@ -1888,89 +1860,6 @@ class MNewTypedArray : public MUnaryInstruction, public NoTypePolicy::Data { bool canRecoverOnBailout() const override { return true; } }; -class MNewTypedArrayDynamicLength : public MUnaryInstruction, - public UnboxedInt32Policy<0>::Data { - CompilerObject templateObject_; - gc::InitialHeap initialHeap_; - - MNewTypedArrayDynamicLength(TempAllocator& alloc, JSObject* templateObject, - gc::InitialHeap initialHeap, MDefinition* length) - : MUnaryInstruction(classOpcode, length), - templateObject_(templateObject), - initialHeap_(initialHeap) { - setGuard(); // Need to throw if length is negative. - setResultType(MIRType::Object); - } - - public: - INSTRUCTION_HEADER(NewTypedArrayDynamicLength) - TRIVIAL_NEW_WRAPPERS_WITH_ALLOC - NAMED_OPERANDS((0, length)) - - JSObject* templateObject() const { return templateObject_; } - gc::InitialHeap initialHeap() const { return initialHeap_; } - - AliasSet getAliasSet() const override { - // Throws if length is negative. - return AliasSet::Store(AliasSet::ExceptionState); - } -}; - -// Create a new TypedArray from an Array (or Array-like object) or a TypedArray. -class MNewTypedArrayFromArray : public MUnaryInstruction, - public SingleObjectPolicy::Data { - CompilerObject templateObject_; - gc::InitialHeap initialHeap_; - - MNewTypedArrayFromArray(TempAllocator& alloc, JSObject* templateObject, - gc::InitialHeap initialHeap, MDefinition* array) - : MUnaryInstruction(classOpcode, array), - templateObject_(templateObject), - initialHeap_(initialHeap) { - setGuard(); // Can throw during construction. - setResultType(MIRType::Object); - } - - public: - INSTRUCTION_HEADER(NewTypedArrayFromArray) - TRIVIAL_NEW_WRAPPERS_WITH_ALLOC - NAMED_OPERANDS((0, array)) - - JSObject* templateObject() const { return templateObject_; } - gc::InitialHeap initialHeap() const { return initialHeap_; } - - bool possiblyCalls() const override { return true; } -}; - -// Create a new TypedArray from an ArrayBuffer (or SharedArrayBuffer). -class MNewTypedArrayFromArrayBuffer - : public MTernaryInstruction, - public MixPolicy, BoxPolicy<1>, BoxPolicy<2>>::Data { - CompilerObject templateObject_; - gc::InitialHeap initialHeap_; - - MNewTypedArrayFromArrayBuffer(TempAllocator& alloc, JSObject* templateObject, - gc::InitialHeap initialHeap, - MDefinition* arrayBuffer, - MDefinition* byteOffset, MDefinition* length) - : MTernaryInstruction(classOpcode, arrayBuffer, byteOffset, length), - templateObject_(templateObject), - initialHeap_(initialHeap) { - setGuard(); // Can throw during construction. - setResultType(MIRType::Object); - } - - public: - INSTRUCTION_HEADER(NewTypedArrayFromArrayBuffer) - TRIVIAL_NEW_WRAPPERS_WITH_ALLOC - NAMED_OPERANDS((0, arrayBuffer), (1, byteOffset), (2, length)) - - JSObject* templateObject() const { return templateObject_; } - gc::InitialHeap initialHeap() const { return initialHeap_; } - - bool possiblyCalls() const override { return true; } -}; - class MNewObject : public MUnaryInstruction, public NoTypePolicy::Data { public: enum Mode { ObjectLiteral, ObjectCreate }; @@ -2250,23 +2139,6 @@ class MArrayState : public MVariadicInstruction, bool canRecoverOnBailout() const override { return true; } }; -class MInitPropGetterSetter - : public MBinaryInstruction, - public MixPolicy, ObjectPolicy<1>>::Data { - CompilerPropertyName name_; - - MInitPropGetterSetter(MDefinition* obj, PropertyName* name, - MDefinition* value) - : MBinaryInstruction(classOpcode, obj, value), name_(name) {} - - public: - INSTRUCTION_HEADER(InitPropGetterSetter) - TRIVIAL_NEW_WRAPPERS - NAMED_OPERANDS((0, object), (1, value)) - - PropertyName* name() const { return name_; } -}; - // WrappedFunction stores information about a function that can safely be used // off-thread. In particular, a function's flags can be modified on the main // thread as functions are relazified and delazified, so we must be careful not @@ -3082,90 +2954,6 @@ class MGetInlinedArgument MDefinition* foldsTo(TempAllocator& alloc) override; }; -class MGetArgumentsObjectArg : public MUnaryInstruction, - public ObjectPolicy<0>::Data { - size_t argno_; - - MGetArgumentsObjectArg(MDefinition* argsObject, size_t argno) - : MUnaryInstruction(classOpcode, argsObject), argno_(argno) { - setResultType(MIRType::Value); - } - - public: - INSTRUCTION_HEADER(GetArgumentsObjectArg) - TRIVIAL_NEW_WRAPPERS - NAMED_OPERANDS((0, getArgsObject)) - - size_t argno() const { return argno_; } - - bool congruentTo(const MDefinition* ins) const override { - if (!ins->isGetArgumentsObjectArg()) { - return false; - } - if (ins->toGetArgumentsObjectArg()->argno() != argno()) { - return false; - } - return congruentIfOperandsEqual(ins); - } - - AliasSet getAliasSet() const override { - return AliasSet::Load(AliasSet::Any); - } -}; - -class MSetArgumentsObjectArg - : public MBinaryInstruction, - public MixPolicy, BoxPolicy<1>>::Data { - size_t argno_; - - MSetArgumentsObjectArg(MDefinition* argsObj, size_t argno, MDefinition* value) - : MBinaryInstruction(classOpcode, argsObj, value), argno_(argno) {} - - public: - INSTRUCTION_HEADER(SetArgumentsObjectArg) - TRIVIAL_NEW_WRAPPERS - NAMED_OPERANDS((0, getArgsObject), (1, getValue)) - - size_t argno() const { return argno_; } - - AliasSet getAliasSet() const override { - return AliasSet::Store(AliasSet::Any); - } -}; - -// Guard that the given flags are not set on the arguments object. -class MGuardArgumentsObjectFlags : public MUnaryInstruction, - public SingleObjectPolicy::Data { - explicit MGuardArgumentsObjectFlags(MDefinition* argsObj, uint32_t flags) - : MUnaryInstruction(classOpcode, argsObj), flags_(flags) { - setResultType(MIRType::Object); - setMovable(); - setGuard(); - } - - uint8_t flags_; - - public: - INSTRUCTION_HEADER(GuardArgumentsObjectFlags) - TRIVIAL_NEW_WRAPPERS - NAMED_OPERANDS((0, getArgsObject)) - - uint8_t flags() const { return flags_; } - - bool congruentTo(const MDefinition* ins) const override { - if (!ins->isGuardArgumentsObjectFlags() || - ins->toGuardArgumentsObjectFlags()->flags() != flags()) { - return false; - } - return congruentIfOperandsEqual(ins); - } - - AliasSet getAliasSet() const override { - // The flags are packed with the length in a fixed private slot. - return AliasSet::Load(AliasSet::FixedSlot); - } -}; - class MToFPInstruction : public MUnaryInstruction, public ToDoublePolicy::Data { public: // Types of values which can be converted. @@ -5854,52 +5642,6 @@ class MStringConvertCase : public MUnaryInstruction, Mode mode() const { return mode_; } }; -// Returns the object to use as |this| value in a non-strict function. See also -// BoxNonStrictThis in Interpreter.h. -class MBoxNonStrictThis : public MUnaryInstruction, public BoxPolicy<0>::Data { - CompilerObject globalThis_; - - MBoxNonStrictThis(MDefinition* def, JSObject* globalThis) - : MUnaryInstruction(classOpcode, def), globalThis_(globalThis) { - setResultType(MIRType::Object); - } - - public: - INSTRUCTION_HEADER(BoxNonStrictThis) - TRIVIAL_NEW_WRAPPERS - - MDefinition* foldsTo(TempAllocator& alloc) override; - - JSObject* globalThis() const { return globalThis_; } - - bool possiblyCalls() const override { return true; } - - AliasSet getAliasSet() const override { - // This instruction can allocate a new object for wrapped primitives, but - // has no effect on existing objects. - return AliasSet::None(); - } -}; - -class MImplicitThis : public MUnaryInstruction, - public SingleObjectPolicy::Data { - CompilerPropertyName name_; - - MImplicitThis(MDefinition* envChain, PropertyName* name) - : MUnaryInstruction(classOpcode, envChain), name_(name) { - setResultType(MIRType::Value); - } - - public: - INSTRUCTION_HEADER(ImplicitThis) - TRIVIAL_NEW_WRAPPERS - NAMED_OPERANDS((0, envChain)) - - PropertyName* name() const { return name_; } - - bool possiblyCalls() const override { return true; } -}; - // This is a 3 state flag used by FlagPhiInputsAsImplicitlyUsed to record and // propagate the information about the consumers of a Phi instruction. This is // then used to set ImplicitlyUsed flags on the inputs of such Phi instructions. @@ -6283,27 +6025,6 @@ class MLexicalCheck : public MUnaryInstruction, public BoxPolicy<0>::Data { } }; -// Unconditionally throw an uninitialized let error. -class MThrowRuntimeLexicalError : public MNullaryInstruction { - unsigned errorNumber_; - - explicit MThrowRuntimeLexicalError(unsigned errorNumber) - : MNullaryInstruction(classOpcode), errorNumber_(errorNumber) { - setGuard(); - setResultType(MIRType::None); - } - - public: - INSTRUCTION_HEADER(ThrowRuntimeLexicalError) - TRIVIAL_NEW_WRAPPERS - - unsigned errorNumber() const { return errorNumber_; } - - AliasSet getAliasSet() const override { - return AliasSet::Store(AliasSet::ExceptionState); - } -}; - // Unconditionally throw a known error number. class MThrowMsg : public MNullaryInstruction { const ThrowMsgKind throwMsgKind_; @@ -6325,27 +6046,6 @@ class MThrowMsg : public MNullaryInstruction { } }; -class MRegExp : public MNullaryInstruction { - CompilerGCPointer source_; - bool hasShared_; - - MRegExp(TempAllocator& alloc, RegExpObject* source, bool hasShared) - : MNullaryInstruction(classOpcode), - source_(source), - hasShared_(hasShared) { - setResultType(MIRType::Object); - } - - public: - INSTRUCTION_HEADER(RegExp) - TRIVIAL_NEW_WRAPPERS_WITH_ALLOC - - bool hasShared() const { return hasShared_; } - RegExpObject* source() const { return source_; } - AliasSet getAliasSet() const override { return AliasSet::None(); } - bool possiblyCalls() const override { return true; } -}; - class MGetFirstDollarIndex : public MUnaryInstruction, public StringPolicy<0>::Data { explicit MGetFirstDollarIndex(MDefinition* str) @@ -6418,21 +6118,6 @@ class MStringReplace : public MTernaryInstruction, bool possiblyCalls() const override { return true; } }; -class MModuleMetadata : public MNullaryInstruction { - CompilerObject module_; - - explicit MModuleMetadata(JSObject* module) - : MNullaryInstruction(classOpcode), module_(module) { - setResultType(MIRType::Object); - } - - public: - INSTRUCTION_HEADER(ModuleMetadata) - TRIVIAL_NEW_WRAPPERS - - JSObject* module() const { return module_; } -}; - struct LambdaFunctionInfo { // The functions used in lambdas are the canonical original function in // the script, and are immutable except for delazification. Record this @@ -6536,25 +6221,6 @@ class MFunctionWithProto : public MTernaryInstruction, bool possiblyCalls() const override { return true; } }; -class MSetFunName : public MBinaryInstruction, - public MixPolicy, BoxPolicy<1>>::Data { - uint8_t prefixKind_; - - explicit MSetFunName(MDefinition* fun, MDefinition* name, uint8_t prefixKind) - : MBinaryInstruction(classOpcode, fun, name), prefixKind_(prefixKind) { - setResultType(MIRType::None); - } - - public: - INSTRUCTION_HEADER(SetFunName) - TRIVIAL_NEW_WRAPPERS - NAMED_OPERANDS((0, fun), (1, name)) - - uint8_t prefixKind() const { return prefixKind_; } - - bool possiblyCalls() const override { return true; } -}; - class MGetNextEntryForIterator : public MBinaryInstruction, public MixPolicy, ObjectPolicy<1>>::Data { @@ -7042,33 +6708,6 @@ class MArrayPopShift : public MUnaryInstruction, ALLOW_CLONE(MArrayPopShift) }; -// Array.prototype.slice on a dense array. -class MArraySlice : public MTernaryInstruction, - public MixPolicy, UnboxedInt32Policy<1>, - UnboxedInt32Policy<2>>::Data { - CompilerObject templateObj_; - gc::InitialHeap initialHeap_; - - MArraySlice(MDefinition* obj, MDefinition* begin, MDefinition* end, - JSObject* templateObj, gc::InitialHeap initialHeap) - : MTernaryInstruction(classOpcode, obj, begin, end), - templateObj_(templateObj), - initialHeap_(initialHeap) { - setResultType(MIRType::Object); - } - - public: - INSTRUCTION_HEADER(ArraySlice) - TRIVIAL_NEW_WRAPPERS - NAMED_OPERANDS((0, object), (1, begin), (2, end)) - - JSObject* templateObj() const { return templateObj_; } - - gc::InitialHeap initialHeap() const { return initialHeap_; } - - bool possiblyCalls() const override { return true; } -}; - // All barriered operations - MCompareExchangeTypedArrayElement, // MExchangeTypedArrayElement, and MAtomicTypedArrayElementBinop, as // well as MLoadUnboxedScalar and MStoreUnboxedScalar when they are @@ -7651,38 +7290,6 @@ class MGetPropSuperCache NAMED_OPERANDS((0, object), (1, receiver), (2, idval)) }; -// Guard on an object's shape. -class MGuardShape : public MUnaryInstruction, public SingleObjectPolicy::Data { - CompilerShape shape_; - - MGuardShape(MDefinition* obj, Shape* shape) - : MUnaryInstruction(classOpcode, obj), shape_(shape) { - setGuard(); - setMovable(); - setResultType(MIRType::Object); - } - - public: - INSTRUCTION_HEADER(GuardShape) - TRIVIAL_NEW_WRAPPERS - NAMED_OPERANDS((0, object)) - - const Shape* shape() const { return shape_; } - bool congruentTo(const MDefinition* ins) const override { - if (!ins->isGuardShape()) { - return false; - } - if (shape() != ins->toGuardShape()->shape()) { - return false; - } - return congruentIfOperandsEqual(ins); - } - MDefinition* foldsTo(TempAllocator& alloc) override; - AliasSet getAliasSet() const override { - return AliasSet::Load(AliasSet::ObjectFields); - } -}; - // Guard the object's proto is |expected|. class MGuardProto : public MBinaryInstruction, public SingleObjectPolicy::Data { MGuardProto(MDefinition* obj, MDefinition* expected) @@ -7744,233 +7351,6 @@ class MGuardNullProto : public MUnaryInstruction, } }; -class MProxyGet : public MUnaryInstruction, public SingleObjectPolicy::Data { - jsid id_; - - MProxyGet(MDefinition* proxy, jsid id) - : MUnaryInstruction(classOpcode, proxy), id_(id) { - setResultType(MIRType::Value); - } - - public: - INSTRUCTION_HEADER(ProxyGet) - TRIVIAL_NEW_WRAPPERS - NAMED_OPERANDS((0, proxy)) - - jsid id() const { return id_; } - - bool possiblyCalls() const override { return true; } -}; - -class MProxyHasProp : public MBinaryInstruction, - public MixPolicy, BoxPolicy<1>>::Data { - bool hasOwn_; - - MProxyHasProp(MDefinition* proxy, MDefinition* idVal, bool hasOwn) - : MBinaryInstruction(classOpcode, proxy, idVal), hasOwn_(hasOwn) { - setResultType(MIRType::Boolean); - } - - public: - INSTRUCTION_HEADER(ProxyHasProp) - TRIVIAL_NEW_WRAPPERS - NAMED_OPERANDS((0, proxy), (1, idVal)) - - bool hasOwn() const { return hasOwn_; } - - bool possiblyCalls() const override { return true; } -}; - -class MProxySet : public MBinaryInstruction, - public MixPolicy, BoxPolicy<1>>::Data { - jsid id_; - bool strict_; - - MProxySet(MDefinition* proxy, jsid id, MDefinition* rhs, bool strict) - : MBinaryInstruction(classOpcode, proxy, rhs), id_(id), strict_(strict) {} - - public: - INSTRUCTION_HEADER(ProxySet) - TRIVIAL_NEW_WRAPPERS - NAMED_OPERANDS((0, proxy), (1, rhs)) - - jsid id() const { return id_; } - bool strict() const { return strict_; } - - bool possiblyCalls() const override { return true; } -}; - -class MProxySetByValue - : public MTernaryInstruction, - public MixPolicy, BoxPolicy<1>, BoxPolicy<2>>::Data { - bool strict_; - - MProxySetByValue(MDefinition* proxy, MDefinition* idVal, MDefinition* rhs, - bool strict) - : MTernaryInstruction(classOpcode, proxy, idVal, rhs), strict_(strict) {} - - public: - INSTRUCTION_HEADER(ProxySetByValue) - TRIVIAL_NEW_WRAPPERS - NAMED_OPERANDS((0, proxy), (1, idVal), (2, rhs)) - - bool strict() const { return strict_; } - - bool possiblyCalls() const override { return true; } -}; - -class MCallSetArrayLength - : public MBinaryInstruction, - public MixPolicy, BoxPolicy<1>>::Data { - bool strict_; - - MCallSetArrayLength(MDefinition* obj, MDefinition* rhs, bool strict) - : MBinaryInstruction(classOpcode, obj, rhs), strict_(strict) {} - - public: - INSTRUCTION_HEADER(CallSetArrayLength) - TRIVIAL_NEW_WRAPPERS - NAMED_OPERANDS((0, obj), (1, rhs)) - - bool strict() const { return strict_; } - - bool possiblyCalls() const override { return true; } -}; - -class MMegamorphicLoadSlot : public MUnaryInstruction, - public SingleObjectPolicy::Data { - CompilerPropertyName name_; - - MMegamorphicLoadSlot(MDefinition* obj, PropertyName* name) - : MUnaryInstruction(classOpcode, obj), name_(name) { - setResultType(MIRType::Value); - - // Bails when non-native or accessor properties are encountered, so we can't - // DCE this instruction. - setGuard(); - } - - public: - INSTRUCTION_HEADER(MegamorphicLoadSlot) - TRIVIAL_NEW_WRAPPERS - NAMED_OPERANDS((0, object)) - - PropertyName* name() const { return name_; } - - bool congruentTo(const MDefinition* ins) const override { - if (!ins->isMegamorphicLoadSlot()) { - return false; - } - if (ins->toMegamorphicLoadSlot()->name() != name()) { - return false; - } - return congruentIfOperandsEqual(ins); - } - AliasSet getAliasSet() const override { - return AliasSet::Load(AliasSet::ObjectFields | AliasSet::FixedSlot | - AliasSet::DynamicSlot); - } - - bool possiblyCalls() const override { return true; } -}; - -class MMegamorphicStoreSlot - : public MBinaryInstruction, - public MixPolicy, BoxPolicy<1>>::Data { - CompilerPropertyName name_; - - MMegamorphicStoreSlot(MDefinition* obj, PropertyName* name, MDefinition* rhs) - : MBinaryInstruction(classOpcode, obj, rhs), name_(name) {} - - public: - INSTRUCTION_HEADER(MegamorphicStoreSlot) - TRIVIAL_NEW_WRAPPERS - NAMED_OPERANDS((0, object), (1, rhs)) - - PropertyName* name() const { return name_; } - - bool congruentTo(const MDefinition* ins) const override { - if (!ins->isMegamorphicStoreSlot()) { - return false; - } - if (ins->toMegamorphicStoreSlot()->name() != name()) { - return false; - } - return congruentIfOperandsEqual(ins); - } - AliasSet getAliasSet() const override { - return AliasSet::Store(AliasSet::ObjectFields | AliasSet::FixedSlot | - AliasSet::DynamicSlot); - } - - bool possiblyCalls() const override { return true; } -}; - -class MMegamorphicHasProp - : public MBinaryInstruction, - public MixPolicy, BoxPolicy<1>>::Data { - bool hasOwn_; - - MMegamorphicHasProp(MDefinition* obj, MDefinition* idVal, bool hasOwn) - : MBinaryInstruction(classOpcode, obj, idVal), hasOwn_(hasOwn) { - setResultType(MIRType::Boolean); - - // Bails when non-native or accessor properties are encountered, so we can't - // DCE this instruction. - setGuard(); - } - - public: - INSTRUCTION_HEADER(MegamorphicHasProp) - TRIVIAL_NEW_WRAPPERS - NAMED_OPERANDS((0, object), (1, idVal)) - - bool hasOwn() const { return hasOwn_; } - - bool congruentTo(const MDefinition* ins) const override { - if (!ins->isMegamorphicHasProp()) { - return false; - } - if (ins->toMegamorphicHasProp()->hasOwn() != hasOwn()) { - return false; - } - return congruentIfOperandsEqual(ins); - } - AliasSet getAliasSet() const override { - return AliasSet::Load(AliasSet::ObjectFields | AliasSet::FixedSlot | - AliasSet::DynamicSlot); - } - - bool possiblyCalls() const override { return true; } -}; - -// Loads a specific JSObject* that was originally nursery-allocated. -// See also WarpObjectField. -class MNurseryObject : public MNullaryInstruction { - // Index in the Vector of objects stored in the WarpSnapshot. - uint32_t nurseryIndex_; - - explicit MNurseryObject(uint32_t nurseryIndex) - : MNullaryInstruction(classOpcode), nurseryIndex_(nurseryIndex) { - setMovable(); - setResultType(MIRType::Object); - } - - public: - INSTRUCTION_HEADER(NurseryObject) - TRIVIAL_NEW_WRAPPERS - - uint32_t nurseryIndex() const { return nurseryIndex_; } - - bool congruentTo(const MDefinition* ins) const override { - if (!ins->isNurseryObject()) { - return false; - } - return nurseryIndex() == ins->toNurseryObject()->nurseryIndex(); - } - AliasSet getAliasSet() const override { return AliasSet::None(); } -}; - // Guard on a specific Value. class MGuardValue : public MUnaryInstruction, public BoxInputsPolicy::Data { Value expected_; @@ -8054,94 +7434,6 @@ class MGuardFunctionFlags : public MUnaryInstruction, } }; -// Guard on function kind -class MGuardFunctionKind : public MUnaryInstruction, - public SingleObjectPolicy::Data { - FunctionFlags::FunctionKind expected_; - bool bailOnEquality_; - - explicit MGuardFunctionKind(MDefinition* fun, - FunctionFlags::FunctionKind expected, - bool bailOnEquality) - : MUnaryInstruction(classOpcode, fun), - expected_(expected), - bailOnEquality_(bailOnEquality) { - setGuard(); - setMovable(); - setResultType(MIRType::Object); - } - - public: - INSTRUCTION_HEADER(GuardFunctionKind) - TRIVIAL_NEW_WRAPPERS - NAMED_OPERANDS((0, function)) - - FunctionFlags::FunctionKind expected() const { return expected_; }; - bool bailOnEquality() const { return bailOnEquality_; } - - bool congruentTo(const MDefinition* ins) const override { - if (!ins->isGuardFunctionKind()) { - return false; - } - if (expected() != ins->toGuardFunctionKind()->expected()) { - return false; - } - if (bailOnEquality() != ins->toGuardFunctionKind()->bailOnEquality()) { - return false; - } - return congruentIfOperandsEqual(ins); - } - AliasSet getAliasSet() const override { - return AliasSet::Load(AliasSet::ObjectFields); - } -}; - -class MGuardFunctionScript : public MUnaryInstruction, - public SingleObjectPolicy::Data { - CompilerBaseScript expected_; - uint16_t nargs_; - FunctionFlags flags_; - - MGuardFunctionScript(MDefinition* fun, BaseScript* expected, uint16_t nargs, - FunctionFlags flags) - : MUnaryInstruction(classOpcode, fun), - expected_(expected), - nargs_(nargs), - flags_(flags) { - setGuard(); - setMovable(); - setResultType(MIRType::Object); - } - - public: - INSTRUCTION_HEADER(GuardFunctionScript) - TRIVIAL_NEW_WRAPPERS - NAMED_OPERANDS((0, function)) - - BaseScript* expected() const { return expected_; } - uint16_t nargs() const { return nargs_; } - FunctionFlags flags() const { return flags_; } - - MDefinition* foldsTo(TempAllocator& alloc) override; - - bool congruentTo(const MDefinition* ins) const override { - if (!ins->isGuardFunctionScript()) { - return false; - } - if (expected() != ins->toGuardFunctionScript()->expected()) { - return false; - } - return congruentIfOperandsEqual(ins); - } - AliasSet getAliasSet() const override { - // A JSFunction's BaseScript pointer is immutable. Relazification of - // self-hosted functions is an exception to this, but we don't use this - // guard for self-hosted functions. - MOZ_ASSERT(!flags_.isSelfHostedOrIntrinsic()); - return AliasSet::None(); - } -}; - // Guard on an object's identity, inclusively or exclusively. class MGuardObjectIdentity : public MBinaryInstruction, public SingleObjectPolicy::Data { @@ -8218,37 +7510,6 @@ class MGuardSpecificFunction : public MBinaryInstruction, AliasSet getAliasSet() const override { return AliasSet::None(); } }; -class MGuardSpecificAtom : public MUnaryInstruction, - public StringPolicy<0>::Data { - CompilerGCPointer atom_; - - MGuardSpecificAtom(MDefinition* str, JSAtom* atom) - : MUnaryInstruction(classOpcode, str), atom_(atom) { - setGuard(); - setMovable(); - setResultType(MIRType::String); - } - - public: - INSTRUCTION_HEADER(GuardSpecificAtom) - TRIVIAL_NEW_WRAPPERS - NAMED_OPERANDS((0, str)) - - JSAtom* atom() const { return atom_; } - - bool congruentTo(const MDefinition* ins) const override { - if (!ins->isGuardSpecificAtom()) { - return false; - } - if (atom() != ins->toGuardSpecificAtom()->atom()) { - return false; - } - return congruentIfOperandsEqual(ins); - } - MDefinition* foldsTo(TempAllocator& alloc) override; - AliasSet getAliasSet() const override { return AliasSet::None(); } -}; - class MGuardSpecificSymbol : public MUnaryInstruction, public SymbolPolicy<0>::Data { CompilerGCPointer expected_; @@ -8365,49 +7626,6 @@ class MNewLexicalEnvironmentObject : public MUnaryInstruction, AliasSet getAliasSet() const override { return AliasSet::None(); } }; -// Allocate a new ClassBodyEnvironmentObject. -class MNewClassBodyEnvironmentObject : public MUnaryInstruction, - public SingleObjectPolicy::Data { - CompilerGCPointer scope_; - - MNewClassBodyEnvironmentObject(MDefinition* enclosing, ClassBodyScope* scope) - : MUnaryInstruction(classOpcode, enclosing), scope_(scope) { - setResultType(MIRType::Object); - } - - public: - INSTRUCTION_HEADER(NewClassBodyEnvironmentObject) - TRIVIAL_NEW_WRAPPERS - NAMED_OPERANDS((0, enclosing)) - - ClassBodyScope* scope() const { return scope_; } - bool possiblyCalls() const override { return true; } - AliasSet getAliasSet() const override { return AliasSet::None(); } -}; - -// Allocate a new BlockLexicalEnvironmentObject from an existing one. -class MCopyLexicalEnvironmentObject : public MUnaryInstruction, - public SingleObjectPolicy::Data { - bool copySlots_; - - MCopyLexicalEnvironmentObject(MDefinition* env, bool copySlots) - : MUnaryInstruction(classOpcode, env), copySlots_(copySlots) { - setResultType(MIRType::Object); - } - - public: - INSTRUCTION_HEADER(CopyLexicalEnvironmentObject) - TRIVIAL_NEW_WRAPPERS - NAMED_OPERANDS((0, env)) - - bool copySlots() const { return copySlots_; } - bool possiblyCalls() const override { return true; } - AliasSet getAliasSet() const override { - return AliasSet::Load(AliasSet::ObjectFields | AliasSet::FixedSlot | - AliasSet::DynamicSlot); - } -}; - class MAddAndStoreSlot : public MBinaryInstruction, public MixPolicy>::Data { @@ -8445,36 +7663,6 @@ class MAddAndStoreSlot } }; -class MAllocateAndStoreSlot - : public MBinaryInstruction, - public MixPolicy>::Data { - private: - CompilerShape shape_; - uint32_t slotOffset_; - uint32_t numNewSlots_; - - MAllocateAndStoreSlot(MDefinition* obj, MDefinition* value, - uint32_t slotOffset, Shape* shape, uint32_t numNewSlots) - : MBinaryInstruction(classOpcode, obj, value), - shape_(shape), - slotOffset_(slotOffset), - numNewSlots_(numNewSlots) {} - - public: - INSTRUCTION_HEADER(AllocateAndStoreSlot) - TRIVIAL_NEW_WRAPPERS - NAMED_OPERANDS((0, object), (1, value)) - - Shape* shape() const { return shape_; } - uint32_t slotOffset() const { return slotOffset_; } - uint32_t numNewSlots() const { return numNewSlots_; } - - AliasSet getAliasSet() const override { - return AliasSet::Store(AliasSet::ObjectFields | AliasSet::DynamicSlot); - } - bool possiblyCalls() const override { return true; } -}; - // Store to vp[slot] (slots that are not inline in an object). class MStoreDynamicSlot : public MBinaryInstruction, public NoFloatPolicy<1>::Data { @@ -8525,57 +7713,6 @@ class MStoreDynamicSlot : public MBinaryInstruction, ALLOW_CLONE(MStoreDynamicSlot) }; -class MCallGetIntrinsicValue : public MNullaryInstruction { - CompilerPropertyName name_; - - explicit MCallGetIntrinsicValue(PropertyName* name) - : MNullaryInstruction(classOpcode), name_(name) { - setResultType(MIRType::Value); - } - - public: - INSTRUCTION_HEADER(CallGetIntrinsicValue) - TRIVIAL_NEW_WRAPPERS - - PropertyName* name() const { return name_; } - AliasSet getAliasSet() const override { return AliasSet::None(); } - bool possiblyCalls() const override { return true; } -}; - -class MDeleteProperty : public MUnaryInstruction, public BoxInputsPolicy::Data { - CompilerPropertyName name_; - bool strict_; - - MDeleteProperty(MDefinition* val, PropertyName* name, bool strict) - : MUnaryInstruction(classOpcode, val), name_(name), strict_(strict) { - setResultType(MIRType::Boolean); - } - - public: - INSTRUCTION_HEADER(DeleteProperty) - TRIVIAL_NEW_WRAPPERS - NAMED_OPERANDS((0, value)) - - PropertyName* name() const { return name_; } - bool strict() const { return strict_; } -}; - -class MDeleteElement : public MBinaryInstruction, public BoxInputsPolicy::Data { - bool strict_; - - MDeleteElement(MDefinition* value, MDefinition* index, bool strict) - : MBinaryInstruction(classOpcode, value, index), strict_(strict) { - setResultType(MIRType::Boolean); - } - - public: - INSTRUCTION_HEADER(DeleteElement) - TRIVIAL_NEW_WRAPPERS - NAMED_OPERANDS((0, value), (1, index)) - - bool strict() const { return strict_; } -}; - class MSetPropertyCache : public MTernaryInstruction, public MixPolicy, NoFloatPolicy<2>>::Data { @@ -8847,40 +7984,6 @@ class MLoadDOMExpandoValueGuardGeneration : public MUnaryInstruction, } }; -// Takes an expando Value as input, then guards it's either UndefinedValue or -// an object with the expected shape. -class MGuardDOMExpandoMissingOrGuardShape : public MUnaryInstruction, - public BoxInputsPolicy::Data { - CompilerShape shape_; - - MGuardDOMExpandoMissingOrGuardShape(MDefinition* obj, Shape* shape) - : MUnaryInstruction(classOpcode, obj), shape_(shape) { - setGuard(); - setMovable(); - setResultType(MIRType::Value); - } - - public: - INSTRUCTION_HEADER(GuardDOMExpandoMissingOrGuardShape) - TRIVIAL_NEW_WRAPPERS - NAMED_OPERANDS((0, expando)) - - const Shape* shape() const { return shape_; } - - bool congruentTo(const MDefinition* ins) const override { - if (!ins->isGuardDOMExpandoMissingOrGuardShape()) { - return false; - } - if (shape() != ins->toGuardDOMExpandoMissingOrGuardShape()->shape()) { - return false; - } - return congruentIfOperandsEqual(ins); - } - AliasSet getAliasSet() const override { - return AliasSet::Load(AliasSet::ObjectFields); - } -}; - // Inlined assembly for Math.floor(double | float32) -> int32. class MFloor : public MUnaryInstruction, public FloatingPointPolicy<0>::Data { explicit MFloor(MDefinition* num) : MUnaryInstruction(classOpcode, num) { @@ -9199,30 +8302,6 @@ class MInstanceOf : public MBinaryInstruction, TRIVIAL_NEW_WRAPPERS }; -class MRest : public MUnaryInstruction, public UnboxedInt32Policy<0>::Data { - unsigned numFormals_; - CompilerGCPointer shape_; - - MRest(TempAllocator& alloc, MDefinition* numActuals, unsigned numFormals, - Shape* shape) - : MUnaryInstruction(classOpcode, numActuals), - numFormals_(numFormals), - shape_(shape) { - setResultType(MIRType::Object); - } - - public: - INSTRUCTION_HEADER(Rest) - TRIVIAL_NEW_WRAPPERS_WITH_ALLOC - NAMED_OPERANDS((0, numActuals)) - - unsigned numFormals() const { return numFormals_; } - Shape* shape() const { return shape_; } - - AliasSet getAliasSet() const override { return AliasSet::None(); } - bool possiblyCalls() const override { return true; } -}; - // Given a value being written to another object, update the generational store // buffer if the value is in the nursery and object is in the tenured heap. class MPostWriteBarrier : public MBinaryInstruction, @@ -9280,22 +8359,6 @@ class MPostWriteElementBarrier ALLOW_CLONE(MPostWriteElementBarrier) }; -class MNewNamedLambdaObject : public MNullaryInstruction { - CompilerGCPointer templateObj_; - - explicit MNewNamedLambdaObject(NamedLambdaObject* templateObj) - : MNullaryInstruction(classOpcode), templateObj_(templateObj) { - setResultType(MIRType::Object); - } - - public: - INSTRUCTION_HEADER(NewNamedLambdaObject) - TRIVIAL_NEW_WRAPPERS - - NamedLambdaObject* templateObj() { return templateObj_; } - AliasSet getAliasSet() const override { return AliasSet::None(); } -}; - class MNewCallObject : public MUnaryInstruction, public SingleObjectPolicy::Data { public: @@ -9646,25 +8709,6 @@ class MIsTypedArray : public MUnaryInstruction, } }; -class MAsyncResolve : public MBinaryInstruction, - public MixPolicy, BoxPolicy<1>>::Data { - AsyncFunctionResolveKind resolveKind_; - - explicit MAsyncResolve(MDefinition* generator, MDefinition* valueOrReason, - AsyncFunctionResolveKind resolveKind) - : MBinaryInstruction(classOpcode, generator, valueOrReason), - resolveKind_(resolveKind) { - setResultType(MIRType::Object); - } - - public: - INSTRUCTION_HEADER(AsyncResolve) - TRIVIAL_NEW_WRAPPERS - NAMED_OPERANDS((0, generator), (1, valueOrReason)) - - AsyncFunctionResolveKind resolveKind() { return resolveKind_; } -}; - // Allocate the generator object for a frame. class MGenerator : public MTernaryInstruction, public MixPolicy, ObjectPolicy<1>>::Data { @@ -9693,22 +8737,6 @@ class MMaybeExtractAwaitValue : public MBinaryInstruction, NAMED_OPERANDS((0, value), (1, canSkip)) }; -class MIncrementWarmUpCounter : public MNullaryInstruction { - private: - JSScript* script_; - - explicit MIncrementWarmUpCounter(JSScript* script) - : MNullaryInstruction(classOpcode), script_(script) {} - - public: - INSTRUCTION_HEADER(IncrementWarmUpCounter) - TRIVIAL_NEW_WRAPPERS - - JSScript* script() const { return script_; } - - AliasSet getAliasSet() const override { return AliasSet::None(); } -}; - class MAtomicIsLockFree : public MUnaryInstruction, public ConvertToInt32Policy<0>::Data { explicit MAtomicIsLockFree(MDefinition* value) @@ -9845,25 +8873,6 @@ class MDebugger : public MNullaryInstruction { TRIVIAL_NEW_WRAPPERS }; -class MCheckIsObj : public MUnaryInstruction, public BoxInputsPolicy::Data { - uint8_t checkKind_; - - MCheckIsObj(TempAllocator& alloc, MDefinition* value, uint8_t checkKind) - : MUnaryInstruction(classOpcode, value), checkKind_(checkKind) { - setResultType(MIRType::Object); - setGuard(); - } - - public: - INSTRUCTION_HEADER(CheckIsObj) - TRIVIAL_NEW_WRAPPERS_WITH_ALLOC - - uint8_t checkKind() const { return checkKind_; } - - MDefinition* foldsTo(TempAllocator& alloc) override; - AliasSet getAliasSet() const override { return AliasSet::None(); } -}; - // Used to load the prototype of an object known to have // a static prototype. class MObjectStaticProto : public MUnaryInstruction, @@ -9895,87 +8904,6 @@ class MObjectStaticProto : public MUnaryInstruction, } }; -class MBuiltinObject : public MNullaryInstruction { - BuiltinObjectKind builtinObjectKind_; - - explicit MBuiltinObject(BuiltinObjectKind kind) - : MNullaryInstruction(classOpcode), builtinObjectKind_(kind) { - setResultType(MIRType::Object); - } - - public: - INSTRUCTION_HEADER(BuiltinObject) - TRIVIAL_NEW_WRAPPERS - - BuiltinObjectKind builtinObjectKind() const { return builtinObjectKind_; } - - bool possiblyCalls() const override { return true; } -}; - -// Guard the accessor shape is present on the object or its prototype chain. -class MGuardHasGetterSetter : public MUnaryInstruction, - public SingleObjectPolicy::Data { - jsid propId_; - CompilerGetterSetter getterSetter_; - - MGuardHasGetterSetter(MDefinition* obj, jsid id, GetterSetter* gs) - : MUnaryInstruction(classOpcode, obj), propId_(id), getterSetter_(gs) { - setResultType(MIRType::Object); - setMovable(); - setGuard(); - } - - public: - INSTRUCTION_HEADER(GuardHasGetterSetter) - TRIVIAL_NEW_WRAPPERS - NAMED_OPERANDS((0, object)) - - jsid propId() const { return propId_; } - GetterSetter* getterSetter() const { return getterSetter_; } - - AliasSet getAliasSet() const override { - return AliasSet::Load(AliasSet::ObjectFields); - } - - bool congruentTo(const MDefinition* ins) const override { - if (!ins->isGuardHasGetterSetter()) { - return false; - } - if (ins->toGuardHasGetterSetter()->propId() != propId()) { - return false; - } - if (ins->toGuardHasGetterSetter()->getterSetter() != getterSetter()) { - return false; - } - return congruentIfOperandsEqual(ins); - } - - bool possiblyCalls() const override { return true; } -}; - -// Add or update a sparse element of an array object. It's allowed for the -// sparse element to be already present on the array. It may also be an accessor -// property, so this instruction is always marked as effectful. -class MCallAddOrUpdateSparseElement - : public MTernaryInstruction, - public MixPolicy, UnboxedInt32Policy<1>, - BoxPolicy<2>>::Data { - bool strict_; - - MCallAddOrUpdateSparseElement(MDefinition* obj, MDefinition* index, - MDefinition* value, bool strict) - : MTernaryInstruction(classOpcode, obj, index, value), strict_(strict) {} - - public: - INSTRUCTION_HEADER(CallAddOrUpdateSparseElement) - TRIVIAL_NEW_WRAPPERS - NAMED_OPERANDS((0, object), (1, index), (2, value)) - - bool strict() const { return strict_; } - - bool possiblyCalls() const override { return true; } -}; - // Flips the input's sign bit, independently of the rest of the number's // payload. Note this is different from multiplying by minus-one, which has // side-effects for e.g. NaNs. @@ -11119,57 +10047,6 @@ class MWasmBinarySimd128WithConstant : public MUnaryInstruction, ALLOW_CLONE(MWasmBinarySimd128WithConstant) }; -// (v128, i32) -> v128 effect-free shift operations. -class MWasmShiftSimd128 : public MBinaryInstruction, public NoTypePolicy::Data { - wasm::SimdOp simdOp_; - - MWasmShiftSimd128(MDefinition* lhs, MDefinition* rhs, wasm::SimdOp simdOp) - : MBinaryInstruction(classOpcode, lhs, rhs), simdOp_(simdOp) { - setMovable(); - setResultType(MIRType::Simd128); - } - - public: - INSTRUCTION_HEADER(WasmShiftSimd128) - TRIVIAL_NEW_WRAPPERS - - AliasSet getAliasSet() const override { return AliasSet::None(); } - bool congruentTo(const MDefinition* ins) const override { - return ins->toWasmShiftSimd128()->simdOp() == simdOp_ && - congruentIfOperandsEqual(ins); - } - - wasm::SimdOp simdOp() const { return simdOp_; } - - ALLOW_CLONE(MWasmShiftSimd128) -}; - -// (v128, v128, mask) -> v128 effect-free operation. -class MWasmShuffleSimd128 : public MBinaryInstruction, - public NoTypePolicy::Data { - SimdConstant control_; - - MWasmShuffleSimd128(MDefinition* lhs, MDefinition* rhs, SimdConstant control) - : MBinaryInstruction(classOpcode, lhs, rhs), control_(control) { - setMovable(); - setResultType(MIRType::Simd128); - } - - public: - INSTRUCTION_HEADER(WasmShuffleSimd128) - TRIVIAL_NEW_WRAPPERS - - AliasSet getAliasSet() const override { return AliasSet::None(); } - bool congruentTo(const MDefinition* ins) const override { - return ins->toWasmShuffleSimd128()->control().bitwiseEqual(control_) && - congruentIfOperandsEqual(ins); - } - - SimdConstant control() const { return control_; } - - ALLOW_CLONE(MWasmShuffleSimd128) -}; - // (v128, scalar, imm) -> v128 effect-free operations. class MWasmReplaceLaneSimd128 : public MBinaryInstruction, public NoTypePolicy::Data { @@ -11202,31 +10079,6 @@ class MWasmReplaceLaneSimd128 : public MBinaryInstruction, ALLOW_CLONE(MWasmReplaceLaneSimd128) }; -// (v128) -> v128 effect-free operations. -class MWasmUnarySimd128 : public MUnaryInstruction, public NoTypePolicy::Data { - wasm::SimdOp simdOp_; - - MWasmUnarySimd128(MDefinition* src, wasm::SimdOp simdOp) - : MUnaryInstruction(classOpcode, src), simdOp_(simdOp) { - setMovable(); - setResultType(MIRType::Simd128); - } - - public: - INSTRUCTION_HEADER(WasmUnarySimd128) - TRIVIAL_NEW_WRAPPERS - - AliasSet getAliasSet() const override { return AliasSet::None(); } - bool congruentTo(const MDefinition* ins) const override { - return ins->toWasmUnarySimd128()->simdOp() == simdOp_ && - congruentIfOperandsEqual(ins); - } - - wasm::SimdOp simdOp() const { return simdOp_; } - - ALLOW_CLONE(MWasmUnarySimd128) -}; - // (scalar) -> v128 effect-free operations. class MWasmScalarToSimd128 : public MUnaryInstruction, public NoTypePolicy::Data { diff --git a/js/src/jit/MIROps.yaml b/js/src/jit/MIROps.yaml index 66a6b23201e1..2be497f49aa7 100644 --- a/js/src/jit/MIROps.yaml +++ b/js/src/jit/MIROps.yaml @@ -26,8 +26,8 @@ # # operands # ======== -# A list of operands for the MIR op class constructor. -# The operand kind is specified from the one of the kinds from +# A list of operands for the MIR op class constructor. Each operand is a +# MIR node. The operand kind is specified from the one of the kinds from # the MIRType enum in IonTypes.h. The specified types for the # operands will decide the type policy for the instruction. # @@ -47,6 +47,31 @@ # - attribute not specified (default): no code generated # - operand list: MIRTypes (See MIRType in jit/IonTypes.h) # +# arguments +# ========= +# A list of non-MIR node arguments to the MIR op class constructor +# that are passed along with the operands. The arguments require +# both a name and a full type signature for each item in the list. +# +# For example: +# templateObject: JSObject* +# initialHeap: gc::InitialHeap +# +# For each argument a private variable declaration will be autogenerated +# in the MIR op class, as well as simple accessor for that variable. If +# the type of the variable is a GC pointer it will by automatically +# wrapped by CompilerGCPointer. The above arguments list will result in +# the following declarations and accessors: +# +# CompilerGCPointer templateObject_; +# gc::InitialHeap initialHeap_; +# +# JSObject* templateObject() const { return templateObject_; } +# gc::InitialHeap initialHeap() const { return initialHeap_; } +# +# - attribute not specified (default): no code generated +# - operand list: argument names and their full type signature +# # type_policy # ============ # If this attribute is present, then the type policy for that opcode will be @@ -194,19 +219,54 @@ gen_boilerplate: false - name: NewArrayDynamicLength - gen_boilerplate: false + operands: + length: Int32 + arguments: + templateObject: JSObject* + initialHeap: gc::InitialHeap + result_type: Object + # Need to throw if length is negative. + guard: true + # Throws if length is negative. + alias_set: custom - name: NewTypedArray gen_boilerplate: false - name: NewTypedArrayDynamicLength - gen_boilerplate: false + operands: + length: Int32 + arguments: + templateObject: JSObject* + initialHeap: gc::InitialHeap + result_type: Object + guard: true + # Throws if length is negative. + alias_set: custom +# Create a new TypedArray from an Array (or Array-like object) or a TypedArray. - name: NewTypedArrayFromArray - gen_boilerplate: false + operands: + array: Object + arguments: + templateObject: JSObject* + initialHeap: gc::InitialHeap + result_type: Object + guard: true + possibly_calls: true +# Create a new TypedArray from an ArrayBuffer (or SharedArrayBuffer). - name: NewTypedArrayFromArrayBuffer - gen_boilerplate: false + operands: + arrayBuffer: Object + byteOffset: Value + length: Value + arguments: + templateObject: JSObject* + initialHeap: gc::InitialHeap + result_type: Object + guard: true + possibly_calls: true - name: NewObject gen_boilerplate: false @@ -235,7 +295,11 @@ possibly_calls: true - name: InitPropGetterSetter - gen_boilerplate: false + operands: + object: Object + value: Object + arguments: + name: PropertyName* - name: InitElemGetterSetter operands: @@ -339,10 +403,21 @@ gen_boilerplate: false - name: GetArgumentsObjectArg - gen_boilerplate: false + operands: + argsObject: Object + arguments: + argno: size_t + result_type: Value + congruent_to: custom + alias_set: custom - name: SetArgumentsObjectArg - gen_boilerplate: false + operands: + argsObject: Object + value: Value + arguments: + argno: size_t + alias_set: custom # Load |arguments[index]| from a mapped or unmapped arguments object. Bails out # if any elements were overridden or deleted. Also bails out if the index is @@ -369,8 +444,18 @@ # property read. alias_set: custom +# Guard that the given flags are not set on the arguments object. - name: GuardArgumentsObjectFlags - gen_boilerplate: false + operands: + argsObject: Object + arguments: + flags: uint32_t + result_type: Object + movable: true + guard: true + congruent_to: custom + # The flags are packed with the length in a fixed private slot. + alias_set: custom # Given a MIRType::Value A and a MIRType::Object B: # If the Value may be safely unboxed to an Object, return Object(A). @@ -705,10 +790,24 @@ can_recover: true - name: BoxNonStrictThis - gen_boilerplate: false + operands: + def: Value + arguments: + globalThis: JSObject* + result_type: Object + folds_to: custom + possibly_calls: true + # This instruction can allocate a new object for wrapped primitives, but + # has no effect on existing objects. + alias_set: none - name: ImplicitThis - gen_boilerplate: false + operands: + envChain: Object + arguments: + name: PropertyName* + result_type: Value + possibly_calls: true # Load an arrow function's |new.target| value. - name: ArrowNewTarget @@ -769,8 +868,13 @@ - name: LexicalCheck gen_boilerplate: false +# Unconditionally throw an uninitialized let error. - name: ThrowRuntimeLexicalError - gen_boilerplate: false + arguments: + errorNumber: unsigned + result_type: None + guard: true + alias_set: custom - name: ThrowMsg gen_boilerplate: false @@ -781,7 +885,12 @@ guard: true - name: RegExp - gen_boilerplate: false + arguments: + source: RegExpObject* + hasShared: bool + result_type: Object + possibly_calls: true + alias_set: none - name: RegExpMatcher operands: @@ -839,7 +948,9 @@ alias_set: none - name: ModuleMetadata - gen_boilerplate: false + arguments: + module: JSObject* + result_type: Object - name: DynamicImport operands: @@ -856,7 +967,13 @@ gen_boilerplate: false - name: SetFunName - gen_boilerplate: false + operands: + fun: Object + name: Value + arguments: + prefixKind: uint8_t + result_type: None + possibly_calls: true # Returns obj->slots. - name: Slots @@ -898,7 +1015,6 @@ alias_set: custom clone: true - # Load the array length from an elements header. - name: ArrayLength operands: @@ -911,7 +1027,6 @@ compute_range: custom clone: true - # Store to the length in an elements header. Note the input is an *index*, one # less than the desired length. - name: SetArrayLength @@ -1063,8 +1178,17 @@ compute_range: custom clone: true +# Array.prototype.slice on a dense array. - name: ArraySlice - gen_boilerplate: false + operands: + object: Object + begin: Int32 + end: Int32 + arguments: + templateObj: JSObject* + initialHeap: gc::InitialHeap + result_type: Object + possibly_calls: true # MArrayJoin doesn't override |getAliasSet()|, because Array.prototype.join # might coerce the elements of the Array to strings. This coercion might @@ -1144,7 +1268,16 @@ alias_set: none - name: GuardShape - gen_boilerplate: false + operands: + object: Object + arguments: + shape: Shape* + result_type: Object + guard: true + movable: true + congruent_to: custom + folds_to: custom + alias_set: custom - name: GuardProto gen_boilerplate: false @@ -1191,7 +1324,12 @@ alias_set: none - name: ProxyGet - gen_boilerplate: false + operands: + proxy: Object + arguments: + id: jsid + result_type: Value + possibly_calls: true - name: ProxyGetByValue operands: @@ -1201,19 +1339,52 @@ possibly_calls: true - name: ProxyHasProp - gen_boilerplate: false + operands: + proxy: Object + idVal: Value + arguments: + hasOwn: bool + result_type: Boolean + possibly_calls: true - name: ProxySet - gen_boilerplate: false + operands: + proxy: Object + rhs: Value + arguments: + id: jsid + strict: bool + possibly_calls: true - name: ProxySetByValue - gen_boilerplate: false + operands: + proxy: Object + idVal: Value + rhs: Value + arguments: + strict: bool + possibly_calls: true - name: CallSetArrayLength - gen_boilerplate: false + operands: + obj: Object + rhs: Value + arguments: + strict: bool + possibly_calls: true - name: MegamorphicLoadSlot - gen_boilerplate: false + operands: + object: Object + arguments: + name: PropertyName* + result_type: Value + # Bails when non-native or accessor properties are encountered, so we can't + # DCE this instruction. + guard: true + possibly_calls: true + congruent_to: custom + alias_set: custom - name: MegamorphicLoadSlotByValue operands: @@ -1228,10 +1399,28 @@ possibly_calls: true - name: MegamorphicStoreSlot - gen_boilerplate: false + operands: + object: Object + rhs: Value + arguments: + name: PropertyName* + congruent_to: custom + alias_set: custom + possibly_calls: true - name: MegamorphicHasProp - gen_boilerplate: false + operands: + object: Object + idVal: Value + arguments: + hasOwn: bool + result_type: Boolean + # Bails when non-native or accessor properties are encountered, so we can't + # DCE this instruction. + guard: true + congruent_to: custom + alias_set: custom + possibly_calls: true - name: GuardIsNotArrayBufferMaybeShared operands: @@ -1252,8 +1441,16 @@ congruent_to: if_operands_equal alias_set: none +# Loads a specific JSObject* that was originally nursery-allocated. +# See also WarpObjectField. - name: NurseryObject - gen_boilerplate: false + arguments: + # Index in the Vector of objects stored in the WarpSnapshot. + nurseryIndex: uint32_t + result_type: Object + movable: true + congruent_to: custom + alias_set: none - name: GuardValue gen_boilerplate: false @@ -1281,10 +1478,33 @@ alias_set: custom - name: GuardFunctionKind - gen_boilerplate: false + operands: + function: Object + arguments: + expected: FunctionFlags::FunctionKind + bailOnEquality: bool + result_type: Object + guard: true + movable: true + congruent_to: custom + alias_set: custom - name: GuardFunctionScript - gen_boilerplate: false + operands: + function: Object + arguments: + expected: BaseScript* + nargs: uint16_t + flags: FunctionFlags + result_type: Object + guard: true + movable: true + folds_to: custom + congruent_to: custom + # A JSFunction's BaseScript pointer is immutable. Relazification of + # self-hosted functions is an exception to this, but we don't use this + # guard for self-hosted functions. + alias_set: custom - name: GuardObjectIdentity gen_boilerplate: false @@ -1293,7 +1513,16 @@ gen_boilerplate: false - name: GuardSpecificAtom - gen_boilerplate: false + operands: + str: String + arguments: + atom: JSAtom* + result_type: String + guard: true + movable: true + congruent_to: custom + folds_to: custom + alias_set: none - name: GuardSpecificSymbol gen_boilerplate: false @@ -1362,11 +1591,25 @@ - name: NewLexicalEnvironmentObject gen_boilerplate: false +# Allocate a new ClassBodyEnvironmentObject. - name: NewClassBodyEnvironmentObject - gen_boilerplate: false + operands: + enclosing: Object + arguments: + scope: ClassBodyScope* + result_type: Object + possibly_calls: true + alias_set: none +# Allocate a new BlockLexicalEnvironmentObject from an existing one. - name: CopyLexicalEnvironmentObject - gen_boilerplate: false + operands: + env: Object + arguments: + copySlots: bool + result_type: Object + possibly_calls: true + alias_set: custom - name: HomeObject operands: @@ -1380,7 +1623,15 @@ gen_boilerplate: false - name: AllocateAndStoreSlot - gen_boilerplate: false + operands: + object: Object + value: Value + arguments: + slotOffset: uint32_t + shape: Shape* + numNewSlots: uint32_t + possibly_calls: true + alias_set: custom - name: StoreDynamicSlot gen_boilerplate: false @@ -1391,13 +1642,27 @@ result_type: Value - name: CallGetIntrinsicValue - gen_boilerplate: false + arguments: + name: PropertyName* + result_type: Value + possibly_calls: true + alias_set: none - name: DeleteProperty - gen_boilerplate: false + operands: + value: Value + arguments: + name: PropertyName* + strict: bool + result_type: Boolean - name: DeleteElement - gen_boilerplate: false + operands: + value: Value + index: Value + arguments: + strict: bool + result_type: Boolean - name: SetPropertyCache gen_boilerplate: false @@ -1437,8 +1702,18 @@ congruent_to: if_operands_equal alias_set: custom +# Takes an expando Value as input, then guards it's either UndefinedValue or +# an object with the expected shape. - name: GuardDOMExpandoMissingOrGuardShape - gen_boilerplate: false + operands: + expando: Value + arguments: + shape: Shape* + result_type: Value + guard: true + movable: true + congruent_to: custom + alias_set: custom - name: StringLength operands: @@ -1546,7 +1821,14 @@ alias_set: none - name: Rest - gen_boilerplate: false + operands: + numActuals: Int32 + arguments: + numFormals: unsigned + shape: Shape* + result_type: Object + possibly_calls: true + alias_set: none - name: PostWriteBarrier gen_boilerplate: false @@ -1555,7 +1837,10 @@ gen_boilerplate: false - name: NewNamedLambdaObject - gen_boilerplate: false + arguments: + templateObj: NamedLambdaObject* + result_type: Object + alias_set: none - name: NewCallObject gen_boilerplate: false @@ -1641,7 +1926,12 @@ alias_set: none - name: AsyncResolve - gen_boilerplate: false + operands: + generator: Object + valueOrReason: Value + arguments: + resolveKind: AsyncFunctionResolveKind + result_type: Object # Returns from this function to the previous caller; this looks like a regular # Unary instruction and is used to lie to the MIR generator about suspending @@ -1679,7 +1969,9 @@ gen_boilerplate: false - name: IncrementWarmUpCounter - gen_boilerplate: false + arguments: + script: JSScript* + alias_set: none - name: AtomicIsLockFree gen_boilerplate: false @@ -1697,7 +1989,14 @@ gen_boilerplate: false - name: CheckIsObj - gen_boilerplate: false + operands: + value: Value + arguments: + checkKind: uint8_t + result_type: Object + guard: true + folds_to: custom + alias_set: none - name: CheckObjCoercible operands: @@ -1761,7 +2060,10 @@ gen_boilerplate: false - name: BuiltinObject - gen_boilerplate: false + arguments: + builtinObjectKind: BuiltinObjectKind + result_type: Object + possibly_calls: true - name: SuperFunction operands: @@ -1809,8 +2111,19 @@ # TODO: Investigate using a narrower or a custom alias set. alias_set: custom +# Guard the accessor shape is present on the object or its prototype chain. - name: GuardHasGetterSetter - gen_boilerplate: false + operands: + object: Object + arguments: + propId: jsid + getterSetter: GetterSetter* + result_type: Object + guard: true + movable: true + possibly_calls: true + congruent_to: custom + alias_set: custom - name: GuardIsExtensible operands: @@ -1855,8 +2168,17 @@ congruent_to: if_operands_equal alias_set: custom +# Add or update a sparse element of an array object. It's allowed for the +# sparse element to be already present on the array. It may also be an accessor +# property, so this instruction is always marked as effectful. - name: CallAddOrUpdateSparseElement - gen_boilerplate: false + operands: + object: Object + index: Int32 + value: Value + arguments: + strict: bool + possibly_calls: true # Get a sparse element from an array object, possibly by calling an accessor # property. @@ -2036,17 +2358,48 @@ - name: WasmBinarySimd128WithConstant gen_boilerplate: false +# (v128, i32) -> v128 effect-free shift operations. - name: WasmShiftSimd128 - gen_boilerplate: false + operands: + lhs: Simd128 + rhs: Int32 + arguments: + simdOp: wasm::SimdOp + type_policy: none + result_type: Simd128 + movable: true + congruent_to: custom + alias_set: none + clone: true +# (v128, v128, mask) -> v128 effect-free operation. - name: WasmShuffleSimd128 - gen_boilerplate: false + operands: + lhs: Simd128 + rhs: Simd128 + arguments: + control: SimdConstant + type_policy: none + result_type: Simd128 + movable: true + congruent_to: custom + alias_set: none + clone: true - name: WasmReplaceLaneSimd128 gen_boilerplate: false - name: WasmUnarySimd128 - gen_boilerplate: false + operands: + src: Simd128 + arguments: + simdOp: wasm::SimdOp + type_policy: none + result_type: Simd128 + movable: true + congruent_to: custom + alias_set: none + clone: true - name: WasmScalarToSimd128 gen_boilerplate: false diff --git a/js/src/jit/ScalarReplacement.cpp b/js/src/jit/ScalarReplacement.cpp index ff9ccdc9aefc..f54147d89a35 100644 --- a/js/src/jit/ScalarReplacement.cpp +++ b/js/src/jit/ScalarReplacement.cpp @@ -1559,7 +1559,7 @@ void ArgumentsReplacer::visitGuardToClass(MGuardToClass* ins) { void ArgumentsReplacer::visitGuardArgumentsObjectFlags( MGuardArgumentsObjectFlags* ins) { // Skip other arguments objects. - if (ins->getArgsObject() != args_) { + if (ins->argsObject() != args_) { return; } @@ -1610,7 +1610,7 @@ void ArgumentsReplacer::visitUnbox(MUnbox* ins) { void ArgumentsReplacer::visitGetArgumentsObjectArg( MGetArgumentsObjectArg* ins) { // Skip other arguments objects. - if (ins->getArgsObject() != args_) { + if (ins->argsObject() != args_) { return; } diff --git a/js/src/jit/WarpBuilder.cpp b/js/src/jit/WarpBuilder.cpp index f140764c6abd..7f09df7f798a 100644 --- a/js/src/jit/WarpBuilder.cpp +++ b/js/src/jit/WarpBuilder.cpp @@ -966,7 +966,7 @@ bool WarpBuilder::build_SetArg(BytecodeLocation loc) { // must go through the arguments object. MDefinition* argsObj = current->argumentsObject(); current->add(MPostWriteBarrier::New(alloc(), argsObj, val)); - auto* ins = MSetArgumentsObjectArg::New(alloc(), argsObj, arg, val); + auto* ins = MSetArgumentsObjectArg::New(alloc(), argsObj, val, arg); current->add(ins); return resumeAfter(ins, loc); } @@ -2525,7 +2525,7 @@ bool WarpBuilder::buildInitPropGetterSetterOp(BytecodeLocation loc) { MDefinition* value = current->pop(); MDefinition* obj = current->peek(-1); - auto* ins = MInitPropGetterSetter::New(alloc(), obj, name, value); + auto* ins = MInitPropGetterSetter::New(alloc(), obj, value, name); current->add(ins); return resumeAfter(ins, loc); } diff --git a/js/src/jit/WarpCacheIRTranspiler.cpp b/js/src/jit/WarpCacheIRTranspiler.cpp index 1677f6e9ff4d..00737a3de625 100644 --- a/js/src/jit/WarpCacheIRTranspiler.cpp +++ b/js/src/jit/WarpCacheIRTranspiler.cpp @@ -508,7 +508,7 @@ bool WarpCacheIRTranspiler::emitProxySet(ObjOperandId objId, uint32_t idOffset, jsid id = idStubField(idOffset); MDefinition* rhs = getOperand(rhsId); - auto* ins = MProxySet::New(alloc(), obj, id, rhs, strict); + auto* ins = MProxySet::New(alloc(), obj, rhs, id, strict); addEffectful(ins); return resumeAfter(ins); @@ -663,7 +663,7 @@ bool WarpCacheIRTranspiler::emitMegamorphicStoreSlot(ObjOperandId objId, PropertyName* name = stringStubField(nameOffset)->asAtom().asPropertyName(); MDefinition* rhs = getOperand(rhsId); - auto* ins = MMegamorphicStoreSlot::New(alloc(), obj, name, rhs); + auto* ins = MMegamorphicStoreSlot::New(alloc(), obj, rhs, name); addEffectful(ins); return resumeAfter(ins); @@ -3577,7 +3577,7 @@ bool WarpCacheIRTranspiler::emitNewArrayFromLengthResult( } } - auto* obj = MNewArrayDynamicLength::New(alloc(), templateObj, heap, length); + auto* obj = MNewArrayDynamicLength::New(alloc(), length, templateObj, heap); addEffectful(obj); pushResult(obj); return resumeAfter(obj); @@ -3604,7 +3604,7 @@ bool WarpCacheIRTranspiler::emitNewTypedArrayFromLengthResult( } auto* obj = - MNewTypedArrayDynamicLength::New(alloc(), templateObj, heap, length); + MNewTypedArrayDynamicLength::New(alloc(), length, templateObj, heap); addEffectful(obj); pushResult(obj); return resumeAfter(obj); @@ -3621,8 +3621,8 @@ bool WarpCacheIRTranspiler::emitNewTypedArrayFromArrayBufferResult( // TODO: support pre-tenuring. gc::InitialHeap heap = gc::DefaultHeap; - auto* obj = MNewTypedArrayFromArrayBuffer::New(alloc(), templateObj, heap, - buffer, byteOffset, length); + auto* obj = MNewTypedArrayFromArrayBuffer::New(alloc(), buffer, byteOffset, + length, templateObj, heap); addEffectful(obj); pushResult(obj); @@ -3637,7 +3637,7 @@ bool WarpCacheIRTranspiler::emitNewTypedArrayFromArrayResult( // TODO: support pre-tenuring. gc::InitialHeap heap = gc::DefaultHeap; - auto* obj = MNewTypedArrayFromArray::New(alloc(), templateObj, heap, array); + auto* obj = MNewTypedArrayFromArray::New(alloc(), array, templateObj, heap); addEffectful(obj); pushResult(obj);