diff --git a/js/src/irregexp/NativeRegExpMacroAssembler.cpp b/js/src/irregexp/NativeRegExpMacroAssembler.cpp index a022210f6f..44a82c3e20 100644 --- a/js/src/irregexp/NativeRegExpMacroAssembler.cpp +++ b/js/src/irregexp/NativeRegExpMacroAssembler.cpp @@ -66,8 +66,8 @@ using namespace js::jit; NativeRegExpMacroAssembler::NativeRegExpMacroAssembler(LifoAlloc* alloc, JSRuntime* rt, Mode mode, int registers_to_save, RegExpShared::JitCodeTables& tables) - : RegExpMacroAssembler(*alloc, registers_to_save), - tables(tables), runtime(rt), mode_(mode) + : RegExpMacroAssembler(cx, *alloc, registers_to_save), + tables(tables), cx(cx), mode_(mode) { // Find physical registers for each compiler register. AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All()); diff --git a/js/src/irregexp/RegExpEngine.cpp b/js/src/irregexp/RegExpEngine.cpp index 75c6f4547a..f8159d81eb 100644 --- a/js/src/irregexp/RegExpEngine.cpp +++ b/js/src/irregexp/RegExpEngine.cpp @@ -1353,7 +1353,7 @@ irregexp::CompilePattern(JSContext* cx, HandleRegExpShared shared, RegExpCompile native_assembler.emplace(&alloc, cx->runtime(), mode, (data->capture_count + 1) * 2, tables); assembler = native_assembler.ptr(); } else { - interpreted_assembler.emplace(&alloc, (data->capture_count + 1) * 2); + interpreted_assembler.emplace(cx, &alloc, (data->capture_count + 1) * 2); assembler = interpreted_assembler.ptr(); } diff --git a/js/src/irregexp/RegExpMacroAssembler.cpp b/js/src/irregexp/RegExpMacroAssembler.cpp index 034fe8e0ab..68b07f695c 100644 --- a/js/src/irregexp/RegExpMacroAssembler.cpp +++ b/js/src/irregexp/RegExpMacroAssembler.cpp @@ -96,9 +96,9 @@ irregexp::CaseInsensitiveCompareUCStrings(const char16_t* substring1, const char16_t* substring2, size_t byteLength); -InterpretedRegExpMacroAssembler::InterpretedRegExpMacroAssembler(LifoAlloc* alloc, +InterpretedRegExpMacroAssembler::InterpretedRegExpMacroAssembler(JSContext* cx, LifoAlloc* alloc, size_t numSavedRegisters) - : RegExpMacroAssembler(*alloc, numSavedRegisters), + : RegExpMacroAssembler(cx, *alloc, numSavedRegisters), pc_(0), advance_current_start_(0), advance_current_offset_(0), diff --git a/js/src/irregexp/RegExpMacroAssembler.h b/js/src/irregexp/RegExpMacroAssembler.h index fd055c7f20..15460372b3 100644 --- a/js/src/irregexp/RegExpMacroAssembler.h +++ b/js/src/irregexp/RegExpMacroAssembler.h @@ -40,7 +40,7 @@ namespace irregexp { class MOZ_STACK_CLASS RegExpMacroAssembler { public: - RegExpMacroAssembler(LifoAlloc& alloc, size_t numSavedRegisters) + RegExpMacroAssembler(JSContext* cx, LifoAlloc& alloc, size_t numSavedRegisters) : slow_safe_compiler_(false), global_mode_(NOT_GLOBAL), alloc_(alloc), @@ -225,7 +225,7 @@ CaseInsensitiveCompareUCStrings(const CharT* substring1, const CharT* substring2 class MOZ_STACK_CLASS InterpretedRegExpMacroAssembler final : public RegExpMacroAssembler { public: - InterpretedRegExpMacroAssembler(LifoAlloc* alloc, size_t numSavedRegisters); + InterpretedRegExpMacroAssembler(JSContext* cx, LifoAlloc* alloc, size_t numSavedRegisters); ~InterpretedRegExpMacroAssembler(); // Inherited virtual methods. diff --git a/js/src/jit/CodeGenerator.cpp b/js/src/jit/CodeGenerator.cpp index a37c3079ef..ff72f7060c 100644 --- a/js/src/jit/CodeGenerator.cpp +++ b/js/src/jit/CodeGenerator.cpp @@ -529,7 +529,7 @@ CodeGenerator::testValueTruthyKernel(const ValueOperand& value, int tagCount = int(mightBeUndefined) + int(mightBeNull) + int(mightBeBoolean) + int(mightBeInt32) + int(mightBeObject) + int(mightBeString) + int(mightBeSymbol) + int(mightBeDouble) + - int(mightBeBigInt);; + int(mightBeBigInt); MOZ_ASSERT_IF(!valueMIR->emptyResultTypeSet(), tagCount > 0); diff --git a/js/src/jit/FlowAliasAnalysis.cpp b/js/src/jit/FlowAliasAnalysis.cpp index 7d0134b0b3..89cf7a4482 100644 --- a/js/src/jit/FlowAliasAnalysis.cpp +++ b/js/src/jit/FlowAliasAnalysis.cpp @@ -462,13 +462,20 @@ FlowAliasAnalysis::analyze() if (!stores_->maybeFreePredecessorBlocks(*block)) return false; - if (block->isLoopHeader()) - loop_ = new(alloc()) LoopInfo(alloc(), loop_, *block); - for (MPhiIterator def(block->phisBegin()), end(block->phisEnd()); def != end; ++def) def->setId(newId++); BlockStoreInfo& blockInfo = stores_->current(); + + // When the store dependencies is empty it means we have a disconnected + // graph. Those blocks will never get reached but it is only fixed up + // after GVN. Don't run AA on those blocks. + if (blockInfo.length() == 0) + continue; + + if (block->isLoopHeader()) + loop_ = new(alloc()) LoopInfo(alloc(), loop_, *block); + for (MInstructionIterator def(block->begin()), end(block->begin(block->lastIns())); def != end; ++def) @@ -587,6 +594,14 @@ FlowAliasAnalysis::processDeferredLoads(LoopInfo* info) DumpLoopInvariant(load, info->loopHeader(), /* loopinvariant = */ loopinvariant, loopInvariantDependency); + // When the store dependencies is empty it means we have a disconnected + // graph. Those blocks will never get reached but it is only fixed up + // after GVN. Don't improve dependency for those loads. + if (loopInvariantDependency.length() == 0) { + load->setDependency(store); + continue; + } + if (loopinvariant) { if (!improveDependency(load, loopInvariantDependency, output_)) return false; @@ -814,7 +829,7 @@ FlowAliasAnalysis::saveStoreDependency(MDefinition* ins, BlockStoreInfo& prevSto // To form a store dependency chain, we store the previous last dependencies // in the current store. - StoreDependency* dependency = new(alloc()) StoreDependency(alloc()); + StoreDependency* dependency = new(alloc().fallible()) StoreDependency(alloc()); if (!dependency) return false; if (!dependency->init(prevStores)) diff --git a/js/src/jit/IonAnalysis.cpp b/js/src/jit/IonAnalysis.cpp index 6f424098e8..38d53e973b 100644 --- a/js/src/jit/IonAnalysis.cpp +++ b/js/src/jit/IonAnalysis.cpp @@ -965,17 +965,22 @@ jit::EliminateDeadResumePointOperands(MIRGenerator* mir, MIRGraph& graph) if (mir->shouldCancel("Eliminate Dead Resume Point Operands (main loop)")) return false; - if (MResumePoint* rp = block->entryResumePoint()) + if (MResumePoint* rp = block->entryResumePoint()) { + if (!graph.alloc().ensureBallast()) + return false; EliminateTriviallyDeadResumePointOperands(graph, rp); + } // The logic below can get confused on infinite loops. if (block->isLoopHeader() && block->backedge() == *block) continue; for (MInstructionIterator ins = block->begin(); ins != block->end(); ins++) { - if (MResumePoint* rp = ins->resumePoint()) + if (MResumePoint* rp = ins->resumePoint()) { + if (!graph.alloc().ensureBallast()) + return false; EliminateTriviallyDeadResumePointOperands(graph, rp); - + } // No benefit to replacing constant operands with other constants. if (ins->isConstant()) continue; diff --git a/js/src/vm/AsyncFunction.cpp b/js/src/vm/AsyncFunction.cpp index 676ad87fdc..4683268b18 100644 --- a/js/src/vm/AsyncFunction.cpp +++ b/js/src/vm/AsyncFunction.cpp @@ -90,6 +90,9 @@ WrappedAsyncFunction(JSContext* cx, unsigned argc, Value* vp) return true; } + if (!cx->isExceptionPending()) + return false; + // Steps 1, 4. RootedValue exc(cx); if (!GetAndClearException(cx, &exc))