Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(9)

Side by Side Diff: src/wasm/wasm-interpreter.cc

Issue 2014373003: [wasm] Add more tests for interpreter breakpoints. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Remove redundant local Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/wasm/wasm-interpreter.h ('k') | test/cctest/wasm/test-run-wasm-interpreter.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/wasm/wasm-interpreter.h" 5 #include "src/wasm/wasm-interpreter.h"
6 #include "src/wasm/ast-decoder.h" 6 #include "src/wasm/ast-decoder.h"
7 #include "src/wasm/decoder.h" 7 #include "src/wasm/decoder.h"
8 #include "src/wasm/wasm-external-refs.h" 8 #include "src/wasm/wasm-external-refs.h"
9 #include "src/wasm/wasm-module.h" 9 #include "src/wasm/wasm-module.h"
10 10
(...skipping 909 matching lines...) Expand 10 before | Expand all | Expand 10 after
920 920
921 // Responsible for executing code directly. 921 // Responsible for executing code directly.
922 class ThreadImpl : public WasmInterpreter::Thread { 922 class ThreadImpl : public WasmInterpreter::Thread {
923 public: 923 public:
924 ThreadImpl(Zone* zone, CodeMap* codemap, WasmModuleInstance* instance) 924 ThreadImpl(Zone* zone, CodeMap* codemap, WasmModuleInstance* instance)
925 : codemap_(codemap), 925 : codemap_(codemap),
926 instance_(instance), 926 instance_(instance),
927 stack_(zone), 927 stack_(zone),
928 frames_(zone), 928 frames_(zone),
929 state_(WasmInterpreter::STOPPED), 929 state_(WasmInterpreter::STOPPED),
930 break_pc_(kInvalidPc),
930 trap_reason_(kTrapCount) {} 931 trap_reason_(kTrapCount) {}
931 932
932 virtual ~ThreadImpl() {} 933 virtual ~ThreadImpl() {}
933 934
934 //========================================================================== 935 //==========================================================================
935 // Implementation of public interface for WasmInterpreter::Thread. 936 // Implementation of public interface for WasmInterpreter::Thread.
936 //========================================================================== 937 //==========================================================================
937 938
938 virtual WasmInterpreter::State state() { return state_; } 939 virtual WasmInterpreter::State state() { return state_; }
939 940
940 virtual void PushFrame(const WasmFunction* function, WasmVal* args) { 941 virtual void PushFrame(const WasmFunction* function, WasmVal* args) {
941 InterpreterCode* code = codemap()->FindCode(function); 942 InterpreterCode* code = codemap()->FindCode(function);
942 CHECK_NOT_NULL(code); 943 CHECK_NOT_NULL(code);
943 frames_.push_back({code, 0, 0, stack_.size()}); 944 frames_.push_back({code, 0, 0, stack_.size()});
944 for (size_t i = 0; i < function->sig->parameter_count(); i++) { 945 for (size_t i = 0; i < function->sig->parameter_count(); i++) {
945 stack_.push_back(args[i]); 946 stack_.push_back(args[i]);
946 } 947 }
947 frames_.back().ret_pc = InitLocals(code); 948 frames_.back().ret_pc = InitLocals(code);
948 TRACE(" => push func#%u @%zu\n", code->function->func_index, 949 TRACE(" => PushFrame(#%u @%zu)\n", code->function->func_index,
949 frames_.back().ret_pc); 950 frames_.back().ret_pc);
950 } 951 }
951 952
952 virtual WasmInterpreter::State Run() { 953 virtual WasmInterpreter::State Run() {
953 do { 954 do {
955 TRACE(" => Run()\n");
954 if (state_ == WasmInterpreter::STOPPED || 956 if (state_ == WasmInterpreter::STOPPED ||
955 state_ == WasmInterpreter::PAUSED) { 957 state_ == WasmInterpreter::PAUSED) {
956 state_ = WasmInterpreter::RUNNING; 958 state_ = WasmInterpreter::RUNNING;
957 Execute(frames_.back().code, frames_.back().ret_pc, kRunSteps); 959 Execute(frames_.back().code, frames_.back().ret_pc, kRunSteps);
958 } 960 }
959 } while (state_ == WasmInterpreter::STOPPED); 961 } while (state_ == WasmInterpreter::STOPPED);
960 return state_; 962 return state_;
961 } 963 }
962 964
963 virtual WasmInterpreter::State Step() { 965 virtual WasmInterpreter::State Step() {
964 UNIMPLEMENTED(); 966 TRACE(" => Step()\n");
965 return WasmInterpreter::STOPPED; 967 if (state_ == WasmInterpreter::STOPPED ||
968 state_ == WasmInterpreter::PAUSED) {
969 state_ = WasmInterpreter::RUNNING;
970 Execute(frames_.back().code, frames_.back().ret_pc, 1);
971 }
972 return state_;
966 } 973 }
967 974
968 virtual void Pause() { UNIMPLEMENTED(); } 975 virtual void Pause() { UNIMPLEMENTED(); }
969 976
970 virtual void Reset() { 977 virtual void Reset() {
971 TRACE("----- RESET -----\n"); 978 TRACE("----- RESET -----\n");
972 stack_.clear(); 979 stack_.clear();
973 frames_.clear(); 980 frames_.clear();
974 state_ = WasmInterpreter::STOPPED; 981 state_ = WasmInterpreter::STOPPED;
975 trap_reason_ = kTrapCount; 982 trap_reason_ = kTrapCount;
(...skipping 11 matching lines...) Expand all
987 return nullptr; 994 return nullptr;
988 } 995 }
989 996
990 virtual WasmVal GetReturnValue() { 997 virtual WasmVal GetReturnValue() {
991 if (state_ == WasmInterpreter::TRAPPED) return WasmVal(0xdeadbeef); 998 if (state_ == WasmInterpreter::TRAPPED) return WasmVal(0xdeadbeef);
992 CHECK_EQ(WasmInterpreter::FINISHED, state_); 999 CHECK_EQ(WasmInterpreter::FINISHED, state_);
993 CHECK_EQ(1, stack_.size()); 1000 CHECK_EQ(1, stack_.size());
994 return stack_[0]; 1001 return stack_[0];
995 } 1002 }
996 1003
1004 virtual pc_t GetBreakpointPc() { return break_pc_; }
1005
997 bool Terminated() { 1006 bool Terminated() {
998 return state_ == WasmInterpreter::TRAPPED || 1007 return state_ == WasmInterpreter::TRAPPED ||
999 state_ == WasmInterpreter::FINISHED; 1008 state_ == WasmInterpreter::FINISHED;
1000 } 1009 }
1001 1010
1002 private: 1011 private:
1003 // Entries on the stack of functions being evaluated. 1012 // Entries on the stack of functions being evaluated.
1004 struct Frame { 1013 struct Frame {
1005 InterpreterCode* code; 1014 InterpreterCode* code;
1006 pc_t call_pc; 1015 pc_t call_pc;
1007 pc_t ret_pc; 1016 pc_t ret_pc;
1008 sp_t sp; 1017 sp_t sp;
1009 1018
1010 // Limit of parameters. 1019 // Limit of parameters.
1011 sp_t plimit() { return sp + code->function->sig->parameter_count(); } 1020 sp_t plimit() { return sp + code->function->sig->parameter_count(); }
1012 // Limit of locals. 1021 // Limit of locals.
1013 sp_t llimit() { return plimit() + code->locals.total_local_count; } 1022 sp_t llimit() { return plimit() + code->locals.total_local_count; }
1014 }; 1023 };
1015 1024
1016 CodeMap* codemap_; 1025 CodeMap* codemap_;
1017 WasmModuleInstance* instance_; 1026 WasmModuleInstance* instance_;
1018 ZoneVector<WasmVal> stack_; 1027 ZoneVector<WasmVal> stack_;
1019 ZoneVector<Frame> frames_; 1028 ZoneVector<Frame> frames_;
1020 WasmInterpreter::State state_; 1029 WasmInterpreter::State state_;
1030 pc_t break_pc_;
1021 TrapReason trap_reason_; 1031 TrapReason trap_reason_;
1022 1032
1023 CodeMap* codemap() { return codemap_; } 1033 CodeMap* codemap() { return codemap_; }
1024 WasmModuleInstance* instance() { return instance_; } 1034 WasmModuleInstance* instance() { return instance_; }
1025 const WasmModule* module() { return instance_->module; } 1035 const WasmModule* module() { return instance_->module; }
1026 1036
1027 void DoTrap(TrapReason trap, pc_t pc) { 1037 void DoTrap(TrapReason trap, pc_t pc) {
1028 state_ = WasmInterpreter::TRAPPED; 1038 state_ = WasmInterpreter::TRAPPED;
1029 trap_reason_ = trap; 1039 trap_reason_ = trap;
1030 CommitPc(pc); 1040 CommitPc(pc);
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1070 return code->locals.decls_encoded_size; 1080 return code->locals.decls_encoded_size;
1071 } 1081 }
1072 1082
1073 void CommitPc(pc_t pc) { 1083 void CommitPc(pc_t pc) {
1074 if (!frames_.empty()) { 1084 if (!frames_.empty()) {
1075 frames_.back().ret_pc = pc; 1085 frames_.back().ret_pc = pc;
1076 } 1086 }
1077 } 1087 }
1078 1088
1079 bool SkipBreakpoint(InterpreterCode* code, pc_t pc) { 1089 bool SkipBreakpoint(InterpreterCode* code, pc_t pc) {
1080 // TODO(titzer): skip a breakpoint if we are resuming from it, or it 1090 if (pc == break_pc_) {
1081 // is set for another thread only. 1091 break_pc_ = kInvalidPc;
1092 return true;
1093 }
1082 return false; 1094 return false;
1083 } 1095 }
1084 1096
1085 bool DoReturn(InterpreterCode** code, pc_t* pc, pc_t* limit, WasmVal val) { 1097 bool DoReturn(InterpreterCode** code, pc_t* pc, pc_t* limit, WasmVal val) {
1086 DCHECK_GT(frames_.size(), 0u); 1098 DCHECK_GT(frames_.size(), 0u);
1087 stack_.resize(frames_.back().sp); 1099 stack_.resize(frames_.back().sp);
1088 frames_.pop_back(); 1100 frames_.pop_back();
1089 if (frames_.size() == 0) { 1101 if (frames_.size() == 0) {
1090 // A return from the top frame terminates the execution. 1102 // A return from the top frame terminates the execution.
1091 state_ = WasmInterpreter::FINISHED; 1103 state_ = WasmInterpreter::FINISHED;
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
1158 1170
1159 if (pc >= limit) { 1171 if (pc >= limit) {
1160 // Fell off end of code; do an implicit return. 1172 // Fell off end of code; do an implicit return.
1161 TRACE("@%-3zu: ImplicitReturn\n", pc); 1173 TRACE("@%-3zu: ImplicitReturn\n", pc);
1162 WasmVal val = PopArity(code->function->sig->return_count()); 1174 WasmVal val = PopArity(code->function->sig->return_count());
1163 if (!DoReturn(&code, &pc, &limit, val)) return; 1175 if (!DoReturn(&code, &pc, &limit, val)) return;
1164 decoder.Reset(code->start, code->end); 1176 decoder.Reset(code->start, code->end);
1165 continue; 1177 continue;
1166 } 1178 }
1167 1179
1168 const char* skip = ""; 1180 const char* skip = " ";
1169 int len = 1; 1181 int len = 1;
1170 byte opcode = code->start[pc]; 1182 byte opcode = code->start[pc];
1171 byte orig = opcode; 1183 byte orig = opcode;
1172 if (opcode == kInternalBreakpoint) { 1184 if (opcode == kInternalBreakpoint) {
1185 orig = code->orig_start[pc];
1173 if (SkipBreakpoint(code, pc)) { 1186 if (SkipBreakpoint(code, pc)) {
1174 // skip breakpoint by switching on original code. 1187 // skip breakpoint by switching on original code.
1175 orig = code->orig_start[pc]; 1188 skip = "[skip] ";
1176 skip = "[skip] ";
1177 } else { 1189 } else {
1178 state_ = WasmInterpreter::PAUSED; 1190 state_ = WasmInterpreter::PAUSED;
1191 TRACE("@%-3zu: [break] %-24s:", pc,
1192 WasmOpcodes::OpcodeName(static_cast<WasmOpcode>(orig)));
1193 TraceValueStack();
1194 TRACE("\n");
1195 break_pc_ = pc;
1179 return CommitPc(pc); 1196 return CommitPc(pc);
1180 } 1197 }
1181 } 1198 }
1182 1199
1183 USE(skip); 1200 USE(skip);
1184 TRACE("@%-3zu: %s%-24s:", pc, skip, 1201 TRACE("@%-3zu: %s%-24s:", pc, skip,
1185 WasmOpcodes::OpcodeName(static_cast<WasmOpcode>(orig))); 1202 WasmOpcodes::OpcodeName(static_cast<WasmOpcode>(orig)));
1186 TraceValueStack(); 1203 TraceValueStack();
1187 TRACE("\n"); 1204 TRACE("\n");
1188 1205
(...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after
1677 base::AccountingAllocator* allocator) 1694 base::AccountingAllocator* allocator)
1678 : zone_(allocator), 1695 : zone_(allocator),
1679 internals_(new (&zone_) WasmInterpreterInternals(&zone_, instance)) {} 1696 internals_(new (&zone_) WasmInterpreterInternals(&zone_, instance)) {}
1680 1697
1681 WasmInterpreter::~WasmInterpreter() {} 1698 WasmInterpreter::~WasmInterpreter() {}
1682 1699
1683 void WasmInterpreter::Run() { internals_->threads_[0].Run(); } 1700 void WasmInterpreter::Run() { internals_->threads_[0].Run(); }
1684 1701
1685 void WasmInterpreter::Pause() { internals_->threads_[0].Pause(); } 1702 void WasmInterpreter::Pause() { internals_->threads_[0].Pause(); }
1686 1703
1687 bool WasmInterpreter::SetBreakpoint(const WasmFunction* function, int pc, 1704 bool WasmInterpreter::SetBreakpoint(const WasmFunction* function, pc_t pc,
1688 bool enabled) { 1705 bool enabled) {
1689 InterpreterCode* code = internals_->codemap_.FindCode(function); 1706 InterpreterCode* code = internals_->codemap_.FindCode(function);
1690 if (!code) return false; 1707 if (!code) return false;
1691 int size = static_cast<int>(code->end - code->start); 1708 size_t size = static_cast<size_t>(code->end - code->start);
1692 // Check bounds for {pc}. 1709 // Check bounds for {pc}.
1693 if (pc < 0 || pc >= size) return false; 1710 if (pc < code->locals.decls_encoded_size || pc >= size) return false;
1694 // Make a copy of the code before enabling a breakpoint. 1711 // Make a copy of the code before enabling a breakpoint.
1695 if (enabled && code->orig_start == code->start) { 1712 if (enabled && code->orig_start == code->start) {
1696 code->start = reinterpret_cast<byte*>(zone_.New(size)); 1713 code->start = reinterpret_cast<byte*>(zone_.New(size));
1697 memcpy(code->start, code->orig_start, size); 1714 memcpy(code->start, code->orig_start, size);
1698 code->end = code->start + size; 1715 code->end = code->start + size;
1699 } 1716 }
1700 bool prev = code->start[pc] == kInternalBreakpoint; 1717 bool prev = code->start[pc] == kInternalBreakpoint;
1701 if (enabled) { 1718 if (enabled) {
1702 code->start[pc] = kInternalBreakpoint; 1719 code->start[pc] = kInternalBreakpoint;
1703 } else { 1720 } else {
1704 code->start[pc] = code->orig_start[pc]; 1721 code->start[pc] = code->orig_start[pc];
1705 } 1722 }
1706 return prev; 1723 return prev;
1707 } 1724 }
1708 1725
1709 bool WasmInterpreter::GetBreakpoint(const WasmFunction* function, int pc) { 1726 bool WasmInterpreter::GetBreakpoint(const WasmFunction* function, pc_t pc) {
1710 InterpreterCode* code = internals_->codemap_.FindCode(function); 1727 InterpreterCode* code = internals_->codemap_.FindCode(function);
1711 if (!code) return false; 1728 if (!code) return false;
1712 int size = static_cast<int>(code->end - code->start); 1729 size_t size = static_cast<size_t>(code->end - code->start);
1713 // Check bounds for {pc}. 1730 // Check bounds for {pc}.
1714 if (pc < 0 || pc >= size) return false; 1731 if (pc < code->locals.decls_encoded_size || pc >= size) return false;
1715 // Check if a breakpoint is present at that place in the code. 1732 // Check if a breakpoint is present at that place in the code.
1716 return code->start[pc] == kInternalBreakpoint; 1733 return code->start[pc] == kInternalBreakpoint;
1717 } 1734 }
1718 1735
1719 bool WasmInterpreter::SetTracing(const WasmFunction* function, bool enabled) { 1736 bool WasmInterpreter::SetTracing(const WasmFunction* function, bool enabled) {
1720 UNIMPLEMENTED(); 1737 UNIMPLEMENTED();
1721 return false; 1738 return false;
1722 } 1739 }
1723 1740
1724 int WasmInterpreter::GetThreadCount() { 1741 int WasmInterpreter::GetThreadCount() {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1778 1795
1779 ControlTransferMap WasmInterpreter::ComputeControlTransfersForTesting( 1796 ControlTransferMap WasmInterpreter::ComputeControlTransfersForTesting(
1780 Zone* zone, const byte* start, const byte* end) { 1797 Zone* zone, const byte* start, const byte* end) {
1781 ControlTransfers targets(zone, 0, start, end); 1798 ControlTransfers targets(zone, 0, start, end);
1782 return targets.map_; 1799 return targets.map_;
1783 } 1800 }
1784 1801
1785 } // namespace wasm 1802 } // namespace wasm
1786 } // namespace internal 1803 } // namespace internal
1787 } // namespace v8 1804 } // namespace v8
OLDNEW
« no previous file with comments | « src/wasm/wasm-interpreter.h ('k') | test/cctest/wasm/test-run-wasm-interpreter.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698