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

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

Issue 2135693002: [wasm] Add a BytecodeIterator and use in non-performance-critical situations. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Add C++ iterator Created 4 years, 5 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
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 743 matching lines...) Expand 10 before | Expand all | Expand 10 after
754 // This works by maintaining a stack of control constructs similar to the 754 // This works by maintaining a stack of control constructs similar to the
755 // AST decoder. The {control_stack} allows matching {br,br_if,br_table} 755 // AST decoder. The {control_stack} allows matching {br,br_if,br_table}
756 // bytecodes with their target, as well as determining whether the current 756 // bytecodes with their target, as well as determining whether the current
757 // bytecodes are within the true or false block of an else. 757 // bytecodes are within the true or false block of an else.
758 // The value stack depth is tracked as {value_depth} and is needed to 758 // The value stack depth is tracked as {value_depth} and is needed to
759 // determine how many values to pop off the stack for explicit and 759 // determine how many values to pop off the stack for explicit and
760 // implicit control flow. 760 // implicit control flow.
761 761
762 std::vector<Control> control_stack; 762 std::vector<Control> control_stack;
763 size_t value_depth = 0; 763 size_t value_depth = 0;
764 Decoder decoder(start, end); // for reading operands. 764 for (BytecodeIterator i(start + locals_encoded_size, end); i.has_next();
765 const byte* pc = start + locals_encoded_size; 765 i.next()) {
766 766 WasmOpcode opcode = i.current();
767 while (pc < end) { 767 TRACE("@%u: control %s (depth = %zu)\n", i.pc_offset(),
768 WasmOpcode opcode = static_cast<WasmOpcode>(*pc);
769 TRACE("@%td: control %s (depth = %zu)\n", (pc - start),
770 WasmOpcodes::OpcodeName(opcode), value_depth); 768 WasmOpcodes::OpcodeName(opcode), value_depth);
771 switch (opcode) { 769 switch (opcode) {
772 case kExprBlock: { 770 case kExprBlock: {
773 TRACE("control @%td $%zu: Block\n", (pc - start), value_depth); 771 TRACE("control @%u $%zu: Block\n", i.pc_offset(), value_depth);
774 CLabel* label = new (zone) CLabel(zone, value_depth); 772 CLabel* label = new (zone) CLabel(zone, value_depth);
775 control_stack.push_back({pc, label, nullptr}); 773 control_stack.push_back({i.pc(), label, nullptr});
776 break; 774 break;
777 } 775 }
778 case kExprLoop: { 776 case kExprLoop: {
779 TRACE("control @%td $%zu: Loop\n", (pc - start), value_depth); 777 TRACE("control @%u $%zu: Loop\n", i.pc_offset(), value_depth);
780 CLabel* label1 = new (zone) CLabel(zone, value_depth); 778 CLabel* label1 = new (zone) CLabel(zone, value_depth);
781 CLabel* label2 = new (zone) CLabel(zone, value_depth); 779 CLabel* label2 = new (zone) CLabel(zone, value_depth);
782 control_stack.push_back({pc, label1, nullptr}); 780 control_stack.push_back({i.pc(), label1, nullptr});
783 control_stack.push_back({pc, label2, nullptr}); 781 control_stack.push_back({i.pc(), label2, nullptr});
784 label2->Bind(&map_, start, pc, false); 782 label2->Bind(&map_, start, i.pc(), false);
785 break; 783 break;
786 } 784 }
787 case kExprIf: { 785 case kExprIf: {
788 TRACE("control @%td $%zu: If\n", (pc - start), value_depth); 786 TRACE("control @%u $%zu: If\n", i.pc_offset(), value_depth);
789 value_depth--; 787 value_depth--;
790 CLabel* end_label = new (zone) CLabel(zone, value_depth); 788 CLabel* end_label = new (zone) CLabel(zone, value_depth);
791 CLabel* else_label = new (zone) CLabel(zone, value_depth); 789 CLabel* else_label = new (zone) CLabel(zone, value_depth);
792 control_stack.push_back({pc, end_label, else_label}); 790 control_stack.push_back({i.pc(), end_label, else_label});
793 else_label->Ref(&map_, start, {pc, value_depth, false}); 791 else_label->Ref(&map_, start, {i.pc(), value_depth, false});
794 break; 792 break;
795 } 793 }
796 case kExprElse: { 794 case kExprElse: {
797 Control* c = &control_stack.back(); 795 Control* c = &control_stack.back();
798 TRACE("control @%td $%zu: Else\n", (pc - start), value_depth); 796 TRACE("control @%u $%zu: Else\n", i.pc_offset(), value_depth);
799 c->end_label->Ref(&map_, start, {pc, value_depth, false}); 797 c->end_label->Ref(&map_, start, {i.pc(), value_depth, false});
800 value_depth = c->end_label->value_depth; 798 value_depth = c->end_label->value_depth;
801 DCHECK_NOT_NULL(c->else_label); 799 DCHECK_NOT_NULL(c->else_label);
802 c->else_label->Bind(&map_, start, pc + 1, false); 800 c->else_label->Bind(&map_, start, i.pc() + 1, false);
803 c->else_label = nullptr; 801 c->else_label = nullptr;
804 break; 802 break;
805 } 803 }
806 case kExprEnd: { 804 case kExprEnd: {
807 Control* c = &control_stack.back(); 805 Control* c = &control_stack.back();
808 TRACE("control @%td $%zu: End\n", (pc - start), value_depth); 806 TRACE("control @%u $%zu: End\n", i.pc_offset(), value_depth);
809 if (c->end_label->target) { 807 if (c->end_label->target) {
810 // only loops have bound labels. 808 // only loops have bound labels.
811 DCHECK_EQ(kExprLoop, *c->pc); 809 DCHECK_EQ(kExprLoop, *c->pc);
812 control_stack.pop_back(); 810 control_stack.pop_back();
813 c = &control_stack.back(); 811 c = &control_stack.back();
814 } 812 }
815 if (c->else_label) c->else_label->Bind(&map_, start, pc + 1, true); 813 if (c->else_label)
816 c->end_label->Ref(&map_, start, {pc, value_depth, false}); 814 c->else_label->Bind(&map_, start, i.pc() + 1, true);
817 c->end_label->Bind(&map_, start, pc + 1, true); 815 c->end_label->Ref(&map_, start, {i.pc(), value_depth, false});
816 c->end_label->Bind(&map_, start, i.pc() + 1, true);
818 value_depth = c->end_label->value_depth + 1; 817 value_depth = c->end_label->value_depth + 1;
819 control_stack.pop_back(); 818 control_stack.pop_back();
820 break; 819 break;
821 } 820 }
822 case kExprBr: { 821 case kExprBr: {
823 BreakDepthOperand operand(&decoder, pc); 822 BreakDepthOperand operand(&i, i.pc());
824 TRACE("control @%td $%zu: Br[arity=%u, depth=%u]\n", (pc - start), 823 TRACE("control @%u $%zu: Br[arity=%u, depth=%u]\n", i.pc_offset(),
825 value_depth, operand.arity, operand.depth); 824 value_depth, operand.arity, operand.depth);
826 value_depth -= operand.arity; 825 value_depth -= operand.arity;
827 control_stack[control_stack.size() - operand.depth - 1].Ref( 826 control_stack[control_stack.size() - operand.depth - 1].Ref(
828 &map_, start, pc, value_depth, operand.arity > 0); 827 &map_, start, i.pc(), value_depth, operand.arity > 0);
829 value_depth++; 828 value_depth++;
830 break; 829 break;
831 } 830 }
832 case kExprBrIf: { 831 case kExprBrIf: {
833 BreakDepthOperand operand(&decoder, pc); 832 BreakDepthOperand operand(&i, i.pc());
834 TRACE("control @%td $%zu: BrIf[arity=%u, depth=%u]\n", (pc - start), 833 TRACE("control @%u $%zu: BrIf[arity=%u, depth=%u]\n", i.pc_offset(),
835 value_depth, operand.arity, operand.depth); 834 value_depth, operand.arity, operand.depth);
836 value_depth -= (operand.arity + 1); 835 value_depth -= (operand.arity + 1);
837 control_stack[control_stack.size() - operand.depth - 1].Ref( 836 control_stack[control_stack.size() - operand.depth - 1].Ref(
838 &map_, start, pc, value_depth, operand.arity > 0); 837 &map_, start, i.pc(), value_depth, operand.arity > 0);
839 value_depth++; 838 value_depth++;
840 break; 839 break;
841 } 840 }
842 case kExprBrTable: { 841 case kExprBrTable: {
843 BranchTableOperand operand(&decoder, pc); 842 BranchTableOperand operand(&i, i.pc());
844 TRACE("control @%td $%zu: BrTable[arity=%u count=%u]\n", (pc - start), 843 TRACE("control @%u $%zu: BrTable[arity=%u count=%u]\n", i.pc_offset(),
845 value_depth, operand.arity, operand.table_count); 844 value_depth, operand.arity, operand.table_count);
846 value_depth -= (operand.arity + 1); 845 value_depth -= (operand.arity + 1);
847 for (uint32_t i = 0; i < operand.table_count + 1; ++i) { 846 for (uint32_t j = 0; j < operand.table_count + 1; ++j) {
848 uint32_t target = operand.read_entry(&decoder, i); 847 uint32_t target = operand.read_entry(&i, j);
849 control_stack[control_stack.size() - target - 1].Ref( 848 control_stack[control_stack.size() - target - 1].Ref(
850 &map_, start, pc + i, value_depth, operand.arity > 0); 849 &map_, start, i.pc() + j, value_depth, operand.arity > 0);
851 } 850 }
852 value_depth++; 851 value_depth++;
853 break; 852 break;
854 } 853 }
855 default: { 854 default: {
856 value_depth = value_depth - OpcodeArity(pc, end) + 1; 855 value_depth = value_depth - OpcodeArity(i.pc(), end) + 1;
857 break; 856 break;
858 } 857 }
859 } 858 }
860
861 pc += OpcodeLength(pc, end);
862 } 859 }
863 } 860 }
864 861
865 ControlTransfer Lookup(pc_t from) { 862 ControlTransfer Lookup(pc_t from) {
866 auto result = map_.find(from); 863 auto result = map_.find(from);
867 if (result == map_.end()) { 864 if (result == map_.end()) {
868 V8_Fatal(__FILE__, __LINE__, "no control target for pc %zu", from); 865 V8_Fatal(__FILE__, __LINE__, "no control target for pc %zu", from);
869 } 866 }
870 return result->second; 867 return result->second;
871 } 868 }
(...skipping 971 matching lines...) Expand 10 before | Expand all | Expand 10 after
1843 1840
1844 ControlTransferMap WasmInterpreter::ComputeControlTransfersForTesting( 1841 ControlTransferMap WasmInterpreter::ComputeControlTransfersForTesting(
1845 Zone* zone, const byte* start, const byte* end) { 1842 Zone* zone, const byte* start, const byte* end) {
1846 ControlTransfers targets(zone, 0, start, end); 1843 ControlTransfers targets(zone, 0, start, end);
1847 return targets.map_; 1844 return targets.map_;
1848 } 1845 }
1849 1846
1850 } // namespace wasm 1847 } // namespace wasm
1851 } // namespace internal 1848 } // namespace internal
1852 } // namespace v8 1849 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698