Bug 1329018 - Part 1: Wasm: Add plumbing for compile threads to report validation errors. r=luke

MozReview-Commit-ID: 2cS7skk5tdk

--HG--
extra : rebase_source : 24dd758202e5b15efc9a0bbb5aa7f115cee25683
This commit is contained in:
David Major 2017-01-06 17:15:23 -06:00
Родитель 839ad41abf
Коммит ce404f2d14
10 изменённых файлов: 44 добавлений и 17 удалений

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

@ -1416,11 +1416,12 @@ HelperThread::handleWasmWorkload(AutoLockHelperThreadState& locked)
currentTask.emplace(HelperThreadState().wasmWorklist(locked).popCopy());
bool success = false;
UniqueChars error;
wasm::CompileTask* task = wasmTask();
{
AutoUnlockHelperThreadState unlock(locked);
success = wasm::CompileFunction(task);
success = wasm::CompileFunction(task, &error);
}
// On success, try to move work to the finished list.
@ -1428,8 +1429,10 @@ HelperThread::handleWasmWorkload(AutoLockHelperThreadState& locked)
success = HelperThreadState().wasmFinishedList(locked).append(task);
// On failure, note the failure for harvesting by the parent.
if (!success)
if (!success) {
HelperThreadState().noteWasmFailure(locked);
HelperThreadState().setWasmError(locked, Move(error));
}
// Notify the main thread in case it's waiting.
HelperThreadState().notifyAll(GlobalHelperThreadState::CONSUMER, locked);

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

@ -220,10 +220,17 @@ class GlobalHelperThreadState
numWasmFailedJobs = 0;
return n;
}
UniqueChars harvestWasmError(const AutoLockHelperThreadState&) {
return Move(firstWasmError);
}
void noteWasmFailure(const AutoLockHelperThreadState&) {
// Be mindful to signal the main thread after calling this function.
numWasmFailedJobs++;
}
void setWasmError(const AutoLockHelperThreadState&, UniqueChars error) {
if (!firstWasmError)
firstWasmError = Move(error);
}
bool wasmFailed(const AutoLockHelperThreadState&) {
return bool(numWasmFailedJobs);
}
@ -243,6 +250,11 @@ class GlobalHelperThreadState
* Their parent is logically the main thread, and this number serves for harvesting.
*/
uint32_t numWasmFailedJobs;
/*
* Error string from wasm validation. Arbitrarily choose to keep the first one that gets
* reported. Nondeterministic if multiple threads have errors.
*/
UniqueChars firstWasmError;
public:
JSScript* finishScriptParseTask(JSContext* cx, void* token);
@ -404,7 +416,7 @@ namespace wasm {
// Performs MIR optimization and LIR generation on one or several functions.
MOZ_MUST_USE bool
CompileFunction(CompileTask* task);
CompileFunction(CompileTask* task, UniqueChars* error);
}

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

@ -1724,6 +1724,7 @@ class MOZ_STACK_CLASS ModuleValidator
arrayViews_(cx),
atomicsPresent_(false),
simdPresent_(false),
mg_(nullptr),
errorString_(nullptr),
errorOffset_(UINT32_MAX),
errorOverRecursed_(false)

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

