Commit 66ed5644 authored by Toan Pham's avatar Toan Pham Committed by Commit Bot

Separate metadata from code in the embedded data blob

Some platforms disable reading of bytes in the .text section,
so move the metadata into a separate .rodata section.

Bug: v8:10707
Change-Id: I30ef7a180f489f175c31f9d4dcd02115c9f516c2
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2301113
Commit-Queue: Toan Pham <toanpham@google.com>
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#68984}
parent 991fc239
...@@ -8887,9 +8887,9 @@ UnwindState Isolate::GetUnwindState() { ...@@ -8887,9 +8887,9 @@ UnwindState Isolate::GetUnwindState() {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
unwind_state.embedded_code_range.start = unwind_state.embedded_code_range.start =
reinterpret_cast<const void*>(isolate->embedded_blob()); reinterpret_cast<const void*>(isolate->embedded_blob_code());
unwind_state.embedded_code_range.length_in_bytes = unwind_state.embedded_code_range.length_in_bytes =
isolate->embedded_blob_size(); isolate->embedded_blob_code_size();
std::array<std::pair<i::Builtins::Name, JSEntryStub*>, 3> entry_stubs = { std::array<std::pair<i::Builtins::Name, JSEntryStub*>, 3> entry_stubs = {
{{i::Builtins::kJSEntry, &unwind_state.js_entry_stub}, {{i::Builtins::kJSEntry, &unwind_state.js_entry_stub},
......
...@@ -350,8 +350,8 @@ constexpr int OffHeapTrampolineGenerator::kBufferSize; ...@@ -350,8 +350,8 @@ constexpr int OffHeapTrampolineGenerator::kBufferSize;
Handle<Code> Builtins::GenerateOffHeapTrampolineFor( Handle<Code> Builtins::GenerateOffHeapTrampolineFor(
Isolate* isolate, Address off_heap_entry, int32_t kind_specfic_flags, Isolate* isolate, Address off_heap_entry, int32_t kind_specfic_flags,
bool generate_jump_to_instruction_stream) { bool generate_jump_to_instruction_stream) {
DCHECK_NOT_NULL(isolate->embedded_blob()); DCHECK_NOT_NULL(isolate->embedded_blob_code());
DCHECK_NE(0, isolate->embedded_blob_size()); DCHECK_NE(0, isolate->embedded_blob_code_size());
OffHeapTrampolineGenerator generator(isolate); OffHeapTrampolineGenerator generator(isolate);
......
...@@ -237,7 +237,7 @@ bool SafeStackFrameIterator::IsNoFrameBytecodeHandlerPc(Isolate* isolate, ...@@ -237,7 +237,7 @@ bool SafeStackFrameIterator::IsNoFrameBytecodeHandlerPc(Isolate* isolate,
Address pc, Address pc,
Address fp) const { Address fp) const {
// Return false for builds with non-embedded bytecode handlers. // Return false for builds with non-embedded bytecode handlers.
if (Isolate::CurrentEmbeddedBlob() == nullptr) return false; if (Isolate::CurrentEmbeddedBlobCode() == nullptr) return false;
EmbeddedData d = EmbeddedData::FromBlob(); EmbeddedData d = EmbeddedData::FromBlob();
if (pc < d.InstructionStartOfBytecodeHandlers() || if (pc < d.InstructionStartOfBytecodeHandlers() ||
......
This diff is collapsed.
...@@ -1372,14 +1372,18 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory { ...@@ -1372,14 +1372,18 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory {
// builtins constants table to remain unchanged from build-time. // builtins constants table to remain unchanged from build-time.
size_t HashIsolateForEmbeddedBlob(); size_t HashIsolateForEmbeddedBlob();
static const uint8_t* CurrentEmbeddedBlob(); static const uint8_t* CurrentEmbeddedBlobCode();
static uint32_t CurrentEmbeddedBlobSize(); static uint32_t CurrentEmbeddedBlobCodeSize();
static const uint8_t* CurrentEmbeddedBlobMetadata();
static uint32_t CurrentEmbeddedBlobMetadataSize();
static bool CurrentEmbeddedBlobIsBinaryEmbedded(); static bool CurrentEmbeddedBlobIsBinaryEmbedded();
// These always return the same result as static methods above, but don't // These always return the same result as static methods above, but don't
// access the global atomic variable (and thus *might be* slightly faster). // access the global atomic variable (and thus *might be* slightly faster).
const uint8_t* embedded_blob() const; const uint8_t* embedded_blob_code() const;
uint32_t embedded_blob_size() const; uint32_t embedded_blob_code_size() const;
const uint8_t* embedded_blob_metadata() const;
uint32_t embedded_blob_metadata_size() const;
void set_array_buffer_allocator(v8::ArrayBuffer::Allocator* allocator) { void set_array_buffer_allocator(v8::ArrayBuffer::Allocator* allocator) {
array_buffer_allocator_ = allocator; array_buffer_allocator_ = allocator;
...@@ -1811,11 +1815,14 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory { ...@@ -1811,11 +1815,14 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory {
void CreateAndSetEmbeddedBlob(); void CreateAndSetEmbeddedBlob();
void TearDownEmbeddedBlob(); void TearDownEmbeddedBlob();
void SetEmbeddedBlob(const uint8_t* blob, uint32_t blob_size); void SetEmbeddedBlob(const uint8_t* code, uint32_t code_size,
const uint8_t* metadata, uint32_t metadata_size);
void ClearEmbeddedBlob(); void ClearEmbeddedBlob();
const uint8_t* embedded_blob_ = nullptr; const uint8_t* embedded_blob_code_ = nullptr;
uint32_t embedded_blob_size_ = 0; uint32_t embedded_blob_code_size_ = 0;
const uint8_t* embedded_blob_metadata_ = nullptr;
uint32_t embedded_blob_metadata_size_ = 0;
v8::ArrayBuffer::Allocator* array_buffer_allocator_ = nullptr; v8::ArrayBuffer::Allocator* array_buffer_allocator_ = nullptr;
std::shared_ptr<v8::ArrayBuffer::Allocator> array_buffer_allocator_shared_; std::shared_ptr<v8::ArrayBuffer::Allocator> array_buffer_allocator_shared_;
......
...@@ -2105,8 +2105,8 @@ Handle<CodeDataContainer> Factory::NewCodeDataContainer( ...@@ -2105,8 +2105,8 @@ Handle<CodeDataContainer> Factory::NewCodeDataContainer(
Handle<Code> Factory::NewOffHeapTrampolineFor(Handle<Code> code, Handle<Code> Factory::NewOffHeapTrampolineFor(Handle<Code> code,
Address off_heap_entry) { Address off_heap_entry) {
CHECK_NOT_NULL(isolate()->embedded_blob()); CHECK_NOT_NULL(isolate()->embedded_blob_code());
CHECK_NE(0, isolate()->embedded_blob_size()); CHECK_NE(0, isolate()->embedded_blob_code_size());
CHECK(Builtins::IsIsolateIndependentBuiltin(*code)); CHECK(Builtins::IsIsolateIndependentBuiltin(*code));
bool generate_jump_to_instruction_stream = bool generate_jump_to_instruction_stream =
......
...@@ -561,8 +561,9 @@ Code Code::GetCodeFromTargetAddress(Address address) { ...@@ -561,8 +561,9 @@ Code Code::GetCodeFromTargetAddress(Address address) {
{ {
// TODO(jgruber,v8:6666): Support embedded builtins here. We'd need to pass // TODO(jgruber,v8:6666): Support embedded builtins here. We'd need to pass
// in the current isolate. // in the current isolate.
Address start = reinterpret_cast<Address>(Isolate::CurrentEmbeddedBlob()); Address start =
Address end = start + Isolate::CurrentEmbeddedBlobSize(); reinterpret_cast<Address>(Isolate::CurrentEmbeddedBlobCode());
Address end = start + Isolate::CurrentEmbeddedBlobCodeSize();
CHECK(address < start || address >= end); CHECK(address < start || address >= end);
} }
......
...@@ -143,21 +143,24 @@ SafepointEntry Code::GetSafepointEntry(Address pc) { ...@@ -143,21 +143,24 @@ SafepointEntry Code::GetSafepointEntry(Address pc) {
int Code::OffHeapInstructionSize() const { int Code::OffHeapInstructionSize() const {
DCHECK(is_off_heap_trampoline()); DCHECK(is_off_heap_trampoline());
if (Isolate::CurrentEmbeddedBlob() == nullptr) return raw_instruction_size(); if (Isolate::CurrentEmbeddedBlobCode() == nullptr)
return raw_instruction_size();
EmbeddedData d = EmbeddedData::FromBlob(); EmbeddedData d = EmbeddedData::FromBlob();
return d.InstructionSizeOfBuiltin(builtin_index()); return d.InstructionSizeOfBuiltin(builtin_index());
} }
Address Code::OffHeapInstructionStart() const { Address Code::OffHeapInstructionStart() const {
DCHECK(is_off_heap_trampoline()); DCHECK(is_off_heap_trampoline());
if (Isolate::CurrentEmbeddedBlob() == nullptr) return raw_instruction_start(); if (Isolate::CurrentEmbeddedBlobCode() == nullptr)
return raw_instruction_start();
EmbeddedData d = EmbeddedData::FromBlob(); EmbeddedData d = EmbeddedData::FromBlob();
return d.InstructionStartOfBuiltin(builtin_index()); return d.InstructionStartOfBuiltin(builtin_index());
} }
Address Code::OffHeapInstructionEnd() const { Address Code::OffHeapInstructionEnd() const {
DCHECK(is_off_heap_trampoline()); DCHECK(is_off_heap_trampoline());
if (Isolate::CurrentEmbeddedBlob() == nullptr) return raw_instruction_end(); if (Isolate::CurrentEmbeddedBlobCode() == nullptr)
return raw_instruction_end();
EmbeddedData d = EmbeddedData::FromBlob(); EmbeddedData d = EmbeddedData::FromBlob();
return d.InstructionStartOfBuiltin(builtin_index()) + return d.InstructionStartOfBuiltin(builtin_index()) +
d.InstructionSizeOfBuiltin(builtin_index()); d.InstructionSizeOfBuiltin(builtin_index());
......
...@@ -848,10 +848,9 @@ RUNTIME_FUNCTION(Runtime_ProfileCreateSnapshotDataBlob) { ...@@ -848,10 +848,9 @@ RUNTIME_FUNCTION(Runtime_ProfileCreateSnapshotDataBlob) {
// Track the embedded blob size as well. // Track the embedded blob size as well.
{ {
int embedded_blob_size = 0;
i::EmbeddedData d = i::EmbeddedData::FromBlob(); i::EmbeddedData d = i::EmbeddedData::FromBlob();
embedded_blob_size = static_cast<int>(d.size()); PrintF("Embedded blob is %d bytes\n",
PrintF("Embedded blob is %d bytes\n", embedded_blob_size); static_cast<int>(d.code_size() + d.metadata_size()));
} }
FreeCurrentEmbeddedBlob(); FreeCurrentEmbeddedBlob();
......
...@@ -501,7 +501,7 @@ void Deserializer::VisitOffHeapTarget(Code host, RelocInfo* rinfo) { ...@@ -501,7 +501,7 @@ void Deserializer::VisitOffHeapTarget(Code host, RelocInfo* rinfo) {
int builtin_index = source_.GetInt(); int builtin_index = source_.GetInt();
DCHECK(Builtins::IsBuiltinId(builtin_index)); DCHECK(Builtins::IsBuiltinId(builtin_index));
CHECK_NOT_NULL(isolate()->embedded_blob()); CHECK_NOT_NULL(isolate()->embedded_blob_code());
EmbeddedData d = EmbeddedData::FromBlob(); EmbeddedData d = EmbeddedData::FromBlob();
Address address = d.InstructionStartOfBuiltin(builtin_index); Address address = d.InstructionStartOfBuiltin(builtin_index);
CHECK_NE(kNullAddress, address); CHECK_NE(kNullAddress, address);
......
This diff is collapsed.
...@@ -30,9 +30,13 @@ class InstructionStream final : public AllStatic { ...@@ -30,9 +30,13 @@ class InstructionStream final : public AllStatic {
// containing all off-heap code. The area is guaranteed to be contiguous. // containing all off-heap code. The area is guaranteed to be contiguous.
// Note that this only applies when building the snapshot, e.g. for // Note that this only applies when building the snapshot, e.g. for
// mksnapshot. Otherwise, off-heap code is embedded directly into the binary. // mksnapshot. Otherwise, off-heap code is embedded directly into the binary.
static void CreateOffHeapInstructionStream(Isolate* isolate, uint8_t** data, static void CreateOffHeapInstructionStream(Isolate* isolate, uint8_t** code,
uint32_t* size); uint32_t* code_size,
static void FreeOffHeapInstructionStream(uint8_t* data, uint32_t size); uint8_t** metadata,
uint32_t* metadata_size);
static void FreeOffHeapInstructionStream(uint8_t* code, uint32_t code_size,
uint8_t* metadata,
uint32_t metadata_size);
}; };
class EmbeddedData final { class EmbeddedData final {
...@@ -40,19 +44,30 @@ class EmbeddedData final { ...@@ -40,19 +44,30 @@ class EmbeddedData final {
static EmbeddedData FromIsolate(Isolate* isolate); static EmbeddedData FromIsolate(Isolate* isolate);
static EmbeddedData FromBlob() { static EmbeddedData FromBlob() {
return EmbeddedData(Isolate::CurrentEmbeddedBlob(), return EmbeddedData(Isolate::CurrentEmbeddedBlobCode(),
Isolate::CurrentEmbeddedBlobSize()); Isolate::CurrentEmbeddedBlobCodeSize(),
Isolate::CurrentEmbeddedBlobMetadata(),
Isolate::CurrentEmbeddedBlobMetadataSize());
} }
static EmbeddedData FromBlob(Isolate* isolate) { static EmbeddedData FromBlob(Isolate* isolate) {
return EmbeddedData(isolate->embedded_blob(), return EmbeddedData(isolate->embedded_blob_code(),
isolate->embedded_blob_size()); isolate->embedded_blob_code_size(),
isolate->embedded_blob_metadata(),
isolate->embedded_blob_metadata_size());
} }
const uint8_t* data() const { return data_; } const uint8_t* code() const { return code_; }
uint32_t size() const { return size_; } uint32_t code_size() const { return code_size_; }
const uint8_t* metadata() const { return metadata_; }
uint32_t metadata_size() const { return metadata_size_; }
void Dispose() { delete[] data_; } void Dispose() {
delete[] code_;
code_ = nullptr;
delete[] metadata_;
metadata_ = nullptr;
}
Address InstructionStartOfBuiltin(int i) const; Address InstructionStartOfBuiltin(int i) const;
uint32_t InstructionSizeOfBuiltin(int i) const; uint32_t InstructionSizeOfBuiltin(int i) const;
...@@ -63,8 +78,8 @@ class EmbeddedData final { ...@@ -63,8 +78,8 @@ class EmbeddedData final {
bool ContainsBuiltin(int i) const { return InstructionSizeOfBuiltin(i) > 0; } bool ContainsBuiltin(int i) const { return InstructionSizeOfBuiltin(i) > 0; }
uint32_t AddressForHashing(Address addr) { uint32_t AddressForHashing(Address addr) {
Address start = reinterpret_cast<Address>(data_); Address start = reinterpret_cast<Address>(code_);
DCHECK(base::IsInRange(addr, start, start + size_)); DCHECK(base::IsInRange(addr, start, start + code_size_));
return static_cast<uint32_t>(addr - start); return static_cast<uint32_t>(addr - start);
} }
...@@ -76,11 +91,12 @@ class EmbeddedData final { ...@@ -76,11 +91,12 @@ class EmbeddedData final {
size_t CreateEmbeddedBlobHash() const; size_t CreateEmbeddedBlobHash() const;
size_t EmbeddedBlobHash() const { size_t EmbeddedBlobHash() const {
return *reinterpret_cast<const size_t*>(data_ + EmbeddedBlobHashOffset()); return *reinterpret_cast<const size_t*>(metadata_ +
EmbeddedBlobHashOffset());
} }
size_t IsolateHash() const { size_t IsolateHash() const {
return *reinterpret_cast<const size_t*>(data_ + IsolateHashOffset()); return *reinterpret_cast<const size_t*>(metadata_ + IsolateHashOffset());
} }
struct Metadata { struct Metadata {
...@@ -94,10 +110,14 @@ class EmbeddedData final { ...@@ -94,10 +110,14 @@ class EmbeddedData final {
// The layout of the blob is as follows: // The layout of the blob is as follows:
// //
// metadata:
// [0] hash of the remaining blob // [0] hash of the remaining blob
// [1] hash of embedded-blob-relevant heap objects // [1] hash of embedded-blob-relevant heap objects
// [2] metadata of instruction stream 0 // [2] metadata of instruction stream 0
// ... metadata // ... metadata
//
// code:
// [0] instruction streams 0
// ... instruction streams // ... instruction streams
static constexpr uint32_t kTableSize = Builtins::builtin_count; static constexpr uint32_t kTableSize = Builtins::builtin_count;
...@@ -107,26 +127,32 @@ class EmbeddedData final { ...@@ -107,26 +127,32 @@ class EmbeddedData final {
return EmbeddedBlobHashOffset() + EmbeddedBlobHashSize(); return EmbeddedBlobHashOffset() + EmbeddedBlobHashSize();
} }
static constexpr uint32_t IsolateHashSize() { return kSizetSize; } static constexpr uint32_t IsolateHashSize() { return kSizetSize; }
static constexpr uint32_t MetadataOffset() { static constexpr uint32_t MetadataTableOffset() {
return IsolateHashOffset() + IsolateHashSize(); return IsolateHashOffset() + IsolateHashSize();
} }
static constexpr uint32_t MetadataSize() { static constexpr uint32_t MetadataTableSize() {
return sizeof(struct Metadata) * kTableSize; return sizeof(struct Metadata) * kTableSize;
} }
static constexpr uint32_t RawDataOffset() { static constexpr uint32_t RawCodeOffset() { return 0; }
return PadAndAlign(MetadataOffset() + MetadataSize());
}
private: private:
EmbeddedData(const uint8_t* data, uint32_t size) : data_(data), size_(size) { EmbeddedData(const uint8_t* code, uint32_t code_size, const uint8_t* metadata,
DCHECK_NOT_NULL(data); uint32_t metadata_size)
DCHECK_LT(0, size); : code_(code),
code_size_(code_size),
metadata_(metadata),
metadata_size_(metadata_size) {
DCHECK_NOT_NULL(code);
DCHECK_LT(0, code_size);
DCHECK_NOT_NULL(metadata);
DCHECK_LT(0, metadata_size);
} }
const Metadata* Metadata() const { const Metadata* Metadata() const {
return reinterpret_cast<const struct Metadata*>(data_ + MetadataOffset()); return reinterpret_cast<const struct Metadata*>(metadata_ +
MetadataTableOffset());
} }
const uint8_t* RawData() const { return data_ + RawDataOffset(); } const uint8_t* RawCode() const { return code_ + RawCodeOffset(); }
static constexpr int PadAndAlign(int size) { static constexpr int PadAndAlign(int size) {
// Ensure we have at least one byte trailing the actual builtin // Ensure we have at least one byte trailing the actual builtin
...@@ -136,8 +162,14 @@ class EmbeddedData final { ...@@ -136,8 +162,14 @@ class EmbeddedData final {
void PrintStatistics() const; void PrintStatistics() const;
const uint8_t* data_; // This points to code for builtins. The contents are potentially unreadable
uint32_t size_; // on platforms that disallow reads from the .text section.
const uint8_t* code_;
uint32_t code_size_;
// This is metadata for the code.
const uint8_t* metadata_;
uint32_t metadata_size_;
}; };
} // namespace internal } // namespace internal
......
...@@ -8,16 +8,24 @@ ...@@ -8,16 +8,24 @@
#include "src/base/macros.h" #include "src/base/macros.h"
extern "C" const uint8_t* v8_Default_embedded_blob_; extern "C" const uint8_t* v8_Default_embedded_blob_code_;
extern "C" uint32_t v8_Default_embedded_blob_size_; extern "C" uint32_t v8_Default_embedded_blob_code_size_;
extern "C" const uint8_t* v8_Default_embedded_blob_metadata_;
extern "C" uint32_t v8_Default_embedded_blob_metadata_size_;
const uint8_t* v8_Default_embedded_blob_ = nullptr; const uint8_t* v8_Default_embedded_blob_code_ = nullptr;
uint32_t v8_Default_embedded_blob_size_ = 0; uint32_t v8_Default_embedded_blob_code_size_ = 0;
const uint8_t* v8_Default_embedded_blob_metadata_ = nullptr;
uint32_t v8_Default_embedded_blob_metadata_size_ = 0;
#ifdef V8_MULTI_SNAPSHOTS #ifdef V8_MULTI_SNAPSHOTS
extern "C" const uint8_t* v8_Trusted_embedded_blob_; extern "C" const uint8_t* v8_Trusted_embedded_blob_code_;
extern "C" uint32_t v8_Trusted_embedded_blob_size_; extern "C" uint32_t v8_Trusted_embedded_blob_code_size_;
extern "C" const uint8_t* v8_Trusted_embedded_blob_metadata_;
extern "C" uint32_t v8_Trusted_embedded_blob_metadata_size_;
const uint8_t* v8_Trusted_embedded_blob_ = nullptr; const uint8_t* v8_Trusted_embedded_blob_code_ = nullptr;
uint32_t v8_Trusted_embedded_blob_size_ = 0; uint32_t v8_Trusted_embedded_blob_code_size_ = 0;
const uint8_t* v8_Trusted_embedded_blob_metadata_ = nullptr;
uint32_t v8_Trusted_embedded_blob_metadata_size_ = 0;
#endif #endif
...@@ -73,27 +73,49 @@ void EmbeddedFileWriter::WriteBuiltin(PlatformEmbeddedFileWriterBase* w, ...@@ -73,27 +73,49 @@ void EmbeddedFileWriter::WriteBuiltin(PlatformEmbeddedFileWriterBase* w,
void EmbeddedFileWriter::WriteFileEpilogue(PlatformEmbeddedFileWriterBase* w, void EmbeddedFileWriter::WriteFileEpilogue(PlatformEmbeddedFileWriterBase* w,
const i::EmbeddedData* blob) const { const i::EmbeddedData* blob) const {
{ {
i::EmbeddedVector<char, kTemporaryStringLength> embedded_blob_symbol; i::EmbeddedVector<char, kTemporaryStringLength> embedded_blob_code_symbol;
i::SNPrintF(embedded_blob_symbol, "v8_%s_embedded_blob_", i::SNPrintF(embedded_blob_code_symbol, "v8_%s_embedded_blob_code_",
embedded_variant_); embedded_variant_);
w->Comment("Pointer to the beginning of the embedded blob."); w->Comment("Pointer to the beginning of the embedded blob code.");
w->SectionData(); w->SectionData();
w->AlignToDataAlignment(); w->AlignToDataAlignment();
w->DeclarePointerToSymbol(embedded_blob_symbol.begin(), w->DeclarePointerToSymbol(embedded_blob_code_symbol.begin(),
EmbeddedBlobDataSymbol().c_str()); EmbeddedBlobCodeDataSymbol().c_str());
w->Newline();
i::EmbeddedVector<char, kTemporaryStringLength>
embedded_blob_metadata_symbol;
i::SNPrintF(embedded_blob_metadata_symbol, "v8_%s_embedded_blob_metadata_",
embedded_variant_);
w->Comment("Pointer to the beginning of the embedded blob metadata.");
w->AlignToDataAlignment();
w->DeclarePointerToSymbol(embedded_blob_metadata_symbol.begin(),
EmbeddedBlobMetadataDataSymbol().c_str());
w->Newline(); w->Newline();
} }
{ {
i::EmbeddedVector<char, kTemporaryStringLength> embedded_blob_size_symbol; i::EmbeddedVector<char, kTemporaryStringLength>
i::SNPrintF(embedded_blob_size_symbol, "v8_%s_embedded_blob_size_", embedded_blob_code_size_symbol;
embedded_variant_); i::SNPrintF(embedded_blob_code_size_symbol,
"v8_%s_embedded_blob_code_size_", embedded_variant_);
w->Comment("The size of the embedded blob in bytes."); w->Comment("The size of the embedded blob code in bytes.");
w->SectionRoData(); w->SectionRoData();
w->AlignToDataAlignment(); w->AlignToDataAlignment();
w->DeclareUint32(embedded_blob_size_symbol.begin(), blob->size()); w->DeclareUint32(embedded_blob_code_size_symbol.begin(), blob->code_size());
w->Newline();
i::EmbeddedVector<char, kTemporaryStringLength>
embedded_blob_metadata_size_symbol;
i::SNPrintF(embedded_blob_metadata_size_symbol,
"v8_%s_embedded_blob_metadata_size_", embedded_variant_);
w->Comment("The size of the embedded blob metadata in bytes.");
w->DeclareUint32(embedded_blob_metadata_size_symbol.begin(),
blob->metadata_size());
w->Newline(); w->Newline();
} }
...@@ -104,7 +126,7 @@ void EmbeddedFileWriter::WriteFileEpilogue(PlatformEmbeddedFileWriterBase* w, ...@@ -104,7 +126,7 @@ void EmbeddedFileWriter::WriteFileEpilogue(PlatformEmbeddedFileWriterBase* w,
embedded_variant_); embedded_variant_);
w->MaybeEmitUnwindData(unwind_info_symbol.begin(), w->MaybeEmitUnwindData(unwind_info_symbol.begin(),
EmbeddedBlobDataSymbol().c_str(), blob, EmbeddedBlobCodeDataSymbol().c_str(), blob,
reinterpret_cast<const void*>(&unwind_infos_[0])); reinterpret_cast<const void*>(&unwind_infos_[0]));
} }
#endif // V8_OS_WIN64 #endif // V8_OS_WIN64
......
...@@ -142,23 +142,31 @@ class EmbeddedFileWriter : public EmbeddedFileWriterInterface { ...@@ -142,23 +142,31 @@ class EmbeddedFileWriter : public EmbeddedFileWriterInterface {
// Fairly arbitrary but should fit all symbol names. // Fairly arbitrary but should fit all symbol names.
static constexpr int kTemporaryStringLength = 256; static constexpr int kTemporaryStringLength = 256;
std::string EmbeddedBlobDataSymbol() const { std::string EmbeddedBlobCodeDataSymbol() const {
i::EmbeddedVector<char, kTemporaryStringLength> embedded_blob_data_symbol; i::EmbeddedVector<char, kTemporaryStringLength>
i::SNPrintF(embedded_blob_data_symbol, "v8_%s_embedded_blob_data_", embedded_blob_code_data_symbol;
embedded_variant_); i::SNPrintF(embedded_blob_code_data_symbol,
return std::string{embedded_blob_data_symbol.begin()}; "v8_%s_embedded_blob_code_data_", embedded_variant_);
return std::string{embedded_blob_code_data_symbol.begin()};
}
std::string EmbeddedBlobMetadataDataSymbol() const {
i::EmbeddedVector<char, kTemporaryStringLength>
embedded_blob_metadata_data_symbol;
i::SNPrintF(embedded_blob_metadata_data_symbol,
"v8_%s_embedded_blob_metadata_data_", embedded_variant_);
return std::string{embedded_blob_metadata_data_symbol.begin()};
} }
void WriteMetadataSection(PlatformEmbeddedFileWriterBase* w, void WriteMetadataSection(PlatformEmbeddedFileWriterBase* w,
const i::EmbeddedData* blob) const { const i::EmbeddedData* blob) const {
w->Comment("The embedded blob starts here. Metadata comes first, followed"); w->Comment("The embedded blob metadata starts here.");
w->Comment("by builtin instruction streams."); w->SectionRoData();
w->SectionText(); w->AlignToDataAlignment();
w->AlignToCodeAlignment(); w->DeclareLabel(EmbeddedBlobMetadataDataSymbol().c_str());
w->DeclareLabel(EmbeddedBlobDataSymbol().c_str());
WriteBinaryContentsAsInlineAssembly(w, blob->data(), WriteBinaryContentsAsInlineAssembly(w, blob->metadata(),
i::EmbeddedData::RawDataOffset()); blob->metadata_size());
} }
void WriteBuiltin(PlatformEmbeddedFileWriterBase* w, void WriteBuiltin(PlatformEmbeddedFileWriterBase* w,
...@@ -166,6 +174,12 @@ class EmbeddedFileWriter : public EmbeddedFileWriterInterface { ...@@ -166,6 +174,12 @@ class EmbeddedFileWriter : public EmbeddedFileWriterInterface {
void WriteInstructionStreams(PlatformEmbeddedFileWriterBase* w, void WriteInstructionStreams(PlatformEmbeddedFileWriterBase* w,
const i::EmbeddedData* blob) const { const i::EmbeddedData* blob) const {
w->Comment("The embedded blob data starts here. It contains the builtin");
w->Comment("instruction streams.");
w->SectionText();
w->AlignToCodeAlignment();
w->DeclareLabel(EmbeddedBlobCodeDataSymbol().c_str());
for (int i = 0; i < i::Builtins::builtin_count; i++) { for (int i = 0; i < i::Builtins::builtin_count; i++) {
if (!blob->ContainsBuiltin(i)) continue; if (!blob->ContainsBuiltin(i)) continue;
......
...@@ -118,7 +118,7 @@ void EmitUnwindData(PlatformEmbeddedFileWriterWin* w, ...@@ -118,7 +118,7 @@ void EmitUnwindData(PlatformEmbeddedFileWriterWin* w,
if (unwind_infos[i].is_leaf_function()) continue; if (unwind_infos[i].is_leaf_function()) continue;
uint64_t builtin_start_offset = blob->InstructionStartOfBuiltin(i) - uint64_t builtin_start_offset = blob->InstructionStartOfBuiltin(i) -
reinterpret_cast<Address>(blob->data()); reinterpret_cast<Address>(blob->code());
uint32_t builtin_size = blob->InstructionSizeOfBuiltin(i); uint32_t builtin_size = blob->InstructionSizeOfBuiltin(i);
const std::vector<int>& xdata_desc = unwind_infos[i].fp_offsets(); const std::vector<int>& xdata_desc = unwind_infos[i].fp_offsets();
...@@ -198,7 +198,7 @@ void EmitUnwindData(PlatformEmbeddedFileWriterWin* w, ...@@ -198,7 +198,7 @@ void EmitUnwindData(PlatformEmbeddedFileWriterWin* w,
if (unwind_infos[i].is_leaf_function()) continue; if (unwind_infos[i].is_leaf_function()) continue;
uint64_t builtin_start_offset = blob->InstructionStartOfBuiltin(i) - uint64_t builtin_start_offset = blob->InstructionStartOfBuiltin(i) -
reinterpret_cast<Address>(blob->data()); reinterpret_cast<Address>(blob->code());
uint32_t builtin_size = blob->InstructionSizeOfBuiltin(i); uint32_t builtin_size = blob->InstructionSizeOfBuiltin(i);
const std::vector<int>& xdata_desc = unwind_infos[i].fp_offsets(); const std::vector<int>& xdata_desc = unwind_infos[i].fp_offsets();
......
...@@ -21,5 +21,20 @@ uint32_t Checksum(Vector<const byte> payload) { ...@@ -21,5 +21,20 @@ uint32_t Checksum(Vector<const byte> payload) {
return static_cast<uint32_t>(adler32(0, payload.begin(), payload.length())); return static_cast<uint32_t>(adler32(0, payload.begin(), payload.length()));
} }
V8_EXPORT_PRIVATE uint32_t Checksum(Vector<const byte> payload1,
Vector<const byte> payload2) {
#ifdef MEMORY_SANITIZER
// Computing the checksum includes padding bytes for objects like strings.
// Mark every object as initialized in the code serializer.
MSAN_MEMORY_IS_INITIALIZED(payload1.begin(), payload1.length());
MSAN_MEMORY_IS_INITIALIZED(payload2.begin(), payload2.length());
#endif // MEMORY_SANITIZER
// Priming the adler32 call so it can see what CPU features are available.
adler32(0, nullptr, 0);
auto sum = adler32(0, payload1.begin(), payload1.length());
sum = adler32(sum, payload2.begin(), payload2.length());
return static_cast<uint32_t>(sum);
}
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
...@@ -11,6 +11,8 @@ namespace v8 { ...@@ -11,6 +11,8 @@ namespace v8 {
namespace internal { namespace internal {
V8_EXPORT_PRIVATE uint32_t Checksum(Vector<const byte> payload); V8_EXPORT_PRIVATE uint32_t Checksum(Vector<const byte> payload);
V8_EXPORT_PRIVATE uint32_t Checksum(Vector<const byte> payload1,
Vector<const byte> payload2);
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
......
...@@ -98,9 +98,9 @@ TEST(CodeRangeCorrectContents) { ...@@ -98,9 +98,9 @@ TEST(CodeRangeCorrectContents) {
// We should only have the code range and the embedded code range. // We should only have the code range and the embedded code range.
CHECK_EQ(2, pages->size()); CHECK_EQ(2, pages->size());
CHECK(PagesHasExactPage(pages, code_range.begin(), code_range.size())); CHECK(PagesHasExactPage(pages, code_range.begin(), code_range.size()));
CHECK(PagesHasExactPage(pages, CHECK(PagesHasExactPage(
reinterpret_cast<Address>(i_isolate->embedded_blob()), pages, reinterpret_cast<Address>(i_isolate->embedded_blob_code()),
i_isolate->embedded_blob_size())); i_isolate->embedded_blob_code_size()));
} }
TEST(CodePagesCorrectContents) { TEST(CodePagesCorrectContents) {
...@@ -120,9 +120,9 @@ TEST(CodePagesCorrectContents) { ...@@ -120,9 +120,9 @@ TEST(CodePagesCorrectContents) {
// We should have the embedded code range even when there is no regular code // We should have the embedded code range even when there is no regular code
// range. // range.
CHECK(PagesHasExactPage(pages, CHECK(PagesHasExactPage(
reinterpret_cast<Address>(i_isolate->embedded_blob()), pages, reinterpret_cast<Address>(i_isolate->embedded_blob_code()),
i_isolate->embedded_blob_size())); i_isolate->embedded_blob_code_size()));
} }
TEST(OptimizedCodeWithCodeRange) { TEST(OptimizedCodeWithCodeRange) {
......
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