Line data Source code
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 43 : void SetupInterpreter::InstallBytecodeHandlers(Interpreter* interpreter) {
19 : DCHECK(!interpreter->IsDispatchTableInitialized());
20 43 : HandleScope scope(interpreter->isolate_);
21 43 : 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 43 : };
29 :
30 172 : for (OperandScale operand_scale : kOperandScales) {
31 : #define GENERATE_CODE(Name, ...) \
32 : InstallBytecodeHandler(interpreter->isolate_, dispatch_table, \
33 : Bytecode::k##Name, operand_scale);
34 129 : 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 43 : Bytecode::kIllegal, OperandScale::kSingle);
41 33067 : for (size_t index = 0; index < Interpreter::kDispatchTableSize; ++index) {
42 33024 : if (dispatch_table[index] == nullptr) {
43 14233 : dispatch_table[index] = dispatch_table[illegal_index];
44 : }
45 : }
46 :
47 : // Initialization should have been successful.
48 : DCHECK(interpreter->IsDispatchTableInitialized());
49 43 : }
50 :
51 : // static
52 18791 : bool SetupInterpreter::ReuseExistingHandler(Address* dispatch_table,
53 : Bytecode bytecode,
54 : OperandScale operand_scale) {
55 18791 : size_t index = Interpreter::GetDispatchTableIndex(bytecode, operand_scale);
56 18791 : switch (bytecode) {
57 : case Bytecode::kLdaImmutableContextSlot:
58 : STATIC_ASSERT(static_cast<int>(Bytecode::kLdaContextSlot) <
59 : static_cast<int>(Bytecode::kLdaImmutableContextSlot));
60 129 : dispatch_table[index] = dispatch_table[Interpreter::GetDispatchTableIndex(
61 129 : Bytecode::kLdaContextSlot, operand_scale)];
62 129 : return true;
63 : case Bytecode::kLdaImmutableCurrentContextSlot:
64 : STATIC_ASSERT(
65 : static_cast<int>(Bytecode::kLdaCurrentContextSlot) <
66 : static_cast<int>(Bytecode::kLdaImmutableCurrentContextSlot));
67 129 : dispatch_table[index] = dispatch_table[Interpreter::GetDispatchTableIndex(
68 129 : Bytecode::kLdaCurrentContextSlot, operand_scale)];
69 129 : return true;
70 : default:
71 : return false;
72 : }
73 : return false;
74 : }
75 :
76 : // static
77 21285 : void SetupInterpreter::InstallBytecodeHandler(Isolate* isolate,
78 : Address* dispatch_table,
79 : Bytecode bytecode,
80 : OperandScale operand_scale) {
81 24037 : if (!Bytecodes::BytecodeHasHandler(bytecode, operand_scale)) return;
82 18791 : if (ReuseExistingHandler(dispatch_table, bytecode, operand_scale)) return;
83 :
84 18533 : size_t index = Interpreter::GetDispatchTableIndex(bytecode, operand_scale);
85 18533 : Handle<Code> code = GenerateBytecodeHandler(isolate, bytecode, operand_scale);
86 37066 : dispatch_table[index] = code->entry();
87 : }
88 :
89 : } // namespace interpreter
90 : } // namespace internal
91 : } // namespace v8
|