@ -7894,13 +7894,13 @@ js::wasm::BaselineCanCompile(const FunctionGenerator* fg)
}
bool
js::wasm::BaselineCompileFunction(CompileTask* task, FuncCompileUnit* unit)
js::wasm::BaselineCompileFunction(CompileTask* task, FuncCompileUnit* unit, UniqueChars* error)
{
MOZ_ASSERT(unit->mode() == CompileMode::Baseline);
const FuncBytes& func = unit->func();
Decoder d(func.bytes());
Decoder d(func.bytes(), error);
// Build the local types vector.

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

@ -19,6 +19,8 @@
#ifndef asmjs_wasm_baseline_compile_h
#define asmjs_wasm_baseline_compile_h
#include "wasm/WasmTypes.h"
namespace js {
namespace wasm {
@ -40,7 +42,7 @@ BaselineCanCompile(const FunctionGenerator* fg);
// Generate adequate code quickly.
bool
BaselineCompileFunction(CompileTask* task, FuncCompileUnit* unit);
BaselineCompileFunction(CompileTask* task, FuncCompileUnit* unit, UniqueChars* error);
} // namespace wasm
} // namespace js

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

@ -117,7 +117,7 @@ wasm::Compile(const ShareableBytes& bytecode, const CompileArgs& args, UniqueCha
if (!DecodeModuleEnvironment(d, env.get()))
return nullptr;
ModuleGenerator mg;
ModuleGenerator mg(error);
if (!mg.init(Move(env), args))
return nullptr;

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

@ -44,8 +44,9 @@ static const unsigned GENERATOR_LIFO_DEFAULT_CHUNK_SIZE = 4 * 1024;
static const unsigned COMPILATION_LIFO_DEFAULT_CHUNK_SIZE = 64 * 1024;
static const uint32_t BAD_CODE_RANGE = UINT32_MAX;
ModuleGenerator::ModuleGenerator()
ModuleGenerator::ModuleGenerator(UniqueChars* error)
: alwaysBaseline_(false),
error_(error),
numSigs_(0),
numTables_(0),
lifo_(GENERATOR_LIFO_DEFAULT_CHUNK_SIZE),
@ -242,8 +243,13 @@ ModuleGenerator::finishOutstandingTask()
while (true) {
MOZ_ASSERT(outstanding_ > 0);
if (HelperThreadState().wasmFailed(lock))
if (HelperThreadState().wasmFailed(lock)) {
if (error_) {
MOZ_ASSERT(!*error_, "Should have stopped earlier");
*error_ = Move(HelperThreadState().harvestWasmError(lock));
}
return false;
}
if (!HelperThreadState().wasmFinishedList(lock).empty()) {
outstanding_--;
@ -917,7 +923,7 @@ ModuleGenerator::launchBatchCompile()
return false;
outstanding_++;
} else {
if (!CompileFunction(currentTask_))
if (!CompileFunction(currentTask_, error_))
return false;
if (!finishTask(currentTask_))
return false;
@ -1165,7 +1171,7 @@ ModuleGenerator::finish(const ShareableBytes& bytecode)
}
bool
wasm::CompileFunction(CompileTask* task)
wasm::CompileFunction(CompileTask* task, UniqueChars* error)
{
TraceLoggerThread* logger = TraceLoggerForCurrentThread();
AutoTraceLog logCompile(logger, TraceLogger_WasmCompilation);
@ -1173,11 +1179,11 @@ wasm::CompileFunction(CompileTask* task)
for (FuncCompileUnit& unit : task->units()) {
switch (unit.mode()) {
case CompileMode::Ion:
if (!IonCompileFunction(task, &unit))
if (!IonCompileFunction(task, &unit, error))
return false;
break;
case CompileMode::Baseline:
if (!BaselineCompileFunction(task, &unit))
if (!BaselineCompileFunction(task, &unit, error))
return false;
break;
}

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

@ -206,6 +206,7 @@ class MOZ_STACK_CLASS ModuleGenerator
// Constant parameters
bool alwaysBaseline_;
UniqueChars* error_;
// Data that is moved into the result of finish()
Assumptions assumptions_;
@ -260,7 +261,7 @@ class MOZ_STACK_CLASS ModuleGenerator
MOZ_MUST_USE bool initWasm();
public:
explicit ModuleGenerator();
explicit ModuleGenerator(UniqueChars* error);
~ModuleGenerator();
MOZ_MUST_USE bool init(UniqueModuleEnvironment env, const CompileArgs& args,

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

@ -3655,14 +3655,14 @@ EmitExpr(FunctionCompiler& f)
}
bool
wasm::IonCompileFunction(CompileTask* task, FuncCompileUnit* unit)
wasm::IonCompileFunction(CompileTask* task, FuncCompileUnit* unit, UniqueChars* error)
{
MOZ_ASSERT(unit->mode() == CompileMode::Ion);
const FuncBytes& func = unit->func();
const ModuleEnvironment& env = task->env();
Decoder d(func.bytes());
Decoder d(func.bytes(), error);
// Build the local types vector.

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

@ -21,6 +21,8 @@
#include "mozilla/Attributes.h"
#include "wasm/WasmTypes.h"
namespace js {
namespace wasm {
@ -29,7 +31,7 @@ class FuncCompileUnit;
// Generates very fast code at the expense of compilation time.
MOZ_MUST_USE bool
IonCompileFunction(CompileTask* task, FuncCompileUnit* unit);
IonCompileFunction(CompileTask* task, FuncCompileUnit* unit, UniqueChars* error);
} // namespace wasm
} // namespace js