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 |