From fcbb532c3e4762b2f8f2f4c99686e5363b1e5cd5 Mon Sep 17 00:00:00 2001 From: Jan de Mooij Date: Sat, 22 Jul 2017 14:21:52 +0200 Subject: [PATCH] Bug 1382973 part 2 - Eliminate some BytecodeAnalysis::maybeInfo checks in IonBuilder. r=nbp --- js/src/jit/BaselineInspector.cpp | 13 ++++-- js/src/jit/BaselineInspector.h | 12 ++++++ js/src/jit/BaselineJIT.cpp | 68 ++++++++++++++++++++------------ js/src/jit/BaselineJIT.h | 4 ++ js/src/jit/IonBuilder.cpp | 4 -- 5 files changed, 68 insertions(+), 33 deletions(-) diff --git a/js/src/jit/BaselineInspector.cpp b/js/src/jit/BaselineInspector.cpp index d486155933ca..c6370b167923 100644 --- a/js/src/jit/BaselineInspector.cpp +++ b/js/src/jit/BaselineInspector.cpp @@ -281,9 +281,14 @@ BaselineInspector::monomorphicStub(jsbytecode* pc) if (!hasBaselineScript()) return nullptr; - const ICEntry& entry = icEntryFromPC(pc); + // IonBuilder::analyzeNewLoopTypes may call this (via expectedResultType + // below) on code that's unreachable, according to BytecodeAnalysis. Use + // maybeICEntryFromPC to handle this. + const ICEntry* entry = maybeICEntryFromPC(pc); + if (!entry) + return nullptr; - ICStub* stub = entry.firstStub(); + ICStub* stub = entry->firstStub(); ICStub* next = stub->next(); if (!next || !next->isFallback()) @@ -316,7 +321,9 @@ MIRType BaselineInspector::expectedResultType(jsbytecode* pc) { // Look at the IC entries for this op to guess what type it will produce, - // returning MIRType::None otherwise. + // returning MIRType::None otherwise. Note that IonBuilder may call this + // for bytecode ops that are unreachable and don't have a Baseline IC, see + // comment in monomorphicStub. ICStub* stub = monomorphicStub(pc); if (!stub) diff --git a/js/src/jit/BaselineInspector.h b/js/src/jit/BaselineInspector.h index 15bbe6576434..1888e90f7c32 100644 --- a/js/src/jit/BaselineInspector.h +++ b/js/src/jit/BaselineInspector.h @@ -77,6 +77,18 @@ class BaselineInspector return ent; } + BaselineICEntry* maybeICEntryFromPC(jsbytecode* pc) { + MOZ_ASSERT(hasBaselineScript()); + MOZ_ASSERT(isValidPC(pc)); + BaselineICEntry* ent = + baselineScript()->maybeICEntryFromPCOffset(script->pcToOffset(pc), prevLookedUpEntry); + if (!ent) + return nullptr; + MOZ_ASSERT(ent->isForOp()); + prevLookedUpEntry = ent; + return ent; + } + template ICInspectorType makeICInspector(jsbytecode* pc, ICStub::Kind expectedFallbackKind) { BaselineICEntry* ent = nullptr; diff --git a/js/src/jit/BaselineJIT.cpp b/js/src/jit/BaselineJIT.cpp index 2092a2e701bb..c15932de4f48 100644 --- a/js/src/jit/BaselineJIT.cpp +++ b/js/src/jit/BaselineJIT.cpp @@ -645,21 +645,19 @@ BaselineScript::icEntryFromReturnOffset(CodeOffset returnOffset) return icEntry(loc); } -static inline size_t -ComputeBinarySearchMid(BaselineScript* baseline, uint32_t pcOffset) +static inline bool +ComputeBinarySearchMid(BaselineScript* baseline, uint32_t pcOffset, size_t* loc) { - size_t loc; - BinarySearchIf(ICEntries(baseline), 0, baseline->numICEntries(), - [pcOffset](BaselineICEntry& entry) { - uint32_t entryOffset = entry.pcOffset(); - if (pcOffset < entryOffset) - return -1; - if (entryOffset < pcOffset) - return 1; - return 0; - }, - &loc); - return loc; + return BinarySearchIf(ICEntries(baseline), 0, baseline->numICEntries(), + [pcOffset](BaselineICEntry& entry) { + uint32_t entryOffset = entry.pcOffset(); + if (pcOffset < entryOffset) + return -1; + if (entryOffset < pcOffset) + return 1; + return 0; + }, + loc); } uint8_t* @@ -668,29 +666,39 @@ BaselineScript::returnAddressForIC(const BaselineICEntry& ent) return method()->raw() + ent.returnOffset().offset(); } -BaselineICEntry& -BaselineScript::icEntryFromPCOffset(uint32_t pcOffset) +BaselineICEntry* +BaselineScript::maybeICEntryFromPCOffset(uint32_t pcOffset) { // Multiple IC entries can have the same PC offset, but this method only looks for // those which have isForOp() set. - size_t mid = ComputeBinarySearchMid(this, pcOffset); + size_t mid; + if (!ComputeBinarySearchMid(this, pcOffset, &mid)) + return nullptr; // Found an IC entry with a matching PC offset. Search backward, and then // forward from this IC entry, looking for one with the same PC offset which // has isForOp() set. for (size_t i = mid; i < numICEntries() && icEntry(i).pcOffset() == pcOffset; i--) { if (icEntry(i).isForOp()) - return icEntry(i); + return &icEntry(i); } for (size_t i = mid+1; i < numICEntries() && icEntry(i).pcOffset() == pcOffset; i++) { if (icEntry(i).isForOp()) - return icEntry(i); + return &icEntry(i); } - MOZ_CRASH("Invalid PC offset for IC entry."); + return nullptr; } BaselineICEntry& -BaselineScript::icEntryFromPCOffset(uint32_t pcOffset, BaselineICEntry* prevLookedUpEntry) +BaselineScript::icEntryFromPCOffset(uint32_t pcOffset) +{ + BaselineICEntry* entry = maybeICEntryFromPCOffset(pcOffset); + MOZ_RELEASE_ASSERT(entry); + return *entry; +} + +BaselineICEntry* +BaselineScript::maybeICEntryFromPCOffset(uint32_t pcOffset, BaselineICEntry* prevLookedUpEntry) { // Do a linear forward search from the last queried PC offset, or fallback to a // binary search if the last offset is too far away. @@ -702,14 +710,21 @@ BaselineScript::icEntryFromPCOffset(uint32_t pcOffset, BaselineICEntry* prevLook BaselineICEntry* curEntry = prevLookedUpEntry; while (curEntry >= firstEntry && curEntry <= lastEntry) { if (curEntry->pcOffset() == pcOffset && curEntry->isForOp()) - break; + return curEntry; curEntry++; } - MOZ_ASSERT(curEntry->pcOffset() == pcOffset && curEntry->isForOp()); - return *curEntry; + return nullptr; } - return icEntryFromPCOffset(pcOffset); + return maybeICEntryFromPCOffset(pcOffset); +} + +BaselineICEntry& +BaselineScript::icEntryFromPCOffset(uint32_t pcOffset, BaselineICEntry* prevLookedUpEntry) +{ + BaselineICEntry* entry = maybeICEntryFromPCOffset(pcOffset, prevLookedUpEntry); + MOZ_RELEASE_ASSERT(entry); + return *entry; } BaselineICEntry& @@ -717,7 +732,8 @@ BaselineScript::callVMEntryFromPCOffset(uint32_t pcOffset) { // Like icEntryFromPCOffset, but only looks for the fake ICEntries // inserted by VM calls. - size_t mid = ComputeBinarySearchMid(this, pcOffset); + size_t mid; + MOZ_ALWAYS_TRUE(ComputeBinarySearchMid(this, pcOffset, &mid)); for (size_t i = mid; i < numICEntries() && icEntry(i).pcOffset() == pcOffset; i--) { if (icEntry(i).kind() == ICEntry::Kind_CallVM) diff --git a/js/src/jit/BaselineJIT.h b/js/src/jit/BaselineJIT.h index ef053fd7a622..d456c0dad6fa 100644 --- a/js/src/jit/BaselineJIT.h +++ b/js/src/jit/BaselineJIT.h @@ -379,6 +379,10 @@ struct BaselineScript return method()->raw() <= addr && addr <= method()->raw() + method()->instructionsSize(); } + BaselineICEntry* maybeICEntryFromPCOffset(uint32_t pcOffset); + BaselineICEntry* maybeICEntryFromPCOffset(uint32_t pcOffset, + BaselineICEntry* prevLookedUpEntry); + BaselineICEntry& icEntry(size_t index); BaselineICEntry& icEntryFromReturnOffset(CodeOffset returnOffset); BaselineICEntry& icEntryFromPCOffset(uint32_t pcOffset); diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp index da8e4a7c0702..c980d90cce80 100644 --- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -583,8 +583,6 @@ IonBuilder::analyzeNewLoopTypes(const CFGBlock* loopEntryBlock) continue; if (slot >= info().firstStackSlot()) continue; - if (!analysis().maybeInfo(pc)) - continue; if (!last) continue; @@ -1760,8 +1758,6 @@ IonBuilder::visitControlInstruction(CFGControlInstruction* ins, bool* restarted) AbortReasonOr IonBuilder::inspectOpcode(JSOp op) { - MOZ_ASSERT(analysis_.maybeInfo(pc), "Compiling unreachable op"); - // Add not yet implemented opcodes at the bottom of the switch! switch (op) { case JSOP_NOP: