Bug 1330891 - Baldr: simplify ModuleGenerator (r=bbouvier)

MozReview-Commit-ID: LrBIuXsUhtX
This commit is contained in:
Luke Wagner 2017-01-17 13:13:51 -06:00
Родитель 0a37fafed0
Коммит 7d79c6f41c
9 изменённых файлов: 58 добавлений и 78 удалений

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

@ -1 +1 @@
|jit-test| test-also-noasmjs; test-also-wasm-baseline
|jit-test| test-also-noasmjs

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

@ -238,14 +238,10 @@ DefaultJitOptions::DefaultJitOptions()
SET_DEFAULT(wasmFoldOffsets, true);
// Until which wasm bytecode size should we accumulate functions, in order
// to compile efficiently on helper threads (see also bug 1320374).
SET_DEFAULT(wasmBatchThreshold, 10000);
// In order to have different batching thresholds for Ion and the wasm
// baseline, and since a same batch can contain both Ion and baseline
// compiled functions, we make Ion functions weight more by using a scaling
// factor.
SET_DEFAULT(wasmBatchIonScaleFactor, 9);
// to compile efficiently on helper threads. Baseline code compiles much
// faster than Ion code so use scaled thresholds (see also bug 1320374).
SET_DEFAULT(wasmBatchBaselineThreshold, 10000);
SET_DEFAULT(wasmBatchIonThreshold, 1100);
// Determines whether we suppress using signal handlers
// for interrupting jit-ed code. This is used only for testing.

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

@ -87,8 +87,8 @@ struct DefaultJitOptions
uint32_t branchPruningBlockSpanFactor;
uint32_t branchPruningEffectfulInstFactor;
uint32_t branchPruningThreshold;
uint32_t wasmBatchThreshold;
uint32_t wasmBatchIonScaleFactor;
uint32_t wasmBatchIonThreshold;
uint32_t wasmBatchBaselineThreshold;
mozilla::Maybe<uint32_t> forcedDefaultIonWarmUpThreshold;
mozilla::Maybe<uint32_t> forcedDefaultIonSmallFunctionWarmUpThreshold;
mozilla::Maybe<IonRegisterAllocator> forcedRegisterAllocator;

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

@ -138,7 +138,7 @@ class JitTest:
t.valgrind = self.valgrind
t.tz_pacific = self.tz_pacific
t.test_also_noasmjs = self.test_also_noasmjs
t.test_also_wasm_baseline = self.test_also_noasmjs
t.test_also_wasm_baseline = self.test_also_wasm_baseline
t.test_also = self.test_also
t.test_join = self.test_join
t.expect_error = self.expect_error

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

