Commit 23ba0667 authored by Jakob Gruber's avatar Jakob Gruber Committed by Commit Bot

[code] Extend comments, use better terms to describe metadata

This addresses comments from [0] by extending comments to also
describe embedded builtins in code.h, and by improving language
around various meaning of 'metadata':

- The Code object's metadata section is still called 'metadata'.
- The embedded blob's table of layout descriptions for builtins is
  now called 'layout descriptions'.
- The embedded blob's data section (containing hashes and layout
  descriptions) is now called 'data' section.

[0] chromium-review.googlesource.com/c/v8/v8/+/2491025

Bug: v8:11036
Change-Id: Ibe84fddb9784cc5d3b66482612dcdb7a2e8d14ae
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2501284
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/master@{#70793}
parent 73a94290
......@@ -107,8 +107,8 @@
extern "C" const uint8_t* v8_Default_embedded_blob_code_;
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_;
extern "C" const uint8_t* v8_Default_embedded_blob_data_;
extern "C" uint32_t v8_Default_embedded_blob_data_size_;
namespace v8 {
namespace internal {
......@@ -131,18 +131,18 @@ const uint8_t* DefaultEmbeddedBlobCode() {
uint32_t DefaultEmbeddedBlobCodeSize() {
return v8_Default_embedded_blob_code_size_;
}
const uint8_t* DefaultEmbeddedBlobMetadata() {
return v8_Default_embedded_blob_metadata_;
const uint8_t* DefaultEmbeddedBlobData() {
return v8_Default_embedded_blob_data_;
}
uint32_t DefaultEmbeddedBlobMetadataSize() {
return v8_Default_embedded_blob_metadata_size_;
uint32_t DefaultEmbeddedBlobDataSize() {
return v8_Default_embedded_blob_data_size_;
}
#ifdef V8_MULTI_SNAPSHOTS
extern "C" const uint8_t* v8_Trusted_embedded_blob_code_;
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_;
extern "C" const uint8_t* v8_Trusted_embedded_blob_data_;
extern "C" uint32_t v8_Trusted_embedded_blob_data_size_;
const uint8_t* TrustedEmbeddedBlobCode() {
return v8_Trusted_embedded_blob_code_;
......@@ -150,11 +150,11 @@ const uint8_t* TrustedEmbeddedBlobCode() {
uint32_t TrustedEmbeddedBlobCodeSize() {
return v8_Trusted_embedded_blob_code_size_;
}
const uint8_t* TrustedEmbeddedBlobMetadata() {
return v8_Trusted_embedded_blob_metadata_;
const uint8_t* TrustedEmbeddedBlobData() {
return v8_Trusted_embedded_blob_data_;
}
uint32_t TrustedEmbeddedBlobMetadataSize() {
return v8_Trusted_embedded_blob_metadata_size_;
uint32_t TrustedEmbeddedBlobDataSize() {
return v8_Trusted_embedded_blob_data_size_;
}
#endif
......@@ -169,8 +169,8 @@ namespace {
std::atomic<const uint8_t*> current_embedded_blob_code_(nullptr);
std::atomic<uint32_t> current_embedded_blob_code_size_(0);
std::atomic<const uint8_t*> current_embedded_blob_metadata_(nullptr);
std::atomic<uint32_t> current_embedded_blob_metadata_size_(0);
std::atomic<const uint8_t*> current_embedded_blob_data_(nullptr);
std::atomic<uint32_t> current_embedded_blob_data_size_(0);
// The various workflows around embedded snapshots are fairly complex. We need
// to support plain old snapshot builds, nosnap builds, and the requirements of
......@@ -196,16 +196,16 @@ std::atomic<uint32_t> current_embedded_blob_metadata_size_(0);
// This mutex protects access to the following variables:
// - sticky_embedded_blob_code_
// - sticky_embedded_blob_code_size_
// - sticky_embedded_blob_metadata_
// - sticky_embedded_blob_metadata_size_
// - sticky_embedded_blob_data_
// - sticky_embedded_blob_data_size_
// - enable_embedded_blob_refcounting_
// - current_embedded_blob_refs_
base::LazyMutex current_embedded_blob_refcount_mutex_ = LAZY_MUTEX_INITIALIZER;
const uint8_t* sticky_embedded_blob_code_ = nullptr;
uint32_t sticky_embedded_blob_code_size_ = 0;
const uint8_t* sticky_embedded_blob_metadata_ = nullptr;
uint32_t sticky_embedded_blob_metadata_size_ = 0;
const uint8_t* sticky_embedded_blob_data_ = nullptr;
uint32_t sticky_embedded_blob_data_size_ = 0;
bool enable_embedded_blob_refcounting_ = true;
int current_embedded_blob_refs_ = 0;
......@@ -214,19 +214,17 @@ const uint8_t* StickyEmbeddedBlobCode() { return sticky_embedded_blob_code_; }
uint32_t StickyEmbeddedBlobCodeSize() {
return sticky_embedded_blob_code_size_;
}
const uint8_t* StickyEmbeddedBlobMetadata() {
return sticky_embedded_blob_metadata_;
}
uint32_t StickyEmbeddedBlobMetadataSize() {
return sticky_embedded_blob_metadata_size_;
const uint8_t* StickyEmbeddedBlobData() { return sticky_embedded_blob_data_; }
uint32_t StickyEmbeddedBlobDataSize() {
return sticky_embedded_blob_data_size_;
}
void SetStickyEmbeddedBlob(const uint8_t* code, uint32_t code_size,
const uint8_t* metadata, uint32_t metadata_size) {
const uint8_t* data, uint32_t data_size) {
sticky_embedded_blob_code_ = code;
sticky_embedded_blob_code_size_ = code_size;
sticky_embedded_blob_metadata_ = metadata;
sticky_embedded_blob_metadata_size_ = metadata_size;
sticky_embedded_blob_data_ = data;
sticky_embedded_blob_data_size_ = data_size;
}
} // namespace
......@@ -243,23 +241,22 @@ void FreeCurrentEmbeddedBlob() {
if (StickyEmbeddedBlobCode() == nullptr) return;
CHECK_EQ(StickyEmbeddedBlobCode(), Isolate::CurrentEmbeddedBlobCode());
CHECK_EQ(StickyEmbeddedBlobMetadata(),
Isolate::CurrentEmbeddedBlobMetadata());
CHECK_EQ(StickyEmbeddedBlobData(), Isolate::CurrentEmbeddedBlobData());
InstructionStream::FreeOffHeapInstructionStream(
const_cast<uint8_t*>(Isolate::CurrentEmbeddedBlobCode()),
Isolate::CurrentEmbeddedBlobCodeSize(),
const_cast<uint8_t*>(Isolate::CurrentEmbeddedBlobMetadata()),
Isolate::CurrentEmbeddedBlobMetadataSize());
const_cast<uint8_t*>(Isolate::CurrentEmbeddedBlobData()),
Isolate::CurrentEmbeddedBlobDataSize());
current_embedded_blob_code_.store(nullptr, std::memory_order_relaxed);
current_embedded_blob_code_size_.store(0, std::memory_order_relaxed);
current_embedded_blob_metadata_.store(nullptr, std::memory_order_relaxed);
current_embedded_blob_metadata_size_.store(0, std::memory_order_relaxed);
current_embedded_blob_data_.store(nullptr, std::memory_order_relaxed);
current_embedded_blob_data_size_.store(0, std::memory_order_relaxed);
sticky_embedded_blob_code_ = nullptr;
sticky_embedded_blob_code_size_ = 0;
sticky_embedded_blob_metadata_ = nullptr;
sticky_embedded_blob_metadata_size_ = 0;
sticky_embedded_blob_data_ = nullptr;
sticky_embedded_blob_data_size_ = 0;
}
// static
......@@ -279,19 +276,18 @@ bool Isolate::CurrentEmbeddedBlobIsBinaryEmbedded() {
}
void Isolate::SetEmbeddedBlob(const uint8_t* code, uint32_t code_size,
const uint8_t* metadata, uint32_t metadata_size) {
const uint8_t* data, uint32_t data_size) {
CHECK_NOT_NULL(code);
CHECK_NOT_NULL(metadata);
CHECK_NOT_NULL(data);
embedded_blob_code_ = code;
embedded_blob_code_size_ = code_size;
embedded_blob_metadata_ = metadata;
embedded_blob_metadata_size_ = metadata_size;
embedded_blob_data_ = data;
embedded_blob_data_size_ = data_size;
current_embedded_blob_code_.store(code, std::memory_order_relaxed);
current_embedded_blob_code_size_.store(code_size, std::memory_order_relaxed);
current_embedded_blob_metadata_.store(metadata, std::memory_order_relaxed);
current_embedded_blob_metadata_size_.store(metadata_size,
std::memory_order_relaxed);
current_embedded_blob_data_.store(data, std::memory_order_relaxed);
current_embedded_blob_data_size_.store(data_size, std::memory_order_relaxed);
#ifdef DEBUG
// Verify that the contents of the embedded blob are unchanged from
......@@ -314,21 +310,21 @@ void Isolate::ClearEmbeddedBlob() {
CHECK(enable_embedded_blob_refcounting_);
CHECK_EQ(embedded_blob_code_, CurrentEmbeddedBlobCode());
CHECK_EQ(embedded_blob_code_, StickyEmbeddedBlobCode());
CHECK_EQ(embedded_blob_metadata_, CurrentEmbeddedBlobMetadata());
CHECK_EQ(embedded_blob_metadata_, StickyEmbeddedBlobMetadata());
CHECK_EQ(embedded_blob_data_, CurrentEmbeddedBlobData());
CHECK_EQ(embedded_blob_data_, StickyEmbeddedBlobData());
embedded_blob_code_ = nullptr;
embedded_blob_code_size_ = 0;
embedded_blob_metadata_ = nullptr;
embedded_blob_metadata_size_ = 0;
embedded_blob_data_ = nullptr;
embedded_blob_data_size_ = 0;
current_embedded_blob_code_.store(nullptr, std::memory_order_relaxed);
current_embedded_blob_code_size_.store(0, std::memory_order_relaxed);
current_embedded_blob_metadata_.store(nullptr, std::memory_order_relaxed);
current_embedded_blob_metadata_size_.store(0, std::memory_order_relaxed);
current_embedded_blob_data_.store(nullptr, std::memory_order_relaxed);
current_embedded_blob_data_size_.store(0, std::memory_order_relaxed);
sticky_embedded_blob_code_ = nullptr;
sticky_embedded_blob_code_size_ = 0;
sticky_embedded_blob_metadata_ = nullptr;
sticky_embedded_blob_metadata_size_ = 0;
sticky_embedded_blob_data_ = nullptr;
sticky_embedded_blob_data_size_ = 0;
}
const uint8_t* Isolate::embedded_blob_code() const {
......@@ -337,11 +333,11 @@ const uint8_t* Isolate::embedded_blob_code() const {
uint32_t Isolate::embedded_blob_code_size() const {
return embedded_blob_code_size_;
}
const uint8_t* Isolate::embedded_blob_metadata() const {
return embedded_blob_metadata_;
const uint8_t* Isolate::embedded_blob_data() const {
return embedded_blob_data_;
}
uint32_t Isolate::embedded_blob_metadata_size() const {
return embedded_blob_metadata_size_;
uint32_t Isolate::embedded_blob_data_size() const {
return embedded_blob_data_size_;
}
// static
......@@ -357,14 +353,14 @@ uint32_t Isolate::CurrentEmbeddedBlobCodeSize() {
}
// static
const uint8_t* Isolate::CurrentEmbeddedBlobMetadata() {
return current_embedded_blob_metadata_.load(
const uint8_t* Isolate::CurrentEmbeddedBlobData() {
return current_embedded_blob_data_.load(
std::memory_order::memory_order_relaxed);
}
// static
uint32_t Isolate::CurrentEmbeddedBlobMetadataSize() {
return current_embedded_blob_metadata_size_.load(
uint32_t Isolate::CurrentEmbeddedBlobDataSize() {
return current_embedded_blob_data_size_.load(
std::memory_order::memory_order_relaxed);
}
......@@ -3292,8 +3288,8 @@ namespace {
void CreateOffHeapTrampolines(Isolate* isolate) {
DCHECK_NOT_NULL(isolate->embedded_blob_code());
DCHECK_NE(0, isolate->embedded_blob_code_size());
DCHECK_NOT_NULL(isolate->embedded_blob_metadata());
DCHECK_NE(0, isolate->embedded_blob_metadata_size());
DCHECK_NOT_NULL(isolate->embedded_blob_data());
DCHECK_NE(0, isolate->embedded_blob_data_size());
HandleScope scope(isolate);
Builtins* builtins = isolate->builtins();
......@@ -3324,15 +3320,15 @@ bool IsolateIsCompatibleWithEmbeddedBlob(Isolate* isolate) {
void Isolate::InitializeDefaultEmbeddedBlob() {
const uint8_t* code = DefaultEmbeddedBlobCode();
uint32_t code_size = DefaultEmbeddedBlobCodeSize();
const uint8_t* metadata = DefaultEmbeddedBlobMetadata();
uint32_t metadata_size = DefaultEmbeddedBlobMetadataSize();
const uint8_t* data = DefaultEmbeddedBlobData();
uint32_t data_size = DefaultEmbeddedBlobDataSize();
#ifdef V8_MULTI_SNAPSHOTS
if (!FLAG_untrusted_code_mitigations) {
code = TrustedEmbeddedBlobCode();
code_size = TrustedEmbeddedBlobCodeSize();
metadata = TrustedEmbeddedBlobMetadata();
metadata_size = TrustedEmbeddedBlobMetadataSize();
data = TrustedEmbeddedBlobData();
data_size = TrustedEmbeddedBlobDataSize();
}
#endif
......@@ -3342,8 +3338,8 @@ void Isolate::InitializeDefaultEmbeddedBlob() {
if (StickyEmbeddedBlobCode() != nullptr) {
code = StickyEmbeddedBlobCode();
code_size = StickyEmbeddedBlobCodeSize();
metadata = StickyEmbeddedBlobMetadata();
metadata_size = StickyEmbeddedBlobMetadataSize();
data = StickyEmbeddedBlobData();
data_size = StickyEmbeddedBlobDataSize();
current_embedded_blob_refs_++;
}
}
......@@ -3351,7 +3347,7 @@ void Isolate::InitializeDefaultEmbeddedBlob() {
if (code == nullptr) {
CHECK_EQ(0, code_size);
} else {
SetEmbeddedBlob(code, code_size, metadata, metadata_size);
SetEmbeddedBlob(code, code_size, data, data_size);
}
}
......@@ -3365,25 +3361,25 @@ void Isolate::CreateAndSetEmbeddedBlob() {
// If a sticky blob has been set, we reuse it.
if (StickyEmbeddedBlobCode() != nullptr) {
CHECK_EQ(embedded_blob_code(), StickyEmbeddedBlobCode());
CHECK_EQ(embedded_blob_metadata(), StickyEmbeddedBlobMetadata());
CHECK_EQ(embedded_blob_data(), StickyEmbeddedBlobData());
CHECK_EQ(CurrentEmbeddedBlobCode(), StickyEmbeddedBlobCode());
CHECK_EQ(CurrentEmbeddedBlobMetadata(), StickyEmbeddedBlobMetadata());
CHECK_EQ(CurrentEmbeddedBlobData(), StickyEmbeddedBlobData());
} else {
// Create and set a new embedded blob.
uint8_t* code;
uint32_t code_size;
uint8_t* metadata;
uint32_t metadata_size;
InstructionStream::CreateOffHeapInstructionStream(
this, &code, &code_size, &metadata, &metadata_size);
uint8_t* data;
uint32_t data_size;
InstructionStream::CreateOffHeapInstructionStream(this, &code, &code_size,
&data, &data_size);
CHECK_EQ(0, current_embedded_blob_refs_);
const uint8_t* const_code = const_cast<const uint8_t*>(code);
const uint8_t* const_metadata = const_cast<const uint8_t*>(metadata);
SetEmbeddedBlob(const_code, code_size, const_metadata, metadata_size);
const uint8_t* const_data = const_cast<const uint8_t*>(data);
SetEmbeddedBlob(const_code, code_size, const_data, data_size);
current_embedded_blob_refs_++;
SetStickyEmbeddedBlob(code, code_size, metadata, metadata_size);
SetStickyEmbeddedBlob(code, code_size, data, data_size);
}
CreateOffHeapTrampolines(this);
......@@ -3394,9 +3390,9 @@ void Isolate::TearDownEmbeddedBlob() {
if (StickyEmbeddedBlobCode() == nullptr) return;
CHECK_EQ(embedded_blob_code(), StickyEmbeddedBlobCode());
CHECK_EQ(embedded_blob_metadata(), StickyEmbeddedBlobMetadata());
CHECK_EQ(embedded_blob_data(), StickyEmbeddedBlobData());
CHECK_EQ(CurrentEmbeddedBlobCode(), StickyEmbeddedBlobCode());
CHECK_EQ(CurrentEmbeddedBlobMetadata(), StickyEmbeddedBlobMetadata());
CHECK_EQ(CurrentEmbeddedBlobData(), StickyEmbeddedBlobData());
base::MutexGuard guard(current_embedded_blob_refcount_mutex_.Pointer());
current_embedded_blob_refs_--;
......@@ -3404,8 +3400,7 @@ void Isolate::TearDownEmbeddedBlob() {
// We own the embedded blob and are the last holder. Free it.
InstructionStream::FreeOffHeapInstructionStream(
const_cast<uint8_t*>(embedded_blob_code()), embedded_blob_code_size(),
const_cast<uint8_t*>(embedded_blob_metadata()),
embedded_blob_metadata_size());
const_cast<uint8_t*>(embedded_blob_data()), embedded_blob_data_size());
ClearEmbeddedBlob();
}
}
......
......@@ -1437,16 +1437,16 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory {
static const uint8_t* CurrentEmbeddedBlobCode();
static uint32_t CurrentEmbeddedBlobCodeSize();
static const uint8_t* CurrentEmbeddedBlobMetadata();
static uint32_t CurrentEmbeddedBlobMetadataSize();
static const uint8_t* CurrentEmbeddedBlobData();
static uint32_t CurrentEmbeddedBlobDataSize();
static bool CurrentEmbeddedBlobIsBinaryEmbedded();
// These always return the same result as static methods above, but don't
// access the global atomic variable (and thus *might be* slightly faster).
const uint8_t* embedded_blob_code() const;
uint32_t embedded_blob_code_size() const;
const uint8_t* embedded_blob_metadata() const;
uint32_t embedded_blob_metadata_size() const;
const uint8_t* embedded_blob_data() const;
uint32_t embedded_blob_data_size() const;
void set_array_buffer_allocator(v8::ArrayBuffer::Allocator* allocator) {
array_buffer_allocator_ = allocator;
......@@ -1920,13 +1920,13 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory {
void TearDownEmbeddedBlob();
void SetEmbeddedBlob(const uint8_t* code, uint32_t code_size,
const uint8_t* metadata, uint32_t metadata_size);
const uint8_t* data, uint32_t data_size);
void ClearEmbeddedBlob();
const uint8_t* embedded_blob_code_ = nullptr;
uint32_t embedded_blob_code_size_ = 0;
const uint8_t* embedded_blob_metadata_ = nullptr;
uint32_t embedded_blob_metadata_size_ = 0;
const uint8_t* embedded_blob_data_ = nullptr;
uint32_t embedded_blob_data_size_ = 0;
v8::ArrayBuffer::Allocator* array_buffer_allocator_ = nullptr;
std::shared_ptr<v8::ArrayBuffer::Allocator> array_buffer_allocator_shared_;
......
......@@ -106,6 +106,28 @@ class Code : public HeapObject {
// raw accessors (e.g. raw_instruction_start) always refer to the on-heap
// Code object, while camel-case accessors (e.g. InstructionStart) may refer
// to an off-heap area in the case of embedded builtins.
//
// Embedded builtins are on-heap Code objects, with an out-of-line body
// section. The on-heap Code object contains an essentially empty body
// section, while accessors, as mentioned above, redirect to the off-heap
// area. Metadata table offsets remain relative to MetadataStart(), i.e. they
// point into the off-heap metadata section. The off-heap layout is described
// in detail in the EmbeddedData class, but at a high level one can assume a
// dedicated, out-of-line, instruction and metadata section for each embedded
// builtin *in addition* to the on-heap Code object:
//
// +--------------------------+ <-- InstructionStart()
// | off-heap instructions |
// | ... |
// +--------------------------+ <-- InstructionEnd()
//
// +--------------------------+ <-- MetadataStart() (MS)
// | off-heap metadata |
// | ... | <-- MS + handler_table_offset()
// | | <-- MS + constant_pool_offset()
// | | <-- MS + code_comments_offset()
// | | <-- MS + unwinding_info_offset()
// +--------------------------+ <-- MetadataEnd()
// TODO(jgruber,v8:11036): Update once no longer true for embedded builtins.
static constexpr bool kOnHeapBodyIsContiguous = true;
......
......@@ -859,7 +859,7 @@ RUNTIME_FUNCTION(Runtime_ProfileCreateSnapshotDataBlob) {
{
i::EmbeddedData d = i::EmbeddedData::FromBlob();
PrintF("Embedded blob is %d bytes\n",
static_cast<int>(d.code_size() + d.metadata_size()));
static_cast<int>(d.code_size() + d.data_size()));
}
FreeCurrentEmbeddedBlob();
......
......@@ -50,9 +50,11 @@ Code InstructionStream::TryLookupCode(Isolate* isolate, Address address) {
}
// static
void InstructionStream::CreateOffHeapInstructionStream(
Isolate* isolate, uint8_t** code, uint32_t* code_size, uint8_t** metadata,
uint32_t* metadata_size) {
void InstructionStream::CreateOffHeapInstructionStream(Isolate* isolate,
uint8_t** code,
uint32_t* code_size,
uint8_t** data,
uint32_t* data_size) {
// Create the embedded blob from scratch using the current Isolate's heap.
EmbeddedData d = EmbeddedData::FromIsolate(isolate);
......@@ -71,14 +73,13 @@ void InstructionStream::CreateOffHeapInstructionStream(
alignment, PageAllocator::kReadWrite));
CHECK_NOT_NULL(allocated_code_bytes);
void* const requested_allocation_metadata_address =
void* const requested_allocation_data_address =
AlignedAddress(isolate->heap()->GetRandomMmapAddr(), alignment);
const uint32_t allocation_metadata_size =
RoundUp(d.metadata_size(), alignment);
uint8_t* allocated_metadata_bytes = static_cast<uint8_t*>(AllocatePages(
page_allocator, requested_allocation_metadata_address,
allocation_metadata_size, alignment, PageAllocator::kReadWrite));
CHECK_NOT_NULL(allocated_metadata_bytes);
const uint32_t allocation_data_size = RoundUp(d.data_size(), alignment);
uint8_t* allocated_data_bytes = static_cast<uint8_t*>(AllocatePages(
page_allocator, requested_allocation_data_address, allocation_data_size,
alignment, PageAllocator::kReadWrite));
CHECK_NOT_NULL(allocated_data_bytes);
// Copy the embedded blob into the newly allocated backing store. Switch
// permissions to read-execute since builtin code is immutable from now on
......@@ -92,14 +93,14 @@ void InstructionStream::CreateOffHeapInstructionStream(
CHECK(SetPermissions(page_allocator, allocated_code_bytes,
allocation_code_size, PageAllocator::kReadExecute));
std::memcpy(allocated_metadata_bytes, d.metadata(), d.metadata_size());
CHECK(SetPermissions(page_allocator, allocated_metadata_bytes,
allocation_metadata_size, PageAllocator::kRead));
std::memcpy(allocated_data_bytes, d.data(), d.data_size());
CHECK(SetPermissions(page_allocator, allocated_data_bytes,
allocation_data_size, PageAllocator::kRead));
*code = allocated_code_bytes;
*code_size = d.code_size();
*metadata = allocated_metadata_bytes;
*metadata_size = d.metadata_size();
*data = allocated_data_bytes;
*data_size = d.data_size();
d.Dispose();
}
......@@ -107,13 +108,13 @@ void InstructionStream::CreateOffHeapInstructionStream(
// static
void InstructionStream::FreeOffHeapInstructionStream(uint8_t* code,
uint32_t code_size,
uint8_t* metadata,
uint32_t metadata_size) {
uint8_t* data,
uint32_t data_size) {
v8::PageAllocator* page_allocator = v8::internal::GetPlatformPageAllocator();
const uint32_t page_size =
static_cast<uint32_t>(page_allocator->AllocatePageSize());
CHECK(FreePages(page_allocator, code, RoundUp(code_size, page_size)));
CHECK(FreePages(page_allocator, metadata, RoundUp(metadata_size, page_size)));
CHECK(FreePages(page_allocator, data, RoundUp(data_size, page_size)));
}
namespace {
......@@ -204,7 +205,7 @@ EmbeddedData EmbeddedData::FromIsolate(Isolate* isolate) {
Builtins* builtins = isolate->builtins();
// Store instruction stream lengths and offsets.
std::vector<struct Metadata> metadata(kTableSize);
std::vector<struct LayoutDescription> layout_descriptions(kTableSize);
bool saw_unsafe_builtin = false;
uint32_t raw_code_size = 0;
......@@ -230,10 +231,10 @@ EmbeddedData EmbeddedData::FromIsolate(Isolate* isolate) {
uint32_t length = instruction_size + metadata_size;
DCHECK_EQ(0, raw_code_size % kCodeAlignment);
metadata[i].instruction_offset = raw_code_size;
metadata[i].instruction_length = instruction_size;
metadata[i].metadata_offset = raw_code_size + instruction_size;
metadata[i].metadata_length = metadata_size;
layout_descriptions[i].instruction_offset = raw_code_size;
layout_descriptions[i].instruction_length = instruction_size;
layout_descriptions[i].metadata_offset = raw_code_size + instruction_size;
layout_descriptions[i].metadata_length = metadata_size;
// Align the start of each instruction stream.
raw_code_size += PadAndAlign(length);
......@@ -247,9 +248,9 @@ EmbeddedData EmbeddedData::FromIsolate(Isolate* isolate) {
const uint32_t blob_code_size = RawCodeOffset() + raw_code_size;
uint8_t* const blob_code = new uint8_t[blob_code_size];
uint8_t* const raw_code_start = blob_code + RawCodeOffset();
const uint32_t blob_metadata_size =
MetadataTableOffset() + MetadataTableSize();
uint8_t* const blob_metadata = new uint8_t[blob_metadata_size];
const uint32_t blob_data_size =
LayoutDescriptionTableOffset() + LayoutDescriptionTableSize();
uint8_t* const blob_data = new uint8_t[blob_data_size];
// Initially zap the entire blob, effectively padding the alignment area
// between two builtins with int3's (on x64/ia32).
......@@ -259,27 +260,28 @@ EmbeddedData EmbeddedData::FromIsolate(Isolate* isolate) {
{
STATIC_ASSERT(IsolateHashSize() == kSizetSize);
const size_t hash = isolate->HashIsolateForEmbeddedBlob();
std::memcpy(blob_metadata + IsolateHashOffset(), &hash, IsolateHashSize());
std::memcpy(blob_data + IsolateHashOffset(), &hash, IsolateHashSize());
}
// Write the metadata tables.
DCHECK_EQ(MetadataTableSize(), sizeof(metadata[0]) * metadata.size());
std::memcpy(blob_metadata + MetadataTableOffset(), metadata.data(),
MetadataTableSize());
// Write the layout_descriptions tables.
DCHECK_EQ(LayoutDescriptionTableSize(),
sizeof(layout_descriptions[0]) * layout_descriptions.size());
std::memcpy(blob_data + LayoutDescriptionTableOffset(),
layout_descriptions.data(), LayoutDescriptionTableSize());
// Write the raw data section.
STATIC_ASSERT(Builtins::kAllBuiltinsAreIsolateIndependent);
for (int i = 0; i < Builtins::builtin_count; i++) {
STATIC_ASSERT(Code::kBodyIsContiguous);
Code code = builtins->builtin(i);
uint32_t offset = metadata[i].instruction_offset;
uint32_t offset = layout_descriptions[i].instruction_offset;
uint8_t* dst = raw_code_start + offset;
DCHECK_LE(RawCodeOffset() + offset + code.raw_body_size(), blob_code_size);
std::memcpy(dst, reinterpret_cast<uint8_t*>(code.raw_body_start()),
code.raw_body_size());
}
EmbeddedData d(blob_code, blob_code_size, blob_metadata, blob_metadata_size);
EmbeddedData d(blob_code, blob_code_size, blob_data, blob_data_size);
// Fix up call targets that point to other embedded builtins.
FinalizeEmbeddedCodeTargets(isolate, &d);
......@@ -288,7 +290,7 @@ EmbeddedData EmbeddedData::FromIsolate(Isolate* isolate) {
{
STATIC_ASSERT(EmbeddedBlobHashSize() == kSizetSize);
const size_t hash = d.CreateEmbeddedBlobHash();
std::memcpy(blob_metadata + EmbeddedBlobHashOffset(), &hash,
std::memcpy(blob_data + EmbeddedBlobHashOffset(), &hash,
EmbeddedBlobHashSize());
DCHECK_EQ(hash, d.CreateEmbeddedBlobHash());
......@@ -302,31 +304,31 @@ EmbeddedData EmbeddedData::FromIsolate(Isolate* isolate) {
Address EmbeddedData::InstructionStartOfBuiltin(int i) const {
DCHECK(Builtins::IsBuiltinId(i));
const struct Metadata* metadata = Metadata();
const uint8_t* result = RawCode() + metadata[i].instruction_offset;
const struct LayoutDescription* descs = LayoutDescription();
const uint8_t* result = RawCode() + descs[i].instruction_offset;
DCHECK_LT(result, code_ + code_size_);
return reinterpret_cast<Address>(result);
}
uint32_t EmbeddedData::InstructionSizeOfBuiltin(int i) const {
DCHECK(Builtins::IsBuiltinId(i));
const struct Metadata* metadata = Metadata();
return metadata[i].instruction_length;
const struct LayoutDescription* descs = LayoutDescription();
return descs[i].instruction_length;
}
Address EmbeddedData::MetadataStartOfBuiltin(int i) const {
DCHECK(Builtins::IsBuiltinId(i));
STATIC_ASSERT(Code::kOffHeapBodyIsContiguous);
const struct Metadata* metadata = Metadata();
const uint8_t* result = RawCode() + metadata[i].metadata_offset;
const struct LayoutDescription* descs = LayoutDescription();
const uint8_t* result = RawCode() + descs[i].metadata_offset;
DCHECK_LT(result, code_ + code_size_);
return reinterpret_cast<Address>(result);
}
uint32_t EmbeddedData::MetadataSizeOfBuiltin(int i) const {
DCHECK(Builtins::IsBuiltinId(i));
const struct Metadata* metadata = Metadata();
return metadata[i].metadata_length;
const struct LayoutDescription* descs = LayoutDescription();
return descs[i].metadata_length;
}
Address EmbeddedData::InstructionStartOfBytecodeHandlers() const {
......@@ -346,8 +348,8 @@ size_t EmbeddedData::CreateEmbeddedBlobHash() const {
STATIC_ASSERT(EmbeddedBlobHashOffset() == 0);
STATIC_ASSERT(EmbeddedBlobHashSize() == kSizetSize);
// Hash the entire blob except the hash field itself.
Vector<const byte> payload1(metadata_ + EmbeddedBlobHashSize(),
metadata_size_ - EmbeddedBlobHashSize());
Vector<const byte> payload1(data_ + EmbeddedBlobHashSize(),
data_size_ - EmbeddedBlobHashSize());
Vector<const byte> payload2(code_, code_size_);
return Checksum(payload1, payload2);
}
......@@ -356,35 +358,26 @@ void EmbeddedData::PrintStatistics() const {
DCHECK(FLAG_serialization_statistics);
constexpr int kCount = Builtins::builtin_count;
int embedded_count = 0;
int instruction_size = 0;
int sizes[kCount];
STATIC_ASSERT(Builtins::kAllBuiltinsAreIsolateIndependent);
for (int i = 0; i < kCount; i++) {
const int size = InstructionSizeOfBuiltin(i);
instruction_size += size;
sizes[embedded_count] = size;
embedded_count++;
sizes[i] = InstructionSizeOfBuiltin(i);
}
// Sort for percentiles.
std::sort(&sizes[0], &sizes[embedded_count]);
std::sort(&sizes[0], &sizes[kCount]);
const int k50th = embedded_count * 0.5;
const int k75th = embedded_count * 0.75;
const int k90th = embedded_count * 0.90;
const int k99th = embedded_count * 0.99;
const int k50th = kCount * 0.5;
const int k75th = kCount * 0.75;
const int k90th = kCount * 0.90;
const int k99th = kCount * 0.99;
PrintF("EmbeddedData:\n");
PrintF(" Total size: %d\n",
static_cast<int>(code_size() + metadata_size()));
PrintF(" Metadata size: %d\n",
static_cast<int>(metadata_size()));
PrintF(" Instruction size: %d\n", instruction_size);
PrintF(" Padding: %d\n",
static_cast<int>(code_size() - instruction_size));
PrintF(" Embedded builtin count: %d\n", embedded_count);
static_cast<int>(code_size() + data_size()));
PrintF(" Data size: %d\n",
static_cast<int>(data_size()));
PrintF(" Code size: %d\n", static_cast<int>(code_size()));
PrintF(" Instruction size (50th percentile): %d\n", sizes[k50th]);
PrintF(" Instruction size (75th percentile): %d\n", sizes[k75th]);
PrintF(" Instruction size (90th percentile): %d\n", sizes[k90th]);
......
......@@ -32,11 +32,10 @@ class InstructionStream final : public AllStatic {
// mksnapshot. Otherwise, off-heap code is embedded directly into the binary.
static void CreateOffHeapInstructionStream(Isolate* isolate, uint8_t** code,
uint32_t* code_size,
uint8_t** metadata,
uint32_t* metadata_size);
uint8_t** data,
uint32_t* data_size);
static void FreeOffHeapInstructionStream(uint8_t* code, uint32_t code_size,
uint8_t* metadata,
uint32_t metadata_size);
uint8_t* data, uint32_t data_size);
};
class EmbeddedData final {
......@@ -46,27 +45,26 @@ class EmbeddedData final {
static EmbeddedData FromBlob() {
return EmbeddedData(Isolate::CurrentEmbeddedBlobCode(),
Isolate::CurrentEmbeddedBlobCodeSize(),
Isolate::CurrentEmbeddedBlobMetadata(),
Isolate::CurrentEmbeddedBlobMetadataSize());
Isolate::CurrentEmbeddedBlobData(),
Isolate::CurrentEmbeddedBlobDataSize());
}
static EmbeddedData FromBlob(Isolate* isolate) {
return EmbeddedData(isolate->embedded_blob_code(),
isolate->embedded_blob_code_size(),
isolate->embedded_blob_metadata(),
isolate->embedded_blob_metadata_size());
return EmbeddedData(
isolate->embedded_blob_code(), isolate->embedded_blob_code_size(),
isolate->embedded_blob_data(), isolate->embedded_blob_data_size());
}
const uint8_t* code() const { return code_; }
uint32_t code_size() const { return code_size_; }
const uint8_t* metadata() const { return metadata_; }
uint32_t metadata_size() const { return metadata_size_; }
const uint8_t* data() const { return data_; }
uint32_t data_size() const { return data_size_; }
void Dispose() {
delete[] code_;
code_ = nullptr;
delete[] metadata_;
metadata_ = nullptr;
delete[] data_;
data_ = nullptr;
}
Address InstructionStartOfBuiltin(int i) const;
......@@ -95,47 +93,45 @@ class EmbeddedData final {
size_t CreateEmbeddedBlobHash() const;
size_t EmbeddedBlobHash() const {
return *reinterpret_cast<const size_t*>(metadata_ +
EmbeddedBlobHashOffset());
return *reinterpret_cast<const size_t*>(data_ + EmbeddedBlobHashOffset());
}
size_t IsolateHash() const {
return *reinterpret_cast<const size_t*>(metadata_ + IsolateHashOffset());
return *reinterpret_cast<const size_t*>(data_ + IsolateHashOffset());
}
// Blob layout information for a single instruction stream. Corresponds
// roughly to Code object layout (see the instruction and metadata area).
// TODO(jgruber): With the addition of metadata sections in Code objects,
// naming here has become confusing. Metadata refers to both this struct
// and the Code section, and the embedded instruction area currently
// contains both Code's instruction and metadata areas. Fix it.
struct Metadata {
struct LayoutDescription {
// The offset and (unpadded) length of this builtin's instruction area
// from the start of the embedded code section.
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.
// TODO(jgruber,v8:11036): Move this to the embedded metadata area.
uint32_t metadata_offset;
uint32_t metadata_length;
};
STATIC_ASSERT(offsetof(Metadata, instruction_offset) == 0 * kUInt32Size);
STATIC_ASSERT(offsetof(Metadata, instruction_length) == 1 * kUInt32Size);
STATIC_ASSERT(offsetof(Metadata, metadata_offset) == 2 * kUInt32Size);
STATIC_ASSERT(offsetof(Metadata, metadata_length) == 3 * kUInt32Size);
STATIC_ASSERT(sizeof(Metadata) == 4 * kUInt32Size);
STATIC_ASSERT(offsetof(LayoutDescription, instruction_offset) ==
0 * kUInt32Size);
STATIC_ASSERT(offsetof(LayoutDescription, instruction_length) ==
1 * kUInt32Size);
STATIC_ASSERT(offsetof(LayoutDescription, metadata_offset) ==
2 * kUInt32Size);
STATIC_ASSERT(offsetof(LayoutDescription, metadata_length) ==
3 * kUInt32Size);
STATIC_ASSERT(sizeof(LayoutDescription) == 4 * kUInt32Size);
// The layout of the blob is as follows:
//
// metadata:
// data:
// [0] hash of the remaining blob
// [1] hash of embedded-blob-relevant heap objects
// [2] metadata of instruction stream 0
// ... metadata
// [2] layout description of instruction stream 0
// ... layout descriptions
//
// code:
// [0] instruction streams 0
// [0] instruction stream 0
// ... instruction streams
static constexpr uint32_t kTableSize = Builtins::builtin_count;
......@@ -145,30 +141,27 @@ class EmbeddedData final {
return EmbeddedBlobHashOffset() + EmbeddedBlobHashSize();
}
static constexpr uint32_t IsolateHashSize() { return kSizetSize; }
static constexpr uint32_t MetadataTableOffset() {
static constexpr uint32_t LayoutDescriptionTableOffset() {
return IsolateHashOffset() + IsolateHashSize();
}
static constexpr uint32_t MetadataTableSize() {
return sizeof(struct Metadata) * kTableSize;
static constexpr uint32_t LayoutDescriptionTableSize() {
return sizeof(struct LayoutDescription) * kTableSize;
}
static constexpr uint32_t RawCodeOffset() { return 0; }
private:
EmbeddedData(const uint8_t* code, uint32_t code_size, const uint8_t* metadata,
uint32_t metadata_size)
: code_(code),
code_size_(code_size),
metadata_(metadata),
metadata_size_(metadata_size) {
EmbeddedData(const uint8_t* code, uint32_t code_size, const uint8_t* data,
uint32_t data_size)
: code_(code), code_size_(code_size), data_(data), data_size_(data_size) {
DCHECK_NOT_NULL(code);
DCHECK_LT(0, code_size);
DCHECK_NOT_NULL(metadata);
DCHECK_LT(0, metadata_size);
DCHECK_NOT_NULL(data);
DCHECK_LT(0, data_size);
}
const Metadata* Metadata() const {
return reinterpret_cast<const struct Metadata*>(metadata_ +
MetadataTableOffset());
const LayoutDescription* LayoutDescription() const {
return reinterpret_cast<const struct LayoutDescription*>(
data_ + LayoutDescriptionTableOffset());
}
const uint8_t* RawCode() const { return code_ + RawCodeOffset(); }
......@@ -185,9 +178,11 @@ class EmbeddedData final {
const uint8_t* code_;
uint32_t code_size_;
// This is metadata for the code.
const uint8_t* metadata_;
uint32_t metadata_size_;
// The data section contains both descriptions of the code section (hashes,
// offsets, sizes) and metadata describing Code objects (see
// Code::MetadataStart()).
const uint8_t* data_;
uint32_t data_size_;
};
} // namespace internal
......
......@@ -10,22 +10,22 @@
extern "C" const uint8_t* v8_Default_embedded_blob_code_;
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_;
extern "C" const uint8_t* v8_Default_embedded_blob_data_;
extern "C" uint32_t v8_Default_embedded_blob_data_size_;
const uint8_t* v8_Default_embedded_blob_code_ = nullptr;
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;
const uint8_t* v8_Default_embedded_blob_data_ = nullptr;
uint32_t v8_Default_embedded_blob_data_size_ = 0;
#ifdef V8_MULTI_SNAPSHOTS
extern "C" const uint8_t* v8_Trusted_embedded_blob_code_;
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_;
extern "C" const uint8_t* v8_Trusted_embedded_blob_data_;
extern "C" uint32_t v8_Trusted_embedded_blob_data_size_;
const uint8_t* v8_Trusted_embedded_blob_code_ = nullptr;
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;
const uint8_t* v8_Trusted_embedded_blob_data_ = nullptr;
uint32_t v8_Trusted_embedded_blob_data_size_ = 0;
#endif
......@@ -177,15 +177,14 @@ void EmbeddedFileWriter::WriteFileEpilogue(PlatformEmbeddedFileWriterBase* w,
EmbeddedBlobCodeDataSymbol().c_str());
w->Newline();
i::EmbeddedVector<char, kTemporaryStringLength>
embedded_blob_metadata_symbol;
i::SNPrintF(embedded_blob_metadata_symbol, "v8_%s_embedded_blob_metadata_",
i::EmbeddedVector<char, kTemporaryStringLength> embedded_blob_data_symbol;
i::SNPrintF(embedded_blob_data_symbol, "v8_%s_embedded_blob_data_",
embedded_variant_);
w->Comment("Pointer to the beginning of the embedded blob metadata.");
w->Comment("Pointer to the beginning of the embedded blob data section.");
w->AlignToDataAlignment();
w->DeclarePointerToSymbol(embedded_blob_metadata_symbol.begin(),
EmbeddedBlobMetadataDataSymbol().c_str());
w->DeclarePointerToSymbol(embedded_blob_data_symbol.begin(),
EmbeddedBlobDataDataSymbol().c_str());
w->Newline();
}
......@@ -202,13 +201,12 @@ void EmbeddedFileWriter::WriteFileEpilogue(PlatformEmbeddedFileWriterBase* w,
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_);
embedded_blob_data_size_symbol;
i::SNPrintF(embedded_blob_data_size_symbol,
"v8_%s_embedded_blob_data_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->Comment("The size of the embedded blob data section in bytes.");
w->DeclareUint32(embedded_blob_data_size_symbol.begin(), blob->data_size());
w->Newline();
}
......
......@@ -109,7 +109,7 @@ class EmbeddedFileWriter : public EmbeddedFileWriterInterface {
WriteFilePrologue(writer.get());
WriteExternalFilenames(writer.get());
WriteMetadataSection(writer.get(), blob);
WriteDataSection(writer.get(), blob);
WriteInstructionStreams(writer.get(), blob);
WriteFileEpilogue(writer.get(), blob);
......@@ -161,23 +161,22 @@ class EmbeddedFileWriter : public EmbeddedFileWriterInterface {
return std::string{embedded_blob_code_data_symbol.begin()};
}
std::string EmbeddedBlobMetadataDataSymbol() const {
std::string EmbeddedBlobDataDataSymbol() 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()};
embedded_blob_data_data_symbol;
i::SNPrintF(embedded_blob_data_data_symbol,
"v8_%s_embedded_blob_data_data_", embedded_variant_);
return std::string{embedded_blob_data_data_symbol.begin()};
}
void WriteMetadataSection(PlatformEmbeddedFileWriterBase* w,
const i::EmbeddedData* blob) const {
w->Comment("The embedded blob metadata starts here.");
void WriteDataSection(PlatformEmbeddedFileWriterBase* w,
const i::EmbeddedData* blob) const {
w->Comment("The embedded blob data section starts here.");
w->SectionRoData();
w->AlignToDataAlignment();
w->DeclareLabel(EmbeddedBlobMetadataDataSymbol().c_str());
w->DeclareLabel(EmbeddedBlobDataDataSymbol().c_str());
WriteBinaryContentsAsInlineAssembly(w, blob->metadata(),
blob->metadata_size());
WriteBinaryContentsAsInlineAssembly(w, blob->data(), blob->data_size());
}
void WriteBuiltin(PlatformEmbeddedFileWriterBase* w,
......
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