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 |