| 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 |