Bug 1269847: Don't pop values that could get reused later in ensurePushInvariants; r=luke

MozReview-Commit-ID: FXjfqOzw4Yy

--HG--
extra : rebase_source : 0fdfb4c5273d7f02e3b28b6405659c5b7b3af255
This commit is contained in:
Benjamin Bouvier 2016-05-04 19:30:24 +02:00
Родитель d82d18c789
Коммит 4385ba4cf1
2 изменённых файлов: 41 добавлений и 12 удалений

Просмотреть файл

@ -83,6 +83,8 @@ class FunctionCompiler
const CompileInfo& info_;
MIRGenerator& mirGen_;
MInstruction* dummyIns_;
MBasicBlock* curBlock_;
CallVector callStack_;
uint32_t maxStackArgBytes_;
@ -109,6 +111,7 @@ class FunctionCompiler
graph_(mirGen.graph()),
info_(mirGen.info()),
mirGen_(mirGen),
dummyIns_(nullptr),
curBlock_(nullptr),
maxStackArgBytes_(0),
loopDepth_(0),
@ -176,6 +179,9 @@ class FunctionCompiler
return false;
}
dummyIns_ = MConstant::NewAsmJS(alloc(), Int32Value(0), MIRType::Int32);
curBlock_->add(dummyIns_);
addInterruptCheck();
return true;
@ -964,24 +970,24 @@ class FunctionCompiler
curBlock_->push(def);
}
MDefinition* popDefIfPushed()
MDefinition* popDefIfPushed(bool shouldReturn = true)
{
if (!hasPushed(curBlock_))
return nullptr;
MDefinition* def = curBlock_->pop();
MOZ_ASSERT(def->type() != MIRType::Value);
return def;
MOZ_ASSERT_IF(def->type() == MIRType::Value, !shouldReturn);
return shouldReturn ? def : nullptr;
}
template <typename GetBlock>
void ensurePushInvariants(const GetBlock& getBlock, size_t numBlocks)
bool ensurePushInvariants(const GetBlock& getBlock, size_t numBlocks)
{
// Preserve the invariant that, for every iterated MBasicBlock, either:
// every MBasicBlock has a pushed expression with the same type (to
// prevent creating phis with type Value) OR no MBasicBlock has any
// prevent creating used phis with type Value) OR no MBasicBlock has any
// pushed expression. This is required by MBasicBlock::addPredecessor.
if (numBlocks < 2)
return;
return true;
MBasicBlock* block = getBlock(0);
@ -997,10 +1003,12 @@ class FunctionCompiler
if (!allPushed) {
for (size_t i = 0; i < numBlocks; i++) {
block = getBlock(i);
if (hasPushed(block))
block->pop();
if (!hasPushed(block))
block->push(dummyIns_);
}
}
return allPushed;
}
private:
@ -1071,7 +1079,7 @@ class FunctionCompiler
blocks[numJoinPreds++] = elseJoinPred;
auto getBlock = [&](size_t i) -> MBasicBlock* { return blocks[i]; };
ensurePushInvariants(getBlock, numJoinPreds);
bool yieldsValue = ensurePushInvariants(getBlock, numJoinPreds);
if (numJoinPreds == 0) {
*def = nullptr;
@ -1087,7 +1095,7 @@ class FunctionCompiler
}
curBlock_ = join;
*def = popDefIfPushed();
*def = popDefIfPushed(yieldsValue);
}
return true;
@ -1398,7 +1406,8 @@ class FunctionCompiler
return patches[i].ins->block();
return curBlock_;
};
ensurePushInvariants(getBlock, patches.length() + !!curBlock_);
bool yieldsValue = ensurePushInvariants(getBlock, patches.length() + !!curBlock_);
MBasicBlock* join = nullptr;
MControlInstruction* ins = patches[0].ins;
@ -1428,9 +1437,10 @@ class FunctionCompiler
if (curBlock_ && !goToExistingBlock(curBlock_, join))
return false;
curBlock_ = join;
*def = popDefIfPushed();
*def = popDefIfPushed(yieldsValue);
patches.clear();
return true;

Просмотреть файл

@ -148,3 +148,22 @@ wasmEvalText(`
)
)
`);
wasmEvalText(`
(module
(func
(i32.add
(block $outer
(block $middle
(block $inner
(br_table $middle $outer $inner (i32.const 42) (i32.const 1))
)
(nop)
)
(i32.const 0)
)
(i32.const 13)
)
)
)
`);