| Index: src/interpreter/interpreter.cc
|
| diff --git a/src/interpreter/interpreter.cc b/src/interpreter/interpreter.cc
|
| index 42b2b18ad10db4fe5fe286a027837855a76b4464..c63e1e41372657125dfd15243bc87e3d0cee384b 100644
|
| --- a/src/interpreter/interpreter.cc
|
| +++ b/src/interpreter/interpreter.cc
|
| @@ -13,9 +13,9 @@
|
| #include "src/counters.h"
|
| #include "src/interpreter/bytecode-generator.h"
|
| #include "src/interpreter/bytecodes.h"
|
| +#include "src/interpreter/interpreter-generator.h"
|
| #include "src/log.h"
|
| #include "src/objects.h"
|
| -#include "src/setup-isolate.h"
|
|
|
| namespace v8 {
|
| namespace internal {
|
| @@ -73,6 +73,11 @@ class InterpreterCompilationJob final : public CompilationJob {
|
|
|
| Interpreter::Interpreter(Isolate* isolate) : isolate_(isolate) {
|
| memset(dispatch_table_, 0, sizeof(dispatch_table_));
|
| +}
|
| +
|
| +void Interpreter::Initialize() {
|
| + if (!ShouldInitializeDispatchTable()) return;
|
| + HandleScope scope(isolate_);
|
|
|
| if (FLAG_trace_ignition_dispatches) {
|
| static const int kBytecodeCount = static_cast<int>(Bytecode::kLast) + 1;
|
| @@ -81,6 +86,71 @@ Interpreter::Interpreter(Isolate* isolate) : isolate_(isolate) {
|
| memset(bytecode_dispatch_counters_table_.get(), 0,
|
| sizeof(uintptr_t) * kBytecodeCount * kBytecodeCount);
|
| }
|
| +
|
| + // 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(isolate_, Bytecode::k##Name, operand_scale);
|
| + BYTECODE_LIST(GENERATE_CODE)
|
| +#undef GENERATE_CODE
|
| + }
|
| +
|
| + // Fill unused entries will the illegal bytecode handler.
|
| + size_t illegal_index =
|
| + GetDispatchTableIndex(Bytecode::kIllegal, OperandScale::kSingle);
|
| + for (size_t index = 0; index < arraysize(dispatch_table_); ++index) {
|
| + if (dispatch_table_[index] == nullptr) {
|
| + dispatch_table_[index] = dispatch_table_[illegal_index];
|
| + }
|
| + }
|
| +
|
| + // Initialization should have been successful.
|
| + DCHECK(IsDispatchTableInitialized());
|
| +}
|
| +
|
| +bool Interpreter::ReuseExistingHandler(Bytecode bytecode,
|
| + OperandScale operand_scale) {
|
| + size_t index = GetDispatchTableIndex(bytecode, operand_scale);
|
| + switch (bytecode) {
|
| + case Bytecode::kCallProperty:
|
| + case Bytecode::kCallProperty0:
|
| + case Bytecode::kCallProperty1:
|
| + case Bytecode::kCallProperty2: {
|
| + const int offset = static_cast<int>(Bytecode::kCallProperty) -
|
| + static_cast<int>(Bytecode::kCall);
|
| + STATIC_ASSERT(offset ==
|
| + static_cast<int>(Bytecode::kCallProperty0) -
|
| + static_cast<int>(Bytecode::kCall0));
|
| + STATIC_ASSERT(offset ==
|
| + static_cast<int>(Bytecode::kCallProperty1) -
|
| + static_cast<int>(Bytecode::kCall1));
|
| + STATIC_ASSERT(offset ==
|
| + static_cast<int>(Bytecode::kCallProperty2) -
|
| + static_cast<int>(Bytecode::kCall2));
|
| + CHECK_LT(offset, index);
|
| + dispatch_table_[index] = dispatch_table_[index - offset];
|
| + return true;
|
| + break;
|
| + }
|
| + default:
|
| + return false;
|
| + }
|
| +}
|
| +
|
| +void Interpreter::InstallBytecodeHandler(Isolate* isolate, Bytecode bytecode,
|
| + OperandScale operand_scale) {
|
| + if (!Bytecodes::BytecodeHasHandler(bytecode, operand_scale)) return;
|
| + if (ReuseExistingHandler(bytecode, operand_scale)) return;
|
| +
|
| + size_t index = GetDispatchTableIndex(bytecode, operand_scale);
|
| + Handle<Code> code = GenerateBytecodeHandler(isolate, bytecode, operand_scale);
|
| + dispatch_table_[index] = code->entry();
|
| }
|
|
|
| Code* Interpreter::GetBytecodeHandler(Bytecode bytecode,
|
| @@ -215,6 +285,16 @@ bool Interpreter::IsDispatchTableInitialized() {
|
| return dispatch_table_[0] != nullptr;
|
| }
|
|
|
| +bool Interpreter::ShouldInitializeDispatchTable() {
|
| + if (FLAG_trace_ignition || FLAG_trace_ignition_codegen ||
|
| + FLAG_trace_ignition_dispatches) {
|
| + // Regenerate table to add bytecode tracing operations, print the assembly
|
| + // code generated by TurboFan or instrument handlers with dispatch counters.
|
| + return true;
|
| + }
|
| + return !IsDispatchTableInitialized();
|
| +}
|
| +
|
| const char* Interpreter::LookupNameOfBytecodeHandler(Code* code) {
|
| #ifdef ENABLE_DISASSEMBLER
|
| #define RETURN_NAME(Name, ...) \
|
|
|