зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1382973 part 2 - Eliminate some BytecodeAnalysis::maybeInfo checks in IonBuilder. r=nbp
This commit is contained in:
Родитель
e2a6ce0202
Коммит
fcbb532c3e
|
@ -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)
|
||||
|
|
|
@ -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 <typename ICInspectorType>
|
||||
ICInspectorType makeICInspector(jsbytecode* pc, ICStub::Kind expectedFallbackKind) {
|
||||
BaselineICEntry* ent = nullptr;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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<Ok>
|
||||
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:
|
||||
|
|
Загрузка…
Ссылка в новой задаче