aboutsummaryrefslogtreecommitdiff
path: root/deps/v8/src/interpreter/interpreter.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/interpreter/interpreter.cc')
-rw-r--r--deps/v8/src/interpreter/interpreter.cc98
1 files changed, 74 insertions, 24 deletions
diff --git a/deps/v8/src/interpreter/interpreter.cc b/deps/v8/src/interpreter/interpreter.cc
index 0446ed494d..ca53fa674c 100644
--- a/deps/v8/src/interpreter/interpreter.cc
+++ b/deps/v8/src/interpreter/interpreter.cc
@@ -7,6 +7,7 @@
#include <fstream>
#include <memory>
+#include "builtins-generated/bytecodes-builtins-list.h"
#include "src/ast/prettyprinter.h"
#include "src/bootstrapper.h"
#include "src/compiler.h"
@@ -59,41 +60,47 @@ Interpreter::Interpreter(Isolate* isolate) : isolate_(isolate) {
}
}
+namespace {
+
+int BuiltinIndexFromBytecode(Bytecode bytecode, OperandScale operand_scale) {
+ int index = BytecodeOperands::OperandScaleAsIndex(operand_scale) *
+ kNumberOfBytecodeHandlers +
+ static_cast<int>(bytecode);
+ int offset = kBytecodeToBuiltinsMapping[index];
+ return offset >= 0 ? Builtins::kFirstBytecodeHandler + offset
+ : Builtins::kIllegalHandler;
+}
+
+} // namespace
+
Code* Interpreter::GetAndMaybeDeserializeBytecodeHandler(
Bytecode bytecode, OperandScale operand_scale) {
- Code* code = GetBytecodeHandler(bytecode, operand_scale);
+ int builtin_index = BuiltinIndexFromBytecode(bytecode, operand_scale);
+ Builtins* builtins = isolate_->builtins();
+ Code* code = builtins->builtin(builtin_index);
// Already deserialized? Then just return the handler.
- if (!isolate_->heap()->IsDeserializeLazyHandler(code)) return code;
+ if (!Builtins::IsLazyDeserializer(code)) return code;
- DCHECK(FLAG_lazy_handler_deserialization);
+ DCHECK(FLAG_lazy_deserialization);
DCHECK(Bytecodes::BytecodeHasHandler(bytecode, operand_scale));
- code = Snapshot::DeserializeHandler(isolate_, bytecode, operand_scale);
+ code = Snapshot::DeserializeBuiltin(isolate_, builtin_index);
DCHECK(code->IsCode());
DCHECK_EQ(code->kind(), Code::BYTECODE_HANDLER);
- DCHECK(!isolate_->heap()->IsDeserializeLazyHandler(code));
+ DCHECK(!Builtins::IsLazyDeserializer(code));
SetBytecodeHandler(bytecode, operand_scale, code);
return code;
}
-Code* Interpreter::GetBytecodeHandler(Bytecode bytecode,
- OperandScale operand_scale) {
- DCHECK(IsDispatchTableInitialized());
- DCHECK(Bytecodes::BytecodeHasHandler(bytecode, operand_scale));
- size_t index = GetDispatchTableIndex(bytecode, operand_scale);
- Address code_entry = dispatch_table_[index];
- return Code::GetCodeFromTargetAddress(code_entry);
-}
-
void Interpreter::SetBytecodeHandler(Bytecode bytecode,
OperandScale operand_scale,
Code* handler) {
DCHECK(handler->kind() == Code::BYTECODE_HANDLER);
size_t index = GetDispatchTableIndex(bytecode, operand_scale);
- dispatch_table_[index] = handler->entry();
+ dispatch_table_[index] = handler->InstructionStart();
}
// static
@@ -101,20 +108,17 @@ size_t Interpreter::GetDispatchTableIndex(Bytecode bytecode,
OperandScale operand_scale) {
static const size_t kEntriesPerOperandScale = 1u << kBitsPerByte;
size_t index = static_cast<size_t>(bytecode);
- switch (operand_scale) {
- case OperandScale::kSingle:
- return index;
- case OperandScale::kDouble:
- return index + kEntriesPerOperandScale;
- case OperandScale::kQuadruple:
- return index + 2 * kEntriesPerOperandScale;
- }
- UNREACHABLE();
+ return index + BytecodeOperands::OperandScaleAsIndex(operand_scale) *
+ kEntriesPerOperandScale;
}
void Interpreter::IterateDispatchTable(RootVisitor* v) {
for (int i = 0; i < kDispatchTableSize; i++) {
Address code_entry = dispatch_table_[i];
+
+ // If the handler is embedded, it is immovable.
+ if (InstructionStream::PcIsOffHeap(isolate_, code_entry)) continue;
+
Object* code = code_entry == kNullAddress
? nullptr
: Code::GetCodeFromTargetAddress(code_entry);
@@ -229,6 +233,52 @@ UnoptimizedCompilationJob* Interpreter::NewCompilationJob(
eager_inner_literals);
}
+void Interpreter::ForEachBytecode(
+ const std::function<void(Bytecode, OperandScale)>& f) {
+ constexpr OperandScale kOperandScales[] = {
+#define VALUE(Name, _) OperandScale::k##Name,
+ OPERAND_SCALE_LIST(VALUE)
+#undef VALUE
+ };
+
+ for (OperandScale operand_scale : kOperandScales) {
+ for (int i = 0; i < Bytecodes::kBytecodeCount; i++) {
+ f(Bytecodes::FromByte(i), operand_scale);
+ }
+ }
+}
+
+void Interpreter::InitializeDispatchTable() {
+ Builtins* builtins = isolate_->builtins();
+ Code* illegal = builtins->builtin(Builtins::kIllegalHandler);
+ int builtin_id = Builtins::kFirstBytecodeHandler;
+ ForEachBytecode([=, &builtin_id](Bytecode bytecode,
+ OperandScale operand_scale) {
+ Code* handler = illegal;
+ if (Bytecodes::BytecodeHasHandler(bytecode, operand_scale)) {
+#ifdef DEBUG
+ std::string builtin_name(Builtins::name(builtin_id));
+ std::string expected_name =
+ Bytecodes::ToString(bytecode, operand_scale, "") + "Handler";
+ DCHECK_EQ(expected_name, builtin_name);
+#endif
+ handler = builtins->builtin(builtin_id++);
+ }
+ SetBytecodeHandler(bytecode, operand_scale, handler);
+ });
+ DCHECK(builtin_id == Builtins::builtin_count);
+ DCHECK(IsDispatchTableInitialized());
+
+#if defined(V8_USE_SNAPSHOT) && !defined(V8_USE_SNAPSHOT_WITH_UNWINDING_INFO)
+ if (!isolate_->serializer_enabled() && FLAG_perf_prof_unwinding_info) {
+ StdoutStream{}
+ << "Warning: The --perf-prof-unwinding-info flag can be passed at "
+ "mksnapshot time to get better results."
+ << std::endl;
+ }
+#endif
+}
+
bool Interpreter::IsDispatchTableInitialized() const {
return dispatch_table_[0] != kNullAddress;
}