Commit b4b5e785 authored by Dan Elphick's avatar Dan Elphick Committed by Commit Bot

[embed handlers] Initialize dispatch table

When v8_enable_embedded_bytecode_handlers is true, initialize the
bytecode dispatch table from the builtins table. Also stops creating
the handlers more than once as the SetupInterpreter will now always do
nothing even when not starting from a snapshot.

In the short term, with the flag enabled all the bytecode handlers are
eagerly deserialized.

Finally, the bytecode handlers are marked as non-isolate independent to
prevent them being embedded in the binary until they can be converted.

Bug: v8:8068
Change-Id: I9e5ef7f1dce1b2d11c7aa26526f06b53f8939697
Reviewed-on: https://chromium-review.googlesource.com/1188477Reviewed-by: 's avatarUlan Degenbaev <ulan@chromium.org>
Reviewed-by: 's avatarRoss McIlroy <rmcilroy@chromium.org>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Commit-Queue: Dan Elphick <delphick@chromium.org>
Cr-Commit-Position: refs/heads/master@{#55581}
parent 1075e6a0
......@@ -147,6 +147,17 @@ Handle<Code> Builtins::builtin_handle(int index) {
reinterpret_cast<Code**>(isolate_->heap()->builtin_address(index)));
}
#ifdef V8_EMBEDDED_BYTECODE_HANDLERS
Code* Builtins::GetBytecodeHandler(interpreter::Bytecode bytecode,
interpreter::OperandScale operand_scale) {
return builtin(
kFirstBytecodeHandler +
static_cast<int>(bytecode) *
interpreter::BytecodeOperands::kOperandScaleCount +
interpreter::BytecodeOperands::OperandScaleAsIndex(operand_scale));
}
#endif
// static
int Builtins::GetStackParameterCount(Name name) {
DCHECK(Builtins::KindOf(name) == TFJ);
......
......@@ -25,6 +25,11 @@ namespace compiler {
class CodeAssemblerState;
}
template <typename T>
static constexpr T FirstFromVarArgs(T x, ...) noexcept {
return x;
}
// Convenience macro to avoid generating named accessors for all builtins.
#define BUILTIN_CODE(isolate, name) \
(isolate)->builtins()->builtin_handle(Builtins::k##name)
......@@ -46,7 +51,15 @@ class Builtins {
DEF_ENUM_BYTECODE_HANDLER, DEF_ENUM)
#undef DEF_ENUM
#undef DEF_ENUM_BYTECODE_HANDLER
builtin_count
builtin_count,
#ifdef V8_EMBEDDED_BYTECODE_HANDLERS
#define EXTRACT_NAME(Name, ...) k##Name##Handler,
// Define kFirstBytecodeHandler,
kFirstBytecodeHandler =
FirstFromVarArgs(BUILTIN_LIST_BYTECODE_HANDLERS(EXTRACT_NAME) 0)
#undef EXTRACT_NAME
#endif // V8_EMBEDDED_BYTECODE_HANDLERS
};
static const int32_t kNoBuiltinId = -1;
......@@ -79,6 +92,11 @@ class Builtins {
Code* builtin(int index);
V8_EXPORT_PRIVATE Handle<Code> builtin_handle(int index);
#ifdef V8_EMBEDDED_BYTECODE_HANDLERS
Code* GetBytecodeHandler(interpreter::Bytecode bytecode,
interpreter::OperandScale operand_scale);
#endif // V8_EMBEDDED_BYTECODE_HANDLERS
V8_EXPORT_PRIVATE static Callable CallableFor(Isolate* isolate, Name name);
static int GetStackParameterCount(Name name);
......
......@@ -12,6 +12,7 @@
#include "src/interface-descriptors.h"
#include "src/interpreter/bytecodes.h"
#include "src/interpreter/interpreter-generator.h"
#include "src/interpreter/interpreter.h"
#include "src/isolate.h"
#include "src/objects-inl.h"
#include "src/objects/shared-function-info.h"
......@@ -310,6 +311,7 @@ void SetupIsolateDelegate::SetupBuiltinsInternal(Isolate* isolate) {
CallDescriptors::InterfaceDescriptor, #Name, 1); \
AddBuiltin(builtins, index++, code);
#ifdef V8_EMBEDDED_BYTECODE_HANDLERS
#define BUILD_BCH_WITH_SCALE(Code, Scale) \
code = GenerateBytecodeHandler(isolate, index, Builtins::name(index), \
interpreter::Bytecode::k##Code, \
......@@ -323,6 +325,9 @@ void SetupIsolateDelegate::SetupBuiltinsInternal(Isolate* isolate) {
BUILD_BCH_WITH_SCALE(Code, Single) \
BUILD_BCH_WITH_SCALE(Code, Double) \
BUILD_BCH_WITH_SCALE(Code, Quadruple)
#else
#define BUILD_BCH(Code, ...) UNREACHABLE();
#endif // V8_EMBEDDED_BYTECODE_HANDLERS
#define BUILD_ASM(Name) \
code = BuildWithMacroAssembler(isolate, index, Builtins::Generate_##Name, \
......
......@@ -4181,8 +4181,10 @@ void Heap::IterateStrongRoots(RootVisitor* v, VisitMode mode) {
if (!isMinorGC) {
IterateBuiltins(v);
v->Synchronize(VisitorSynchronization::kBuiltins);
#ifndef V8_EMBEDDED_BYTECODE_HANDLERS
isolate_->interpreter()->IterateDispatchTable(v);
v->Synchronize(VisitorSynchronization::kDispatchTable);
#endif // V8_EMBEDDED_BYTECODE_HANDLERS
}
// Iterate over global handles.
......
......@@ -145,6 +145,19 @@ class BytecodeOperands : public AllStatic {
0 OPERAND_SCALE_LIST(OPERAND_SCALE_COUNT);
#undef OPERAND_SCALE_COUNT
static int OperandScaleAsIndex(OperandScale operand_scale) {
switch (operand_scale) {
case OperandScale::kSingle:
return 0;
case OperandScale::kDouble:
return 1;
case OperandScale::kQuadruple:
return 2;
default:
UNREACHABLE();
}
}
// Returns true if |accumulator_use| reads the accumulator.
static constexpr bool ReadsAccumulator(AccumulatorUse accumulator_use) {
return accumulator_use == AccumulatorUse::kRead ||
......
......@@ -66,6 +66,9 @@ Code* Interpreter::GetAndMaybeDeserializeBytecodeHandler(
// Already deserialized? Then just return the handler.
if (!isolate_->heap()->IsDeserializeLazyHandler(code)) return code;
#ifdef V8_EMBEDDED_BYTECODE_HANDLERS
UNREACHABLE();
#else
DCHECK(FLAG_lazy_handler_deserialization);
DCHECK(Bytecodes::BytecodeHasHandler(bytecode, operand_scale));
code = Snapshot::DeserializeHandler(isolate_, bytecode, operand_scale);
......@@ -77,15 +80,22 @@ Code* Interpreter::GetAndMaybeDeserializeBytecodeHandler(
SetBytecodeHandler(bytecode, operand_scale, code);
return code;
#endif // V8_EMBEDDED_BYTECODE_HANDLERS
}
Code* Interpreter::GetBytecodeHandler(Bytecode bytecode,
OperandScale operand_scale) {
#ifdef V8_EMBEDDED_BYTECODE_HANDLERS
// The dispatch table has pointers to the offheap instruction stream, so it's
// not possible to use that to get hold of the Code object.
return isolate_->builtins()->GetBytecodeHandler(bytecode, operand_scale);
#else
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);
#endif
}
void Interpreter::SetBytecodeHandler(Bytecode bytecode,
......@@ -93,7 +103,7 @@ void Interpreter::SetBytecodeHandler(Bytecode bytecode,
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,17 +111,11 @@ 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;
}
#ifndef V8_EMBEDDED_BYTECODE_HANDLERS
void Interpreter::IterateDispatchTable(RootVisitor* v) {
for (int i = 0; i < kDispatchTableSize; i++) {
Address code_entry = dispatch_table_[i];
......@@ -125,6 +129,7 @@ void Interpreter::IterateDispatchTable(RootVisitor* v) {
}
}
}
#endif // V8_EMBEDDED_BYTECODE_HANDLERS
int Interpreter::InterruptBudget() {
return FLAG_interrupt_budget;
......@@ -229,6 +234,34 @@ 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() {
#ifdef V8_EMBEDDED_BYTECODE_HANDLERS
Builtins* builtins = isolate_->builtins();
Code* illegal = builtins->builtin(Builtins::kIllegalHandler);
ForEachBytecode([=](Bytecode bytecode, OperandScale operand_scale) {
Code* handler = Bytecodes::BytecodeHasHandler(bytecode, operand_scale)
? builtins->GetBytecodeHandler(bytecode, operand_scale)
: illegal;
SetBytecodeHandler(bytecode, operand_scale, handler);
});
#endif // V8_EMBEDDED_BYTECODE_HANDLERS
}
bool Interpreter::IsDispatchTableInitialized() const {
return dispatch_table_[0] != kNullAddress;
}
......
......@@ -61,14 +61,20 @@ class Interpreter {
void SetBytecodeHandler(Bytecode bytecode, OperandScale operand_scale,
Code* handler);
#ifndef V8_EMBEDDED_BYTECODE_HANDLERS
// GC support.
void IterateDispatchTable(RootVisitor* v);
#endif // V8_EMBEDDED_BYTECODE_HANDLERS
// Disassembler support (only useful with ENABLE_DISASSEMBLER defined).
const char* LookupNameOfBytecodeHandler(const Code* code);
V8_EXPORT_PRIVATE Local<v8::Object> GetDispatchCountersObject();
void ForEachBytecode(const std::function<void(Bytecode, OperandScale)>& f);
void InitializeDispatchTable();
bool IsDispatchTableInitialized() const;
Address dispatch_table_address() {
......
......@@ -3026,6 +3026,7 @@ bool Isolate::Init(StartupDeserializer* des) {
if (!create_heap_objects) des->DeserializeInto(this);
load_stub_cache_->Initialize();
store_stub_cache_->Initialize();
interpreter_->InitializeDispatchTable();
setup_delegate_->SetupInterpreter(interpreter_);
heap_.NotifyDeserializationComplete();
......
......@@ -19,7 +19,8 @@ void SetupIsolateDelegate::SetupBuiltins(Isolate* isolate) {
void SetupIsolateDelegate::SetupInterpreter(
interpreter::Interpreter* interpreter) {
#if defined(V8_USE_SNAPSHOT) && !defined(V8_USE_SNAPSHOT_WITH_UNWINDING_INFO)
#if !defined(V8_EMBEDDED_BYTECODE_HANDLERS) && defined(V8_USE_SNAPSHOT) && \
!defined(V8_USE_SNAPSHOT_WITH_UNWINDING_INFO)
if (FLAG_perf_prof_unwinding_info) {
StdoutStream{}
<< "Warning: The --perf-prof-unwinding-info flag can be passed at "
......
......@@ -23,11 +23,12 @@ void SetupIsolateDelegate::SetupBuiltins(Isolate* isolate) {
void SetupIsolateDelegate::SetupInterpreter(
interpreter::Interpreter* interpreter) {
#ifndef V8_EMBEDDED_BYTECODE_HANDLERS
if (create_heap_objects_) {
interpreter::SetupInterpreter::InstallBytecodeHandlers(interpreter);
} else {
CHECK(interpreter->IsDispatchTableInitialized());
}
#endif // V8_EMBEDDED_BYTECODE_HANDLERS
CHECK(interpreter->IsDispatchTableInitialized());
}
bool SetupIsolateDelegate::SetupHeap(Heap* heap) {
......
......@@ -23,11 +23,13 @@ BuiltinDeserializerAllocator::~BuiltinDeserializerAllocator() {
delete handler_allocations_;
}
#ifndef V8_EMBEDDED_BYTECODE_HANDLERS
namespace {
int HandlerAllocationIndex(int code_object_id) {
return code_object_id - BuiltinSnapshotUtils::kFirstHandlerIndex;
}
} // namespace
#endif // V8_EMBEDDED_BYTECODE_HANDLERS
Address BuiltinDeserializerAllocator::Allocate(AllocationSpace space,
int size) {
......@@ -43,6 +45,9 @@ Address BuiltinDeserializerAllocator::Allocate(AllocationSpace space,
Object* obj = isolate()->builtins()->builtin(code_object_id);
DCHECK(Internals::HasHeapObjectTag(obj));
return HeapObject::cast(obj)->address();
#ifdef V8_EMBEDDED_BYTECODE_HANDLERS
}
#else
} else if (BSU::IsHandlerIndex(code_object_id)) {
if (handler_allocation_ != kNullAddress) {
// Lazy deserialization.
......@@ -57,6 +62,7 @@ Address BuiltinDeserializerAllocator::Allocate(AllocationSpace space,
return handler_allocations_->at(index);
}
}
#endif // V8_EMBEDDED_BYTECODE_HANDLERS
UNREACHABLE();
}
......@@ -91,6 +97,7 @@ BuiltinDeserializerAllocator::CreateReservationsForEagerBuiltinsAndHandlers() {
result.push_back({builtin_size, kNullAddress, kNullAddress});
}
#ifndef V8_EMBEDDED_BYTECODE_HANDLERS
// Reservations for bytecode handlers.
BSU::ForEachBytecode(
......@@ -112,6 +119,7 @@ BuiltinDeserializerAllocator::CreateReservationsForEagerBuiltinsAndHandlers() {
DCHECK_LE(handler_size, MemoryAllocator::PageAreaSize(CODE_SPACE));
result.push_back({handler_size, kNullAddress, kNullAddress});
});
#endif // V8_EMBEDDED_BYTECODE_HANDLERS
return result;
}
......@@ -130,6 +138,7 @@ void BuiltinDeserializerAllocator::InitializeBuiltinFromReservation(
#endif
}
#ifndef V8_EMBEDDED_BYTECODE_HANDLERS
void BuiltinDeserializerAllocator::InitializeHandlerFromReservation(
const Heap::Chunk& chunk, interpreter::Bytecode bytecode,
interpreter::OperandScale operand_scale) {
......@@ -149,6 +158,7 @@ void BuiltinDeserializerAllocator::InitializeHandlerFromReservation(
RegisterCodeObjectReservation(BSU::BytecodeToIndex(bytecode, operand_scale));
#endif
}
#endif // V8_EMBEDDED_BYTECODE_HANDLERS
void BuiltinDeserializerAllocator::InitializeFromReservations(
const Heap::Reservation& reservation) {
......@@ -181,6 +191,7 @@ void BuiltinDeserializerAllocator::InitializeFromReservations(
}
}
#ifndef V8_EMBEDDED_BYTECODE_HANDLERS
// Initialize interpreter bytecode handler reservations.
DCHECK_NULL(handler_allocations_);
......@@ -202,6 +213,7 @@ void BuiltinDeserializerAllocator::InitializeFromReservations(
bytecode, operand_scale);
reservation_index++;
});
#endif // V8_EMBEDDED_BYTECODE_HANDLERS
DCHECK_EQ(reservation.size(), reservation_index);
}
......@@ -236,6 +248,7 @@ void BuiltinDeserializerAllocator::ReserveAndInitializeBuiltinsTableForBuiltin(
#endif
}
#ifndef V8_EMBEDDED_BYTECODE_HANDLERS
void BuiltinDeserializerAllocator::ReserveForHandler(
Bytecode bytecode, OperandScale operand_scale) {
DCHECK(AllowHeapAllocation::IsAllowed());
......@@ -257,6 +270,7 @@ void BuiltinDeserializerAllocator::ReserveForHandler(
RegisterCodeObjectReservation(code_object_id);
#endif
}
#endif // V8_EMBEDDED_BYTECODE_HANDLERS
#ifdef DEBUG
void BuiltinDeserializerAllocator::RegisterCodeObjectReservation(
......
......@@ -87,10 +87,10 @@ void BuiltinDeserializer::DeserializeEagerBuiltinsAndHandlers() {
}
#endif
#ifndef V8_EMBEDDED_BYTECODE_HANDLERS
// Deserialize bytecode handlers.
Interpreter* interpreter = isolate()->interpreter();
DCHECK(!isolate()->interpreter()->IsDispatchTableInitialized());
DCHECK(!interpreter->IsDispatchTableInitialized());
BSU::ForEachBytecode([=](Bytecode bytecode, OperandScale operand_scale) {
// Bytecodes without a dedicated handler are patched up in a second pass.
......@@ -118,6 +118,7 @@ void BuiltinDeserializer::DeserializeEagerBuiltinsAndHandlers() {
});
DCHECK(isolate()->interpreter()->IsDispatchTableInitialized());
#endif // V8_EMBEDDED_BYTECODE_HANDLERS
}
Code* BuiltinDeserializer::DeserializeBuiltin(int builtin_id) {
......@@ -135,12 +136,14 @@ Code* BuiltinDeserializer::DeserializeBuiltin(int builtin_id) {
return code;
}
#ifndef V8_EMBEDDED_BYTECODE_HANDLERS
Code* BuiltinDeserializer::DeserializeHandler(Bytecode bytecode,
OperandScale operand_scale) {
allocator()->ReserveForHandler(bytecode, operand_scale);
DisallowHeapAllocation no_gc;
return DeserializeHandlerRaw(bytecode, operand_scale);
}
#endif // V8_EMBEDDED_BYTECODE_HANDLERS
Code* BuiltinDeserializer::DeserializeBuiltinRaw(int builtin_id) {
DCHECK(!AllowHeapAllocation::IsAllowed());
......@@ -172,6 +175,7 @@ Code* BuiltinDeserializer::DeserializeBuiltinRaw(int builtin_id) {
return code;
}
#ifndef V8_EMBEDDED_BYTECODE_HANDLERS
Code* BuiltinDeserializer::DeserializeHandlerRaw(Bytecode bytecode,
OperandScale operand_scale) {
DCHECK(!AllowHeapAllocation::IsAllowed());
......@@ -205,6 +209,7 @@ Code* BuiltinDeserializer::DeserializeHandlerRaw(Bytecode bytecode,
return code;
}
#endif // V8_EMBEDDED_BYTECODE_HANDLERS
uint32_t BuiltinDeserializer::ExtractCodeObjectSize(int code_object_id) {
DCHECK_LT(code_object_id, BSU::kNumberOfCodeObjects);
......
......@@ -38,18 +38,22 @@ class BuiltinDeserializer final
// lazily deserialized at runtime.
Code* DeserializeBuiltin(int builtin_id);
#ifndef V8_EMBEDDED_BYTECODE_HANDLERS
// Deserializes the single given handler. This is used whenever a handler is
// lazily deserialized at runtime.
Code* DeserializeHandler(Bytecode bytecode, OperandScale operand_scale);
#endif // V8_EMBEDDED_BYTECODE_HANDLERS
private:
// Deserializes the single given builtin. Assumes that reservations have
// already been allocated.
Code* DeserializeBuiltinRaw(int builtin_id);
#ifndef V8_EMBEDDED_BYTECODE_HANDLERS
// Deserializes the single given bytecode handler. Assumes that reservations
// have already been allocated.
Code* DeserializeHandlerRaw(Bytecode bytecode, OperandScale operand_scale);
#endif // V8_EMBEDDED_BYTECODE_HANDLERS
// Extracts the size builtin Code objects (baked into the snapshot).
uint32_t ExtractCodeObjectSize(int builtin_id);
......
......@@ -33,6 +33,9 @@ void BuiltinSerializer::SerializeBuiltinsAndHandlers() {
SerializeBuiltin(isolate()->builtins()->builtin(i));
}
#ifdef V8_EMBEDDED_BYTECODE_HANDLERS
STATIC_ASSERT(BSU::kNumberOfBuiltins == BSU::kNumberOfCodeObjects);
#else
// Serialize bytecode handlers.
STATIC_ASSERT(BSU::kNumberOfBuiltins == BSU::kFirstHandlerIndex);
......@@ -54,6 +57,7 @@ void BuiltinSerializer::SerializeBuiltinsAndHandlers() {
DCHECK(isolate()->heap()->deserialize_lazy_handler()->IsCode());
DCHECK(isolate()->heap()->deserialize_lazy_handler_wide()->IsCode());
DCHECK(isolate()->heap()->deserialize_lazy_handler_extra_wide()->IsCode());
#endif // V8_EMBEDDED_BYTECODE_HANDLERS
// Pad with kNop since GetInt() might read too far.
Pad();
......@@ -132,6 +136,7 @@ void BuiltinSerializer::SetBuiltinOffset(int builtin_id, uint32_t offset) {
code_offsets_[builtin_id] = offset;
}
#ifndef V8_EMBEDDED_BYTECODE_HANDLERS
void BuiltinSerializer::SetHandlerOffset(Bytecode bytecode,
OperandScale operand_scale,
uint32_t offset) {
......@@ -139,6 +144,7 @@ void BuiltinSerializer::SetHandlerOffset(Bytecode bytecode,
DCHECK(BSU::IsHandlerIndex(index));
code_offsets_[index] = offset;
}
#endif // V8_EMBEDDED_BYTECODE_HANDLERS
} // namespace internal
} // namespace v8
......@@ -13,6 +13,7 @@ bool BuiltinSnapshotUtils::IsBuiltinIndex(int maybe_index) {
maybe_index < kFirstBuiltinIndex + kNumberOfBuiltins);
}
#ifndef V8_EMBEDDED_BYTECODE_HANDLERS
// static
bool BuiltinSnapshotUtils::IsHandlerIndex(int maybe_index) {
return (kFirstHandlerIndex <= maybe_index &&
......@@ -62,6 +63,7 @@ void BuiltinSnapshotUtils::ForEachBytecode(
}
}
}
#endif // V8_EMBEDDED_BYTECODE_HANDLERS
} // namespace internal
} // namespace v8
......@@ -25,6 +25,9 @@ class BuiltinSnapshotUtils : public AllStatic {
static const int kFirstBuiltinIndex = 0;
static const int kNumberOfBuiltins = Builtins::builtin_count;
#ifdef V8_EMBEDDED_BYTECODE_HANDLERS
static const int kNumberOfCodeObjects = kNumberOfBuiltins;
#else
static const int kFirstHandlerIndex = kFirstBuiltinIndex + kNumberOfBuiltins;
static const int kNumberOfHandlers =
Bytecodes::kBytecodeCount * BytecodeOperands::kOperandScaleCount;
......@@ -34,10 +37,12 @@ class BuiltinSnapshotUtils : public AllStatic {
// {bytecode, operand_scale} combination has an associated handler
// (see Bytecodes::BytecodeHasHandler).
static const int kNumberOfCodeObjects = kNumberOfBuiltins + kNumberOfHandlers;
#endif // V8_EMBEDDED_BYTECODE_HANDLERS
// Indexes into the offsets vector contained in snapshot.
// See e.g. BuiltinSerializer::code_offsets_.
static bool IsBuiltinIndex(int maybe_index);
#ifndef V8_EMBEDDED_BYTECODE_HANDLERS
static bool IsHandlerIndex(int maybe_index);
static int BytecodeToIndex(Bytecode bytecode, OperandScale operand_scale);
......@@ -48,6 +53,7 @@ class BuiltinSnapshotUtils : public AllStatic {
// Iteration over all {bytecode,operand_scale} pairs. Implemented here since
// (de)serialization depends on the iteration order.
static void ForEachBytecode(std::function<void(Bytecode, OperandScale)> f);
#endif // V8_EMBEDDED_BYTECODE_HANDLERS
};
} // namespace internal
......
......@@ -168,6 +168,7 @@ Code* Snapshot::EnsureBuiltinIsDeserialized(Isolate* isolate,
return code;
}
#ifndef V8_EMBEDDED_BYTECODE_HANDLERS
// static
Code* Snapshot::DeserializeHandler(Isolate* isolate,
interpreter::Bytecode bytecode,
......@@ -203,6 +204,7 @@ Code* Snapshot::DeserializeHandler(Isolate* isolate,
return code;
}
#endif // V8_EMBEDDED_BYTECODE_HANDLERS
void ProfileDeserialization(
const SnapshotData* startup_snapshot, const SnapshotData* builtin_snapshot,
......
......@@ -175,11 +175,13 @@ class Snapshot : public AllStatic {
static Code* EnsureBuiltinIsDeserialized(Isolate* isolate,
Handle<SharedFunctionInfo> shared);
#ifndef V8_EMBEDDED_BYTECODE_HANDLERS
// Deserializes a single given handler code object. Intended to be called at
// runtime after the isolate has been fully initialized.
static Code* DeserializeHandler(Isolate* isolate,
interpreter::Bytecode bytecode,
interpreter::OperandScale operand_scale);
#endif // V8_EMBEDDED_BYTECODE_HANDLERS
// ---------------- Helper methods ----------------
......
......@@ -164,6 +164,7 @@ v8_source_set("cctest_sources") {
"test-bignum-dtoa.cc",
"test-bignum.cc",
"test-bit-vector.cc",
"test-builtins.cc",
"test-circular-queue.cc",
"test-code-layout.cc",
"test-code-stub-assembler.cc",
......
......@@ -17,9 +17,11 @@ void SetupIsolateDelegateForTests::SetupBuiltins(Isolate* isolate) {
void SetupIsolateDelegateForTests::SetupInterpreter(
interpreter::Interpreter* interpreter) {
#ifndef V8_EMBEDDED_BYTECODE_HANDLERS
if (create_heap_objects_) {
interpreter::SetupInterpreter::InstallBytecodeHandlers(interpreter);
}
#endif
}
bool SetupIsolateDelegateForTests::SetupHeap(Heap* heap) {
......
// Copyright 2016 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/builtins/builtins.h"
#include "src/interpreter/bytecode-operands.h"
#include "test/cctest/cctest.h"
namespace {
TEST(GetBytecodeHandler) {
#ifdef V8_EMBEDDED_BYTECODE_HANDLERS
using Bytecode = i::interpreter::Bytecode;
using OperandScale = i::interpreter::OperandScale;
using Builtins = i::Builtins;
Builtins* builtins = CcTest::i_isolate()->builtins();
CHECK_EQ(builtins->GetBytecodeHandler(Bytecode::kWide, OperandScale::kSingle),
builtins->builtin(Builtins::kWideHandler));
CHECK_EQ(builtins->GetBytecodeHandler(Bytecode::kLdaImmutableContextSlot,
OperandScale::kSingle),
builtins->builtin(Builtins::kLdaImmutableContextSlotHandler));
CHECK_EQ(builtins->GetBytecodeHandler(Bytecode::kLdaImmutableContextSlot,
OperandScale::kDouble),
builtins->builtin(Builtins::kLdaImmutableContextSlotWideHandler));
CHECK_EQ(
builtins->GetBytecodeHandler(Bytecode::kLdaImmutableContextSlot,
OperandScale::kQuadruple),
builtins->builtin(Builtins::kLdaImmutableContextSlotExtraWideHandler));
#endif // V8_EMBEDDED_BYTECODE_HANDLERS
}
} // namespace
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment