OLD | NEW |
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 <type_traits> | 5 #include <type_traits> |
6 | 6 |
7 #include "src/wasm/wasm-interpreter.h" | 7 #include "src/wasm/wasm-interpreter.h" |
8 | 8 |
9 #include "src/conversions.h" | 9 #include "src/conversions.h" |
10 #include "src/objects-inl.h" | 10 #include "src/objects-inl.h" |
(...skipping 917 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
928 | 928 |
929 //========================================================================== | 929 //========================================================================== |
930 // Implementation of public interface for WasmInterpreter::Thread. | 930 // Implementation of public interface for WasmInterpreter::Thread. |
931 //========================================================================== | 931 //========================================================================== |
932 | 932 |
933 WasmInterpreter::State state() { return state_; } | 933 WasmInterpreter::State state() { return state_; } |
934 | 934 |
935 void PushFrame(const WasmFunction* function, WasmVal* args) { | 935 void PushFrame(const WasmFunction* function, WasmVal* args) { |
936 InterpreterCode* code = codemap()->FindCode(function); | 936 InterpreterCode* code = codemap()->FindCode(function); |
937 CHECK_NOT_NULL(code); | 937 CHECK_NOT_NULL(code); |
| 938 ++num_interpreted_calls_; |
938 frames_.push_back({code, 0, 0, stack_.size()}); | 939 frames_.push_back({code, 0, 0, stack_.size()}); |
939 for (size_t i = 0; i < function->sig->parameter_count(); ++i) { | 940 for (size_t i = 0; i < function->sig->parameter_count(); ++i) { |
940 stack_.push_back(args[i]); | 941 stack_.push_back(args[i]); |
941 } | 942 } |
942 frames_.back().ret_pc = InitLocals(code); | 943 frames_.back().ret_pc = InitLocals(code); |
943 blocks_.push_back( | 944 blocks_.push_back( |
944 {0, stack_.size(), frames_.size(), | 945 {0, stack_.size(), frames_.size(), |
945 static_cast<uint32_t>(code->function->sig->return_count())}); | 946 static_cast<uint32_t>(code->function->sig->return_count())}); |
946 TRACE(" => PushFrame(#%u @%zu)\n", code->function->func_index, | 947 TRACE(" => PushFrame(#%u @%zu)\n", code->function->func_index, |
947 frames_.back().ret_pc); | 948 frames_.back().ret_pc); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1002 if (state_ == WasmInterpreter::TRAPPED) return WasmVal(0xdeadbeef); | 1003 if (state_ == WasmInterpreter::TRAPPED) return WasmVal(0xdeadbeef); |
1003 CHECK_EQ(WasmInterpreter::FINISHED, state_); | 1004 CHECK_EQ(WasmInterpreter::FINISHED, state_); |
1004 CHECK_LT(static_cast<size_t>(index), stack_.size()); | 1005 CHECK_LT(static_cast<size_t>(index), stack_.size()); |
1005 return stack_[index]; | 1006 return stack_[index]; |
1006 } | 1007 } |
1007 | 1008 |
1008 pc_t GetBreakpointPc() { return break_pc_; } | 1009 pc_t GetBreakpointPc() { return break_pc_; } |
1009 | 1010 |
1010 bool PossibleNondeterminism() { return possible_nondeterminism_; } | 1011 bool PossibleNondeterminism() { return possible_nondeterminism_; } |
1011 | 1012 |
| 1013 uint64_t NumInterpretedCalls() { return num_interpreted_calls_; } |
| 1014 |
1012 void AddBreakFlags(uint8_t flags) { break_flags_ |= flags; } | 1015 void AddBreakFlags(uint8_t flags) { break_flags_ |= flags; } |
1013 | 1016 |
1014 void ClearBreakFlags() { break_flags_ = WasmInterpreter::BreakFlag::None; } | 1017 void ClearBreakFlags() { break_flags_ = WasmInterpreter::BreakFlag::None; } |
1015 | 1018 |
1016 private: | 1019 private: |
1017 // Entries on the stack of functions being evaluated. | 1020 // Entries on the stack of functions being evaluated. |
1018 struct Frame { | 1021 struct Frame { |
1019 InterpreterCode* code; | 1022 InterpreterCode* code; |
1020 pc_t call_pc; | 1023 pc_t call_pc; |
1021 pc_t ret_pc; | 1024 pc_t ret_pc; |
(...skipping 15 matching lines...) Expand all Loading... |
1037 CodeMap* codemap_; | 1040 CodeMap* codemap_; |
1038 WasmInstance* instance_; | 1041 WasmInstance* instance_; |
1039 ZoneVector<WasmVal> stack_; | 1042 ZoneVector<WasmVal> stack_; |
1040 ZoneVector<Frame> frames_; | 1043 ZoneVector<Frame> frames_; |
1041 ZoneVector<Block> blocks_; | 1044 ZoneVector<Block> blocks_; |
1042 WasmInterpreter::State state_ = WasmInterpreter::STOPPED; | 1045 WasmInterpreter::State state_ = WasmInterpreter::STOPPED; |
1043 pc_t break_pc_ = kInvalidPc; | 1046 pc_t break_pc_ = kInvalidPc; |
1044 TrapReason trap_reason_ = kTrapCount; | 1047 TrapReason trap_reason_ = kTrapCount; |
1045 bool possible_nondeterminism_ = false; | 1048 bool possible_nondeterminism_ = false; |
1046 uint8_t break_flags_ = 0; // a combination of WasmInterpreter::BreakFlag | 1049 uint8_t break_flags_ = 0; // a combination of WasmInterpreter::BreakFlag |
| 1050 uint64_t num_interpreted_calls_ = 0; |
1047 | 1051 |
1048 CodeMap* codemap() { return codemap_; } | 1052 CodeMap* codemap() { return codemap_; } |
1049 WasmInstance* instance() { return instance_; } | 1053 WasmInstance* instance() { return instance_; } |
1050 const WasmModule* module() { return instance_->module; } | 1054 const WasmModule* module() { return instance_->module; } |
1051 | 1055 |
1052 void DoTrap(TrapReason trap, pc_t pc) { | 1056 void DoTrap(TrapReason trap, pc_t pc) { |
1053 state_ = WasmInterpreter::TRAPPED; | 1057 state_ = WasmInterpreter::TRAPPED; |
1054 trap_reason_ = trap; | 1058 trap_reason_ = trap; |
1055 CommitPc(pc); | 1059 CommitPc(pc); |
1056 } | 1060 } |
1057 | 1061 |
1058 // Push a frame with arguments already on the stack. | 1062 // Push a frame with arguments already on the stack. |
1059 void PushFrame(InterpreterCode* code, pc_t call_pc, pc_t ret_pc) { | 1063 void PushFrame(InterpreterCode* code, pc_t call_pc, pc_t ret_pc) { |
1060 CHECK_NOT_NULL(code); | 1064 CHECK_NOT_NULL(code); |
1061 DCHECK(!frames_.empty()); | 1065 DCHECK(!frames_.empty()); |
| 1066 ++num_interpreted_calls_; |
1062 frames_.back().call_pc = call_pc; | 1067 frames_.back().call_pc = call_pc; |
1063 frames_.back().ret_pc = ret_pc; | 1068 frames_.back().ret_pc = ret_pc; |
1064 size_t arity = code->function->sig->parameter_count(); | 1069 size_t arity = code->function->sig->parameter_count(); |
1065 DCHECK_GE(stack_.size(), arity); | 1070 DCHECK_GE(stack_.size(), arity); |
1066 // The parameters will overlap the arguments already on the stack. | 1071 // The parameters will overlap the arguments already on the stack. |
1067 frames_.push_back({code, 0, 0, stack_.size() - arity}); | 1072 frames_.push_back({code, 0, 0, stack_.size() - arity}); |
1068 blocks_.push_back( | 1073 blocks_.push_back( |
1069 {0, stack_.size(), frames_.size(), | 1074 {0, stack_.size(), frames_.size(), |
1070 static_cast<uint32_t>(code->function->sig->return_count())}); | 1075 static_cast<uint32_t>(code->function->sig->return_count())}); |
1071 frames_.back().ret_pc = InitLocals(code); | 1076 frames_.back().ret_pc = InitLocals(code); |
(...skipping 718 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1790 return InterpretedFrame(function, pc, fp, sp); | 1795 return InterpretedFrame(function, pc, fp, sp); |
1791 }; | 1796 }; |
1792 return ToImpl(this)->GetMutableFrame(index, frame_cons); | 1797 return ToImpl(this)->GetMutableFrame(index, frame_cons); |
1793 } | 1798 } |
1794 WasmVal WasmInterpreter::Thread::GetReturnValue(int index) { | 1799 WasmVal WasmInterpreter::Thread::GetReturnValue(int index) { |
1795 return ToImpl(this)->GetReturnValue(index); | 1800 return ToImpl(this)->GetReturnValue(index); |
1796 } | 1801 } |
1797 bool WasmInterpreter::Thread::PossibleNondeterminism() { | 1802 bool WasmInterpreter::Thread::PossibleNondeterminism() { |
1798 return ToImpl(this)->PossibleNondeterminism(); | 1803 return ToImpl(this)->PossibleNondeterminism(); |
1799 } | 1804 } |
| 1805 uint64_t WasmInterpreter::Thread::NumInterpretedCalls() { |
| 1806 return ToImpl(this)->NumInterpretedCalls(); |
| 1807 } |
1800 void WasmInterpreter::Thread::AddBreakFlags(uint8_t flags) { | 1808 void WasmInterpreter::Thread::AddBreakFlags(uint8_t flags) { |
1801 ToImpl(this)->AddBreakFlags(flags); | 1809 ToImpl(this)->AddBreakFlags(flags); |
1802 } | 1810 } |
1803 void WasmInterpreter::Thread::ClearBreakFlags() { | 1811 void WasmInterpreter::Thread::ClearBreakFlags() { |
1804 ToImpl(this)->ClearBreakFlags(); | 1812 ToImpl(this)->ClearBreakFlags(); |
1805 } | 1813 } |
1806 | 1814 |
1807 //============================================================================ | 1815 //============================================================================ |
1808 // The implementation details of the interpreter. | 1816 // The implementation details of the interpreter. |
1809 //============================================================================ | 1817 //============================================================================ |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1943 return none; | 1951 return none; |
1944 } | 1952 } |
1945 | 1953 |
1946 void InterpretedFrame::SetLocalVal(int index, WasmVal val) { UNIMPLEMENTED(); } | 1954 void InterpretedFrame::SetLocalVal(int index, WasmVal val) { UNIMPLEMENTED(); } |
1947 | 1955 |
1948 void InterpretedFrame::SetExprVal(int pc, WasmVal val) { UNIMPLEMENTED(); } | 1956 void InterpretedFrame::SetExprVal(int pc, WasmVal val) { UNIMPLEMENTED(); } |
1949 | 1957 |
1950 } // namespace wasm | 1958 } // namespace wasm |
1951 } // namespace internal | 1959 } // namespace internal |
1952 } // namespace v8 | 1960 } // namespace v8 |
OLD | NEW |