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