diff options
author | wolfbeast <mcwerewolf@wolfbeast.com> | 2019-12-22 01:23:56 +0100 |
---|---|---|
committer | wolfbeast <mcwerewolf@wolfbeast.com> | 2019-12-22 01:26:49 +0100 |
commit | 54091ecab46c93c2e1b2c689e9179a980beaabe6 (patch) | |
tree | 5cead66d889007e1b06c5dbb8e3d37b2538d0557 /js/src/jit | |
parent | c1013e9122456b342d65e4eb4c38a7281d8d83d2 (diff) | |
parent | 492624a7106ecbc18994b465ca1dd23fa472bf7e (diff) | |
download | UXP-54091ecab46c93c2e1b2c689e9179a980beaabe6.tar UXP-54091ecab46c93c2e1b2c689e9179a980beaabe6.tar.gz UXP-54091ecab46c93c2e1b2c689e9179a980beaabe6.tar.lz UXP-54091ecab46c93c2e1b2c689e9179a980beaabe6.tar.xz UXP-54091ecab46c93c2e1b2c689e9179a980beaabe6.zip |
Forward to new tree structure.
Diffstat (limited to 'js/src/jit')
-rw-r--r-- | js/src/jit/BaselineCompiler.cpp | 94 | ||||
-rw-r--r-- | js/src/jit/BaselineCompiler.h | 11 | ||||
-rw-r--r-- | js/src/jit/BaselineIC.cpp | 13 | ||||
-rw-r--r-- | js/src/jit/BaselineJIT.cpp | 6 | ||||
-rw-r--r-- | js/src/jit/BaselineJIT.h | 2 | ||||
-rw-r--r-- | js/src/jit/CodeGenerator.cpp | 23 | ||||
-rw-r--r-- | js/src/jit/CodeGenerator.h | 2 | ||||
-rw-r--r-- | js/src/jit/InlinableNatives.h | 1 | ||||
-rw-r--r-- | js/src/jit/Ion.cpp | 11 | ||||
-rw-r--r-- | js/src/jit/IonAnalysis.cpp | 40 | ||||
-rw-r--r-- | js/src/jit/IonAnalysis.h | 7 | ||||
-rw-r--r-- | js/src/jit/IonBuilder.cpp | 40 | ||||
-rw-r--r-- | js/src/jit/IonBuilder.h | 2 | ||||
-rw-r--r-- | js/src/jit/IonCaches.cpp | 5 | ||||
-rw-r--r-- | js/src/jit/Lowering.cpp | 16 | ||||
-rw-r--r-- | js/src/jit/Lowering.h | 2 | ||||
-rw-r--r-- | js/src/jit/MCallOptimize.cpp | 2 | ||||
-rw-r--r-- | js/src/jit/MIR.h | 30 | ||||
-rw-r--r-- | js/src/jit/MOpcodes.h | 2 | ||||
-rw-r--r-- | js/src/jit/VMFunctions.cpp | 4 | ||||
-rw-r--r-- | js/src/jit/arm/MacroAssembler-arm.cpp | 4 | ||||
-rw-r--r-- | js/src/jit/shared/LIR-shared.h | 26 | ||||
-rw-r--r-- | js/src/jit/shared/LOpcodes-shared.h | 2 |
23 files changed, 279 insertions, 66 deletions
diff --git a/js/src/jit/BaselineCompiler.cpp b/js/src/jit/BaselineCompiler.cpp index b2f9d3b23..d254b9826 100644 --- a/js/src/jit/BaselineCompiler.cpp +++ b/js/src/jit/BaselineCompiler.cpp @@ -25,6 +25,7 @@ #include "jit/VMFunctions.h" #include "js/UniquePtr.h" #include "vm/AsyncFunction.h" +#include "vm/AsyncIteration.h" #include "vm/EnvironmentObject.h" #include "vm/Interpreter.h" #include "vm/TraceLogging.h" @@ -43,7 +44,7 @@ using mozilla::AssertedCast; BaselineCompiler::BaselineCompiler(JSContext* cx, TempAllocator& alloc, JSScript* script) : BaselineCompilerSpecific(cx, alloc, script), - yieldOffsets_(cx), + yieldAndAwaitOffsets_(cx), modifiesArguments_(false) { } @@ -210,7 +211,7 @@ BaselineCompiler::compile() pcMappingIndexEntries.length(), pcEntries.length(), bytecodeTypeMapEntries, - yieldOffsets_.length(), + yieldAndAwaitOffsets_.length(), traceLoggerToggleOffsets_.length()), JS::DeletePolicy<BaselineScript>(cx->runtime())); if (!baselineScript) { @@ -275,7 +276,7 @@ BaselineCompiler::compile() // searches for the sought entry when queries are in linear order. bytecodeMap[script->nTypeSets()] = 0; - baselineScript->copyYieldEntries(script, yieldOffsets_); + baselineScript->copyYieldAndAwaitEntries(script, yieldAndAwaitOffsets_); if (compileDebugInstrumentation_) baselineScript->setHasDebugInstrumentation(); @@ -3908,6 +3909,50 @@ BaselineCompiler::emit_JSOP_TOASYNC() return true; } +typedef JSObject* (*ToAsyncGenFn)(JSContext*, HandleFunction); +static const VMFunction ToAsyncGenInfo = + FunctionInfo<ToAsyncGenFn>(js::WrapAsyncGenerator, "ToAsyncGen"); + +bool +BaselineCompiler::emit_JSOP_TOASYNCGEN() +{ + frame.syncStack(0); + masm.unboxObject(frame.addressOfStackValue(frame.peek(-1)), R0.scratchReg()); + + prepareVMCall(); + pushArg(R0.scratchReg()); + + if (!callVM(ToAsyncGenInfo)) + return false; + + masm.tagValue(JSVAL_TYPE_OBJECT, ReturnReg, R0); + frame.pop(); + frame.push(R0); + return true; +} + +typedef JSObject* (*ToAsyncIterFn)(JSContext*, HandleObject); +static const VMFunction ToAsyncIterInfo = + FunctionInfo<ToAsyncIterFn>(js::CreateAsyncFromSyncIterator, "ToAsyncIter"); + +bool +BaselineCompiler::emit_JSOP_TOASYNCITER() +{ + frame.syncStack(0); + masm.unboxObject(frame.addressOfStackValue(frame.peek(-1)), R0.scratchReg()); + + prepareVMCall(); + pushArg(R0.scratchReg()); + + if (!callVM(ToAsyncIterInfo)) + return false; + + masm.tagValue(JSVAL_TYPE_OBJECT, ReturnReg, R0); + frame.pop(); + frame.push(R0); + return true; +} + typedef bool (*ThrowObjectCoercibleFn)(JSContext*, HandleValue); static const VMFunction ThrowObjectCoercibleInfo = FunctionInfo<ThrowObjectCoercibleFn>(ThrowObjectCoercible, "ThrowObjectCoercible"); @@ -4174,27 +4219,28 @@ BaselineCompiler::emit_JSOP_GENERATOR() } bool -BaselineCompiler::addYieldOffset() +BaselineCompiler::addYieldAndAwaitOffset() { - MOZ_ASSERT(*pc == JSOP_INITIALYIELD || *pc == JSOP_YIELD); + MOZ_ASSERT(*pc == JSOP_INITIALYIELD || *pc == JSOP_YIELD || *pc == JSOP_AWAIT); - uint32_t yieldIndex = GET_UINT24(pc); + uint32_t yieldAndAwaitIndex = GET_UINT24(pc); - while (yieldIndex >= yieldOffsets_.length()) { - if (!yieldOffsets_.append(0)) + while (yieldAndAwaitIndex >= yieldAndAwaitOffsets_.length()) { + if (!yieldAndAwaitOffsets_.append(0)) return false; } - static_assert(JSOP_INITIALYIELD_LENGTH == JSOP_YIELD_LENGTH, - "code below assumes INITIALYIELD and YIELD have same length"); - yieldOffsets_[yieldIndex] = script->pcToOffset(pc + JSOP_YIELD_LENGTH); + static_assert(JSOP_INITIALYIELD_LENGTH == JSOP_YIELD_LENGTH && + JSOP_INITIALYIELD_LENGTH == JSOP_AWAIT_LENGTH, + "code below assumes INITIALYIELD and YIELD and AWAIT have same length"); + yieldAndAwaitOffsets_[yieldAndAwaitIndex] = script->pcToOffset(pc + JSOP_YIELD_LENGTH); return true; } bool BaselineCompiler::emit_JSOP_INITIALYIELD() { - if (!addYieldOffset()) + if (!addYieldAndAwaitOffset()) return false; frame.syncStack(0); @@ -4204,7 +4250,8 @@ BaselineCompiler::emit_JSOP_INITIALYIELD() masm.unboxObject(frame.addressOfStackValue(frame.peek(-1)), genObj); MOZ_ASSERT(GET_UINT24(pc) == 0); - masm.storeValue(Int32Value(0), Address(genObj, GeneratorObject::offsetOfYieldIndexSlot())); + masm.storeValue(Int32Value(0), + Address(genObj, GeneratorObject::offsetOfYieldAndAwaitIndexSlot())); Register envObj = R0.scratchReg(); Address envChainSlot(genObj, GeneratorObject::offsetOfEnvironmentChainSlot()); @@ -4233,7 +4280,7 @@ static const VMFunction NormalSuspendInfo = bool BaselineCompiler::emit_JSOP_YIELD() { - if (!addYieldOffset()) + if (!addYieldAndAwaitOffset()) return false; // Store generator in R0. @@ -4250,7 +4297,7 @@ BaselineCompiler::emit_JSOP_YIELD() // generator is in the closing state, see GeneratorObject::suspend. masm.storeValue(Int32Value(GET_UINT24(pc)), - Address(genObj, GeneratorObject::offsetOfYieldIndexSlot())); + Address(genObj, GeneratorObject::offsetOfYieldAndAwaitIndexSlot())); Register envObj = R0.scratchReg(); Address envChainSlot(genObj, GeneratorObject::offsetOfEnvironmentChainSlot()); @@ -4282,6 +4329,12 @@ BaselineCompiler::emit_JSOP_YIELD() return emitReturn(); } +bool +BaselineCompiler::emit_JSOP_AWAIT() +{ + return emit_JSOP_YIELD(); +} + typedef bool (*DebugAfterYieldFn)(JSContext*, BaselineFrame*); static const VMFunction DebugAfterYieldInfo = FunctionInfo<DebugAfterYieldFn>(jit::DebugAfterYield, "DebugAfterYield"); @@ -4501,16 +4554,17 @@ BaselineCompiler::emit_JSOP_RESUME() masm.pushValue(retVal); if (resumeKind == GeneratorObject::NEXT) { - // Determine the resume address based on the yieldIndex and the - // yieldIndex -> native table in the BaselineScript. + // Determine the resume address based on the yieldAndAwaitIndex and the + // yieldAndAwaitIndex -> native table in the BaselineScript. masm.load32(Address(scratch1, BaselineScript::offsetOfYieldEntriesOffset()), scratch2); masm.addPtr(scratch2, scratch1); - masm.unboxInt32(Address(genObj, GeneratorObject::offsetOfYieldIndexSlot()), scratch2); + masm.unboxInt32(Address(genObj, GeneratorObject::offsetOfYieldAndAwaitIndexSlot()), + scratch2); masm.loadPtr(BaseIndex(scratch1, scratch2, ScaleFromElemWidth(sizeof(uintptr_t))), scratch1); // Mark as running and jump to the generator's JIT code. - masm.storeValue(Int32Value(GeneratorObject::YIELD_INDEX_RUNNING), - Address(genObj, GeneratorObject::offsetOfYieldIndexSlot())); + masm.storeValue(Int32Value(GeneratorObject::YIELD_AND_AWAIT_INDEX_RUNNING), + Address(genObj, GeneratorObject::offsetOfYieldAndAwaitIndexSlot())); masm.jump(scratch1); } else { MOZ_ASSERT(resumeKind == GeneratorObject::THROW || resumeKind == GeneratorObject::CLOSE); diff --git a/js/src/jit/BaselineCompiler.h b/js/src/jit/BaselineCompiler.h index 95e0c77ad..a200f7ab9 100644 --- a/js/src/jit/BaselineCompiler.h +++ b/js/src/jit/BaselineCompiler.h @@ -196,6 +196,8 @@ namespace jit { _(JSOP_RUNONCE) \ _(JSOP_REST) \ _(JSOP_TOASYNC) \ + _(JSOP_TOASYNCGEN) \ + _(JSOP_TOASYNCITER) \ _(JSOP_TOID) \ _(JSOP_TOSTRING) \ _(JSOP_TABLESWITCH) \ @@ -207,6 +209,7 @@ namespace jit { _(JSOP_GENERATOR) \ _(JSOP_INITIALYIELD) \ _(JSOP_YIELD) \ + _(JSOP_AWAIT) \ _(JSOP_DEBUGAFTERYIELD) \ _(JSOP_FINALYIELDRVAL) \ _(JSOP_RESUME) \ @@ -255,9 +258,9 @@ class BaselineCompiler : public BaselineCompilerSpecific // equivalent positions when debug mode is off. CodeOffset postDebugPrologueOffset_; - // For each INITIALYIELD or YIELD op, this Vector maps the yield index - // to the bytecode offset of the next op. - Vector<uint32_t> yieldOffsets_; + // For each INITIALYIELD or YIELD or AWAIT op, this Vector maps the yield + // index to the bytecode offset of the next op. + Vector<uint32_t> yieldAndAwaitOffsets_; // Whether any on stack arguments are modified. bool modifiesArguments_; @@ -349,7 +352,7 @@ class BaselineCompiler : public BaselineCompilerSpecific MOZ_MUST_USE bool addPCMappingEntry(bool addIndexEntry); - MOZ_MUST_USE bool addYieldOffset(); + MOZ_MUST_USE bool addYieldAndAwaitOffset(); void getEnvironmentCoordinateObject(Register reg); Address getEnvironmentCoordinateAddressFromObject(Register objReg, Register reg); diff --git a/js/src/jit/BaselineIC.cpp b/js/src/jit/BaselineIC.cpp index a001357f8..e65f10aac 100644 --- a/js/src/jit/BaselineIC.cpp +++ b/js/src/jit/BaselineIC.cpp @@ -4053,9 +4053,6 @@ TryAttachSetValuePropStub(JSContext* cx, HandleScript script, jsbytecode* pc, IC { MOZ_ASSERT(!*attached); - if (obj->watched()) - return true; - RootedShape shape(cx); RootedObject holder(cx); if (!EffectlesslyLookupProperty(cx, obj, id, &holder, &shape)) @@ -4151,9 +4148,6 @@ TryAttachSetAccessorPropStub(JSContext* cx, HandleScript script, jsbytecode* pc, MOZ_ASSERT(!*attached); MOZ_ASSERT(!*isTemporarilyUnoptimizable); - if (obj->watched()) - return true; - RootedShape shape(cx); RootedObject holder(cx); if (!EffectlesslyLookupProperty(cx, obj, id, &holder, &shape)) @@ -6606,12 +6600,13 @@ ICCall_IsSuspendedStarGenerator::Compiler::generateStubCode(MacroAssembler& masm masm.branchTestObjClass(Assembler::NotEqual, genObj, scratch, &StarGeneratorObject::class_, &returnFalse); - // If the yield index slot holds an int32 value < YIELD_INDEX_CLOSING, + // If the yield index slot holds an int32 value < YIELD_AND_AWAIT_INDEX_CLOSING, // the generator is suspended. - masm.loadValue(Address(genObj, GeneratorObject::offsetOfYieldIndexSlot()), argVal); + masm.loadValue(Address(genObj, GeneratorObject::offsetOfYieldAndAwaitIndexSlot()), argVal); masm.branchTestInt32(Assembler::NotEqual, argVal, &returnFalse); masm.unboxInt32(argVal, scratch); - masm.branch32(Assembler::AboveOrEqual, scratch, Imm32(StarGeneratorObject::YIELD_INDEX_CLOSING), + masm.branch32(Assembler::AboveOrEqual, scratch, + Imm32(StarGeneratorObject::YIELD_AND_AWAIT_INDEX_CLOSING), &returnFalse); masm.moveValue(BooleanValue(true), R0); diff --git a/js/src/jit/BaselineJIT.cpp b/js/src/jit/BaselineJIT.cpp index 5c21926b5..94e018252 100644 --- a/js/src/jit/BaselineJIT.cpp +++ b/js/src/jit/BaselineJIT.cpp @@ -760,12 +760,12 @@ BaselineScript::icEntryFromReturnAddress(uint8_t* returnAddr) } void -BaselineScript::copyYieldEntries(JSScript* script, Vector<uint32_t>& yieldOffsets) +BaselineScript::copyYieldAndAwaitEntries(JSScript* script, Vector<uint32_t>& yieldAndAwaitOffsets) { uint8_t** entries = yieldEntryList(); - for (size_t i = 0; i < yieldOffsets.length(); i++) { - uint32_t offset = yieldOffsets[i]; + for (size_t i = 0; i < yieldAndAwaitOffsets.length(); i++) { + uint32_t offset = yieldAndAwaitOffsets[i]; entries[i] = nativeCodeForPC(script, script->offsetToPC(offset)); } } diff --git a/js/src/jit/BaselineJIT.h b/js/src/jit/BaselineJIT.h index 5e7775a61..b6ccd2ff9 100644 --- a/js/src/jit/BaselineJIT.h +++ b/js/src/jit/BaselineJIT.h @@ -397,7 +397,7 @@ struct BaselineScript void copyICEntries(JSScript* script, const BaselineICEntry* entries, MacroAssembler& masm); void adoptFallbackStubs(FallbackICStubSpace* stubSpace); - void copyYieldEntries(JSScript* script, Vector<uint32_t>& yieldOffsets); + void copyYieldAndAwaitEntries(JSScript* script, Vector<uint32_t>& yieldAndAwaitOffsets); PCMappingIndexEntry& pcMappingIndexEntry(size_t index); CompactBufferReader pcMappingReader(size_t indexEntry); diff --git a/js/src/jit/CodeGenerator.cpp b/js/src/jit/CodeGenerator.cpp index 205812942..2b1c671d1 100644 --- a/js/src/jit/CodeGenerator.cpp +++ b/js/src/jit/CodeGenerator.cpp @@ -41,6 +41,7 @@ #include "jit/RangeAnalysis.h" #include "jit/SharedICHelpers.h" #include "vm/AsyncFunction.h" +#include "vm/AsyncIteration.h" #include "vm/MatchPairs.h" #include "vm/RegExpObject.h" #include "vm/RegExpStatics.h" @@ -10213,6 +10214,28 @@ CodeGenerator::visitToAsync(LToAsync* lir) callVM(ToAsyncInfo, lir); } +typedef JSObject* (*ToAsyncGenFn)(JSContext*, HandleFunction); +static const VMFunction ToAsyncGenInfo = + FunctionInfo<ToAsyncGenFn>(js::WrapAsyncGenerator, "ToAsyncGen"); + +void +CodeGenerator::visitToAsyncGen(LToAsyncGen* lir) +{ + pushArg(ToRegister(lir->unwrapped())); + callVM(ToAsyncGenInfo, lir); +} + +typedef JSObject* (*ToAsyncIterFn)(JSContext*, HandleObject); +static const VMFunction ToAsyncIterInfo = + FunctionInfo<ToAsyncIterFn>(js::CreateAsyncFromSyncIterator, "ToAsyncIter"); + +void +CodeGenerator::visitToAsyncIter(LToAsyncIter* lir) +{ + pushArg(ToRegister(lir->unwrapped())); + callVM(ToAsyncIterInfo, lir); +} + typedef bool (*ToIdFn)(JSContext*, HandleScript, jsbytecode*, HandleValue, MutableHandleValue); static const VMFunction ToIdInfo = FunctionInfo<ToIdFn>(ToIdOperation, "ToIdOperation"); diff --git a/js/src/jit/CodeGenerator.h b/js/src/jit/CodeGenerator.h index 12f1238ef..65acfe274 100644 --- a/js/src/jit/CodeGenerator.h +++ b/js/src/jit/CodeGenerator.h @@ -286,6 +286,8 @@ class CodeGenerator final : public CodeGeneratorSpecific void visitTypeOfV(LTypeOfV* lir); void visitOutOfLineTypeOfV(OutOfLineTypeOfV* ool); void visitToAsync(LToAsync* lir); + void visitToAsyncGen(LToAsyncGen* lir); + void visitToAsyncIter(LToAsyncIter* lir); void visitToIdV(LToIdV* lir); template<typename T> void emitLoadElementT(LLoadElementT* lir, const T& source); void visitLoadElementT(LLoadElementT* lir); diff --git a/js/src/jit/InlinableNatives.h b/js/src/jit/InlinableNatives.h index 1d0506f74..9c864515d 100644 --- a/js/src/jit/InlinableNatives.h +++ b/js/src/jit/InlinableNatives.h @@ -119,7 +119,6 @@ _(IntrinsicGuardToArrayIterator) \ _(IntrinsicGuardToMapIterator) \ _(IntrinsicGuardToSetIterator) \ - _(IntrinsicIsListIterator) \ _(IntrinsicGuardToStringIterator) \ \ _(IntrinsicGuardToMapObject) \ diff --git a/js/src/jit/Ion.cpp b/js/src/jit/Ion.cpp index b8a2d2fba..9337f6150 100644 --- a/js/src/jit/Ion.cpp +++ b/js/src/jit/Ion.cpp @@ -2320,7 +2320,9 @@ IonCompile(JSContext* cx, JSScript* script, static bool CheckFrame(JSContext* cx, BaselineFrame* frame) { - MOZ_ASSERT(!frame->script()->isGenerator()); + MOZ_ASSERT(!frame->script()->isStarGenerator()); + MOZ_ASSERT(!frame->script()->isLegacyGenerator()); + MOZ_ASSERT(!frame->script()->isAsync()); MOZ_ASSERT(!frame->isDebuggerEvalFrame()); MOZ_ASSERT(!frame->isEvalFrame()); @@ -2351,11 +2353,16 @@ CheckScript(JSContext* cx, JSScript* script, bool osr) return false; } - if (script->isGenerator()) { + if (script->isStarGenerator() || script->isLegacyGenerator()) { TrackAndSpewIonAbort(cx, script, "generator script"); return false; } + if (script->isAsync()) { + TrackAndSpewIonAbort(cx, script, "async script"); + return false; + } + if (script->hasNonSyntacticScope() && !script->functionNonDelazifying()) { // Support functions with a non-syntactic global scope but not other // scripts. For global scripts, IonBuilder currently uses the global diff --git a/js/src/jit/IonAnalysis.cpp b/js/src/jit/IonAnalysis.cpp index 5fc624fb1..a4724bca4 100644 --- a/js/src/jit/IonAnalysis.cpp +++ b/js/src/jit/IonAnalysis.cpp @@ -4005,7 +4005,7 @@ jit::ConvertLinearInequality(TempAllocator& alloc, MBasicBlock* block, const Lin } static bool -AnalyzePoppedThis(JSContext* cx, ObjectGroup* group, +AnalyzePoppedThis(JSContext* cx, DPAConstraintInfo& constraintInfo, ObjectGroup* group, MDefinition* thisValue, MInstruction* ins, bool definitelyExecuted, HandlePlainObject baseobj, Vector<TypeNewScript::Initializer>* initializerList, @@ -4046,7 +4046,12 @@ AnalyzePoppedThis(JSContext* cx, ObjectGroup* group, return true; RootedId id(cx, NameToId(setprop->name())); - if (!AddClearDefiniteGetterSetterForPrototypeChain(cx, group, id)) { + bool added = false; + if (!AddClearDefiniteGetterSetterForPrototypeChain(cx, constraintInfo, + group, id, &added)) { + return false; + } + if (!added) { // The prototype chain already contains a getter/setter for this // property, or type information is too imprecise. return true; @@ -4106,7 +4111,12 @@ AnalyzePoppedThis(JSContext* cx, ObjectGroup* group, if (!baseobj->lookup(cx, id) && !accessedProperties->append(get->name())) return false; - if (!AddClearDefiniteGetterSetterForPrototypeChain(cx, group, id)) { + bool added = false; + if (!AddClearDefiniteGetterSetterForPrototypeChain(cx, constraintInfo, + group, id, &added)) { + return false; + } + if (!added) { // The |this| value can escape if any property reads it does go // through a getter. return true; @@ -4132,8 +4142,11 @@ CmpInstructions(const void* a, const void* b) } bool -jit::AnalyzeNewScriptDefiniteProperties(JSContext* cx, HandleFunction fun, - ObjectGroup* group, HandlePlainObject baseobj, +jit::AnalyzeNewScriptDefiniteProperties(JSContext* cx, + DPAConstraintInfo& constraintInfo, + HandleFunction fun, + ObjectGroup* group, + HandlePlainObject baseobj, Vector<TypeNewScript::Initializer>* initializerList) { MOZ_ASSERT(cx->zone()->types.activeAnalysis); @@ -4293,7 +4306,7 @@ jit::AnalyzeNewScriptDefiniteProperties(JSContext* cx, HandleFunction fun, bool handled = false; size_t slotSpan = baseobj->slotSpan(); - if (!AnalyzePoppedThis(cx, group, thisValue, ins, definitelyExecuted, + if (!AnalyzePoppedThis(cx, constraintInfo, group, thisValue, ins, definitelyExecuted, baseobj, initializerList, &accessedProperties, &handled)) { return false; @@ -4312,7 +4325,6 @@ jit::AnalyzeNewScriptDefiniteProperties(JSContext* cx, HandleFunction fun, // contingent on the correct frames being inlined. Add constraints to // invalidate the definite properties if additional functions could be // called at the inline frame sites. - Vector<MBasicBlock*> exitBlocks(cx); for (MBasicBlockIterator block(graph.begin()); block != graph.end(); block++) { // Inlining decisions made after the last new property was added to // the object don't need to be frozen. @@ -4320,9 +4332,11 @@ jit::AnalyzeNewScriptDefiniteProperties(JSContext* cx, HandleFunction fun, break; if (MResumePoint* rp = block->callerResumePoint()) { if (block->numPredecessors() == 1 && block->getPredecessor(0) == rp->block()) { - JSScript* script = rp->block()->info().script(); - if (!AddClearDefiniteFunctionUsesInScript(cx, group, script, block->info().script())) + JSScript* caller = rp->block()->info().script(); + JSScript* callee = block->info().script(); + if (!constraintInfo.addInliningConstraint(caller, callee)) { return false; + } } } } @@ -4388,8 +4402,14 @@ jit::AnalyzeArgumentsUsage(JSContext* cx, JSScript* scriptArg) // direct eval is present. // // FIXME: Don't build arguments for ES6 generator expressions. - if (scriptArg->isDebuggee() || script->isGenerator() || script->bindingsAccessedDynamically()) + if (scriptArg->isDebuggee() || + script->isStarGenerator() || + script->isLegacyGenerator() || + script->isAsync() || + script->bindingsAccessedDynamically()) + { return true; + } if (!jit::IsIonEnabled(cx)) return true; diff --git a/js/src/jit/IonAnalysis.h b/js/src/jit/IonAnalysis.h index efd31415b..49bc0b591 100644 --- a/js/src/jit/IonAnalysis.h +++ b/js/src/jit/IonAnalysis.h @@ -196,8 +196,11 @@ MCompare* ConvertLinearInequality(TempAllocator& alloc, MBasicBlock* block, const LinearSum& sum); MOZ_MUST_USE bool -AnalyzeNewScriptDefiniteProperties(JSContext* cx, HandleFunction fun, - ObjectGroup* group, HandlePlainObject baseobj, +AnalyzeNewScriptDefiniteProperties(JSContext* cx, + DPAConstraintInfo& constraintInfo, + HandleFunction fun, + ObjectGroup* group, + HandlePlainObject baseobj, Vector<TypeNewScript::Initializer>* initializerList); MOZ_MUST_USE bool diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp index 2d053de5a..1e12f5dbe 100644 --- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -2130,6 +2130,12 @@ IonBuilder::inspectOpcode(JSOp op) case JSOP_TOASYNC: return jsop_toasync(); + case JSOP_TOASYNCGEN: + return jsop_toasyncgen(); + + case JSOP_TOASYNCITER: + return jsop_toasynciter(); + case JSOP_TOID: return jsop_toid(); @@ -3351,7 +3357,7 @@ IonBuilder::whileOrForInLoop(jssrcnote* sn) unsigned stackPhiCount; if (SN_TYPE(sn) == SRC_FOR_OF) - stackPhiCount = 2; + stackPhiCount = 3; else if (SN_TYPE(sn) == SRC_FOR_IN) stackPhiCount = 1; else @@ -8895,10 +8901,8 @@ IonBuilder::jsop_getimport(PropertyName* name) if (!emitted) { // This can happen if we don't have type information. - TypeSet::ObjectKey* staticKey = TypeSet::ObjectKey::get(targetEnv); TemporaryTypeSet* types = bytecodeTypes(pc); - BarrierKind barrier = PropertyReadNeedsTypeBarrier(analysisContext, constraints(), staticKey, - name, types, /* updateObserved = */ true); + BarrierKind barrier = BarrierKind::TypeSet; if (!loadStaticSlot(targetEnv, barrier, types, shape->slot())) return false; @@ -13198,6 +13202,34 @@ IonBuilder::jsop_toasync() } bool +IonBuilder::jsop_toasyncgen() +{ + MDefinition* unwrapped = current->pop(); + MOZ_ASSERT(unwrapped->type() == MIRType::Object); + + MToAsyncGen* ins = MToAsyncGen::New(alloc(), unwrapped); + + current->add(ins); + current->push(ins); + + return resumeAfter(ins); +} + +bool +IonBuilder::jsop_toasynciter() +{ + MDefinition* unwrapped = current->pop(); + MOZ_ASSERT(unwrapped->type() == MIRType::Object); + + MToAsyncIter* ins = MToAsyncIter::New(alloc(), unwrapped); + + current->add(ins); + current->push(ins); + + return resumeAfter(ins); +} + +bool IonBuilder::jsop_toid() { // No-op if the index is an integer. diff --git a/js/src/jit/IonBuilder.h b/js/src/jit/IonBuilder.h index 1f763a4f2..6a3b61232 100644 --- a/js/src/jit/IonBuilder.h +++ b/js/src/jit/IonBuilder.h @@ -762,6 +762,8 @@ class IonBuilder MOZ_MUST_USE bool jsop_globalthis(); MOZ_MUST_USE bool jsop_typeof(); MOZ_MUST_USE bool jsop_toasync(); + MOZ_MUST_USE bool jsop_toasyncgen(); + MOZ_MUST_USE bool jsop_toasynciter(); MOZ_MUST_USE bool jsop_toid(); MOZ_MUST_USE bool jsop_iter(uint8_t flags); MOZ_MUST_USE bool jsop_itermore(); diff --git a/js/src/jit/IonCaches.cpp b/js/src/jit/IonCaches.cpp index 48e0792bb..fb4291188 100644 --- a/js/src/jit/IonCaches.cpp +++ b/js/src/jit/IonCaches.cpp @@ -3232,7 +3232,7 @@ SetPropertyIC::tryAttachStub(JSContext* cx, HandleScript outerScript, IonScript* MOZ_ASSERT(!*emitted); MOZ_ASSERT(!*tryNativeAddSlot); - if (!canAttachStub() || obj->watched()) + if (!canAttachStub()) return true; // Fail cache emission if the object is frozen @@ -3897,9 +3897,6 @@ IsDenseElementSetInlineable(JSObject* obj, const Value& idval, const ConstantOrR if (!obj->is<ArrayObject>()) return false; - if (obj->watched()) - return false; - if (!idval.isInt32()) return false; diff --git a/js/src/jit/Lowering.cpp b/js/src/jit/Lowering.cpp index 22f1d5f70..108450983 100644 --- a/js/src/jit/Lowering.cpp +++ b/js/src/jit/Lowering.cpp @@ -1176,6 +1176,22 @@ LIRGenerator::visitToAsync(MToAsync* ins) } void +LIRGenerator::visitToAsyncGen(MToAsyncGen* ins) +{ + LToAsyncGen* lir = new(alloc()) LToAsyncGen(useRegisterAtStart(ins->input())); + defineReturn(lir, ins); + assignSafepoint(lir, ins); +} + +void +LIRGenerator::visitToAsyncIter(MToAsyncIter* ins) +{ + LToAsyncIter* lir = new(alloc()) LToAsyncIter(useRegisterAtStart(ins->input())); + defineReturn(lir, ins); + assignSafepoint(lir, ins); +} + +void LIRGenerator::visitToId(MToId* ins) { LToIdV* lir = new(alloc()) LToIdV(useBox(ins->input()), tempDouble()); diff --git a/js/src/jit/Lowering.h b/js/src/jit/Lowering.h index 9342ef471..81e6abbbb 100644 --- a/js/src/jit/Lowering.h +++ b/js/src/jit/Lowering.h @@ -121,6 +121,8 @@ class LIRGenerator : public LIRGeneratorSpecific void visitCompare(MCompare* comp); void visitTypeOf(MTypeOf* ins); void visitToAsync(MToAsync* ins); + void visitToAsyncGen(MToAsyncGen* ins); + void visitToAsyncIter(MToAsyncIter* ins); void visitToId(MToId* ins); void visitBitNot(MBitNot* ins); void visitBitAnd(MBitAnd* ins); diff --git a/js/src/jit/MCallOptimize.cpp b/js/src/jit/MCallOptimize.cpp index 5eee30e49..236354530 100644 --- a/js/src/jit/MCallOptimize.cpp +++ b/js/src/jit/MCallOptimize.cpp @@ -285,8 +285,6 @@ IonBuilder::inlineNativeCall(CallInfo& callInfo, JSFunction* target) return inlineGuardToClass(callInfo, &SetIteratorObject::class_); case InlinableNative::IntrinsicGuardToStringIterator: return inlineGuardToClass(callInfo, &StringIteratorObject::class_); - case InlinableNative::IntrinsicIsListIterator: - return inlineHasClass(callInfo, &ListIteratorObject::class_); case InlinableNative::IntrinsicDefineDataProperty: return inlineDefineDataProperty(callInfo); case InlinableNative::IntrinsicObjectHasPrototype: diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h index 6c376d528..e7186ed30 100644 --- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -5784,6 +5784,36 @@ class MToAsync TRIVIAL_NEW_WRAPPERS }; +class MToAsyncGen + : public MUnaryInstruction, + public SingleObjectPolicy::Data +{ + explicit MToAsyncGen(MDefinition* unwrapped) + : MUnaryInstruction(unwrapped) + { + setResultType(MIRType::Object); + } + + public: + INSTRUCTION_HEADER(ToAsyncGen) + TRIVIAL_NEW_WRAPPERS +}; + +class MToAsyncIter + : public MUnaryInstruction, + public SingleObjectPolicy::Data +{ + explicit MToAsyncIter(MDefinition* unwrapped) + : MUnaryInstruction(unwrapped) + { + setResultType(MIRType::Object); + } + + public: + INSTRUCTION_HEADER(ToAsyncIter) + TRIVIAL_NEW_WRAPPERS +}; + class MToId : public MUnaryInstruction, public BoxInputsPolicy::Data diff --git a/js/src/jit/MOpcodes.h b/js/src/jit/MOpcodes.h index 9e460a2ba..589dde077 100644 --- a/js/src/jit/MOpcodes.h +++ b/js/src/jit/MOpcodes.h @@ -79,6 +79,8 @@ namespace jit { _(BitNot) \ _(TypeOf) \ _(ToAsync) \ + _(ToAsyncGen) \ + _(ToAsyncIter) \ _(ToId) \ _(BitAnd) \ _(BitOr) \ diff --git a/js/src/jit/VMFunctions.cpp b/js/src/jit/VMFunctions.cpp index 1ff7adfd1..652c23bf1 100644 --- a/js/src/jit/VMFunctions.cpp +++ b/js/src/jit/VMFunctions.cpp @@ -735,7 +735,7 @@ bool NormalSuspend(JSContext* cx, HandleObject obj, BaselineFrame* frame, jsbytecode* pc, uint32_t stackDepth) { - MOZ_ASSERT(*pc == JSOP_YIELD); + MOZ_ASSERT(*pc == JSOP_YIELD || *pc == JSOP_AWAIT); // Return value is still on the stack. MOZ_ASSERT(stackDepth >= 1); @@ -816,7 +816,7 @@ GeneratorThrowOrClose(JSContext* cx, BaselineFrame* frame, Handle<GeneratorObjec // work. This function always returns false, so we're guaranteed to enter // the exception handler where we will clear the pc. JSScript* script = frame->script(); - uint32_t offset = script->yieldOffsets()[genObj->yieldIndex()]; + uint32_t offset = script->yieldAndAwaitOffsets()[genObj->yieldAndAwaitIndex()]; frame->setOverridePc(script->offsetToPC(offset)); MOZ_ALWAYS_TRUE(DebugAfterYield(cx, frame)); diff --git a/js/src/jit/arm/MacroAssembler-arm.cpp b/js/src/jit/arm/MacroAssembler-arm.cpp index a4161ab00..3421001f7 100644 --- a/js/src/jit/arm/MacroAssembler-arm.cpp +++ b/js/src/jit/arm/MacroAssembler-arm.cpp @@ -3462,8 +3462,8 @@ MacroAssemblerARMCompat::storePayload(const Value& val, const Address& dest) ScratchRegisterScope scratch(asMasm()); SecondScratchRegisterScope scratch2(asMasm()); - if (val.isMarkable()) - ma_mov(ImmGCPtr(val.toMarkablePointer()), scratch); + if (val.isGCThing()) + ma_mov(ImmGCPtr(val.toGCThing()), scratch); else ma_mov(Imm32(val.toNunboxPayload()), scratch); ma_str(scratch, ToPayload(dest), scratch2); diff --git a/js/src/jit/shared/LIR-shared.h b/js/src/jit/shared/LIR-shared.h index ecf02816e..ff4915d1a 100644 --- a/js/src/jit/shared/LIR-shared.h +++ b/js/src/jit/shared/LIR-shared.h @@ -1606,6 +1606,32 @@ class LToAsync : public LCallInstructionHelper<1, 1, 0> } }; +class LToAsyncGen : public LCallInstructionHelper<1, 1, 0> +{ + public: + LIR_HEADER(ToAsyncGen) + explicit LToAsyncGen(const LAllocation& input) { + setOperand(0, input); + } + + const LAllocation* unwrapped() { + return getOperand(0); + } +}; + +class LToAsyncIter : public LCallInstructionHelper<1, 1, 0> +{ + public: + LIR_HEADER(ToAsyncIter) + explicit LToAsyncIter(const LAllocation& input) { + setOperand(0, input); + } + + const LAllocation* unwrapped() { + return getOperand(0); + } +}; + class LToIdV : public LInstructionHelper<BOX_PIECES, BOX_PIECES, 1> { public: diff --git a/js/src/jit/shared/LOpcodes-shared.h b/js/src/jit/shared/LOpcodes-shared.h index e260d7e94..56b98940a 100644 --- a/js/src/jit/shared/LOpcodes-shared.h +++ b/js/src/jit/shared/LOpcodes-shared.h @@ -353,6 +353,8 @@ _(Rest) \ _(TypeOfV) \ _(ToAsync) \ + _(ToAsyncGen) \ + _(ToAsyncIter) \ _(ToIdV) \ _(Floor) \ _(FloorF) \ |