@ -7902,7 +7902,7 @@ LiveRegisterSet BaseCompiler::VolatileReturnGPR = volatileReturnGPR();
} // js
bool
js::wasm::BaselineCanCompile(const FunctionGenerator* fg)
js::wasm::BaselineCanCompile()
{
// On all platforms we require signals for AsmJS/Wasm.
// If we made it this far we must have signals.
@ -7920,12 +7920,6 @@ js::wasm::BaselineCanCompile(const FunctionGenerator* fg)
#endif
#if defined(JS_CODEGEN_X64) || defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_ARM)
// AsmJS code may use SIMD or atomics, which Baseline doesn't currently
// handle. Since we haven't yet validated the function, we don't know
// whether it actually uses those features. Assume the worst.
if (fg->isAsmJS())
return false;
return true;
#else
return false;
@ -7935,7 +7929,7 @@ js::wasm::BaselineCanCompile(const FunctionGenerator* fg)
bool
js::wasm::BaselineCompileFunction(CompileTask* task, FuncCompileUnit* unit, UniqueChars *error)
{
MOZ_ASSERT(unit->mode() == CompileMode::Baseline);
MOZ_ASSERT(task->mode() == CompileMode::Baseline);
const FuncBytes& func = unit->func();
uint32_t bodySize = func.bytes().length();

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

@ -24,21 +24,13 @@
namespace js {
namespace wasm {
class FunctionGenerator;
class CompileTask;
class FuncCompileUnit;
// Return true if BaselineCompileFunction can generate code for the
// function held in the FunctionGenerator. If false is returned a
// different compilation strategy must be chosen.
//
// This allows the baseline compiler to have different capabilities on
// different platforms and defer to the full Ion compiler if
// capabilities are missing. The FunctionGenerator and other data
// structures contain information about the capabilities that are
// required to compile the function.
// Return whether BaselineCompileFunction can generate code on the current device.
// Note: asm.js is also currently not supported due to Atomics and SIMD.
bool
BaselineCanCompile(const FunctionGenerator* fg);
BaselineCanCompile();
// Generate adequate code quickly.
bool

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

@ -45,8 +45,7 @@ static const unsigned COMPILATION_LIFO_DEFAULT_CHUNK_SIZE = 64 * 1024;
static const uint32_t BAD_CODE_RANGE = UINT32_MAX;
ModuleGenerator::ModuleGenerator(UniqueChars* error)
: alwaysBaseline_(false),
debugEnabled_(false),
: compileMode_(CompileMode(-1)),
error_(error),
numSigs_(0),
numTables_(0),
@ -112,6 +111,12 @@ ModuleGenerator::initAsmJS(Metadata* asmJSMetadata)
metadata_ = asmJSMetadata;
MOZ_ASSERT(isAsmJS());
// Enabling debugging requires baseline and baseline is only enabled for
// wasm (since the baseline does not currently support Atomics or SIMD).
metadata_->debugEnabled = false;
compileMode_ = CompileMode::Ion;
// For asm.js, the Vectors in ModuleEnvironment are max-sized reservations
// and will be initialized in a linear order via init* functions as the
// module is generated.
@ -124,7 +129,7 @@ ModuleGenerator::initAsmJS(Metadata* asmJSMetadata)
}
bool
ModuleGenerator::initWasm()
ModuleGenerator::initWasm(const CompileArgs& args)
{
MOZ_ASSERT(!env_->isAsmJS());
@ -134,6 +139,11 @@ ModuleGenerator::initWasm()
MOZ_ASSERT(!isAsmJS());
metadata_->debugEnabled = args.debugEnabled && BaselineCanCompile();
compileMode_ = args.alwaysBaseline || metadata_->debugEnabled
? CompileMode::Baseline
: CompileMode::Ion;
// For wasm, the Vectors are correctly-sized and already initialized.
numSigs_ = env_->sigs.length();
@ -202,9 +212,6 @@ ModuleGenerator::init(UniqueModuleEnvironment env, const CompileArgs& args,
linkData_.globalDataLength = AlignBytes(InitialGlobalDataBytes, sizeof(void*));
alwaysBaseline_ = args.alwaysBaseline;
debugEnabled_ = args.debugEnabled;
if (!funcToCodeRange_.appendN(BAD_CODE_RANGE, env_->funcSigs.length()))
return false;
@ -214,7 +221,7 @@ ModuleGenerator::init(UniqueModuleEnvironment env, const CompileArgs& args,
if (!exportedFuncs_.init())
return false;
if (env_->isAsmJS() ? !initAsmJS(maybeAsmJSMetadata) : !initWasm())
if (env_->isAsmJS() ? !initAsmJS(maybeAsmJSMetadata) : !initWasm(args))
return false;
if (args.scriptedCaller.filename) {
@ -903,7 +910,7 @@ ModuleGenerator::startFuncDefs()
if (!tasks_.initCapacity(numTasks))
return false;
for (size_t i = 0; i < numTasks; i++)
tasks_.infallibleEmplaceBack(*env_, COMPILATION_LIFO_DEFAULT_CHUNK_SIZE);
tasks_.infallibleEmplaceBack(*env_, compileMode_, COMPILATION_LIFO_DEFAULT_CHUNK_SIZE);
if (!freeTasks_.reserve(numTasks))
return false;
@ -948,7 +955,7 @@ ModuleGenerator::launchBatchCompile()
{
MOZ_ASSERT(currentTask_);
currentTask_->setDebugEnabled(debugEnabled_);
currentTask_->setDebugEnabled(metadata_->debugEnabled);
size_t numBatchedFuncs = currentTask_->units().length();
MOZ_ASSERT(numBatchedFuncs);
@ -977,30 +984,20 @@ ModuleGenerator::finishFuncDef(uint32_t funcIndex, FunctionGenerator* fg)
MOZ_ASSERT(activeFuncDef_ == fg);
UniqueFuncBytes func = Move(fg->funcBytes_);
func->setFunc(funcIndex, &funcSig(funcIndex));
CompileMode mode;
if ((alwaysBaseline_ || debugEnabled_) && BaselineCanCompile(fg)) {
mode = CompileMode::Baseline;
} else {
mode = CompileMode::Ion;
// Ion does not support debugging -- reset debugEnabled_ flags to avoid
// turning debugging for wasm::Code.
debugEnabled_ = false;
}
CheckedInt<uint32_t> newBatched = func->bytes().length();
if (mode == CompileMode::Ion)
newBatched *= JitOptions.wasmBatchIonScaleFactor;
newBatched += batchedBytecode_;
if (!currentTask_->units().emplaceBack(Move(func), mode))
uint32_t funcBytecodeLength = func->bytes().length();
if (!currentTask_->units().emplaceBack(Move(func)))
return false;
if (newBatched.isValid() && newBatched.value() < JitOptions.wasmBatchThreshold)
batchedBytecode_ = newBatched.value();
else if (!launchBatchCompile())
uint32_t threshold;
switch (compileMode_) {
case CompileMode::Baseline: threshold = JitOptions.wasmBatchBaselineThreshold; break;
case CompileMode::Ion: threshold = JitOptions.wasmBatchIonThreshold; break;
}
batchedBytecode_ += funcBytecodeLength;
MOZ_ASSERT(batchedBytecode_ <= MaxModuleBytes);
if (batchedBytecode_ > threshold && !launchBatchCompile())
return false;
fg->m_ = nullptr;
@ -1189,8 +1186,6 @@ ModuleGenerator::finish(const ShareableBytes& bytecode)
if (isAsmJS() && !metadata_->tables.resize(numTables_))
return nullptr;
metadata_->debugEnabled = debugEnabled_;
// Assert CodeRanges are sorted.
#ifdef DEBUG
uint32_t lastEnd = 0;
@ -1229,17 +1224,19 @@ wasm::CompileFunction(CompileTask* task, UniqueChars* error)
TraceLoggerThread* logger = TraceLoggerForCurrentThread();
AutoTraceLog logCompile(logger, TraceLogger_WasmCompilation);
for (FuncCompileUnit& unit : task->units()) {
switch (unit.mode()) {
case CompileMode::Ion:
switch (task->mode()) {
case CompileMode::Ion:
for (FuncCompileUnit& unit : task->units()) {
if (!IonCompileFunction(task, &unit, error))
return false;
break;
case CompileMode::Baseline:
}
break;
case CompileMode::Baseline:
for (FuncCompileUnit& unit : task->units()) {
if (!BaselineCompileFunction(task, &unit, error))
return false;
break;
}
break;
}
return true;

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

@ -101,19 +101,16 @@ enum class CompileMode
class FuncCompileUnit
{
UniqueFuncBytes func_;
CompileMode mode_;
FuncOffsets offsets_;
DebugOnly<bool> finished_;
public:
FuncCompileUnit(UniqueFuncBytes func, CompileMode mode)
explicit FuncCompileUnit(UniqueFuncBytes func)
: func_(Move(func)),
mode_(mode),
finished_(false)
{}
const FuncBytes& func() const { return *func_; }
CompileMode mode() const { return mode_; }
FuncOffsets offsets() const { MOZ_ASSERT(finished_); return offsets_; }
void finish(FuncOffsets offsets) {
@ -140,6 +137,7 @@ typedef Vector<FuncCompileUnit, 8, SystemAllocPolicy> FuncCompileUnitVector;
class CompileTask
{
const ModuleEnvironment& env_;
CompileMode mode_;
LifoAlloc lifo_;
Maybe<jit::TempAllocator> alloc_;
Maybe<jit::MacroAssembler> masm_;
@ -156,8 +154,9 @@ class CompileTask
}
public:
CompileTask(const ModuleEnvironment& env, size_t defaultChunkSize)
CompileTask(const ModuleEnvironment& env, CompileMode mode, size_t defaultChunkSize)
: env_(env),
mode_(mode),
lifo_(defaultChunkSize)
{
init();
@ -177,6 +176,9 @@ class CompileTask
FuncCompileUnitVector& units() {
return units_;
}
CompileMode mode() const {
return mode_;
}
bool debugEnabled() const {
return debugEnabled_;
}
@ -213,8 +215,7 @@ class MOZ_STACK_CLASS ModuleGenerator
typedef EnumeratedArray<Trap, Trap::Limit, ProfilingOffsets> TrapExitOffsetArray;
// Constant parameters
bool alwaysBaseline_;
bool debugEnabled_;
CompileMode compileMode_;
UniqueChars* error_;
// Data that is moved into the result of finish()
@ -268,7 +269,7 @@ class MOZ_STACK_CLASS ModuleGenerator
MOZ_MUST_USE bool launchBatchCompile();
MOZ_MUST_USE bool initAsmJS(Metadata* asmJSMetadata);
MOZ_MUST_USE bool initWasm();
MOZ_MUST_USE bool initWasm(const CompileArgs& args);
public:
explicit ModuleGenerator(UniqueChars* error);

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

@ -3657,7 +3657,7 @@ EmitExpr(FunctionCompiler& f)
bool
wasm::IonCompileFunction(CompileTask* task, FuncCompileUnit* unit, UniqueChars* error)
{
MOZ_ASSERT(unit->mode() == CompileMode::Ion);
MOZ_ASSERT(task->mode() == CompileMode::Ion);
const FuncBytes& func = unit->func();
const ModuleEnvironment& env = task->env();