| // Copyright 2017 the V8 project authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "src/interpreter/setup-interpreter.h" |
| |
| #include "src/handles-inl.h" |
| #include "src/interpreter/bytecodes.h" |
| #include "src/interpreter/interpreter-generator.h" |
| #include "src/interpreter/interpreter.h" |
| #include "src/objects-inl.h" |
| |
| namespace v8 { |
| namespace internal { |
| namespace interpreter { |
| |
| namespace { |
| void PrintBuiltinSize(Bytecode bytecode, OperandScale operand_scale, |
| Handle<Code> code) { |
| PrintF(stdout, "Ignition Handler, %s, %d\n", |
| Bytecodes::ToString(bytecode, operand_scale).c_str(), |
| code->instruction_size()); |
| } |
| } // namespace |
| |
| // static |
| void SetupInterpreter::InstallBytecodeHandlers(Interpreter* interpreter) { |
| DCHECK(!interpreter->IsDispatchTableInitialized()); |
| HandleScope scope(interpreter->isolate_); |
| // Canonicalize handles, so that we can share constant pool entries pointing |
| // to code targets without dereferencing their handles. |
| CanonicalHandleScope canonical(interpreter->isolate_); |
| Address* dispatch_table = interpreter->dispatch_table_; |
| |
| // Generate bytecode handlers for all bytecodes and scales. |
| const OperandScale kOperandScales[] = { |
| #define VALUE(Name, _) OperandScale::k##Name, |
| OPERAND_SCALE_LIST(VALUE) |
| #undef VALUE |
| }; |
| |
| for (OperandScale operand_scale : kOperandScales) { |
| #define GENERATE_CODE(Name, ...) \ |
| InstallBytecodeHandler(interpreter->isolate_, dispatch_table, \ |
| Bytecode::k##Name, operand_scale); |
| BYTECODE_LIST(GENERATE_CODE) |
| #undef GENERATE_CODE |
| } |
| |
| // Fill unused entries will the illegal bytecode handler. |
| size_t illegal_index = Interpreter::GetDispatchTableIndex( |
| Bytecode::kIllegal, OperandScale::kSingle); |
| for (size_t index = 0; index < Interpreter::kDispatchTableSize; ++index) { |
| if (dispatch_table[index] == nullptr) { |
| dispatch_table[index] = dispatch_table[illegal_index]; |
| } |
| } |
| |
| // Generate the DeserializeLazy handlers, one for each operand scale. |
| Heap* heap = interpreter->isolate_->heap(); |
| DCHECK_EQ(Smi::kZero, heap->deserialize_lazy_handler()); |
| heap->SetDeserializeLazyHandler(*GenerateDeserializeLazyHandler( |
| interpreter->isolate_, OperandScale::kSingle)); |
| DCHECK_EQ(Smi::kZero, heap->deserialize_lazy_handler_wide()); |
| heap->SetDeserializeLazyHandlerWide(*GenerateDeserializeLazyHandler( |
| interpreter->isolate_, OperandScale::kDouble)); |
| DCHECK_EQ(Smi::kZero, heap->deserialize_lazy_handler_extra_wide()); |
| heap->SetDeserializeLazyHandlerExtraWide(*GenerateDeserializeLazyHandler( |
| interpreter->isolate_, OperandScale::kQuadruple)); |
| |
| // Initialization should have been successful. |
| DCHECK(interpreter->IsDispatchTableInitialized()); |
| } |
| |
| // static |
| void SetupInterpreter::InstallBytecodeHandler(Isolate* isolate, |
| Address* dispatch_table, |
| Bytecode bytecode, |
| OperandScale operand_scale) { |
| if (!Bytecodes::BytecodeHasHandler(bytecode, operand_scale)) return; |
| |
| size_t index = Interpreter::GetDispatchTableIndex(bytecode, operand_scale); |
| Handle<Code> code = GenerateBytecodeHandler(isolate, bytecode, operand_scale); |
| dispatch_table[index] = code->entry(); |
| |
| if (FLAG_print_builtin_size) PrintBuiltinSize(bytecode, operand_scale, code); |
| } |
| |
| } // namespace interpreter |
| } // namespace internal |
| } // namespace v8 |