mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-22 17:55:50 +00:00
Bug 1395587 - Baldr: remove FunctionGenerator (r=lth)
MozReview-Commit-ID: 4MIQEVy94OU --HG-- extra : rebase_source : 97559c214a4e325f6ea16719aa2586f509438fdf
This commit is contained in:
parent
4cc7b26afd
commit
36b63a570d
@ -2892,10 +2892,9 @@ class MOZ_STACK_CLASS FunctionValidator
|
|||||||
|
|
||||||
ModuleValidator& m_;
|
ModuleValidator& m_;
|
||||||
ParseNode* fn_;
|
ParseNode* fn_;
|
||||||
|
Bytes bytes_;
|
||||||
FunctionGenerator fg_;
|
Encoder encoder_;
|
||||||
Maybe<Encoder> encoder_;
|
Uint32Vector callSiteLineNums_;
|
||||||
|
|
||||||
LocalMap locals_;
|
LocalMap locals_;
|
||||||
|
|
||||||
// Labels
|
// Labels
|
||||||
@ -2912,6 +2911,7 @@ class MOZ_STACK_CLASS FunctionValidator
|
|||||||
FunctionValidator(ModuleValidator& m, ParseNode* fn)
|
FunctionValidator(ModuleValidator& m, ParseNode* fn)
|
||||||
: m_(m),
|
: m_(m),
|
||||||
fn_(fn),
|
fn_(fn),
|
||||||
|
encoder_(bytes_),
|
||||||
locals_(m.cx()),
|
locals_(m.cx()),
|
||||||
breakLabels_(m.cx()),
|
breakLabels_(m.cx()),
|
||||||
continueLabels_(m.cx()),
|
continueLabels_(m.cx()),
|
||||||
@ -2924,24 +2924,19 @@ class MOZ_STACK_CLASS FunctionValidator
|
|||||||
JSContext* cx() const { return m_.cx(); }
|
JSContext* cx() const { return m_.cx(); }
|
||||||
ParseNode* fn() const { return fn_; }
|
ParseNode* fn() const { return fn_; }
|
||||||
|
|
||||||
bool init(PropertyName* name, unsigned line) {
|
bool init() {
|
||||||
if (!locals_.init() || !breakLabels_.init() || !continueLabels_.init())
|
return locals_.init() &&
|
||||||
return false;
|
breakLabels_.init() &&
|
||||||
|
continueLabels_.init();
|
||||||
if (!m_.mg().startFuncDef(line, &fg_))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
encoder_.emplace(fg_.bytes());
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool finish(uint32_t funcIndex) {
|
bool finish(uint32_t funcIndex, unsigned line) {
|
||||||
MOZ_ASSERT(!blockDepth_);
|
MOZ_ASSERT(!blockDepth_);
|
||||||
MOZ_ASSERT(breakableStack_.empty());
|
MOZ_ASSERT(breakableStack_.empty());
|
||||||
MOZ_ASSERT(continuableStack_.empty());
|
MOZ_ASSERT(continuableStack_.empty());
|
||||||
MOZ_ASSERT(breakLabels_.empty());
|
MOZ_ASSERT(breakLabels_.empty());
|
||||||
MOZ_ASSERT(continueLabels_.empty());
|
MOZ_ASSERT(continueLabels_.empty());
|
||||||
return m_.mg().finishFuncDef(funcIndex, &fg_);
|
return m_.mg().compileFuncDef(funcIndex, line, Move(bytes_), Move(callSiteLineNums_));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool fail(ParseNode* pn, const char* str) {
|
bool fail(ParseNode* pn, const char* str) {
|
||||||
@ -3136,7 +3131,7 @@ class MOZ_STACK_CLASS FunctionValidator
|
|||||||
|
|
||||||
/**************************************************** Encoding interface */
|
/**************************************************** Encoding interface */
|
||||||
|
|
||||||
Encoder& encoder() { return *encoder_; }
|
Encoder& encoder() { return encoder_; }
|
||||||
|
|
||||||
MOZ_MUST_USE bool writeInt32Lit(int32_t i32) {
|
MOZ_MUST_USE bool writeInt32Lit(int32_t i32) {
|
||||||
return encoder().writeOp(Op::I32Const) &&
|
return encoder().writeOp(Op::I32Const) &&
|
||||||
@ -3188,14 +3183,14 @@ class MOZ_STACK_CLASS FunctionValidator
|
|||||||
}
|
}
|
||||||
MOZ_MUST_USE bool writeCall(ParseNode* pn, Op op) {
|
MOZ_MUST_USE bool writeCall(ParseNode* pn, Op op) {
|
||||||
return encoder().writeOp(op) &&
|
return encoder().writeOp(op) &&
|
||||||
fg_.addCallSiteLineNum(m().tokenStream().srcCoords.lineNum(pn->pn_pos.begin));
|
callSiteLineNums_.append(m().tokenStream().srcCoords.lineNum(pn->pn_pos.begin));
|
||||||
}
|
}
|
||||||
MOZ_MUST_USE bool writeCall(ParseNode* pn, MozOp op) {
|
MOZ_MUST_USE bool writeCall(ParseNode* pn, MozOp op) {
|
||||||
return encoder().writeOp(op) &&
|
return encoder().writeOp(op) &&
|
||||||
fg_.addCallSiteLineNum(m().tokenStream().srcCoords.lineNum(pn->pn_pos.begin));
|
callSiteLineNums_.append(m().tokenStream().srcCoords.lineNum(pn->pn_pos.begin));
|
||||||
}
|
}
|
||||||
MOZ_MUST_USE bool prepareCall(ParseNode* pn) {
|
MOZ_MUST_USE bool prepareCall(ParseNode* pn) {
|
||||||
return fg_.addCallSiteLineNum(m().tokenStream().srcCoords.lineNum(pn->pn_pos.begin));
|
return callSiteLineNums_.append(m().tokenStream().srcCoords.lineNum(pn->pn_pos.begin));
|
||||||
}
|
}
|
||||||
MOZ_MUST_USE bool writeSimdOp(SimdType simdType, SimdOperation simdOp) {
|
MOZ_MUST_USE bool writeSimdOp(SimdType simdType, SimdOperation simdOp) {
|
||||||
MozOp op = SimdToOp(simdType, simdOp);
|
MozOp op = SimdToOp(simdType, simdOp);
|
||||||
@ -7104,7 +7099,7 @@ CheckFunction(ModuleValidator& m)
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
FunctionValidator f(m, fn);
|
FunctionValidator f(m, fn);
|
||||||
if (!f.init(FunctionName(fn), line))
|
if (!f.init())
|
||||||
return m.fail(fn, "internal compiler failure (probably out of memory)");
|
return m.fail(fn, "internal compiler failure (probably out of memory)");
|
||||||
|
|
||||||
ParseNode* stmtIter = ListHead(FunctionStatementList(fn));
|
ParseNode* stmtIter = ListHead(FunctionStatementList(fn));
|
||||||
@ -7138,7 +7133,7 @@ CheckFunction(ModuleValidator& m)
|
|||||||
|
|
||||||
func->define(fn);
|
func->define(fn);
|
||||||
|
|
||||||
if (!f.finish(func->index()))
|
if (!f.finish(func->index(), line))
|
||||||
return m.fail(fn, "internal compiler failure (probably out of memory)");
|
return m.fail(fn, "internal compiler failure (probably out of memory)");
|
||||||
|
|
||||||
// Release the parser's lifo memory only after the last use of a parse node.
|
// Release the parser's lifo memory only after the last use of a parse node.
|
||||||
|
@ -570,7 +570,7 @@ class BaseCompiler
|
|||||||
|
|
||||||
const ModuleEnvironment& env_;
|
const ModuleEnvironment& env_;
|
||||||
BaseOpIter iter_;
|
BaseOpIter iter_;
|
||||||
const FuncBytes& func_;
|
const FuncCompileUnit& func_;
|
||||||
size_t lastReadCallSite_;
|
size_t lastReadCallSite_;
|
||||||
TempAllocator& alloc_;
|
TempAllocator& alloc_;
|
||||||
const ValTypeVector& locals_; // Types of parameters and locals
|
const ValTypeVector& locals_; // Types of parameters and locals
|
||||||
@ -645,7 +645,7 @@ class BaseCompiler
|
|||||||
public:
|
public:
|
||||||
BaseCompiler(const ModuleEnvironment& env,
|
BaseCompiler(const ModuleEnvironment& env,
|
||||||
Decoder& decoder,
|
Decoder& decoder,
|
||||||
const FuncBytes& func,
|
const FuncCompileUnit& func,
|
||||||
const ValTypeVector& locals,
|
const ValTypeVector& locals,
|
||||||
bool debugEnabled,
|
bool debugEnabled,
|
||||||
TempAllocator* alloc,
|
TempAllocator* alloc,
|
||||||
@ -659,6 +659,8 @@ class BaseCompiler
|
|||||||
MOZ_MUST_USE bool emitFunction();
|
MOZ_MUST_USE bool emitFunction();
|
||||||
void emitInitStackLocals();
|
void emitInitStackLocals();
|
||||||
|
|
||||||
|
const SigWithId& sig() const { return *env_.funcSigs[func_.index()]; }
|
||||||
|
|
||||||
// Used by some of the ScratchRegister implementations.
|
// Used by some of the ScratchRegister implementations.
|
||||||
operator MacroAssembler&() const { return masm; }
|
operator MacroAssembler&() const { return masm; }
|
||||||
|
|
||||||
@ -2236,7 +2238,7 @@ class BaseCompiler
|
|||||||
|
|
||||||
// Copy arguments from registers to stack.
|
// Copy arguments from registers to stack.
|
||||||
|
|
||||||
const ValTypeVector& args = func_.sig().args();
|
const ValTypeVector& args = sig().args();
|
||||||
|
|
||||||
for (ABIArgIter<const ValTypeVector> i(args); !i.done(); i++) {
|
for (ABIArgIter<const ValTypeVector> i(args); !i.done(); i++) {
|
||||||
Local& l = localInfo_[i.index()];
|
Local& l = localInfo_[i.index()];
|
||||||
@ -2273,7 +2275,7 @@ class BaseCompiler
|
|||||||
MOZ_ASSERT(debugEnabled_);
|
MOZ_ASSERT(debugEnabled_);
|
||||||
size_t debugFrameOffset = masm.framePushed() - DebugFrame::offsetOfFrame();
|
size_t debugFrameOffset = masm.framePushed() - DebugFrame::offsetOfFrame();
|
||||||
Address resultsAddress(StackPointer, debugFrameOffset + DebugFrame::offsetOfResults());
|
Address resultsAddress(StackPointer, debugFrameOffset + DebugFrame::offsetOfResults());
|
||||||
switch (func_.sig().ret()) {
|
switch (sig().ret()) {
|
||||||
case ExprType::Void:
|
case ExprType::Void:
|
||||||
break;
|
break;
|
||||||
case ExprType::I32:
|
case ExprType::I32:
|
||||||
@ -2298,7 +2300,7 @@ class BaseCompiler
|
|||||||
MOZ_ASSERT(debugEnabled_);
|
MOZ_ASSERT(debugEnabled_);
|
||||||
size_t debugFrameOffset = masm.framePushed() - DebugFrame::offsetOfFrame();
|
size_t debugFrameOffset = masm.framePushed() - DebugFrame::offsetOfFrame();
|
||||||
Address resultsAddress(StackPointer, debugFrameOffset + DebugFrame::offsetOfResults());
|
Address resultsAddress(StackPointer, debugFrameOffset + DebugFrame::offsetOfResults());
|
||||||
switch (func_.sig().ret()) {
|
switch (sig().ret()) {
|
||||||
case ExprType::Void:
|
case ExprType::Void:
|
||||||
break;
|
break;
|
||||||
case ExprType::I32:
|
case ExprType::I32:
|
||||||
@ -5822,7 +5824,7 @@ BaseCompiler::emitReturn()
|
|||||||
if (deadCode_)
|
if (deadCode_)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
doReturn(func_.sig().ret(), PopStack(true));
|
doReturn(sig().ret(), PopStack(true));
|
||||||
deadCode_ = true;
|
deadCode_ = true;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -6891,7 +6893,7 @@ BaseCompiler::emitCurrentMemory()
|
|||||||
bool
|
bool
|
||||||
BaseCompiler::emitBody()
|
BaseCompiler::emitBody()
|
||||||
{
|
{
|
||||||
if (!iter_.readFunctionStart(func_.sig().ret()))
|
if (!iter_.readFunctionStart(sig().ret()))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
initControl(controlItem());
|
initControl(controlItem());
|
||||||
@ -6973,7 +6975,7 @@ BaseCompiler::emitBody()
|
|||||||
|
|
||||||
if (iter_.controlStackEmpty()) {
|
if (iter_.controlStackEmpty()) {
|
||||||
if (!deadCode_)
|
if (!deadCode_)
|
||||||
doReturn(func_.sig().ret(), PopStack(false));
|
doReturn(sig().ret(), PopStack(false));
|
||||||
return iter_.readFunctionEnd(iter_.end());
|
return iter_.readFunctionEnd(iter_.end());
|
||||||
}
|
}
|
||||||
NEXT();
|
NEXT();
|
||||||
@ -7584,7 +7586,7 @@ BaseCompiler::emitInitStackLocals()
|
|||||||
|
|
||||||
BaseCompiler::BaseCompiler(const ModuleEnvironment& env,
|
BaseCompiler::BaseCompiler(const ModuleEnvironment& env,
|
||||||
Decoder& decoder,
|
Decoder& decoder,
|
||||||
const FuncBytes& func,
|
const FuncCompileUnit& func,
|
||||||
const ValTypeVector& locals,
|
const ValTypeVector& locals,
|
||||||
bool debugEnabled,
|
bool debugEnabled,
|
||||||
TempAllocator* alloc,
|
TempAllocator* alloc,
|
||||||
@ -7673,11 +7675,10 @@ BaseCompiler::init()
|
|||||||
if (!SigI64I64_.append(ValType::I64) || !SigI64I64_.append(ValType::I64))
|
if (!SigI64I64_.append(ValType::I64) || !SigI64I64_.append(ValType::I64))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const ValTypeVector& args = func_.sig().args();
|
|
||||||
|
|
||||||
if (!localInfo_.resize(locals_.length()))
|
if (!localInfo_.resize(locals_.length()))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
const ValTypeVector& args = sig().args();
|
||||||
BaseLocalIter i(locals_, args.length(), debugEnabled_);
|
BaseLocalIter i(locals_, args.length(), debugEnabled_);
|
||||||
varLow_ = i.reservedSize();
|
varLow_ = i.reservedSize();
|
||||||
for (; !i.done() && i.index() < args.length(); i++) {
|
for (; !i.done() && i.index() < args.length(); i++) {
|
||||||
@ -7742,19 +7743,17 @@ js::wasm::BaselineCanCompile()
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
js::wasm::BaselineCompileFunction(CompileTask* task, FuncCompileUnit* unit, UniqueChars *error)
|
js::wasm::BaselineCompileFunction(CompileTask* task, FuncCompileUnit* func, UniqueChars* error)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(task->tier() == Tier::Baseline);
|
MOZ_ASSERT(task->tier() == Tier::Baseline);
|
||||||
MOZ_ASSERT(task->env().kind == ModuleKind::Wasm);
|
MOZ_ASSERT(task->env().kind == ModuleKind::Wasm);
|
||||||
|
|
||||||
const FuncBytes& func = unit->func();
|
Decoder d(func->begin(), func->end(), func->lineOrBytecode(), error);
|
||||||
|
|
||||||
Decoder d(func.bytes().begin(), func.bytes().end(), func.lineOrBytecode(), error);
|
|
||||||
|
|
||||||
// Build the local types vector.
|
// Build the local types vector.
|
||||||
|
|
||||||
ValTypeVector locals;
|
ValTypeVector locals;
|
||||||
if (!locals.appendAll(func.sig().args()))
|
if (!locals.appendAll(task->env().funcSigs[func->index()]->args()))
|
||||||
return false;
|
return false;
|
||||||
if (!DecodeLocalEntries(d, task->env().kind, &locals))
|
if (!DecodeLocalEntries(d, task->env().kind, &locals))
|
||||||
return false;
|
return false;
|
||||||
@ -7765,7 +7764,7 @@ js::wasm::BaselineCompileFunction(CompileTask* task, FuncCompileUnit* unit, Uniq
|
|||||||
|
|
||||||
// One-pass baseline compilation.
|
// One-pass baseline compilation.
|
||||||
|
|
||||||
BaseCompiler f(task->env(), d, func, locals, task->debugEnabled(), &task->alloc(),
|
BaseCompiler f(task->env(), d, *func, locals, task->debugEnabled(), &task->alloc(),
|
||||||
&task->masm(), task->mode());
|
&task->masm(), task->mode());
|
||||||
if (!f.init())
|
if (!f.init())
|
||||||
return false;
|
return false;
|
||||||
@ -7773,7 +7772,7 @@ js::wasm::BaselineCompileFunction(CompileTask* task, FuncCompileUnit* unit, Uniq
|
|||||||
if (!f.emitFunction())
|
if (!f.emitFunction())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
unit->finish(f.finish());
|
func->finish(f.finish());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,21 +42,12 @@ DecodeFunctionBody(Decoder& d, ModuleGenerator& mg, uint32_t funcIndex)
|
|||||||
|
|
||||||
const size_t offsetInModule = d.currentOffset();
|
const size_t offsetInModule = d.currentOffset();
|
||||||
|
|
||||||
// Skip over the function body; we'll validate it later.
|
// Skip over the function body; it will be validated by the compilation thread.
|
||||||
const uint8_t* bodyBegin;
|
const uint8_t* bodyBegin;
|
||||||
if (!d.readBytes(bodySize, &bodyBegin))
|
if (!d.readBytes(bodySize, &bodyBegin))
|
||||||
return d.fail("function body length too big");
|
return d.fail("function body length too big");
|
||||||
|
|
||||||
FunctionGenerator fg;
|
return mg.compileFuncDef(funcIndex, offsetInModule, bodyBegin, bodyBegin + bodySize);
|
||||||
if (!mg.startFuncDef(offsetInModule, &fg))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!fg.bytes().resize(bodySize))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
memcpy(fg.bytes().begin(), bodyBegin, bodySize);
|
|
||||||
|
|
||||||
return mg.finishFuncDef(funcIndex, &fg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
@ -64,7 +64,6 @@ ModuleGenerator::ModuleGenerator(const CompileArgs& args, ModuleEnvironment* env
|
|||||||
outstanding_(0),
|
outstanding_(0),
|
||||||
currentTask_(nullptr),
|
currentTask_(nullptr),
|
||||||
batchedBytecode_(0),
|
batchedBytecode_(0),
|
||||||
activeFuncDef_(nullptr),
|
|
||||||
startedFuncDefs_(false),
|
startedFuncDefs_(false),
|
||||||
finishedFuncDefs_(false),
|
finishedFuncDefs_(false),
|
||||||
numFinishedFuncDefs_(0)
|
numFinishedFuncDefs_(0)
|
||||||
@ -432,12 +431,10 @@ ModuleGenerator::finishTask(CompileTask* task)
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32_t offsetInWhole = masm_.size();
|
uint32_t offsetInWhole = masm_.size();
|
||||||
for (const FuncCompileUnit& unit : task->units()) {
|
for (const FuncCompileUnit& func : task->units()) {
|
||||||
const FuncBytes& func = unit.func();
|
|
||||||
|
|
||||||
// Offset the recorded FuncOffsets by the offset of the function in the
|
// Offset the recorded FuncOffsets by the offset of the function in the
|
||||||
// whole module's code segment.
|
// whole module's code segment.
|
||||||
FuncOffsets offsets = unit.offsets();
|
FuncOffsets offsets = func.offsets();
|
||||||
offsets.offsetBy(offsetInWhole);
|
offsets.offsetBy(offsetInWhole);
|
||||||
|
|
||||||
// Add the CodeRange for this function.
|
// Add the CodeRange for this function.
|
||||||
@ -455,7 +452,7 @@ ModuleGenerator::finishTask(CompileTask* task)
|
|||||||
return false;
|
return false;
|
||||||
MOZ_ASSERT(masm_.size() == offsetInWhole + task->masm().size());
|
MOZ_ASSERT(masm_.size() == offsetInWhole + task->masm().size());
|
||||||
|
|
||||||
if (!task->reset(&freeFuncBytes_))
|
if (!task->reset())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
freeTasks_.infallibleAppend(task);
|
freeTasks_.infallibleAppend(task);
|
||||||
@ -885,34 +882,6 @@ ModuleGenerator::startFuncDefs()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
|
||||||
ModuleGenerator::startFuncDef(uint32_t lineOrBytecode, FunctionGenerator* fg)
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(startedFuncDefs_);
|
|
||||||
MOZ_ASSERT(!activeFuncDef_);
|
|
||||||
MOZ_ASSERT(!finishedFuncDefs_);
|
|
||||||
|
|
||||||
if (!freeFuncBytes_.empty()) {
|
|
||||||
fg->funcBytes_ = Move(freeFuncBytes_.back());
|
|
||||||
freeFuncBytes_.popBack();
|
|
||||||
} else {
|
|
||||||
fg->funcBytes_ = js::MakeUnique<FuncBytes>();
|
|
||||||
if (!fg->funcBytes_)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!currentTask_) {
|
|
||||||
if (freeTasks_.empty() && !finishOutstandingTask())
|
|
||||||
return false;
|
|
||||||
currentTask_ = freeTasks_.popCopy();
|
|
||||||
}
|
|
||||||
|
|
||||||
fg->funcBytes_->setLineOrBytecode(lineOrBytecode);
|
|
||||||
fg->m_ = this;
|
|
||||||
activeFuncDef_ = fg;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ModuleGenerator::launchBatchCompile()
|
ModuleGenerator::launchBatchCompile()
|
||||||
{
|
{
|
||||||
@ -943,15 +912,24 @@ ModuleGenerator::launchBatchCompile()
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ModuleGenerator::finishFuncDef(uint32_t funcIndex, FunctionGenerator* fg)
|
ModuleGenerator::compileFuncDef(uint32_t funcIndex, uint32_t lineOrBytecode,
|
||||||
|
Bytes&& bytes, const uint8_t* begin, const uint8_t* end,
|
||||||
|
Uint32Vector&& lineNums)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(activeFuncDef_ == fg);
|
MOZ_ASSERT(startedFuncDefs_);
|
||||||
|
MOZ_ASSERT(!finishedFuncDefs_);
|
||||||
MOZ_ASSERT_IF(mode() == CompileMode::Tier1, funcIndex < env_->numFuncs());
|
MOZ_ASSERT_IF(mode() == CompileMode::Tier1, funcIndex < env_->numFuncs());
|
||||||
|
|
||||||
UniqueFuncBytes func = Move(fg->funcBytes_);
|
if (!currentTask_) {
|
||||||
func->setFunc(funcIndex, &funcSig(funcIndex));
|
if (freeTasks_.empty() && !finishOutstandingTask())
|
||||||
uint32_t funcBytecodeLength = func->bytes().length();
|
return false;
|
||||||
if (!currentTask_->units().emplaceBack(Move(func)))
|
currentTask_ = freeTasks_.popCopy();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t funcBytecodeLength = end - begin;
|
||||||
|
|
||||||
|
FuncCompileUnitVector& units = currentTask_->units();
|
||||||
|
if (!units.emplaceBack(funcIndex, lineOrBytecode, Move(bytes), begin, end, Move(lineNums)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
uint32_t threshold;
|
uint32_t threshold;
|
||||||
@ -963,19 +941,27 @@ ModuleGenerator::finishFuncDef(uint32_t funcIndex, FunctionGenerator* fg)
|
|||||||
|
|
||||||
batchedBytecode_ += funcBytecodeLength;
|
batchedBytecode_ += funcBytecodeLength;
|
||||||
MOZ_ASSERT(batchedBytecode_ <= MaxModuleBytes);
|
MOZ_ASSERT(batchedBytecode_ <= MaxModuleBytes);
|
||||||
if (batchedBytecode_ > threshold && !launchBatchCompile())
|
return batchedBytecode_ <= threshold || launchBatchCompile();
|
||||||
return false;
|
}
|
||||||
|
|
||||||
fg->m_ = nullptr;
|
bool
|
||||||
activeFuncDef_ = nullptr;
|
ModuleGenerator::compileFuncDef(uint32_t funcIndex, uint32_t lineOrBytecode,
|
||||||
return true;
|
const uint8_t* begin, const uint8_t* end)
|
||||||
|
{
|
||||||
|
return compileFuncDef(funcIndex, lineOrBytecode, Bytes(), begin, end, Uint32Vector());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ModuleGenerator::compileFuncDef(uint32_t funcIndex, uint32_t lineOrBytecode,
|
||||||
|
Bytes&& bytes, Uint32Vector&& lineNums)
|
||||||
|
{
|
||||||
|
return compileFuncDef(funcIndex, lineOrBytecode, Move(bytes), bytes.begin(), bytes.end(), Move(lineNums));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ModuleGenerator::finishFuncDefs()
|
ModuleGenerator::finishFuncDefs()
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(startedFuncDefs_);
|
MOZ_ASSERT(startedFuncDefs_);
|
||||||
MOZ_ASSERT(!activeFuncDef_);
|
|
||||||
MOZ_ASSERT(!finishedFuncDefs_);
|
MOZ_ASSERT(!finishedFuncDefs_);
|
||||||
|
|
||||||
if (currentTask_ && !launchBatchCompile())
|
if (currentTask_ && !launchBatchCompile())
|
||||||
@ -1155,7 +1141,6 @@ ModuleGenerator::finishMetadata(const ShareableBytes& bytecode)
|
|||||||
UniqueConstCodeSegment
|
UniqueConstCodeSegment
|
||||||
ModuleGenerator::finishCodeSegment(const ShareableBytes& bytecode)
|
ModuleGenerator::finishCodeSegment(const ShareableBytes& bytecode)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(!activeFuncDef_);
|
|
||||||
MOZ_ASSERT(finishedFuncDefs_);
|
MOZ_ASSERT(finishedFuncDefs_);
|
||||||
|
|
||||||
if (!finishFuncExports())
|
if (!finishFuncExports())
|
||||||
|
@ -29,77 +29,43 @@ namespace wasm {
|
|||||||
|
|
||||||
struct CompileArgs;
|
struct CompileArgs;
|
||||||
struct ModuleEnvironment;
|
struct ModuleEnvironment;
|
||||||
class FunctionGenerator;
|
|
||||||
|
|
||||||
// The FuncBytes class represents a single, concurrently-compilable function.
|
|
||||||
// A FuncBytes object is composed of the wasm function body bytes along with the
|
|
||||||
// ambient metadata describing the function necessary to compile it.
|
|
||||||
|
|
||||||
class FuncBytes
|
|
||||||
{
|
|
||||||
Bytes bytes_;
|
|
||||||
uint32_t index_;
|
|
||||||
const SigWithId* sig_;
|
|
||||||
uint32_t lineOrBytecode_;
|
|
||||||
Uint32Vector callSiteLineNums_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
FuncBytes()
|
|
||||||
: index_(UINT32_MAX),
|
|
||||||
sig_(nullptr),
|
|
||||||
lineOrBytecode_(UINT32_MAX)
|
|
||||||
{}
|
|
||||||
|
|
||||||
Bytes& bytes() {
|
|
||||||
return bytes_;
|
|
||||||
}
|
|
||||||
MOZ_MUST_USE bool addCallSiteLineNum(uint32_t lineno) {
|
|
||||||
return callSiteLineNums_.append(lineno);
|
|
||||||
}
|
|
||||||
void setLineOrBytecode(uint32_t lineOrBytecode) {
|
|
||||||
MOZ_ASSERT(lineOrBytecode_ == UINT32_MAX);
|
|
||||||
lineOrBytecode_ = lineOrBytecode;
|
|
||||||
}
|
|
||||||
void setFunc(uint32_t index, const SigWithId* sig) {
|
|
||||||
MOZ_ASSERT(index_ == UINT32_MAX);
|
|
||||||
MOZ_ASSERT(sig_ == nullptr);
|
|
||||||
index_ = index;
|
|
||||||
sig_ = sig;
|
|
||||||
}
|
|
||||||
void reset() {
|
|
||||||
bytes_.clear();
|
|
||||||
index_ = UINT32_MAX;
|
|
||||||
sig_ = nullptr;
|
|
||||||
lineOrBytecode_ = UINT32_MAX;
|
|
||||||
callSiteLineNums_.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
const Bytes& bytes() const { return bytes_; }
|
|
||||||
uint32_t index() const { return index_; }
|
|
||||||
const SigWithId& sig() const { return *sig_; }
|
|
||||||
uint32_t lineOrBytecode() const { return lineOrBytecode_; }
|
|
||||||
const Uint32Vector& callSiteLineNums() const { return callSiteLineNums_; }
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef UniquePtr<FuncBytes> UniqueFuncBytes;
|
|
||||||
typedef Vector<UniqueFuncBytes, 8, SystemAllocPolicy> UniqueFuncBytesVector;
|
|
||||||
|
|
||||||
// FuncCompileUnit contains all the data necessary to produce and store the
|
// FuncCompileUnit contains all the data necessary to produce and store the
|
||||||
// results of a single function's compilation.
|
// results of a single function's compilation.
|
||||||
|
|
||||||
class FuncCompileUnit
|
class FuncCompileUnit
|
||||||
{
|
{
|
||||||
UniqueFuncBytes func_;
|
// Input:
|
||||||
|
Bytes bytesToDelete_;
|
||||||
|
const uint8_t* begin_;
|
||||||
|
const uint8_t* end_;
|
||||||
|
uint32_t index_;
|
||||||
|
uint32_t lineOrBytecode_;
|
||||||
|
Uint32Vector callSiteLineNums_;
|
||||||
|
|
||||||
|
// Output:
|
||||||
FuncOffsets offsets_;
|
FuncOffsets offsets_;
|
||||||
DebugOnly<bool> finished_;
|
DebugOnly<bool> finished_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit FuncCompileUnit(UniqueFuncBytes func)
|
explicit FuncCompileUnit(uint32_t index, uint32_t lineOrBytecode,
|
||||||
: func_(Move(func)),
|
Bytes&& bytesToDelete, const uint8_t* begin, const uint8_t* end,
|
||||||
|
Uint32Vector&& callSiteLineNums)
|
||||||
|
: bytesToDelete_(Move(bytesToDelete)),
|
||||||
|
begin_(begin),
|
||||||
|
end_(end),
|
||||||
|
index_(index),
|
||||||
|
lineOrBytecode_(lineOrBytecode),
|
||||||
|
callSiteLineNums_(Move(callSiteLineNums)),
|
||||||
finished_(false)
|
finished_(false)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
const FuncBytes& func() const { return *func_; }
|
const uint8_t* begin() const { return begin_; }
|
||||||
|
const uint8_t* end() const { return end_; }
|
||||||
|
uint32_t index() const { return index_; }
|
||||||
|
uint32_t lineOrBytecode() const { return lineOrBytecode_; }
|
||||||
|
const Uint32Vector& callSiteLineNums() const { return callSiteLineNums_; }
|
||||||
|
|
||||||
FuncOffsets offsets() const { MOZ_ASSERT(finished_); return offsets_; }
|
FuncOffsets offsets() const { MOZ_ASSERT(finished_); return offsets_; }
|
||||||
|
|
||||||
void finish(FuncOffsets offsets) {
|
void finish(FuncOffsets offsets) {
|
||||||
@ -107,12 +73,6 @@ class FuncCompileUnit
|
|||||||
offsets_ = offsets;
|
offsets_ = offsets;
|
||||||
finished_ = true;
|
finished_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
UniqueFuncBytes recycle() {
|
|
||||||
MOZ_ASSERT(finished_);
|
|
||||||
func_->reset();
|
|
||||||
return Move(func_);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef Vector<FuncCompileUnit, 8, SystemAllocPolicy> FuncCompileUnitVector;
|
typedef Vector<FuncCompileUnit, 8, SystemAllocPolicy> FuncCompileUnitVector;
|
||||||
@ -120,8 +80,7 @@ typedef Vector<FuncCompileUnit, 8, SystemAllocPolicy> FuncCompileUnitVector;
|
|||||||
// A CompileTask represents the task of compiling a batch of functions. It is
|
// A CompileTask represents the task of compiling a batch of functions. It is
|
||||||
// filled with a certain number of function's bodies that are sent off to a
|
// filled with a certain number of function's bodies that are sent off to a
|
||||||
// compilation helper thread, which fills in the resulting code offsets, and
|
// compilation helper thread, which fills in the resulting code offsets, and
|
||||||
// finally sent back to the validation thread. To save time allocating and
|
// finally sent back to the validation thread.
|
||||||
// freeing memory, CompileTasks are reset() and reused.
|
|
||||||
|
|
||||||
class CompileTask
|
class CompileTask
|
||||||
{
|
{
|
||||||
@ -170,17 +129,11 @@ class CompileTask
|
|||||||
bool debugEnabled() const {
|
bool debugEnabled() const {
|
||||||
return env_.debug == DebugEnabled::True;
|
return env_.debug == DebugEnabled::True;
|
||||||
}
|
}
|
||||||
bool reset(UniqueFuncBytesVector* freeFuncBytes) {
|
bool reset() {
|
||||||
for (FuncCompileUnit& unit : units_) {
|
|
||||||
if (!freeFuncBytes->emplaceBack(Move(unit.recycle())))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
units_.clear();
|
units_.clear();
|
||||||
masm_.reset();
|
masm_.reset();
|
||||||
alloc_.reset();
|
alloc_.reset();
|
||||||
lifo_.releaseAll();
|
lifo_.releaseAll();
|
||||||
|
|
||||||
init();
|
init();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -233,12 +186,10 @@ class MOZ_STACK_CLASS ModuleGenerator
|
|||||||
uint32_t outstanding_;
|
uint32_t outstanding_;
|
||||||
CompileTaskVector tasks_;
|
CompileTaskVector tasks_;
|
||||||
CompileTaskPtrVector freeTasks_;
|
CompileTaskPtrVector freeTasks_;
|
||||||
UniqueFuncBytesVector freeFuncBytes_;
|
|
||||||
CompileTask* currentTask_;
|
CompileTask* currentTask_;
|
||||||
uint32_t batchedBytecode_;
|
uint32_t batchedBytecode_;
|
||||||
|
|
||||||
// Assertions
|
// Assertions
|
||||||
DebugOnly<FunctionGenerator*> activeFuncDef_;
|
|
||||||
DebugOnly<bool> startedFuncDefs_;
|
DebugOnly<bool> startedFuncDefs_;
|
||||||
DebugOnly<bool> finishedFuncDefs_;
|
DebugOnly<bool> finishedFuncDefs_;
|
||||||
DebugOnly<uint32_t> numFinishedFuncDefs_;
|
DebugOnly<uint32_t> numFinishedFuncDefs_;
|
||||||
@ -262,6 +213,9 @@ class MOZ_STACK_CLASS ModuleGenerator
|
|||||||
MOZ_MUST_USE bool allocateGlobal(GlobalDesc* global);
|
MOZ_MUST_USE bool allocateGlobal(GlobalDesc* global);
|
||||||
|
|
||||||
MOZ_MUST_USE bool launchBatchCompile();
|
MOZ_MUST_USE bool launchBatchCompile();
|
||||||
|
MOZ_MUST_USE bool compileFuncDef(uint32_t funcIndex, uint32_t lineOrBytecode,
|
||||||
|
Bytes&& bytes, const uint8_t* begin, const uint8_t* end,
|
||||||
|
Uint32Vector&& lineNums);
|
||||||
|
|
||||||
MOZ_MUST_USE bool initAsmJS(Metadata* asmJSMetadata);
|
MOZ_MUST_USE bool initAsmJS(Metadata* asmJSMetadata);
|
||||||
MOZ_MUST_USE bool initWasm();
|
MOZ_MUST_USE bool initWasm();
|
||||||
@ -280,8 +234,10 @@ class MOZ_STACK_CLASS ModuleGenerator
|
|||||||
|
|
||||||
// Function definitions:
|
// Function definitions:
|
||||||
MOZ_MUST_USE bool startFuncDefs();
|
MOZ_MUST_USE bool startFuncDefs();
|
||||||
MOZ_MUST_USE bool startFuncDef(uint32_t lineOrBytecode, FunctionGenerator* fg);
|
MOZ_MUST_USE bool compileFuncDef(uint32_t funcIndex, uint32_t lineOrBytecode,
|
||||||
MOZ_MUST_USE bool finishFuncDef(uint32_t funcIndex, FunctionGenerator* fg);
|
const uint8_t* begin, const uint8_t* end);
|
||||||
|
MOZ_MUST_USE bool compileFuncDef(uint32_t funcIndex, uint32_t lineOrBytecode,
|
||||||
|
Bytes&& bytes, Uint32Vector&& callSiteLineNums);
|
||||||
MOZ_MUST_USE bool finishFuncDefs();
|
MOZ_MUST_USE bool finishFuncDefs();
|
||||||
|
|
||||||
// asm.js accessors:
|
// asm.js accessors:
|
||||||
@ -309,33 +265,6 @@ class MOZ_STACK_CLASS ModuleGenerator
|
|||||||
MOZ_MUST_USE bool finishTier2(Module& module);
|
MOZ_MUST_USE bool finishTier2(Module& module);
|
||||||
};
|
};
|
||||||
|
|
||||||
// A FunctionGenerator encapsulates the generation of a single function body.
|
|
||||||
// ModuleGenerator::startFuncDef must be called after construction and before
|
|
||||||
// doing anything else.
|
|
||||||
//
|
|
||||||
// After the body is complete, ModuleGenerator::finishFuncDef must be called
|
|
||||||
// before the FunctionGenerator is destroyed and the next function is started.
|
|
||||||
|
|
||||||
class MOZ_STACK_CLASS FunctionGenerator
|
|
||||||
{
|
|
||||||
friend class ModuleGenerator;
|
|
||||||
|
|
||||||
ModuleGenerator* m_;
|
|
||||||
UniqueFuncBytes funcBytes_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
FunctionGenerator()
|
|
||||||
: m_(nullptr), funcBytes_(nullptr)
|
|
||||||
{}
|
|
||||||
|
|
||||||
Bytes& bytes() {
|
|
||||||
return funcBytes_->bytes();
|
|
||||||
}
|
|
||||||
MOZ_MUST_USE bool addCallSiteLineNum(uint32_t lineno) {
|
|
||||||
return funcBytes_->addCallSiteLineNum(lineno);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace wasm
|
} // namespace wasm
|
||||||
} // namespace js
|
} // namespace js
|
||||||
|
|
||||||
|
@ -126,7 +126,7 @@ class FunctionCompiler
|
|||||||
|
|
||||||
const ModuleEnvironment& env_;
|
const ModuleEnvironment& env_;
|
||||||
IonOpIter iter_;
|
IonOpIter iter_;
|
||||||
const FuncBytes& func_;
|
const FuncCompileUnit& func_;
|
||||||
const ValTypeVector& locals_;
|
const ValTypeVector& locals_;
|
||||||
size_t lastReadCallSite_;
|
size_t lastReadCallSite_;
|
||||||
|
|
||||||
@ -149,7 +149,7 @@ class FunctionCompiler
|
|||||||
public:
|
public:
|
||||||
FunctionCompiler(const ModuleEnvironment& env,
|
FunctionCompiler(const ModuleEnvironment& env,
|
||||||
Decoder& decoder,
|
Decoder& decoder,
|
||||||
const FuncBytes& func,
|
const FuncCompileUnit& func,
|
||||||
const ValTypeVector& locals,
|
const ValTypeVector& locals,
|
||||||
MIRGenerator& mirGen)
|
MIRGenerator& mirGen)
|
||||||
: env_(env),
|
: env_(env),
|
||||||
@ -171,7 +171,7 @@ class FunctionCompiler
|
|||||||
const ModuleEnvironment& env() const { return env_; }
|
const ModuleEnvironment& env() const { return env_; }
|
||||||
IonOpIter& iter() { return iter_; }
|
IonOpIter& iter() { return iter_; }
|
||||||
TempAllocator& alloc() const { return alloc_; }
|
TempAllocator& alloc() const { return alloc_; }
|
||||||
const Sig& sig() const { return func_.sig(); }
|
const Sig& sig() const { return *env_.funcSigs[func_.index()]; }
|
||||||
|
|
||||||
BytecodeOffset bytecodeOffset() const {
|
BytecodeOffset bytecodeOffset() const {
|
||||||
return iter_.bytecodeOffset();
|
return iter_.bytecodeOffset();
|
||||||
@ -184,7 +184,7 @@ class FunctionCompiler
|
|||||||
{
|
{
|
||||||
// Prepare the entry block for MIR generation:
|
// Prepare the entry block for MIR generation:
|
||||||
|
|
||||||
const ValTypeVector& args = func_.sig().args();
|
const ValTypeVector& args = sig().args();
|
||||||
|
|
||||||
if (!mirGen_.ensureBallast())
|
if (!mirGen_.ensureBallast())
|
||||||
return false;
|
return false;
|
||||||
@ -3852,19 +3852,18 @@ EmitBodyExprs(FunctionCompiler& f)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
wasm::IonCompileFunction(CompileTask* task, FuncCompileUnit* unit, UniqueChars* error)
|
wasm::IonCompileFunction(CompileTask* task, FuncCompileUnit* func, UniqueChars* error)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(task->tier() == Tier::Ion);
|
MOZ_ASSERT(task->tier() == Tier::Ion);
|
||||||
|
|
||||||
const FuncBytes& func = unit->func();
|
|
||||||
const ModuleEnvironment& env = task->env();
|
const ModuleEnvironment& env = task->env();
|
||||||
|
|
||||||
Decoder d(func.bytes().begin(), func.bytes().end(), func.lineOrBytecode(), error);
|
Decoder d(func->begin(), func->end(), func->lineOrBytecode(), error);
|
||||||
|
|
||||||
// Build the local types vector.
|
// Build the local types vector.
|
||||||
|
|
||||||
ValTypeVector locals;
|
ValTypeVector locals;
|
||||||
if (!locals.appendAll(func.sig().args()))
|
if (!locals.appendAll(task->env().funcSigs[func->index()]->args()))
|
||||||
return false;
|
return false;
|
||||||
if (!DecodeLocalEntries(d, env.kind, &locals))
|
if (!DecodeLocalEntries(d, env.kind, &locals))
|
||||||
return false;
|
return false;
|
||||||
@ -3881,7 +3880,7 @@ wasm::IonCompileFunction(CompileTask* task, FuncCompileUnit* unit, UniqueChars*
|
|||||||
|
|
||||||
// Build MIR graph
|
// Build MIR graph
|
||||||
{
|
{
|
||||||
FunctionCompiler f(env, d, func, locals, mir);
|
FunctionCompiler f(env, d, *func, locals, mir);
|
||||||
if (!f.init())
|
if (!f.init())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -3906,16 +3905,16 @@ wasm::IonCompileFunction(CompileTask* task, FuncCompileUnit* unit, UniqueChars*
|
|||||||
if (!lir)
|
if (!lir)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
SigIdDesc sigId = env.funcSigs[func.index()]->id;
|
SigIdDesc sigId = env.funcSigs[func->index()]->id;
|
||||||
|
|
||||||
CodeGenerator codegen(&mir, lir, &task->masm());
|
CodeGenerator codegen(&mir, lir, &task->masm());
|
||||||
|
|
||||||
BytecodeOffset prologueTrapOffset(func.lineOrBytecode());
|
BytecodeOffset prologueTrapOffset(func->lineOrBytecode());
|
||||||
FuncOffsets offsets;
|
FuncOffsets offsets;
|
||||||
if (!codegen.generateWasm(sigId, prologueTrapOffset, &offsets))
|
if (!codegen.generateWasm(sigId, prologueTrapOffset, &offsets))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
unit->finish(offsets);
|
func->finish(offsets);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
Loading…
Reference in New Issue
Block a user