OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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/interpreter/interpreter.h" | 5 #include "src/interpreter/interpreter.h" |
6 | 6 |
7 #include <fstream> | 7 #include <fstream> |
8 | 8 |
9 #include "src/ast/prettyprinter.h" | 9 #include "src/ast/prettyprinter.h" |
10 #include "src/code-factory.h" | 10 #include "src/code-factory.h" |
(...skipping 27 matching lines...) Expand all Loading... |
38 | 38 |
39 if (FLAG_trace_ignition_dispatches) { | 39 if (FLAG_trace_ignition_dispatches) { |
40 static const int kBytecodeCount = static_cast<int>(Bytecode::kLast) + 1; | 40 static const int kBytecodeCount = static_cast<int>(Bytecode::kLast) + 1; |
41 bytecode_dispatch_counters_table_.Reset( | 41 bytecode_dispatch_counters_table_.Reset( |
42 new uintptr_t[kBytecodeCount * kBytecodeCount]); | 42 new uintptr_t[kBytecodeCount * kBytecodeCount]); |
43 memset(bytecode_dispatch_counters_table_.get(), 0, | 43 memset(bytecode_dispatch_counters_table_.get(), 0, |
44 sizeof(uintptr_t) * kBytecodeCount * kBytecodeCount); | 44 sizeof(uintptr_t) * kBytecodeCount * kBytecodeCount); |
45 } | 45 } |
46 | 46 |
47 // Generate bytecode handlers for all bytecodes and scales. | 47 // Generate bytecode handlers for all bytecodes and scales. |
48 for (OperandScale operand_scale = OperandScale::kSingle; | 48 const OperandScale kOperandScales[] = { |
49 operand_scale <= OperandScale::kMaxValid; | 49 #define VALUE(Name, _) OperandScale::k##Name, |
50 operand_scale = Bytecodes::NextOperandScale(operand_scale)) { | 50 OPERAND_SCALE_LIST(VALUE) |
| 51 #undef VALUE |
| 52 }; |
| 53 |
| 54 for (OperandScale operand_scale : kOperandScales) { |
51 #define GENERATE_CODE(Name, ...) \ | 55 #define GENERATE_CODE(Name, ...) \ |
52 { \ | 56 { \ |
53 if (Bytecodes::BytecodeHasHandler(Bytecode::k##Name, operand_scale)) { \ | 57 if (Bytecodes::BytecodeHasHandler(Bytecode::k##Name, operand_scale)) { \ |
54 InterpreterAssembler assembler(isolate_, &zone, Bytecode::k##Name, \ | 58 InterpreterAssembler assembler(isolate_, &zone, Bytecode::k##Name, \ |
55 operand_scale); \ | 59 operand_scale); \ |
56 Do##Name(&assembler); \ | 60 Do##Name(&assembler); \ |
57 Handle<Code> code = assembler.GenerateCode(); \ | 61 Handle<Code> code = assembler.GenerateCode(); \ |
58 size_t index = GetDispatchTableIndex(Bytecode::k##Name, operand_scale); \ | 62 size_t index = GetDispatchTableIndex(Bytecode::k##Name, operand_scale); \ |
59 dispatch_table_[index] = code->entry(); \ | 63 dispatch_table_[index] = code->entry(); \ |
60 TraceCodegen(code); \ | 64 TraceCodegen(code); \ |
(...skipping 25 matching lines...) Expand all Loading... |
86 size_t index = GetDispatchTableIndex(bytecode, operand_scale); | 90 size_t index = GetDispatchTableIndex(bytecode, operand_scale); |
87 Address code_entry = dispatch_table_[index]; | 91 Address code_entry = dispatch_table_[index]; |
88 return Code::GetCodeFromTargetAddress(code_entry); | 92 return Code::GetCodeFromTargetAddress(code_entry); |
89 } | 93 } |
90 | 94 |
91 // static | 95 // static |
92 size_t Interpreter::GetDispatchTableIndex(Bytecode bytecode, | 96 size_t Interpreter::GetDispatchTableIndex(Bytecode bytecode, |
93 OperandScale operand_scale) { | 97 OperandScale operand_scale) { |
94 static const size_t kEntriesPerOperandScale = 1u << kBitsPerByte; | 98 static const size_t kEntriesPerOperandScale = 1u << kBitsPerByte; |
95 size_t index = static_cast<size_t>(bytecode); | 99 size_t index = static_cast<size_t>(bytecode); |
96 OperandScale current_scale = OperandScale::kSingle; | 100 switch (operand_scale) { |
97 while (current_scale != operand_scale) { | 101 case OperandScale::kSingle: |
98 index += kEntriesPerOperandScale; | 102 return index; |
99 current_scale = Bytecodes::NextOperandScale(current_scale); | 103 case OperandScale::kDouble: |
| 104 return index + kEntriesPerOperandScale; |
| 105 case OperandScale::kQuadruple: |
| 106 return index + 2 * kEntriesPerOperandScale; |
100 } | 107 } |
101 return index; | 108 UNREACHABLE(); |
| 109 return 0; |
102 } | 110 } |
103 | 111 |
104 void Interpreter::IterateDispatchTable(ObjectVisitor* v) { | 112 void Interpreter::IterateDispatchTable(ObjectVisitor* v) { |
105 for (int i = 0; i < kDispatchTableSize; i++) { | 113 for (int i = 0; i < kDispatchTableSize; i++) { |
106 Address code_entry = dispatch_table_[i]; | 114 Address code_entry = dispatch_table_[i]; |
107 Object* code = code_entry == nullptr | 115 Object* code = code_entry == nullptr |
108 ? nullptr | 116 ? nullptr |
109 : Code::GetCodeFromTargetAddress(code_entry); | 117 : Code::GetCodeFromTargetAddress(code_entry); |
110 Object* old_code = code; | 118 Object* old_code = code; |
111 v->VisitPointer(&code); | 119 v->VisitPointer(&code); |
(...skipping 1648 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1760 __ DispatchWide(OperandScale::kQuadruple); | 1768 __ DispatchWide(OperandScale::kQuadruple); |
1761 } | 1769 } |
1762 | 1770 |
1763 // Illegal | 1771 // Illegal |
1764 // | 1772 // |
1765 // An invalid bytecode aborting execution if dispatched. | 1773 // An invalid bytecode aborting execution if dispatched. |
1766 void Interpreter::DoIllegal(InterpreterAssembler* assembler) { | 1774 void Interpreter::DoIllegal(InterpreterAssembler* assembler) { |
1767 __ Abort(kInvalidBytecode); | 1775 __ Abort(kInvalidBytecode); |
1768 } | 1776 } |
1769 | 1777 |
| 1778 // Nop |
| 1779 // |
| 1780 // No operation. |
| 1781 void Interpreter::DoNop(InterpreterAssembler* assembler) { __ Dispatch(); } |
| 1782 |
1770 // SuspendGenerator <generator> | 1783 // SuspendGenerator <generator> |
1771 // | 1784 // |
1772 // Exports the register file and stores it into the generator. Also stores the | 1785 // Exports the register file and stores it into the generator. Also stores the |
1773 // current context and the state given in the accumulator into the generator. | 1786 // current context and the state given in the accumulator into the generator. |
1774 void Interpreter::DoSuspendGenerator(InterpreterAssembler* assembler) { | 1787 void Interpreter::DoSuspendGenerator(InterpreterAssembler* assembler) { |
1775 Node* generator_reg = __ BytecodeOperandReg(0); | 1788 Node* generator_reg = __ BytecodeOperandReg(0); |
1776 Node* generator = __ LoadRegister(generator_reg); | 1789 Node* generator = __ LoadRegister(generator_reg); |
1777 | 1790 |
1778 Node* array = | 1791 Node* array = |
1779 __ LoadObjectField(generator, JSGeneratorObject::kOperandStackOffset); | 1792 __ LoadObjectField(generator, JSGeneratorObject::kOperandStackOffset); |
(...skipping 25 matching lines...) Expand all Loading... |
1805 __ StoreObjectField(generator, JSGeneratorObject::kContinuationOffset, | 1818 __ StoreObjectField(generator, JSGeneratorObject::kContinuationOffset, |
1806 __ SmiTag(new_state)); | 1819 __ SmiTag(new_state)); |
1807 __ SetAccumulator(old_state); | 1820 __ SetAccumulator(old_state); |
1808 | 1821 |
1809 __ Dispatch(); | 1822 __ Dispatch(); |
1810 } | 1823 } |
1811 | 1824 |
1812 } // namespace interpreter | 1825 } // namespace interpreter |
1813 } // namespace internal | 1826 } // namespace internal |
1814 } // namespace v8 | 1827 } // namespace v8 |
OLD | NEW |