| OLD | NEW |
| (Empty) |
| 1 // Copyright 2017 the V8 project authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "src/interpreter/setup-interpreter.h" | |
| 6 | |
| 7 #include "src/handles-inl.h" | |
| 8 #include "src/interpreter/bytecodes.h" | |
| 9 #include "src/interpreter/interpreter-generator.h" | |
| 10 #include "src/interpreter/interpreter.h" | |
| 11 #include "src/objects-inl.h" | |
| 12 | |
| 13 namespace v8 { | |
| 14 namespace internal { | |
| 15 namespace interpreter { | |
| 16 | |
| 17 // static | |
| 18 void SetupInterpreter::InstallBytecodeHandlers(Interpreter* interpreter) { | |
| 19 DCHECK(!interpreter->IsDispatchTableInitialized()); | |
| 20 HandleScope scope(interpreter->isolate_); | |
| 21 Address* dispatch_table = interpreter->dispatch_table_; | |
| 22 | |
| 23 // Generate bytecode handlers for all bytecodes and scales. | |
| 24 const OperandScale kOperandScales[] = { | |
| 25 #define VALUE(Name, _) OperandScale::k##Name, | |
| 26 OPERAND_SCALE_LIST(VALUE) | |
| 27 #undef VALUE | |
| 28 }; | |
| 29 | |
| 30 for (OperandScale operand_scale : kOperandScales) { | |
| 31 #define GENERATE_CODE(Name, ...) \ | |
| 32 InstallBytecodeHandler(interpreter->isolate_, dispatch_table, \ | |
| 33 Bytecode::k##Name, operand_scale); | |
| 34 BYTECODE_LIST(GENERATE_CODE) | |
| 35 #undef GENERATE_CODE | |
| 36 } | |
| 37 | |
| 38 // Fill unused entries will the illegal bytecode handler. | |
| 39 size_t illegal_index = Interpreter::GetDispatchTableIndex( | |
| 40 Bytecode::kIllegal, OperandScale::kSingle); | |
| 41 for (size_t index = 0; index < Interpreter::kDispatchTableSize; ++index) { | |
| 42 if (dispatch_table[index] == nullptr) { | |
| 43 dispatch_table[index] = dispatch_table[illegal_index]; | |
| 44 } | |
| 45 } | |
| 46 | |
| 47 // Initialization should have been successful. | |
| 48 DCHECK(interpreter->IsDispatchTableInitialized()); | |
| 49 } | |
| 50 | |
| 51 // static | |
| 52 bool SetupInterpreter::ReuseExistingHandler(Address* dispatch_table, | |
| 53 Bytecode bytecode, | |
| 54 OperandScale operand_scale) { | |
| 55 size_t index = Interpreter::GetDispatchTableIndex(bytecode, operand_scale); | |
| 56 switch (bytecode) { | |
| 57 case Bytecode::kCallProperty: | |
| 58 case Bytecode::kCallProperty0: | |
| 59 case Bytecode::kCallProperty1: | |
| 60 case Bytecode::kCallProperty2: { | |
| 61 const int offset = static_cast<int>(Bytecode::kCallProperty) - | |
| 62 static_cast<int>(Bytecode::kCall); | |
| 63 STATIC_ASSERT(offset == static_cast<int>(Bytecode::kCallProperty0) - | |
| 64 static_cast<int>(Bytecode::kCall0)); | |
| 65 STATIC_ASSERT(offset == static_cast<int>(Bytecode::kCallProperty1) - | |
| 66 static_cast<int>(Bytecode::kCall1)); | |
| 67 STATIC_ASSERT(offset == static_cast<int>(Bytecode::kCallProperty2) - | |
| 68 static_cast<int>(Bytecode::kCall2)); | |
| 69 CHECK_LT(offset, index); | |
| 70 dispatch_table[index] = dispatch_table[index - offset]; | |
| 71 return true; | |
| 72 break; | |
| 73 } | |
| 74 default: | |
| 75 return false; | |
| 76 } | |
| 77 } | |
| 78 | |
| 79 // static | |
| 80 void SetupInterpreter::InstallBytecodeHandler(Isolate* isolate, | |
| 81 Address* dispatch_table, | |
| 82 Bytecode bytecode, | |
| 83 OperandScale operand_scale) { | |
| 84 if (!Bytecodes::BytecodeHasHandler(bytecode, operand_scale)) return; | |
| 85 if (ReuseExistingHandler(dispatch_table, bytecode, operand_scale)) return; | |
| 86 | |
| 87 size_t index = Interpreter::GetDispatchTableIndex(bytecode, operand_scale); | |
| 88 Handle<Code> code = GenerateBytecodeHandler(isolate, bytecode, operand_scale); | |
| 89 dispatch_table[index] = code->entry(); | |
| 90 } | |
| 91 | |
| 92 } // namespace interpreter | |
| 93 } // namespace internal | |
| 94 } // namespace v8 | |
| OLD | NEW |