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 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
47 operand_scale <= OperandScale::kMaxValid; | 47 operand_scale <= OperandScale::kMaxValid; |
48 operand_scale = Bytecodes::NextOperandScale(operand_scale)) { | 48 operand_scale = Bytecodes::NextOperandScale(operand_scale)) { |
49 #define GENERATE_CODE(Name, ...) \ | 49 #define GENERATE_CODE(Name, ...) \ |
50 { \ | 50 { \ |
51 if (Bytecodes::BytecodeHasHandler(Bytecode::k##Name, operand_scale)) { \ | 51 if (Bytecodes::BytecodeHasHandler(Bytecode::k##Name, operand_scale)) { \ |
52 InterpreterAssembler assembler(isolate_, &zone, Bytecode::k##Name, \ | 52 InterpreterAssembler assembler(isolate_, &zone, Bytecode::k##Name, \ |
53 operand_scale); \ | 53 operand_scale); \ |
54 Do##Name(&assembler); \ | 54 Do##Name(&assembler); \ |
55 Handle<Code> code = assembler.GenerateCode(); \ | 55 Handle<Code> code = assembler.GenerateCode(); \ |
56 size_t index = GetDispatchTableIndex(Bytecode::k##Name, operand_scale); \ | 56 size_t index = GetDispatchTableIndex(Bytecode::k##Name, operand_scale); \ |
57 dispatch_table_[index] = *code; \ | 57 dispatch_table_[index] = code->entry(); \ |
58 TraceCodegen(code); \ | 58 TraceCodegen(code); \ |
59 LOG_CODE_EVENT( \ | 59 LOG_CODE_EVENT( \ |
60 isolate_, \ | 60 isolate_, \ |
61 CodeCreateEvent( \ | 61 CodeCreateEvent( \ |
62 Logger::BYTECODE_HANDLER_TAG, AbstractCode::cast(*code), \ | 62 Logger::BYTECODE_HANDLER_TAG, AbstractCode::cast(*code), \ |
63 Bytecodes::ToString(Bytecode::k##Name, operand_scale).c_str())); \ | 63 Bytecodes::ToString(Bytecode::k##Name, operand_scale).c_str())); \ |
64 } \ | 64 } \ |
65 } | 65 } |
66 BYTECODE_LIST(GENERATE_CODE) | 66 BYTECODE_LIST(GENERATE_CODE) |
67 #undef GENERATE_CODE | 67 #undef GENERATE_CODE |
68 } | 68 } |
69 | 69 |
70 // Fill unused entries will the illegal bytecode handler. | 70 // Fill unused entries will the illegal bytecode handler. |
71 size_t illegal_index = | 71 size_t illegal_index = |
72 GetDispatchTableIndex(Bytecode::kIllegal, OperandScale::kSingle); | 72 GetDispatchTableIndex(Bytecode::kIllegal, OperandScale::kSingle); |
73 for (size_t index = 0; index < arraysize(dispatch_table_); ++index) { | 73 for (size_t index = 0; index < arraysize(dispatch_table_); ++index) { |
74 if (dispatch_table_[index] == nullptr) { | 74 if (dispatch_table_[index] == nullptr) { |
75 dispatch_table_[index] = dispatch_table_[illegal_index]; | 75 dispatch_table_[index] = dispatch_table_[illegal_index]; |
76 } | 76 } |
77 } | 77 } |
78 } | 78 } |
79 | 79 |
80 Code* Interpreter::GetBytecodeHandler(Bytecode bytecode, | 80 Code* Interpreter::GetBytecodeHandler(Bytecode bytecode, |
81 OperandScale operand_scale) { | 81 OperandScale operand_scale) { |
82 DCHECK(IsDispatchTableInitialized()); | 82 DCHECK(IsDispatchTableInitialized()); |
83 DCHECK(Bytecodes::BytecodeHasHandler(bytecode, operand_scale)); | 83 DCHECK(Bytecodes::BytecodeHasHandler(bytecode, operand_scale)); |
84 size_t index = GetDispatchTableIndex(bytecode, operand_scale); | 84 size_t index = GetDispatchTableIndex(bytecode, operand_scale); |
85 return dispatch_table_[index]; | 85 Address code_entry = dispatch_table_[index]; |
| 86 return Code::GetCodeFromTargetAddress(code_entry); |
86 } | 87 } |
87 | 88 |
88 // static | 89 // static |
89 size_t Interpreter::GetDispatchTableIndex(Bytecode bytecode, | 90 size_t Interpreter::GetDispatchTableIndex(Bytecode bytecode, |
90 OperandScale operand_scale) { | 91 OperandScale operand_scale) { |
91 static const size_t kEntriesPerOperandScale = 1u << kBitsPerByte; | 92 static const size_t kEntriesPerOperandScale = 1u << kBitsPerByte; |
92 size_t index = static_cast<size_t>(bytecode); | 93 size_t index = static_cast<size_t>(bytecode); |
93 OperandScale current_scale = OperandScale::kSingle; | 94 OperandScale current_scale = OperandScale::kSingle; |
94 while (current_scale != operand_scale) { | 95 while (current_scale != operand_scale) { |
95 index += kEntriesPerOperandScale; | 96 index += kEntriesPerOperandScale; |
96 current_scale = Bytecodes::NextOperandScale(current_scale); | 97 current_scale = Bytecodes::NextOperandScale(current_scale); |
97 } | 98 } |
98 return index; | 99 return index; |
99 } | 100 } |
100 | 101 |
101 void Interpreter::IterateDispatchTable(ObjectVisitor* v) { | 102 void Interpreter::IterateDispatchTable(ObjectVisitor* v) { |
102 v->VisitPointers( | 103 for (int i = 0; i < kDispatchTableSize; i++) { |
103 reinterpret_cast<Object**>(&dispatch_table_[0]), | 104 Address code_entry = dispatch_table_[i]; |
104 reinterpret_cast<Object**>(&dispatch_table_[0] + kDispatchTableSize)); | 105 Object* code = code_entry == nullptr |
| 106 ? nullptr |
| 107 : Code::GetCodeFromTargetAddress(code_entry); |
| 108 Object* old_code = code; |
| 109 v->VisitPointer(&code); |
| 110 if (code != old_code) { |
| 111 dispatch_table_[i] = reinterpret_cast<Code*>(code)->entry(); |
| 112 } |
| 113 } |
105 } | 114 } |
106 | 115 |
107 // static | 116 // static |
108 int Interpreter::InterruptBudget() { | 117 int Interpreter::InterruptBudget() { |
109 // TODO(ignition): Tune code size multiplier. | 118 // TODO(ignition): Tune code size multiplier. |
110 const int kCodeSizeMultiplier = 32; | 119 const int kCodeSizeMultiplier = 32; |
111 return FLAG_interrupt_budget * kCodeSizeMultiplier; | 120 return FLAG_interrupt_budget * kCodeSizeMultiplier; |
112 } | 121 } |
113 | 122 |
114 bool Interpreter::MakeBytecode(CompilationInfo* info) { | 123 bool Interpreter::MakeBytecode(CompilationInfo* info) { |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
172 if (FLAG_trace_ignition_codegen) { | 181 if (FLAG_trace_ignition_codegen) { |
173 OFStream os(stdout); | 182 OFStream os(stdout); |
174 code->Disassemble(nullptr, os); | 183 code->Disassemble(nullptr, os); |
175 os << std::flush; | 184 os << std::flush; |
176 } | 185 } |
177 #endif // ENABLE_DISASSEMBLER | 186 #endif // ENABLE_DISASSEMBLER |
178 } | 187 } |
179 | 188 |
180 const char* Interpreter::LookupNameOfBytecodeHandler(Code* code) { | 189 const char* Interpreter::LookupNameOfBytecodeHandler(Code* code) { |
181 #ifdef ENABLE_DISASSEMBLER | 190 #ifdef ENABLE_DISASSEMBLER |
182 #define RETURN_NAME(Name, ...) \ | 191 #define RETURN_NAME(Name, ...) \ |
183 if (dispatch_table_[Bytecodes::ToByte(Bytecode::k##Name)] == code) { \ | 192 if (dispatch_table_[Bytecodes::ToByte(Bytecode::k##Name)] == \ |
184 return #Name; \ | 193 code->entry()) { \ |
| 194 return #Name; \ |
185 } | 195 } |
186 BYTECODE_LIST(RETURN_NAME) | 196 BYTECODE_LIST(RETURN_NAME) |
187 #undef RETURN_NAME | 197 #undef RETURN_NAME |
188 #endif // ENABLE_DISASSEMBLER | 198 #endif // ENABLE_DISASSEMBLER |
189 return nullptr; | 199 return nullptr; |
190 } | 200 } |
191 | 201 |
192 void Interpreter::WriteDispatchCounters() { | 202 void Interpreter::WriteDispatchCounters() { |
193 std::ofstream stream(FLAG_trace_ignition_dispatches_output_file); | 203 std::ofstream stream(FLAG_trace_ignition_dispatches_output_file); |
194 static const int kBytecodeCount = static_cast<int>(Bytecode::kLast) + 1; | 204 static const int kBytecodeCount = static_cast<int>(Bytecode::kLast) + 1; |
(...skipping 1476 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1671 // Illegal | 1681 // Illegal |
1672 // | 1682 // |
1673 // An invalid bytecode aborting execution if dispatched. | 1683 // An invalid bytecode aborting execution if dispatched. |
1674 void Interpreter::DoIllegal(InterpreterAssembler* assembler) { | 1684 void Interpreter::DoIllegal(InterpreterAssembler* assembler) { |
1675 __ Abort(kInvalidBytecode); | 1685 __ Abort(kInvalidBytecode); |
1676 } | 1686 } |
1677 | 1687 |
1678 } // namespace interpreter | 1688 } // namespace interpreter |
1679 } // namespace internal | 1689 } // namespace internal |
1680 } // namespace v8 | 1690 } // namespace v8 |
OLD | NEW |