Commit 26afd571 authored by titzer's avatar titzer Committed by Commit bot

[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}
parent 280b8382
...@@ -1675,13 +1675,19 @@ class WasmInterpreterInternals : public ZoneObject { ...@@ -1675,13 +1675,19 @@ class WasmInterpreterInternals : public ZoneObject {
public: public:
WasmModuleInstance* instance_; WasmModuleInstance* instance_;
CodeMap codemap_; CodeMap codemap_;
ZoneVector<ThreadImpl> threads_; ZoneVector<ThreadImpl*> threads_;
WasmInterpreterInternals(Zone* zone, WasmModuleInstance* instance) WasmInterpreterInternals(Zone* zone, WasmModuleInstance* instance)
: instance_(instance), : instance_(instance),
codemap_(instance_ ? instance_->module : nullptr, zone), codemap_(instance_ ? instance_->module : nullptr, zone),
threads_(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, ...@@ -1693,11 +1699,11 @@ WasmInterpreter::WasmInterpreter(WasmModuleInstance* instance,
: zone_(allocator), : zone_(allocator),
internals_(new (&zone_) WasmInterpreterInternals(&zone_, instance)) {} 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 WasmInterpreter::SetBreakpoint(const WasmFunction* function, pc_t pc,
bool enabled) { bool enabled) {
...@@ -1740,7 +1746,7 @@ int WasmInterpreter::GetThreadCount() { ...@@ -1740,7 +1746,7 @@ int WasmInterpreter::GetThreadCount() {
return 1; // only one thread for now. 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. CHECK_EQ(0, id); // only one thread for now.
return internals_->threads_[id]; return internals_->threads_[id];
} }
......
...@@ -163,7 +163,7 @@ class WasmInterpreter { ...@@ -163,7 +163,7 @@ class WasmInterpreter {
// Thread iteration and inspection. // Thread iteration and inspection.
//========================================================================== //==========================================================================
int GetThreadCount(); int GetThreadCount();
Thread& GetThread(int id); Thread* GetThread(int id);
//========================================================================== //==========================================================================
// Stack frame inspection. // Stack frame inspection.
......
...@@ -176,7 +176,7 @@ TEST(Breakpoint_I32Add) { ...@@ -176,7 +176,7 @@ TEST(Breakpoint_I32Add) {
r.Build(code, code + arraysize(code)); r.Build(code, code + arraysize(code));
WasmInterpreter* interpreter = r.interpreter(); WasmInterpreter* interpreter = r.interpreter();
WasmInterpreter::Thread& thread = interpreter->GetThread(0); WasmInterpreter::Thread* thread = interpreter->GetThread(0);
for (int i = 0; i < kNumBreakpoints; i++) { for (int i = 0; i < kNumBreakpoints; i++) {
interpreter->SetBreakpoint(r.function(), kLocalsDeclSize + offsets[i], interpreter->SetBreakpoint(r.function(), kLocalsDeclSize + offsets[i],
true); true);
...@@ -184,23 +184,23 @@ TEST(Breakpoint_I32Add) { ...@@ -184,23 +184,23 @@ TEST(Breakpoint_I32Add) {
FOR_UINT32_INPUTS(a) { FOR_UINT32_INPUTS(a) {
for (uint32_t b = 11; b < 3000000000u; b += 1000000000u) { for (uint32_t b = 11; b < 3000000000u; b += 1000000000u) {
thread.Reset(); thread->Reset();
WasmVal args[] = {WasmVal(*a), WasmVal(b)}; WasmVal args[] = {WasmVal(*a), WasmVal(b)};
thread.PushFrame(r.function(), args); thread->PushFrame(r.function(), args);
for (int i = 0; i < kNumBreakpoints; i++) { 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 the thread stopped at the right pc.
CHECK_EQ(WasmInterpreter::PAUSED, thread.state()); CHECK_EQ(WasmInterpreter::PAUSED, thread->state());
CHECK_EQ(kLocalsDeclSize + offsets[i], thread.GetBreakpointPc()); 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 the thread finished with the right value.
CHECK_EQ(WasmInterpreter::FINISHED, thread.state()); CHECK_EQ(WasmInterpreter::FINISHED, thread->state());
uint32_t expected = (*a) + (b); 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) { ...@@ -215,28 +215,28 @@ TEST(Step_I32Mul) {
r.Build(code, code + arraysize(code)); r.Build(code, code + arraysize(code));
WasmInterpreter* interpreter = r.interpreter(); WasmInterpreter* interpreter = r.interpreter();
WasmInterpreter::Thread& thread = interpreter->GetThread(0); WasmInterpreter::Thread* thread = interpreter->GetThread(0);
FOR_UINT32_INPUTS(a) { FOR_UINT32_INPUTS(a) {
for (uint32_t b = 33; b < 3000000000u; b += 1000000000u) { for (uint32_t b = 33; b < 3000000000u; b += 1000000000u) {
thread.Reset(); thread->Reset();
WasmVal args[] = {WasmVal(*a), WasmVal(b)}; WasmVal args[] = {WasmVal(*a), WasmVal(b)};
thread.PushFrame(r.function(), args); thread->PushFrame(r.function(), args);
// Run instructions one by one. // Run instructions one by one.
for (int i = 0; i < kTraceLength - 1; i++) { for (int i = 0; i < kTraceLength - 1; i++) {
thread.Step(); thread->Step();
// Check the thread stopped. // Check the thread stopped.
CHECK_EQ(WasmInterpreter::PAUSED, thread.state()); CHECK_EQ(WasmInterpreter::PAUSED, thread->state());
} }
// Run last instruction. // Run last instruction.
thread.Step(); thread->Step();
// Check the thread finished with the right value. // 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); 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) { ...@@ -254,7 +254,7 @@ TEST(Breakpoint_I32And_disable) {
r.Build(code, code + arraysize(code)); r.Build(code, code + arraysize(code));
WasmInterpreter* interpreter = r.interpreter(); WasmInterpreter* interpreter = r.interpreter();
WasmInterpreter::Thread& thread = interpreter->GetThread(0); WasmInterpreter::Thread* thread = interpreter->GetThread(0);
FOR_UINT32_INPUTS(a) { FOR_UINT32_INPUTS(a) {
for (uint32_t b = 11; b < 3000000000u; b += 1000000000u) { for (uint32_t b = 11; b < 3000000000u; b += 1000000000u) {
...@@ -262,23 +262,23 @@ TEST(Breakpoint_I32And_disable) { ...@@ -262,23 +262,23 @@ TEST(Breakpoint_I32And_disable) {
for (int do_break = 0; do_break < 2; do_break++) { for (int do_break = 0; do_break < 2; do_break++) {
interpreter->SetBreakpoint(r.function(), kLocalsDeclSize + offsets[0], interpreter->SetBreakpoint(r.function(), kLocalsDeclSize + offsets[0],
do_break); do_break);
thread.Reset(); thread->Reset();
WasmVal args[] = {WasmVal(*a), WasmVal(b)}; WasmVal args[] = {WasmVal(*a), WasmVal(b)};
thread.PushFrame(r.function(), args); thread->PushFrame(r.function(), args);
if (do_break) { if (do_break) {
thread.Run(); // run to next breakpoint thread->Run(); // run to next breakpoint
// Check the thread stopped at the right pc. // Check the thread stopped at the right pc.
CHECK_EQ(WasmInterpreter::PAUSED, thread.state()); CHECK_EQ(WasmInterpreter::PAUSED, thread->state());
CHECK_EQ(kLocalsDeclSize + offsets[0], thread.GetBreakpointPc()); 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 the thread finished with the right value.
CHECK_EQ(WasmInterpreter::FINISHED, thread.state()); CHECK_EQ(WasmInterpreter::FINISHED, thread->state());
uint32_t expected = (*a) & (b); uint32_t expected = (*a) & (b);
CHECK_EQ(expected, thread.GetReturnValue().to<uint32_t>()); CHECK_EQ(expected, thread->GetReturnValue().to<uint32_t>());
} }
} }
} }
......
...@@ -706,13 +706,13 @@ class WasmRunner { ...@@ -706,13 +706,13 @@ class WasmRunner {
ReturnType CallInterpreter(Vector<WasmVal> args) { ReturnType CallInterpreter(Vector<WasmVal> args) {
CHECK_EQ(args.length(), CHECK_EQ(args.length(),
static_cast<int>(compiler_.function_->sig->parameter_count())); static_cast<int>(compiler_.function_->sig->parameter_count()));
WasmInterpreter::Thread& thread = interpreter()->GetThread(0); WasmInterpreter::Thread* thread = interpreter()->GetThread(0);
thread.Reset(); thread->Reset();
thread.PushFrame(compiler_.function_, args.start()); thread->PushFrame(compiler_.function_, args.start());
if (thread.Run() == WasmInterpreter::FINISHED) { if (thread->Run() == WasmInterpreter::FINISHED) {
WasmVal val = thread.GetReturnValue(); WasmVal val = thread->GetReturnValue();
return val.to<ReturnType>(); return val.to<ReturnType>();
} else if (thread.state() == WasmInterpreter::TRAPPED) { } else if (thread->state() == WasmInterpreter::TRAPPED) {
// TODO(titzer): return the correct trap code // TODO(titzer): return the correct trap code
int64_t result = 0xdeadbeefdeadbeef; int64_t result = 0xdeadbeefdeadbeef;
return static_cast<ReturnType>(result); return static_cast<ReturnType>(result);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment