[wasm] Fix CFI failures due to Wasm threads.

R=ahaas@chromium.org,machenbach@chromium.org
BUG=

Review-Url: https://codereview.chromium.org/2055803002
Cr-Commit-Position: refs/heads/master@{#36866}
This commit is contained in:
titzer 2016-06-09 07:22:05 -07:00 committed by Commit bot
parent 280b838255
commit 26afd571c5
4 changed files with 45 additions and 39 deletions

View File

@ -1675,13 +1675,19 @@ class WasmInterpreterInternals : public ZoneObject {
public:
WasmModuleInstance* instance_;
CodeMap codemap_;
ZoneVector<ThreadImpl> threads_;
ZoneVector<ThreadImpl*> threads_;
WasmInterpreterInternals(Zone* zone, WasmModuleInstance* instance)
: instance_(instance),
codemap_(instance_ ? instance_->module : nullptr, zone),
threads_(zone) {
threads_.push_back(ThreadImpl(zone, &codemap_, instance));
threads_.push_back(new ThreadImpl(zone, &codemap_, instance));
}
void Delete() {
// TODO(titzer): CFI doesn't like threads in the ZoneVector.
for (auto t : threads_) delete t;
threads_.resize(0);
}
};
@ -1693,11 +1699,11 @@ WasmInterpreter::WasmInterpreter(WasmModuleInstance* instance,
: zone_(allocator),
internals_(new (&zone_) WasmInterpreterInternals(&zone_, instance)) {}
WasmInterpreter::~WasmInterpreter() {}
WasmInterpreter::~WasmInterpreter() { internals_->Delete(); }
void WasmInterpreter::Run() { internals_->threads_[0].Run(); }
void WasmInterpreter::Run() { internals_->threads_[0]->Run(); }
void WasmInterpreter::Pause() { internals_->threads_[0].Pause(); }
void WasmInterpreter::Pause() { internals_->threads_[0]->Pause(); }
bool WasmInterpreter::SetBreakpoint(const WasmFunction* function, pc_t pc,
bool enabled) {
@ -1740,7 +1746,7 @@ int WasmInterpreter::GetThreadCount() {
return 1; // only one thread for now.
}
WasmInterpreter::Thread& WasmInterpreter::GetThread(int id) {
WasmInterpreter::Thread* WasmInterpreter::GetThread(int id) {
CHECK_EQ(0, id); // only one thread for now.
return internals_->threads_[id];
}

View File

@ -163,7 +163,7 @@ class WasmInterpreter {
// Thread iteration and inspection.
//==========================================================================
int GetThreadCount();
Thread& GetThread(int id);
Thread* GetThread(int id);
//==========================================================================
// Stack frame inspection.

View File

@ -176,7 +176,7 @@ TEST(Breakpoint_I32Add) {
r.Build(code, code + arraysize(code));
WasmInterpreter* interpreter = r.interpreter();
WasmInterpreter::Thread& thread = interpreter->GetThread(0);
WasmInterpreter::Thread* thread = interpreter->GetThread(0);
for (int i = 0; i < kNumBreakpoints; i++) {
interpreter->SetBreakpoint(r.function(), kLocalsDeclSize + offsets[i],
true);
@ -184,23 +184,23 @@ TEST(Breakpoint_I32Add) {
FOR_UINT32_INPUTS(a) {
for (uint32_t b = 11; b < 3000000000u; b += 1000000000u) {
thread.Reset();
thread->Reset();
WasmVal args[] = {WasmVal(*a), WasmVal(b)};
thread.PushFrame(r.function(), args);
thread->PushFrame(r.function(), args);
for (int i = 0; i < kNumBreakpoints; i++) {
thread.Run(); // run to next breakpoint
thread->Run(); // run to next breakpoint
// Check the thread stopped at the right pc.
CHECK_EQ(WasmInterpreter::PAUSED, thread.state());
CHECK_EQ(kLocalsDeclSize + offsets[i], thread.GetBreakpointPc());
CHECK_EQ(WasmInterpreter::PAUSED, thread->state());
CHECK_EQ(kLocalsDeclSize + offsets[i], thread->GetBreakpointPc());
}
thread.Run(); // run to completion
thread->Run(); // run to completion
// Check the thread finished with the right value.
CHECK_EQ(WasmInterpreter::FINISHED, thread.state());
CHECK_EQ(WasmInterpreter::FINISHED, thread->state());
uint32_t expected = (*a) + (b);
CHECK_EQ(expected, thread.GetReturnValue().to<uint32_t>());
CHECK_EQ(expected, thread->GetReturnValue().to<uint32_t>());
}
}
}
@ -215,28 +215,28 @@ TEST(Step_I32Mul) {
r.Build(code, code + arraysize(code));
WasmInterpreter* interpreter = r.interpreter();
WasmInterpreter::Thread& thread = interpreter->GetThread(0);
WasmInterpreter::Thread* thread = interpreter->GetThread(0);
FOR_UINT32_INPUTS(a) {
for (uint32_t b = 33; b < 3000000000u; b += 1000000000u) {
thread.Reset();
thread->Reset();
WasmVal args[] = {WasmVal(*a), WasmVal(b)};
thread.PushFrame(r.function(), args);
thread->PushFrame(r.function(), args);
// Run instructions one by one.
for (int i = 0; i < kTraceLength - 1; i++) {
thread.Step();
thread->Step();
// Check the thread stopped.
CHECK_EQ(WasmInterpreter::PAUSED, thread.state());
CHECK_EQ(WasmInterpreter::PAUSED, thread->state());
}
// Run last instruction.
thread.Step();
thread->Step();
// Check the thread finished with the right value.
CHECK_EQ(WasmInterpreter::FINISHED, thread.state());
CHECK_EQ(WasmInterpreter::FINISHED, thread->state());
uint32_t expected = (*a) * (b);
CHECK_EQ(expected, thread.GetReturnValue().to<uint32_t>());
CHECK_EQ(expected, thread->GetReturnValue().to<uint32_t>());
}
}
}
@ -254,7 +254,7 @@ TEST(Breakpoint_I32And_disable) {
r.Build(code, code + arraysize(code));
WasmInterpreter* interpreter = r.interpreter();
WasmInterpreter::Thread& thread = interpreter->GetThread(0);
WasmInterpreter::Thread* thread = interpreter->GetThread(0);
FOR_UINT32_INPUTS(a) {
for (uint32_t b = 11; b < 3000000000u; b += 1000000000u) {
@ -262,23 +262,23 @@ TEST(Breakpoint_I32And_disable) {
for (int do_break = 0; do_break < 2; do_break++) {
interpreter->SetBreakpoint(r.function(), kLocalsDeclSize + offsets[0],
do_break);
thread.Reset();
thread->Reset();
WasmVal args[] = {WasmVal(*a), WasmVal(b)};
thread.PushFrame(r.function(), args);
thread->PushFrame(r.function(), args);
if (do_break) {
thread.Run(); // run to next breakpoint
thread->Run(); // run to next breakpoint
// Check the thread stopped at the right pc.
CHECK_EQ(WasmInterpreter::PAUSED, thread.state());
CHECK_EQ(kLocalsDeclSize + offsets[0], thread.GetBreakpointPc());
CHECK_EQ(WasmInterpreter::PAUSED, thread->state());
CHECK_EQ(kLocalsDeclSize + offsets[0], thread->GetBreakpointPc());
}
thread.Run(); // run to completion
thread->Run(); // run to completion
// Check the thread finished with the right value.
CHECK_EQ(WasmInterpreter::FINISHED, thread.state());
CHECK_EQ(WasmInterpreter::FINISHED, thread->state());
uint32_t expected = (*a) & (b);
CHECK_EQ(expected, thread.GetReturnValue().to<uint32_t>());
CHECK_EQ(expected, thread->GetReturnValue().to<uint32_t>());
}
}
}

View File

@ -706,13 +706,13 @@ class WasmRunner {
ReturnType CallInterpreter(Vector<WasmVal> args) {
CHECK_EQ(args.length(),
static_cast<int>(compiler_.function_->sig->parameter_count()));
WasmInterpreter::Thread& thread = interpreter()->GetThread(0);
thread.Reset();
thread.PushFrame(compiler_.function_, args.start());
if (thread.Run() == WasmInterpreter::FINISHED) {
WasmVal val = thread.GetReturnValue();
WasmInterpreter::Thread* thread = interpreter()->GetThread(0);
thread->Reset();
thread->PushFrame(compiler_.function_, args.start());
if (thread->Run() == WasmInterpreter::FINISHED) {
WasmVal val = thread->GetReturnValue();
return val.to<ReturnType>();
} else if (thread.state() == WasmInterpreter::TRAPPED) {
} else if (thread->state() == WasmInterpreter::TRAPPED) {
// TODO(titzer): return the correct trap code
int64_t result = 0xdeadbeefdeadbeef;
return static_cast<ReturnType>(result);