| 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 "src/wasm/wasm-interpreter.h" | 5 #include "src/wasm/wasm-interpreter.h" |
| 6 | 6 |
| 7 #include "src/utils.h" | 7 #include "src/utils.h" |
| 8 #include "src/wasm/ast-decoder.h" | 8 #include "src/wasm/ast-decoder.h" |
| 9 #include "src/wasm/decoder.h" | 9 #include "src/wasm/decoder.h" |
| 10 #include "src/wasm/wasm-external-refs.h" | 10 #include "src/wasm/wasm-external-refs.h" |
| (...skipping 703 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 714 | 714 |
| 715 static const int kRunSteps = 1000; | 715 static const int kRunSteps = 1000; |
| 716 | 716 |
| 717 // A helper class to compute the control transfers for each bytecode offset. | 717 // A helper class to compute the control transfers for each bytecode offset. |
| 718 // Control transfers allow Br, BrIf, BrTable, If, Else, and End bytecodes to | 718 // Control transfers allow Br, BrIf, BrTable, If, Else, and End bytecodes to |
| 719 // be directly executed without the need to dynamically track blocks. | 719 // be directly executed without the need to dynamically track blocks. |
| 720 class ControlTransfers : public ZoneObject { | 720 class ControlTransfers : public ZoneObject { |
| 721 public: | 721 public: |
| 722 ControlTransferMap map_; | 722 ControlTransferMap map_; |
| 723 | 723 |
| 724 ControlTransfers(Zone* zone, ModuleEnv* env, AstLocalDecls* locals, | 724 ControlTransfers(Zone* zone, AstLocalDecls* locals, const byte* start, |
| 725 const byte* start, const byte* end) | 725 const byte* end) |
| 726 : map_(zone) { | 726 : map_(zone) { |
| 727 // Represents a control flow label. | 727 // Represents a control flow label. |
| 728 struct CLabel : public ZoneObject { | 728 struct CLabel : public ZoneObject { |
| 729 const byte* target; | 729 const byte* target; |
| 730 ZoneVector<const byte*> refs; | 730 ZoneVector<const byte*> refs; |
| 731 | 731 |
| 732 explicit CLabel(Zone* zone) : target(nullptr), refs(zone) {} | 732 explicit CLabel(Zone* zone) : target(nullptr), refs(zone) {} |
| 733 | 733 |
| 734 // Bind this label to the given PC. | 734 // Bind this label to the given PC. |
| 735 void Bind(ControlTransferMap* map, const byte* start, const byte* pc) { | 735 void Bind(ControlTransferMap* map, const byte* start, const byte* pc) { |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 883 }; | 883 }; |
| 884 | 884 |
| 885 // The main storage for interpreter code. It maps {WasmFunction} to the | 885 // The main storage for interpreter code. It maps {WasmFunction} to the |
| 886 // metadata needed to execute each function. | 886 // metadata needed to execute each function. |
| 887 class CodeMap { | 887 class CodeMap { |
| 888 public: | 888 public: |
| 889 Zone* zone_; | 889 Zone* zone_; |
| 890 const WasmModule* module_; | 890 const WasmModule* module_; |
| 891 ZoneVector<InterpreterCode> interpreter_code_; | 891 ZoneVector<InterpreterCode> interpreter_code_; |
| 892 | 892 |
| 893 CodeMap(const WasmModule* module, Zone* zone) | 893 CodeMap(const WasmModule* module, const uint8_t* module_start, Zone* zone) |
| 894 : zone_(zone), module_(module), interpreter_code_(zone) { | 894 : zone_(zone), module_(module), interpreter_code_(zone) { |
| 895 if (module == nullptr) return; | 895 if (module == nullptr) return; |
| 896 for (size_t i = 0; i < module->functions.size(); ++i) { | 896 for (size_t i = 0; i < module->functions.size(); ++i) { |
| 897 const WasmFunction* function = &module->functions[i]; | 897 const WasmFunction* function = &module->functions[i]; |
| 898 const byte* code_start = | 898 const byte* code_start = module_start + function->code_start_offset; |
| 899 module->module_start + function->code_start_offset; | 899 const byte* code_end = module_start + function->code_end_offset; |
| 900 const byte* code_end = module->module_start + function->code_end_offset; | |
| 901 AddFunction(function, code_start, code_end); | 900 AddFunction(function, code_start, code_end); |
| 902 } | 901 } |
| 903 } | 902 } |
| 904 | 903 |
| 905 InterpreterCode* FindCode(const WasmFunction* function) { | 904 InterpreterCode* FindCode(const WasmFunction* function) { |
| 906 if (function->func_index < interpreter_code_.size()) { | 905 if (function->func_index < interpreter_code_.size()) { |
| 907 InterpreterCode* code = &interpreter_code_[function->func_index]; | 906 InterpreterCode* code = &interpreter_code_[function->func_index]; |
| 908 DCHECK_EQ(function, code->function); | 907 DCHECK_EQ(function, code->function); |
| 909 return Preprocess(code); | 908 return Preprocess(code); |
| 910 } | 909 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 923 if (entry_index >= table->values.size()) return nullptr; | 922 if (entry_index >= table->values.size()) return nullptr; |
| 924 uint32_t index = table->values[entry_index]; | 923 uint32_t index = table->values[entry_index]; |
| 925 if (index >= interpreter_code_.size()) return nullptr; | 924 if (index >= interpreter_code_.size()) return nullptr; |
| 926 return GetCode(index); | 925 return GetCode(index); |
| 927 } | 926 } |
| 928 | 927 |
| 929 InterpreterCode* Preprocess(InterpreterCode* code) { | 928 InterpreterCode* Preprocess(InterpreterCode* code) { |
| 930 if (code->targets == nullptr && code->start) { | 929 if (code->targets == nullptr && code->start) { |
| 931 // Compute the control targets map and the local declarations. | 930 // Compute the control targets map and the local declarations. |
| 932 CHECK(DecodeLocalDecls(code->locals, code->start, code->end)); | 931 CHECK(DecodeLocalDecls(code->locals, code->start, code->end)); |
| 933 ModuleEnv env = {module_, nullptr, kWasmOrigin}; | |
| 934 code->targets = new (zone_) ControlTransfers( | 932 code->targets = new (zone_) ControlTransfers( |
| 935 zone_, &env, &code->locals, code->orig_start, code->orig_end); | 933 zone_, &code->locals, code->orig_start, code->orig_end); |
| 936 } | 934 } |
| 937 return code; | 935 return code; |
| 938 } | 936 } |
| 939 | 937 |
| 940 int AddFunction(const WasmFunction* function, const byte* code_start, | 938 int AddFunction(const WasmFunction* function, const byte* code_start, |
| 941 const byte* code_end) { | 939 const byte* code_end) { |
| 942 InterpreterCode code = { | 940 InterpreterCode code = { |
| 943 function, AstLocalDecls(zone_), code_start, | 941 function, AstLocalDecls(zone_), code_start, |
| 944 code_end, const_cast<byte*>(code_start), const_cast<byte*>(code_end), | 942 code_end, const_cast<byte*>(code_start), const_cast<byte*>(code_end), |
| 945 nullptr}; | 943 nullptr}; |
| (...skipping 807 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1753 } | 1751 } |
| 1754 } | 1752 } |
| 1755 }; | 1753 }; |
| 1756 | 1754 |
| 1757 //============================================================================ | 1755 //============================================================================ |
| 1758 // The implementation details of the interpreter. | 1756 // The implementation details of the interpreter. |
| 1759 //============================================================================ | 1757 //============================================================================ |
| 1760 class WasmInterpreterInternals : public ZoneObject { | 1758 class WasmInterpreterInternals : public ZoneObject { |
| 1761 public: | 1759 public: |
| 1762 WasmInstance* instance_; | 1760 WasmInstance* instance_; |
| 1761 // Create a copy of the module bytes for the interpreter, since the passed |
| 1762 // pointer might be invalidated after constructing the interpreter. |
| 1763 const ZoneVector<uint8_t> module_bytes_; |
| 1763 CodeMap codemap_; | 1764 CodeMap codemap_; |
| 1764 ZoneVector<ThreadImpl*> threads_; | 1765 ZoneVector<ThreadImpl*> threads_; |
| 1765 | 1766 |
| 1766 WasmInterpreterInternals(Zone* zone, WasmInstance* instance) | 1767 WasmInterpreterInternals(Zone* zone, const ModuleBytesEnv& env) |
| 1767 : instance_(instance), | 1768 : instance_(env.instance), |
| 1768 codemap_(instance_ ? instance_->module : nullptr, zone), | 1769 module_bytes_(env.module_bytes.start(), env.module_bytes.end(), zone), |
| 1770 codemap_(env.instance ? env.instance->module : nullptr, |
| 1771 module_bytes_.data(), zone), |
| 1769 threads_(zone) { | 1772 threads_(zone) { |
| 1770 threads_.push_back(new ThreadImpl(zone, &codemap_, instance)); | 1773 threads_.push_back(new ThreadImpl(zone, &codemap_, env.instance)); |
| 1771 } | 1774 } |
| 1772 | 1775 |
| 1773 void Delete() { | 1776 void Delete() { |
| 1774 // TODO(titzer): CFI doesn't like threads in the ZoneVector. | 1777 // TODO(titzer): CFI doesn't like threads in the ZoneVector. |
| 1775 for (auto t : threads_) delete t; | 1778 for (auto t : threads_) delete t; |
| 1776 threads_.resize(0); | 1779 threads_.resize(0); |
| 1777 } | 1780 } |
| 1778 }; | 1781 }; |
| 1779 | 1782 |
| 1780 //============================================================================ | 1783 //============================================================================ |
| 1781 // Implementation of the public interface of the interpreter. | 1784 // Implementation of the public interface of the interpreter. |
| 1782 //============================================================================ | 1785 //============================================================================ |
| 1783 WasmInterpreter::WasmInterpreter(WasmInstance* instance, | 1786 WasmInterpreter::WasmInterpreter(const ModuleBytesEnv& env, |
| 1784 AccountingAllocator* allocator) | 1787 AccountingAllocator* allocator) |
| 1785 : zone_(allocator, ZONE_NAME), | 1788 : zone_(allocator, ZONE_NAME), |
| 1786 internals_(new (&zone_) WasmInterpreterInternals(&zone_, instance)) {} | 1789 internals_(new (&zone_) WasmInterpreterInternals(&zone_, env)) {} |
| 1787 | 1790 |
| 1788 WasmInterpreter::~WasmInterpreter() { internals_->Delete(); } | 1791 WasmInterpreter::~WasmInterpreter() { internals_->Delete(); } |
| 1789 | 1792 |
| 1790 void WasmInterpreter::Run() { internals_->threads_[0]->Run(); } | 1793 void WasmInterpreter::Run() { internals_->threads_[0]->Run(); } |
| 1791 | 1794 |
| 1792 void WasmInterpreter::Pause() { internals_->threads_[0]->Pause(); } | 1795 void WasmInterpreter::Pause() { internals_->threads_[0]->Pause(); } |
| 1793 | 1796 |
| 1794 bool WasmInterpreter::SetBreakpoint(const WasmFunction* function, pc_t pc, | 1797 bool WasmInterpreter::SetBreakpoint(const WasmFunction* function, pc_t pc, |
| 1795 bool enabled) { | 1798 bool enabled) { |
| 1796 InterpreterCode* code = internals_->codemap_.FindCode(function); | 1799 InterpreterCode* code = internals_->codemap_.FindCode(function); |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1878 } | 1881 } |
| 1879 | 1882 |
| 1880 bool WasmInterpreter::SetFunctionCodeForTesting(const WasmFunction* function, | 1883 bool WasmInterpreter::SetFunctionCodeForTesting(const WasmFunction* function, |
| 1881 const byte* start, | 1884 const byte* start, |
| 1882 const byte* end) { | 1885 const byte* end) { |
| 1883 return internals_->codemap_.SetFunctionCode(function, start, end); | 1886 return internals_->codemap_.SetFunctionCode(function, start, end); |
| 1884 } | 1887 } |
| 1885 | 1888 |
| 1886 ControlTransferMap WasmInterpreter::ComputeControlTransfersForTesting( | 1889 ControlTransferMap WasmInterpreter::ComputeControlTransfersForTesting( |
| 1887 Zone* zone, const byte* start, const byte* end) { | 1890 Zone* zone, const byte* start, const byte* end) { |
| 1888 ControlTransfers targets(zone, nullptr, nullptr, start, end); | 1891 ControlTransfers targets(zone, nullptr, start, end); |
| 1889 return targets.map_; | 1892 return targets.map_; |
| 1890 } | 1893 } |
| 1891 | 1894 |
| 1892 } // namespace wasm | 1895 } // namespace wasm |
| 1893 } // namespace internal | 1896 } // namespace internal |
| 1894 } // namespace v8 | 1897 } // namespace v8 |
| OLD | NEW |