Assert fixes and sec-fix.

Bug 1335146: IonMonkey - Don't do flow-aa on blocks without entry predecessor.

1329665 - Use fallible allocator in FlowAliasAnalysis::saveStoreDependency.

1329651: IonMonkey - Ensure ballast in EliminateDeadResumePointOperands.

Sec-fix: 1355050 - Root the RegExpShared in RegExpMacroAssembler

1375436: Assertion failure: throwing, at js/src/jscntxt.cpp:1466 with Debugger and async

Fix typo while at it in CodeGenerator.cpp
This commit is contained in:
win7-7 2025-12-22 11:10:08 +02:00 committed by wuggy
commit 8a82d779d7
8 changed files with 38 additions and 15 deletions

View file

@ -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());

View file

@ -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();
}

View file

@ -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),

View file

@ -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.

View file

@ -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);

View file

@ -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))

View file

@ -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;

View file

@ -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))