Skip to content
Permalink
Browse files

Recover perf regression from CVE-2019-0992. Recognize induction varia…

…ble like patterns which are preserving number values
  • Loading branch information...
LouisLaf authored and pleath committed May 3, 2019
1 parent 53b75c5 commit c84ba704b4d6893e68694dd8e7492ddcd9650768
Showing with 65 additions and 2 deletions.
  1. +50 −1 lib/Backend/BackwardPass.cpp
  2. +3 −0 lib/Backend/BackwardPass.h
  3. +2 −0 lib/Backend/FlowGraph.h
  4. +10 −1 lib/Backend/GlobOpt.cpp
@@ -1645,6 +1645,8 @@ BackwardPass::ProcessLoop(BasicBlock * lastBlock)
{
Assert(loop->symsAssignedToInLoop == nullptr);
loop->symsAssignedToInLoop = JitAnew(this->globOpt->alloc, BVSparse<JitArenaAllocator>, this->globOpt->alloc);
Assert(loop->preservesNumberValue == nullptr);
loop->preservesNumberValue = JitAnew(this->globOpt->alloc, BVSparse<JitArenaAllocator>, this->globOpt->alloc);
}

FOREACH_BLOCK_BACKWARD_IN_RANGE_DEAD_OR_ALIVE(block, lastBlock, nullptr)
@@ -7418,6 +7420,41 @@ BackwardPass::TrackFloatSymEquivalence(IR::Instr *const instr)
}
}

bool
BackwardPass::SymIsIntconstOrSelf(Sym *sym, IR::Opnd *opnd)
{
Assert(sym->IsStackSym());
if (!opnd->IsRegOpnd())
{
return false;
}
StackSym *opndSym = opnd->AsRegOpnd()->m_sym;

if (sym == opndSym)
{
return true;
}

if (!opndSym->IsSingleDef())
{
return false;
}

if (opndSym->GetInstrDef()->m_opcode == Js::OpCode::LdC_A_I4)
{
return true;
}

return false;
}

bool
BackwardPass::InstrPreservesNumberValues(IR::Instr *instr, Sym *defSym)
{
return (OpCodeAttr::ProducesNumber(instr->m_opcode) ||
(instr->m_opcode == Js::OpCode::Add_A && this->SymIsIntconstOrSelf(defSym, instr->GetSrc1()) && this->SymIsIntconstOrSelf(defSym, instr->GetSrc2())));
}

bool
BackwardPass::ProcessDef(IR::Opnd * opnd)
{
@@ -7432,7 +7469,19 @@ BackwardPass::ProcessDef(IR::Opnd * opnd)
this->InvalidateCloneStrCandidate(opnd);
if ((tag == Js::BackwardPhase) && IsPrePass())
{
this->currentPrePassLoop->symsAssignedToInLoop->Set(sym->m_id);
bool firstDef = !this->currentPrePassLoop->symsAssignedToInLoop->TestAndSet(sym->m_id);

if (firstDef)
{
if (this->InstrPreservesNumberValues(this->currentInstr, sym))
{
this->currentPrePassLoop->preservesNumberValue->Set(sym->m_id);
}
}
else if (!this->InstrPreservesNumberValues(this->currentInstr, sym))
{
this->currentPrePassLoop->preservesNumberValue->Clear(sym->m_id);
}
}
}
}
@@ -36,6 +36,9 @@ class BackwardPass
bool ProcessDef(IR::Opnd * opnd);
void ProcessTransfers(IR::Instr * instr);
void ProcessFieldKills(IR::Instr * instr);
bool SymIsIntconstOrSelf(Sym *sym, IR::Opnd *opnd);
bool InstrPreservesNumberValues(IR::Instr *instr, Sym *defSym);

template<typename T> void ClearBucketsOnFieldKill(IR::Instr *instr, HashTable<T> *table);
StackSym* ProcessByteCodeUsesDst(IR::ByteCodeUsesInstr * byteCodeUsesInstr);
const BVSparse<JitArenaAllocator>* ProcessByteCodeUsesSrcs(IR::ByteCodeUsesInstr * byteCodeUsesInstr);
@@ -588,6 +588,7 @@ class Loop
// cleanup in PreOptPeep in the pre-pass of a loop. For aggressively transferring
// values in prepass, we need to know if a source sym was ever assigned to in a loop.
BVSparse<JitArenaAllocator> *symsAssignedToInLoop;
BVSparse<JitArenaAllocator> *preservesNumberValue;

BailOutInfo * bailOutInfo;
IR::BailOutInstr * toPrimitiveSideEffectCheck;
@@ -733,6 +734,7 @@ class Loop
symsAssignedToInLoop(nullptr),
needImplicitCallBailoutChecksForJsArrayCheckHoist(false),
inductionVariables(nullptr),
preservesNumberValue(nullptr),
dominatingLoopCountableBlock(nullptr),
loopCount(nullptr),
loopCountBasedBoundBaseSyms(nullptr),
@@ -2721,7 +2721,16 @@ GlobOpt::IsNonNumericRegOpnd(IR::RegOpnd *opnd, bool inGlobOpt) const

Value * opndValue = this->currentBlock->globOptData.FindValue(opnd->m_sym);
ValueInfo * opndValueInfo = opndValue ? opndValue->GetValueInfo() : nullptr;
return !opndValueInfo || !this->IsSafeToTransferInPrepass(opnd->m_sym, opndValueInfo);
if (!opndValueInfo)
{
return true;
}
if (currentBlock->loop->preservesNumberValue->Test(opnd->m_sym->m_id))
{
return false;
}

return !this->IsSafeToTransferInPrepass(opnd->m_sym, opndValueInfo);
}

return true;

0 comments on commit c84ba70

Please sign in to comment.
You can’t perform that action at this time.