[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:
parent
cb916625f4
commit
388fdafcd4
@ -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());
|
||||
|
@ -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";
|
||||
|
@ -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);
|
||||
|
@ -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 {
|
||||
|
@ -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(); }
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user