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, ...) \ |