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 : namespace {
18 : void PrintBuiltinSize(Bytecode bytecode, OperandScale operand_scale,
19 : Handle<Code> code) {
20 : PrintF(stdout, "Ignition Handler, %s, %d\n",
21 : Bytecodes::ToString(bytecode, operand_scale).c_str(),
22 : code->instruction_size());
23 : }
24 : } // namespace
25 :
26 : // static
27 31 : void SetupInterpreter::InstallBytecodeHandlers(Interpreter* interpreter) {
28 : DCHECK(!interpreter->IsDispatchTableInitialized());
29 31 : HandleScope scope(interpreter->isolate_);
30 : // Canonicalize handles, so that we can share constant pool entries pointing
31 : // to code targets without dereferencing their handles.
32 31 : CanonicalHandleScope canonical(interpreter->isolate_);
33 31 : Address* dispatch_table = interpreter->dispatch_table_;
34 :
35 : // Generate bytecode handlers for all bytecodes and scales.
36 : const OperandScale kOperandScales[] = {
37 : #define VALUE(Name, _) OperandScale::k##Name,
38 : OPERAND_SCALE_LIST(VALUE)
39 : #undef VALUE
40 31 : };
41 :
42 124 : for (OperandScale operand_scale : kOperandScales) {
43 : #define GENERATE_CODE(Name, ...) \
44 : InstallBytecodeHandler(interpreter->isolate_, dispatch_table, \
45 : Bytecode::k##Name, operand_scale);
46 93 : BYTECODE_LIST(GENERATE_CODE)
47 : #undef GENERATE_CODE
48 : }
49 :
50 : // Fill unused entries will the illegal bytecode handler.
51 : size_t illegal_index = Interpreter::GetDispatchTableIndex(
52 31 : Bytecode::kIllegal, OperandScale::kSingle);
53 23839 : for (size_t index = 0; index < Interpreter::kDispatchTableSize; ++index) {
54 23808 : if (dispatch_table[index] == nullptr) {
55 9734 : dispatch_table[index] = dispatch_table[illegal_index];
56 : }
57 : }
58 :
59 : // Initialization should have been successful.
60 : DCHECK(interpreter->IsDispatchTableInitialized());
61 31 : }
62 :
63 : // static
64 14074 : bool SetupInterpreter::ReuseExistingHandler(Address* dispatch_table,
65 : Bytecode bytecode,
66 : OperandScale operand_scale) {
67 14074 : size_t index = Interpreter::GetDispatchTableIndex(bytecode, operand_scale);
68 14074 : switch (bytecode) {
69 : case Bytecode::kLdaImmutableContextSlot:
70 : STATIC_ASSERT(static_cast<int>(Bytecode::kLdaContextSlot) <
71 : static_cast<int>(Bytecode::kLdaImmutableContextSlot));
72 93 : dispatch_table[index] = dispatch_table[Interpreter::GetDispatchTableIndex(
73 93 : Bytecode::kLdaContextSlot, operand_scale)];
74 93 : return true;
75 : case Bytecode::kLdaImmutableCurrentContextSlot:
76 : STATIC_ASSERT(
77 : static_cast<int>(Bytecode::kLdaCurrentContextSlot) <
78 : static_cast<int>(Bytecode::kLdaImmutableCurrentContextSlot));
79 93 : dispatch_table[index] = dispatch_table[Interpreter::GetDispatchTableIndex(
80 93 : Bytecode::kLdaCurrentContextSlot, operand_scale)];
81 93 : return true;
82 : default:
83 : return false;
84 : }
85 : return false;
86 : }
87 :
88 : // static
89 15996 : void SetupInterpreter::InstallBytecodeHandler(Isolate* isolate,
90 : Address* dispatch_table,
91 : Bytecode bytecode,
92 : OperandScale operand_scale) {
93 18104 : if (!Bytecodes::BytecodeHasHandler(bytecode, operand_scale)) return;
94 14074 : if (ReuseExistingHandler(dispatch_table, bytecode, operand_scale)) return;
95 :
96 13888 : size_t index = Interpreter::GetDispatchTableIndex(bytecode, operand_scale);
97 13888 : Handle<Code> code = GenerateBytecodeHandler(isolate, bytecode, operand_scale);
98 27776 : dispatch_table[index] = code->entry();
99 :
100 : if (FLAG_print_builtin_size) PrintBuiltinSize(bytecode, operand_scale, code);
101 : }
102 :
103 : } // namespace interpreter
104 : } // namespace internal
105 : } // namespace v8
|