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 {
PrintBuiltinSize(Bytecode bytecode,OperandScale operand_scale,Handle<Code> code)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->InstructionSize());
23 }
24 } // namespace
25
26 // static
InstallBytecodeHandlers(Interpreter * interpreter)27 void SetupInterpreter::InstallBytecodeHandlers(Interpreter* interpreter) {
28 DCHECK(!interpreter->IsDispatchTableInitialized());
29 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 CanonicalHandleScope canonical(interpreter->isolate_);
33 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 };
41
42 for (OperandScale operand_scale : kOperandScales) {
43 #define GENERATE_CODE(Name, ...) \
44 InstallBytecodeHandler(interpreter->isolate_, dispatch_table, \
45 Bytecode::k##Name, operand_scale);
46 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 Bytecode::kIllegal, OperandScale::kSingle);
53 for (size_t index = 0; index < Interpreter::kDispatchTableSize; ++index) {
54 if (dispatch_table[index] == kNullAddress) {
55 dispatch_table[index] = dispatch_table[illegal_index];
56 }
57 }
58
59 // Generate the DeserializeLazy handlers, one for each operand scale.
60 Heap* heap = interpreter->isolate_->heap();
61 DCHECK_EQ(Smi::kZero, heap->deserialize_lazy_handler());
62 heap->SetDeserializeLazyHandler(*GenerateDeserializeLazyHandler(
63 interpreter->isolate_, OperandScale::kSingle));
64 DCHECK_EQ(Smi::kZero, heap->deserialize_lazy_handler_wide());
65 heap->SetDeserializeLazyHandlerWide(*GenerateDeserializeLazyHandler(
66 interpreter->isolate_, OperandScale::kDouble));
67 DCHECK_EQ(Smi::kZero, heap->deserialize_lazy_handler_extra_wide());
68 heap->SetDeserializeLazyHandlerExtraWide(*GenerateDeserializeLazyHandler(
69 interpreter->isolate_, OperandScale::kQuadruple));
70
71 // Initialization should have been successful.
72 DCHECK(interpreter->IsDispatchTableInitialized());
73 }
74
75 // static
InstallBytecodeHandler(Isolate * isolate,Address * dispatch_table,Bytecode bytecode,OperandScale operand_scale)76 void SetupInterpreter::InstallBytecodeHandler(Isolate* isolate,
77 Address* dispatch_table,
78 Bytecode bytecode,
79 OperandScale operand_scale) {
80 if (!Bytecodes::BytecodeHasHandler(bytecode, operand_scale)) return;
81
82 size_t index = Interpreter::GetDispatchTableIndex(bytecode, operand_scale);
83 // Here we explicitly set the bytecode handler to not be a builtin with an
84 // index of kNoBuiltinId.
85 // TODO(delphick): Use builtins version instead.
86 Handle<Code> code = GenerateBytecodeHandler(isolate, bytecode, operand_scale,
87 Builtins::kNoBuiltinId);
88 dispatch_table[index] = code->entry();
89
90 if (FLAG_print_builtin_size) PrintBuiltinSize(bytecode, operand_scale, code);
91
92 #ifdef ENABLE_DISASSEMBLER
93 if (FLAG_print_builtin_code) {
94 std::string name = Bytecodes::ToString(bytecode, operand_scale);
95 code->PrintBuiltinCode(isolate, name.c_str());
96 }
97 #endif // ENABLE_DISASSEMBLER
98 }
99
100 } // namespace interpreter
101 } // namespace internal
102 } // namespace v8
103