[ext-code-space] Store metadata offsets in the blob

... instead of Code objects. This is a step towards not creating Code
objects for embedded builtins.

Bug: v8:11880
Change-Id: Ie9f87b09d06e6b872ce3a5fa5d03a2502df979d9
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3564565
Reviewed-by: Jakob Linke <jgruber@chromium.org>
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/heads/main@{#79733}
This commit is contained in:
Igor Sheludko 2022-04-04 12:32:57 +02:00 committed by V8 LUCI CQ
parent cb916625f4
commit 388fdafcd4
5 changed files with 379 additions and 177 deletions

View File

@ -383,8 +383,9 @@ int Code::raw_body_size() const {
}
int Code::InstructionSize() const {
return V8_UNLIKELY(is_off_heap_trampoline()) ? OffHeapInstructionSize()
: raw_instruction_size();
return V8_UNLIKELY(is_off_heap_trampoline())
? OffHeapInstructionSize(*this, builtin_id())
: raw_instruction_size();
}
Address Code::raw_instruction_start() const {
@ -392,8 +393,9 @@ Address Code::raw_instruction_start() const {
}
Address Code::InstructionStart() const {
return V8_UNLIKELY(is_off_heap_trampoline()) ? OffHeapInstructionStart()
: raw_instruction_start();
return V8_UNLIKELY(is_off_heap_trampoline())
? i::OffHeapInstructionStart(*this, builtin_id())
: raw_instruction_start();
}
Address Code::raw_instruction_end() const {
@ -401,8 +403,9 @@ Address Code::raw_instruction_end() const {
}
Address Code::InstructionEnd() const {
return V8_UNLIKELY(is_off_heap_trampoline()) ? OffHeapInstructionEnd()
: raw_instruction_end();
return V8_UNLIKELY(is_off_heap_trampoline())
? i::OffHeapInstructionEnd(*this, builtin_id())
: raw_instruction_end();
}
Address Code::raw_metadata_start() const {
@ -428,24 +431,14 @@ int Code::GetOffsetFromInstructionStart(Isolate* isolate, Address pc) const {
return static_cast<int>(offset);
}
Address Code::MetadataStart() const {
STATIC_ASSERT(kOnHeapBodyIsContiguous);
return V8_UNLIKELY(is_off_heap_trampoline()) ? OffHeapMetadataStart()
: raw_metadata_start();
}
Address Code::raw_metadata_end() const {
return raw_metadata_start() + raw_metadata_size();
}
Address Code::MetadataEnd() const {
return V8_UNLIKELY(is_off_heap_trampoline()) ? OffHeapMetadataEnd()
: raw_metadata_end();
}
int Code::MetadataSize() const {
return V8_UNLIKELY(is_off_heap_trampoline()) ? OffHeapMetadataSize()
: raw_metadata_size();
return V8_UNLIKELY(is_off_heap_trampoline())
? OffHeapMetadataSize(*this, builtin_id())
: raw_metadata_size();
}
int Code::SizeIncludingMetadata() const {
@ -457,6 +450,48 @@ int Code::SizeIncludingMetadata() const {
return size;
}
Address Code::SafepointTableAddress() const {
return V8_UNLIKELY(is_off_heap_trampoline())
? OffHeapSafepointTableAddress(*this, builtin_id())
: raw_metadata_start() + safepoint_table_offset();
}
int Code::safepoint_table_size() const {
DCHECK_GE(handler_table_offset() - safepoint_table_offset(), 0);
return handler_table_offset() - safepoint_table_offset();
}
bool Code::has_safepoint_table() const { return safepoint_table_size() > 0; }
Address Code::HandlerTableAddress() const {
return V8_UNLIKELY(is_off_heap_trampoline())
? OffHeapHandlerTableAddress(*this, builtin_id())
: raw_metadata_start() + handler_table_offset();
}
int Code::handler_table_size() const {
DCHECK_GE(constant_pool_offset() - handler_table_offset(), 0);
return constant_pool_offset() - handler_table_offset();
}
bool Code::has_handler_table() const { return handler_table_size() > 0; }
int Code::constant_pool_size() const {
const int size = code_comments_offset() - constant_pool_offset();
DCHECK_IMPLIES(!FLAG_enable_embedded_constant_pool, size == 0);
DCHECK_GE(size, 0);
return size;
}
bool Code::has_constant_pool() const { return constant_pool_size() > 0; }
int Code::code_comments_size() const {
DCHECK_GE(unwinding_info_offset() - code_comments_offset(), 0);
return unwinding_info_offset() - code_comments_offset();
}
bool Code::has_code_comments() const { return code_comments_size() > 0; }
ByteArray Code::unchecked_relocation_info() const {
PtrComprCageBase cage_base = main_cage_base();
return ByteArray::unchecked_cast(
@ -777,18 +812,28 @@ void Code::set_constant_pool_offset(int value) {
Address Code::constant_pool() const {
if (!has_constant_pool()) return kNullAddress;
return MetadataStart() + constant_pool_offset();
return V8_UNLIKELY(is_off_heap_trampoline())
? OffHeapConstantPoolAddress(*this, builtin_id())
: raw_metadata_start() + constant_pool_offset();
}
Address Code::code_comments() const {
return MetadataStart() + code_comments_offset();
return V8_UNLIKELY(is_off_heap_trampoline())
? OffHeapCodeCommentsAddress(*this, builtin_id())
: raw_metadata_start() + code_comments_offset();
}
Address Code::unwinding_info_start() const {
return MetadataStart() + unwinding_info_offset();
return V8_UNLIKELY(is_off_heap_trampoline())
? OffHeapUnwindingInfoAddress(*this, builtin_id())
: raw_metadata_start() + unwinding_info_offset();
}
Address Code::unwinding_info_end() const { return MetadataEnd(); }
Address Code::unwinding_info_end() const {
return V8_UNLIKELY(is_off_heap_trampoline())
? OffHeapMetadataEnd(*this, builtin_id())
: raw_metadata_end();
}
int Code::unwinding_info_size() const {
DCHECK_GE(unwinding_info_end(), unwinding_info_start());

View File

@ -33,43 +33,117 @@
namespace v8 {
namespace internal {
Address Code::SafepointTableAddress() const {
return MetadataStart() + safepoint_table_offset();
namespace {
// Helper function for getting an EmbeddedData that can handle un-embedded
// builtins when short builtin calls are enabled.
inline EmbeddedData EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(
HeapObject code) {
#if defined(V8_COMPRESS_POINTERS_IN_ISOLATE_CAGE)
// GetIsolateFromWritableObject(*this) works for both read-only and writable
// objects when pointer compression is enabled with a per-Isolate cage.
return EmbeddedData::FromBlob(GetIsolateFromWritableObject(code));
#elif defined(V8_COMPRESS_POINTERS_IN_SHARED_CAGE)
// When pointer compression is enabled with a shared cage, there is also a
// shared CodeRange. When short builtin calls are enabled, there is a single
// copy of the re-embedded builtins in the shared CodeRange, so use that if
// it's present.
if (FLAG_jitless) return EmbeddedData::FromBlob();
CodeRange* code_range = CodeRange::GetProcessWideCodeRange().get();
return (code_range && code_range->embedded_blob_code_copy() != nullptr)
? EmbeddedData::FromBlob(code_range)
: EmbeddedData::FromBlob();
#else
// Otherwise there is a single copy of the blob across all Isolates, use the
// global atomic variables.
return EmbeddedData::FromBlob();
#endif
}
int Code::safepoint_table_size() const {
DCHECK_GE(handler_table_offset() - safepoint_table_offset(), 0);
return handler_table_offset() - safepoint_table_offset();
} // namespace
Address OffHeapInstructionStart(HeapObject code, Builtin builtin) {
// TODO(11527): Here and below: pass Isolate as an argument for getting
// the EmbeddedData.
EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(code);
return d.InstructionStartOfBuiltin(builtin);
}
bool Code::has_safepoint_table() const { return safepoint_table_size() > 0; }
Address Code::HandlerTableAddress() const {
return MetadataStart() + handler_table_offset();
Address OffHeapInstructionEnd(HeapObject code, Builtin builtin) {
EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(code);
return d.InstructionStartOfBuiltin(builtin) +
d.InstructionSizeOfBuiltin(builtin);
}
int Code::handler_table_size() const {
DCHECK_GE(constant_pool_offset() - handler_table_offset(), 0);
return constant_pool_offset() - handler_table_offset();
int OffHeapInstructionSize(HeapObject code, Builtin builtin) {
EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(code);
return d.InstructionSizeOfBuiltin(builtin);
}
bool Code::has_handler_table() const { return handler_table_size() > 0; }
int Code::constant_pool_size() const {
const int size = code_comments_offset() - constant_pool_offset();
DCHECK_IMPLIES(!FLAG_enable_embedded_constant_pool, size == 0);
DCHECK_GE(size, 0);
return size;
Address OffHeapMetadataStart(HeapObject code, Builtin builtin) {
EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(code);
return d.MetadataStartOfBuiltin(builtin);
}
bool Code::has_constant_pool() const { return constant_pool_size() > 0; }
int Code::code_comments_size() const {
DCHECK_GE(unwinding_info_offset() - code_comments_offset(), 0);
return unwinding_info_offset() - code_comments_offset();
Address OffHeapMetadataEnd(HeapObject code, Builtin builtin) {
EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(code);
return d.MetadataStartOfBuiltin(builtin) + d.MetadataSizeOfBuiltin(builtin);
}
bool Code::has_code_comments() const { return code_comments_size() > 0; }
int OffHeapMetadataSize(HeapObject code, Builtin builtin) {
EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(code);
return d.MetadataSizeOfBuiltin(builtin);
}
Address OffHeapSafepointTableAddress(HeapObject code, Builtin builtin) {
EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(code);
return d.SafepointTableStartOf(builtin);
}
int OffHeapSafepointTableSize(HeapObject code, Builtin builtin) {
EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(code);
return d.SafepointTableSizeOf(builtin);
}
Address OffHeapHandlerTableAddress(HeapObject code, Builtin builtin) {
EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(code);
return d.HandlerTableStartOf(builtin);
}
int OffHeapHandlerTableSize(HeapObject code, Builtin builtin) {
EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(code);
return d.HandlerTableSizeOf(builtin);
}
Address OffHeapConstantPoolAddress(HeapObject code, Builtin builtin) {
EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(code);
return d.ConstantPoolStartOf(builtin);
}
int OffHeapConstantPoolSize(HeapObject code, Builtin builtin) {
EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(code);
return d.ConstantPoolSizeOf(builtin);
}
Address OffHeapCodeCommentsAddress(HeapObject code, Builtin builtin) {
EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(code);
return d.CodeCommentsStartOf(builtin);
}
int OffHeapCodeCommentsSize(HeapObject code, Builtin builtin) {
EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(code);
return d.CodeCommentsSizeOf(builtin);
}
Address OffHeapUnwindingInfoAddress(HeapObject code, Builtin builtin) {
EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(code);
return d.UnwindingInfoStartOf(builtin);
}
int OffHeapUnwindingInfoSize(HeapObject code, Builtin builtin) {
EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(code);
return d.UnwindingInfoSizeOf(builtin);
}
void Code::ClearEmbeddedObjects(Heap* heap) {
HeapObject undefined = ReadOnlyRoots(heap).undefined_value();
@ -145,66 +219,6 @@ SafepointEntry Code::GetSafepointEntry(Isolate* isolate, Address pc) {
return table.FindEntry(pc);
}
int Code::OffHeapInstructionSize() const {
DCHECK(is_off_heap_trampoline());
if (Isolate::CurrentEmbeddedBlobCode() == nullptr) {
return raw_instruction_size();
}
EmbeddedData d = EmbeddedData::FromBlob();
return d.InstructionSizeOfBuiltin(builtin_id());
}
namespace {
// Helper function for getting an EmbeddedData that can handle un-embedded
// builtins when short builtin calls are enabled.
inline EmbeddedData EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(Code code) {
#if defined(V8_COMPRESS_POINTERS_IN_ISOLATE_CAGE)
// GetIsolateFromWritableObject(*this) works for both read-only and writable
// objects when pointer compression is enabled with a per-Isolate cage.
return EmbeddedData::FromBlob(GetIsolateFromWritableObject(code));
#elif defined(V8_COMPRESS_POINTERS_IN_SHARED_CAGE)
// When pointer compression is enabled with a shared cage, there is also a
// shared CodeRange. When short builtin calls are enabled, there is a single
// copy of the re-embedded builtins in the shared CodeRange, so use that if
// it's present.
if (FLAG_jitless) return EmbeddedData::FromBlob();
CodeRange* code_range = CodeRange::GetProcessWideCodeRange().get();
return (code_range && code_range->embedded_blob_code_copy() != nullptr)
? EmbeddedData::FromBlob(code_range)
: EmbeddedData::FromBlob();
#else
// Otherwise there is a single copy of the blob across all Isolates, use the
// global atomic variables.
return EmbeddedData::FromBlob();
#endif
}
} // namespace
Address Code::OffHeapInstructionStart() const {
DCHECK(is_off_heap_trampoline());
if (Isolate::CurrentEmbeddedBlobCode() == nullptr) {
return raw_instruction_size();
}
// TODO(11527): pass Isolate as an argument for getting the EmbeddedData.
EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(*this);
return d.InstructionStartOfBuiltin(builtin_id());
}
Address Code::OffHeapInstructionEnd() const {
DCHECK(is_off_heap_trampoline());
if (Isolate::CurrentEmbeddedBlobCode() == nullptr) {
return raw_instruction_size();
}
// TODO(11527): pass Isolate as an argument for getting the EmbeddedData.
EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(*this);
return d.InstructionStartOfBuiltin(builtin_id()) +
d.InstructionSizeOfBuiltin(builtin_id());
}
Address Code::OffHeapInstructionStart(Isolate* isolate, Address pc) const {
DCHECK(is_off_heap_trampoline());
EmbeddedData d = EmbeddedData::GetEmbeddedDataForPC(isolate, pc);
@ -218,34 +232,6 @@ Address Code::OffHeapInstructionEnd(Isolate* isolate, Address pc) const {
d.InstructionSizeOfBuiltin(builtin_id());
}
int Code::OffHeapMetadataSize() const {
DCHECK(is_off_heap_trampoline());
if (Isolate::CurrentEmbeddedBlobCode() == nullptr) {
return raw_instruction_size();
}
EmbeddedData d = EmbeddedData::FromBlob();
return d.MetadataSizeOfBuiltin(builtin_id());
}
Address Code::OffHeapMetadataStart() const {
DCHECK(is_off_heap_trampoline());
if (Isolate::CurrentEmbeddedBlobCode() == nullptr) {
return raw_instruction_size();
}
EmbeddedData d = EmbeddedData::FromBlob();
return d.MetadataStartOfBuiltin(builtin_id());
}
Address Code::OffHeapMetadataEnd() const {
DCHECK(is_off_heap_trampoline());
if (Isolate::CurrentEmbeddedBlobCode() == nullptr) {
return raw_instruction_size();
}
EmbeddedData d = EmbeddedData::FromBlob();
return d.MetadataStartOfBuiltin(builtin_id()) +
d.MetadataSizeOfBuiltin(builtin_id());
}
// TODO(cbruni): Move to BytecodeArray
int AbstractCode::SourcePosition(int offset) {
CHECK_NE(kind(), CodeKind::BASELINE);
@ -537,8 +523,7 @@ void Code::Disassemble(const char* name, std::ostream& os, Isolate* isolate,
DCHECK_EQ(pool_size & kPointerAlignmentMask, 0);
os << "\nConstant Pool (size = " << pool_size << ")\n";
base::Vector<char> buf = base::Vector<char>::New(50);
intptr_t* ptr =
reinterpret_cast<intptr_t*>(MetadataStart() + constant_pool_offset());
intptr_t* ptr = reinterpret_cast<intptr_t*>(constant_pool());
for (int i = 0; i < pool_size; i += kSystemPointerSize, ptr++) {
SNPrintF(buf, "%4d %08" V8PRIxPTR, i, *ptr);
os << static_cast<const void*>(ptr) << " " << buf.begin() << "\n";

View File

@ -289,11 +289,9 @@ class Code : public HeapObject {
inline Address raw_instruction_start() const;
inline Address InstructionStart() const;
V8_EXPORT_PRIVATE Address OffHeapInstructionStart() const;
inline Address raw_instruction_end() const;
inline Address InstructionEnd() const;
V8_EXPORT_PRIVATE Address OffHeapInstructionEnd() const;
// When builtins un-embedding is enabled for the Isolate
// (see Isolate::is_short_builtin_calls_enabled()) then both embedded and
@ -320,49 +318,43 @@ class Code : public HeapObject {
inline int raw_instruction_size() const;
inline void set_raw_instruction_size(int value);
inline int InstructionSize() const;
V8_EXPORT_PRIVATE int OffHeapInstructionSize() const;
inline Address raw_metadata_start() const;
inline Address MetadataStart() const;
V8_EXPORT_PRIVATE Address OffHeapMetadataStart() const;
inline Address raw_metadata_end() const;
inline Address MetadataEnd() const;
V8_EXPORT_PRIVATE Address OffHeapMetadataEnd() const;
inline int raw_metadata_size() const;
inline void set_raw_metadata_size(int value);
inline int MetadataSize() const;
int OffHeapMetadataSize() const;
// The metadata section is aligned to this value.
static constexpr int kMetadataAlignment = kIntSize;
// [safepoint_table_offset]: The offset where the safepoint table starts.
inline int safepoint_table_offset() const { return 0; }
Address SafepointTableAddress() const;
int safepoint_table_size() const;
bool has_safepoint_table() const;
inline Address SafepointTableAddress() const;
inline int safepoint_table_size() const;
inline bool has_safepoint_table() const;
// [handler_table_offset]: The offset where the exception handler table
// starts.
inline int handler_table_offset() const;
inline void set_handler_table_offset(int offset);
Address HandlerTableAddress() const;
int handler_table_size() const;
bool has_handler_table() const;
inline Address HandlerTableAddress() const;
inline int handler_table_size() const;
inline bool has_handler_table() const;
// [constant_pool offset]: Offset of the constant pool.
inline int constant_pool_offset() const;
inline void set_constant_pool_offset(int offset);
inline Address constant_pool() const;
int constant_pool_size() const;
bool has_constant_pool() const;
inline int constant_pool_size() const;
inline bool has_constant_pool() const;
// [code_comments_offset]: Offset of the code comment section.
inline int code_comments_offset() const;
inline void set_code_comments_offset(int offset);
inline Address code_comments() const;
V8_EXPORT_PRIVATE int code_comments_size() const;
V8_EXPORT_PRIVATE bool has_code_comments() const;
inline int code_comments_size() const;
inline bool has_code_comments() const;
// [unwinding_info_offset]: Offset of the unwinding info section.
inline int32_t unwinding_info_offset() const;
@ -736,6 +728,37 @@ class Code : public HeapObject {
OBJECT_CONSTRUCTORS(Code, HeapObject);
};
// TODO(v8:11880): move these functions to CodeDataContainer once they are no
// longer used from Code.
V8_EXPORT_PRIVATE Address OffHeapInstructionStart(HeapObject code,
Builtin builtin);
V8_EXPORT_PRIVATE Address OffHeapInstructionEnd(HeapObject code,
Builtin builtin);
V8_EXPORT_PRIVATE int OffHeapInstructionSize(HeapObject code, Builtin builtin);
V8_EXPORT_PRIVATE Address OffHeapMetadataStart(HeapObject code,
Builtin builtin);
V8_EXPORT_PRIVATE Address OffHeapMetadataEnd(HeapObject code, Builtin builtin);
V8_EXPORT_PRIVATE int OffHeapMetadataSize(HeapObject code, Builtin builtin);
V8_EXPORT_PRIVATE Address OffHeapSafepointTableAddress(HeapObject code,
Builtin builtin);
V8_EXPORT_PRIVATE int OffHeapSafepointTableSize(HeapObject code,
Builtin builtin);
V8_EXPORT_PRIVATE Address OffHeapHandlerTableAddress(HeapObject code,
Builtin builtin);
V8_EXPORT_PRIVATE int OffHeapHandlerTableSize(HeapObject code, Builtin builtin);
V8_EXPORT_PRIVATE Address OffHeapConstantPoolAddress(HeapObject code,
Builtin builtin);
V8_EXPORT_PRIVATE int OffHeapConstantPoolSize(HeapObject code, Builtin builtin);
V8_EXPORT_PRIVATE Address OffHeapCodeCommentsAddress(HeapObject code,
Builtin builtin);
V8_EXPORT_PRIVATE int OffHeapCodeCommentsSize(HeapObject code, Builtin builtin);
V8_EXPORT_PRIVATE Address OffHeapUnwindingInfoAddress(HeapObject code,
Builtin builtin);
V8_EXPORT_PRIVATE int OffHeapUnwindingInfoSize(HeapObject code,
Builtin builtin);
class Code::OptimizedCodeIterator {
public:
explicit OptimizedCodeIterator(Isolate* isolate);

View File

@ -10,6 +10,7 @@
#include "src/objects/objects-inl.h"
#include "src/snapshot/snapshot-utils.h"
#include "src/snapshot/snapshot.h"
#include "v8-internal.h"
namespace v8 {
namespace internal {
@ -295,12 +296,26 @@ EmbeddedData EmbeddedData::FromIsolate(Isolate* isolate) {
uint32_t metadata_size = static_cast<uint32_t>(code.raw_metadata_size());
DCHECK_EQ(0, raw_code_size % kCodeAlignment);
const int builtin_index = static_cast<int>(builtin);
layout_descriptions[builtin_index].instruction_offset = raw_code_size;
layout_descriptions[builtin_index].instruction_length = instruction_size;
layout_descriptions[builtin_index].metadata_offset = raw_data_size;
layout_descriptions[builtin_index].metadata_length = metadata_size;
{
const int builtin_index = static_cast<int>(builtin);
struct LayoutDescription& layout_desc =
layout_descriptions[builtin_index];
layout_desc.instruction_offset = raw_code_size;
layout_desc.instruction_length = instruction_size;
layout_desc.metadata_offset = raw_data_size;
layout_desc.metadata_length = metadata_size;
layout_desc.handler_table_offset =
raw_data_size + static_cast<uint32_t>(code.handler_table_offset());
#if V8_EMBEDDED_CONSTANT_POOL
layout_desc.constant_pool_offset =
raw_data_size + static_cast<uint32_t>(code.constant_pool_offset());
#endif
layout_desc.code_comments_offset_offset =
raw_data_size + static_cast<uint32_t>(code.code_comments_offset());
layout_desc.unwinding_info_offset_offset =
raw_data_size + static_cast<uint32_t>(code.unwinding_info_offset());
}
// Align the start of each section.
raw_code_size += PadAndAlignCode(instruction_size);
raw_data_size += PadAndAlignData(metadata_size);
@ -398,32 +413,123 @@ EmbeddedData EmbeddedData::FromIsolate(Isolate* isolate) {
Address EmbeddedData::InstructionStartOfBuiltin(Builtin builtin) const {
DCHECK(Builtins::IsBuiltinId(builtin));
const struct LayoutDescription* descs = LayoutDescription();
const uint8_t* result =
RawCode() + descs[static_cast<int>(builtin)].instruction_offset;
const struct LayoutDescription& desc = LayoutDescription(builtin);
const uint8_t* result = RawCode() + desc.instruction_offset;
DCHECK_LT(result, code_ + code_size_);
return reinterpret_cast<Address>(result);
}
uint32_t EmbeddedData::InstructionSizeOfBuiltin(Builtin builtin) const {
DCHECK(Builtins::IsBuiltinId(builtin));
const struct LayoutDescription* descs = LayoutDescription();
return descs[static_cast<int>(builtin)].instruction_length;
const struct LayoutDescription& desc = LayoutDescription(builtin);
return desc.instruction_length;
}
Address EmbeddedData::MetadataStartOfBuiltin(Builtin builtin) const {
DCHECK(Builtins::IsBuiltinId(builtin));
const struct LayoutDescription* descs = LayoutDescription();
const uint8_t* result =
RawMetadata() + descs[static_cast<int>(builtin)].metadata_offset;
DCHECK_LE(descs[static_cast<int>(builtin)].metadata_offset, data_size_);
const struct LayoutDescription& desc = LayoutDescription(builtin);
const uint8_t* result = RawMetadata() + desc.metadata_offset;
DCHECK_LE(desc.metadata_offset, data_size_);
return reinterpret_cast<Address>(result);
}
uint32_t EmbeddedData::MetadataSizeOfBuiltin(Builtin builtin) const {
DCHECK(Builtins::IsBuiltinId(builtin));
const struct LayoutDescription* descs = LayoutDescription();
return descs[static_cast<int>(builtin)].metadata_length;
const struct LayoutDescription& desc = LayoutDescription(builtin);
return desc.metadata_length;
}
Address EmbeddedData::SafepointTableStartOf(Builtin builtin) const {
DCHECK(Builtins::IsBuiltinId(builtin));
const struct LayoutDescription& desc = LayoutDescription(builtin);
const uint8_t* result = RawMetadata() + desc.metadata_offset;
DCHECK_LE(desc.handler_table_offset, data_size_);
return reinterpret_cast<Address>(result);
}
uint32_t EmbeddedData::SafepointTableSizeOf(Builtin builtin) const {
DCHECK(Builtins::IsBuiltinId(builtin));
const struct LayoutDescription& desc = LayoutDescription(builtin);
#if V8_EMBEDDED_CONSTANT_POOL
DCHECK_LE(desc.handler_table_offset, desc.constant_pool_offset);
#else
DCHECK_LE(desc.handler_table_offset, desc.code_comments_offset_offset);
#endif
return desc.handler_table_offset;
}
Address EmbeddedData::HandlerTableStartOf(Builtin builtin) const {
DCHECK(Builtins::IsBuiltinId(builtin));
const struct LayoutDescription& desc = LayoutDescription(builtin);
const uint8_t* result = RawMetadata() + desc.handler_table_offset;
DCHECK_LE(desc.handler_table_offset, data_size_);
return reinterpret_cast<Address>(result);
}
uint32_t EmbeddedData::HandlerTableSizeOf(Builtin builtin) const {
DCHECK(Builtins::IsBuiltinId(builtin));
const struct LayoutDescription& desc = LayoutDescription(builtin);
#if V8_EMBEDDED_CONSTANT_POOL
DCHECK_LE(desc.handler_table_offset, desc.constant_pool_offset);
return desc.constant_pool_offset - desc.handler_table_offset;
#else
DCHECK_LE(desc.handler_table_offset, desc.code_comments_offset_offset);
return desc.code_comments_offset_offset - desc.handler_table_offset;
#endif
}
Address EmbeddedData::ConstantPoolStartOf(Builtin builtin) const {
DCHECK(Builtins::IsBuiltinId(builtin));
#if V8_EMBEDDED_CONSTANT_POOL
const struct LayoutDescription& desc = LayoutDescription(builtin);
const uint8_t* result = RawMetadata() + desc.constant_pool_offset;
DCHECK_LE(desc.constant_pool_offset, data_size_);
return reinterpret_cast<Address>(result);
#else
return kNullAddress;
#endif
}
uint32_t EmbeddedData::ConstantPoolSizeOf(Builtin builtin) const {
DCHECK(Builtins::IsBuiltinId(builtin));
#if V8_EMBEDDED_CONSTANT_POOL
const struct LayoutDescription& desc = LayoutDescription(builtin);
DCHECK_LE(desc.constant_pool_offset, desc.code_comments_offset_offset);
return desc.code_comments_offset_offset - desc.constant_pool_offset;
#else
return 0;
#endif
}
Address EmbeddedData::CodeCommentsStartOf(Builtin builtin) const {
DCHECK(Builtins::IsBuiltinId(builtin));
const struct LayoutDescription& desc = LayoutDescription(builtin);
const uint8_t* result = RawMetadata() + desc.code_comments_offset_offset;
DCHECK_LE(desc.code_comments_offset_offset, data_size_);
return reinterpret_cast<Address>(result);
}
uint32_t EmbeddedData::CodeCommentsSizeOf(Builtin builtin) const {
DCHECK(Builtins::IsBuiltinId(builtin));
const struct LayoutDescription& desc = LayoutDescription(builtin);
DCHECK_LE(desc.code_comments_offset_offset,
desc.unwinding_info_offset_offset);
return desc.unwinding_info_offset_offset - desc.code_comments_offset_offset;
}
Address EmbeddedData::UnwindingInfoStartOf(Builtin builtin) const {
DCHECK(Builtins::IsBuiltinId(builtin));
const struct LayoutDescription& desc = LayoutDescription(builtin);
const uint8_t* result = RawMetadata() + desc.unwinding_info_offset_offset;
DCHECK_LE(desc.unwinding_info_offset_offset, data_size_);
return reinterpret_cast<Address>(result);
}
uint32_t EmbeddedData::UnwindingInfoSizeOf(Builtin builtin) const {
DCHECK(Builtins::IsBuiltinId(builtin));
const struct LayoutDescription& desc = LayoutDescription(builtin);
DCHECK_LE(desc.unwinding_info_offset_offset, desc.metadata_length);
return desc.metadata_length - desc.unwinding_info_offset_offset;
}
Address EmbeddedData::InstructionStartOfBytecodeHandlers() const {

View File

@ -127,6 +127,7 @@ class EmbeddedData final {
data_ = nullptr;
}
// TODO(ishell): rename XyzOfBuiltin() to XyzOf().
Address InstructionStartOfBuiltin(Builtin builtin) const;
uint32_t InstructionSizeOfBuiltin(Builtin builtin) const;
@ -136,6 +137,21 @@ class EmbeddedData final {
Address MetadataStartOfBuiltin(Builtin builtin) const;
uint32_t MetadataSizeOfBuiltin(Builtin builtin) const;
Address SafepointTableStartOf(Builtin builtin) const;
uint32_t SafepointTableSizeOf(Builtin builtin) const;
Address HandlerTableStartOf(Builtin builtin) const;
uint32_t HandlerTableSizeOf(Builtin builtin) const;
Address ConstantPoolStartOf(Builtin builtin) const;
uint32_t ConstantPoolSizeOf(Builtin builtin) const;
Address CodeCommentsStartOf(Builtin builtin) const;
uint32_t CodeCommentsSizeOf(Builtin builtin) const;
Address UnwindingInfoStartOf(Builtin builtin) const;
uint32_t UnwindingInfoSizeOf(Builtin builtin) const;
uint32_t AddressForHashing(Address addr) {
DCHECK(IsInCodeRange(addr));
Address start = reinterpret_cast<Address>(code_);
@ -173,9 +189,18 @@ class EmbeddedData final {
uint32_t instruction_offset;
uint32_t instruction_length;
// The offset and (unpadded) length of this builtin's metadata area
// from the start of the embedded code section.
// from the start of the embedded data section.
uint32_t metadata_offset;
uint32_t metadata_length;
// The offsets describing inline metadata tables, relative to the start
// of the embedded data section.
uint32_t handler_table_offset;
#if V8_EMBEDDED_CONSTANT_POOL
uint32_t constant_pool_offset;
#endif
uint32_t code_comments_offset_offset;
uint32_t unwinding_info_offset_offset;
};
STATIC_ASSERT(offsetof(LayoutDescription, instruction_offset) ==
0 * kUInt32Size);
@ -185,7 +210,23 @@ class EmbeddedData final {
2 * kUInt32Size);
STATIC_ASSERT(offsetof(LayoutDescription, metadata_length) ==
3 * kUInt32Size);
STATIC_ASSERT(sizeof(LayoutDescription) == 4 * kUInt32Size);
STATIC_ASSERT(offsetof(LayoutDescription, handler_table_offset) ==
4 * kUInt32Size);
#if V8_EMBEDDED_CONSTANT_POOL
STATIC_ASSERT(offsetof(LayoutDescription, constant_pool_offset) ==
5 * kUInt32Size);
STATIC_ASSERT(offsetof(LayoutDescription, code_comments_offset_offset) ==
6 * kUInt32Size);
STATIC_ASSERT(offsetof(LayoutDescription, unwinding_info_offset_offset) ==
7 * kUInt32Size);
STATIC_ASSERT(sizeof(LayoutDescription) == 8 * kUInt32Size);
#else
STATIC_ASSERT(offsetof(LayoutDescription, code_comments_offset_offset) ==
5 * kUInt32Size);
STATIC_ASSERT(offsetof(LayoutDescription, unwinding_info_offset_offset) ==
6 * kUInt32Size);
STATIC_ASSERT(sizeof(LayoutDescription) == 7 * kUInt32Size);
#endif
// The layout of the blob is as follows:
//
@ -240,9 +281,11 @@ class EmbeddedData final {
const uint8_t* RawCode() const { return code_ + RawCodeOffset(); }
const LayoutDescription* LayoutDescription() const {
return reinterpret_cast<const struct LayoutDescription*>(
data_ + LayoutDescriptionTableOffset());
const LayoutDescription& LayoutDescription(Builtin builtin) const {
const struct LayoutDescription* descs =
reinterpret_cast<const struct LayoutDescription*>(
data_ + LayoutDescriptionTableOffset());
return descs[static_cast<int>(builtin)];
}
const uint8_t* RawMetadata() const { return data_ + RawMetadataOffset(); }