Bug 1394146 - Avoid overflow on backwards iteration of IC entries. r=jandem

This commit is contained in:
Sean Stangl 2017-09-21 15:37:00 -04:00
parent 7c72086a7b
commit e12cd767a3
2 changed files with 21 additions and 6 deletions

View File

@ -669,12 +669,16 @@ BaselineScript::maybeICEntryFromPCOffset(uint32_t pcOffset)
if (!ComputeBinarySearchMid(this, pcOffset, &mid))
return nullptr;
MOZ_ASSERT(mid < numICEntries());
// 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--) {
for (size_t i = mid; icEntry(i).pcOffset() == pcOffset; i--) {
if (icEntry(i).isForOp())
return &icEntry(i);
if (i == 0)
break;
}
for (size_t i = mid+1; i < numICEntries() && icEntry(i).pcOffset() == pcOffset; i++) {
if (icEntry(i).isForOp())
@ -728,10 +732,13 @@ BaselineScript::callVMEntryFromPCOffset(uint32_t pcOffset)
// inserted by VM calls.
size_t mid;
MOZ_ALWAYS_TRUE(ComputeBinarySearchMid(this, pcOffset, &mid));
MOZ_ASSERT(mid < numICEntries());
for (size_t i = mid; i < numICEntries() && icEntry(i).pcOffset() == pcOffset; i--) {
for (size_t i = mid; icEntry(i).pcOffset() == pcOffset; i--) {
if (icEntry(i).kind() == ICEntry::Kind_CallVM)
return icEntry(i);
if (i == 0)
break;
}
for (size_t i = mid+1; i < numICEntries() && icEntry(i).pcOffset() == pcOffset; i++) {
if (icEntry(i).kind() == ICEntry::Kind_CallVM)

View File

@ -1619,7 +1619,7 @@ ControlFlowGenerator::processBreak(JSOp op, jssrcnote* sn)
DebugOnly<bool> found = false;
if (SN_TYPE(sn) == SRC_BREAK2LABEL) {
for (size_t i = labels_.length() - 1; i < labels_.length(); i--) {
for (size_t i = labels_.length() - 1; ; i--) {
CFGState& cfg = cfgStack_[labels_[i].cfgEntry];
MOZ_ASSERT(cfg.state == CFGState::LABEL);
if (cfg.stopAt == target) {
@ -1627,9 +1627,11 @@ ControlFlowGenerator::processBreak(JSOp op, jssrcnote* sn)
found = true;
break;
}
if (i == 0)
break;
}
} else {
for (size_t i = loops_.length() - 1; i < loops_.length(); i--) {
for (size_t i = loops_.length() - 1; ; i--) {
CFGState& cfg = cfgStack_[loops_[i].cfgEntry];
MOZ_ASSERT(cfg.isLoop());
if (cfg.loop.exitpc == target) {
@ -1637,6 +1639,8 @@ ControlFlowGenerator::processBreak(JSOp op, jssrcnote* sn)
found = true;
break;
}
if (i == 0)
break;
}
}
@ -1665,7 +1669,7 @@ ControlFlowGenerator::processContinue(JSOp op)
// Find the target loop.
CFGState* found = nullptr;
jsbytecode* target = pc + GetJumpOffset(pc);
for (size_t i = loops_.length() - 1; i < loops_.length(); i--) {
for (size_t i = loops_.length() - 1; ; i--) {
// +1 to skip JSOP_JUMPTARGET.
if (loops_[i].continuepc == target + 1 ||
EffectiveContinue(loops_[i].continuepc) == target)
@ -1673,6 +1677,8 @@ ControlFlowGenerator::processContinue(JSOp op)
found = &cfgStack_[loops_[i].cfgEntry];
break;
}
if (i == 0)
break;
}
// There must always be a valid target loop structure. If not, there's
@ -1698,11 +1704,13 @@ ControlFlowGenerator::processSwitchBreak(JSOp op)
// Find the target switch.
CFGState* found = nullptr;
jsbytecode* target = pc + GetJumpOffset(pc);
for (size_t i = switches_.length() - 1; i < switches_.length(); i--) {
for (size_t i = switches_.length() - 1; ; i--) {
if (switches_[i].continuepc == target) {
found = &cfgStack_[switches_[i].cfgEntry];
break;
}
if (i == 0)
break;
}
// There must always be a valid target loop structure. If not, there's