[snapshot] Dedicated files for snapshot data

The intent of this work is to create a clean interface header file for
the snapshot component. As a first step, move SerializedData and
SnapshotData into their own dedicated files.

Bug: v8:10416
Change-Id: I95af08508555a2ec3c2364094b81a76e3e6bb38a
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2144117
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: Dan Elphick <delphick@chromium.org>
Cr-Commit-Position: refs/heads/master@{#67269}
This commit is contained in:
Jakob Gruber 2020-04-15 09:22:02 +02:00 committed by Commit Bot
parent fe60913945
commit b39ee29d46
15 changed files with 225 additions and 176 deletions

View File

@ -2960,6 +2960,8 @@ v8_source_set("v8_base_without_compiler") {
"src/snapshot/snapshot-common.cc",
"src/snapshot/snapshot-compression.cc",
"src/snapshot/snapshot-compression.h",
"src/snapshot/snapshot-data.cc",
"src/snapshot/snapshot-data.h",
"src/snapshot/snapshot-source-sink.cc",
"src/snapshot/snapshot-source-sink.h",
"src/snapshot/snapshot.h",

View File

@ -10,7 +10,8 @@
#include "src/deoptimizer/deoptimizer.h"
#include "src/heap/heap-write-barrier-inl.h"
#include "src/objects/code-inl.h"
#include "src/snapshot/snapshot.h"
#include "src/snapshot/embedded/embedded-data.h"
#include "src/snapshot/serializer-common.h" // For ExternalReferenceEncoder.
namespace v8 {
namespace internal {

View File

@ -21,7 +21,7 @@
#include "src/objects/slots.h"
#include "src/objects/smi.h"
#include "src/objects/visitors.h"
#include "src/snapshot/snapshot.h"
#include "src/snapshot/embedded/embedded-data.h"
#include "src/strings/string-stream.h"
#include "src/wasm/wasm-code-manager.h"
#include "src/wasm/wasm-engine.h"

View File

@ -25,6 +25,7 @@
#endif // ENABLE_VTUNE_TRACEMARK
#include "src/heap/heap-inl.h"
#include "src/logging/counters.h"
#include "src/logging/log.h"
#include "src/numbers/math-random.h"
#include "src/objects/api-callbacks.h"
#include "src/objects/arguments.h"

View File

@ -27,6 +27,7 @@
#include "src/objects/js-promise-inl.h"
#include "src/runtime/runtime-utils.h"
#include "src/runtime/runtime.h"
#include "src/snapshot/embedded/embedded-data.h"
#include "src/snapshot/snapshot.h"
#include "src/wasm/wasm-objects-inl.h"

View File

@ -9,6 +9,7 @@
#include "src/heap/heap.h"
#include "src/objects/heap-object.h"
#include "src/snapshot/serializer-common.h"
#include "src/snapshot/snapshot-data.h"
namespace v8 {
namespace internal {

View File

@ -22,6 +22,7 @@
#include "src/objects/smi.h"
#include "src/objects/string.h"
#include "src/roots/roots.h"
#include "src/snapshot/embedded/embedded-data.h"
#include "src/snapshot/snapshot.h"
#include "src/tracing/trace-event.h"
#include "src/tracing/traced-value.h"

View File

@ -6,6 +6,7 @@
#define V8_SNAPSHOT_SERIALIZER_ALLOCATOR_H_
#include "src/snapshot/serializer-common.h"
#include "src/snapshot/snapshot-data.h"
namespace v8 {
namespace internal {

View File

@ -96,16 +96,6 @@ const char* ExternalReferenceEncoder::NameOfAddress(Isolate* isolate,
return isolate->external_reference_table()->name(value.index());
}
void SerializedData::AllocateData(uint32_t size) {
DCHECK(!owns_data_);
data_ = NewArray<byte>(size);
size_ = size;
owns_data_ = true;
}
// static
constexpr uint32_t SerializedData::kMagicNumber;
// The partial snapshot cache is terminated by undefined. We visit the
// partial snapshot...
// - during deserialization to populate it.

View File

@ -293,70 +293,6 @@ class SerializerDeserializer : public RootVisitor {
HotObjectsList hot_objects_;
};
class SerializedData {
public:
class Reservation {
public:
Reservation() : reservation_(0) {}
explicit Reservation(uint32_t size)
: reservation_(ChunkSizeBits::encode(size)) {}
uint32_t chunk_size() const { return ChunkSizeBits::decode(reservation_); }
bool is_last() const { return IsLastChunkBits::decode(reservation_); }
void mark_as_last() { reservation_ |= IsLastChunkBits::encode(true); }
private:
uint32_t reservation_;
};
SerializedData(byte* data, int size)
: data_(data), size_(size), owns_data_(false) {}
SerializedData() : data_(nullptr), size_(0), owns_data_(false) {}
SerializedData(SerializedData&& other) V8_NOEXCEPT
: data_(other.data_),
size_(other.size_),
owns_data_(other.owns_data_) {
// Ensure |other| will not attempt to destroy our data in destructor.
other.owns_data_ = false;
}
virtual ~SerializedData() {
if (owns_data_) DeleteArray<byte>(data_);
}
uint32_t GetMagicNumber() const { return GetHeaderValue(kMagicNumberOffset); }
using ChunkSizeBits = base::BitField<uint32_t, 0, 31>;
using IsLastChunkBits = base::BitField<bool, 31, 1>;
static constexpr uint32_t kMagicNumberOffset = 0;
static constexpr uint32_t kMagicNumber =
0xC0DE0000 ^ ExternalReferenceTable::kSize;
protected:
void SetHeaderValue(uint32_t offset, uint32_t value) {
base::WriteLittleEndianValue(reinterpret_cast<Address>(data_) + offset,
value);
}
uint32_t GetHeaderValue(uint32_t offset) const {
return base::ReadLittleEndianValue<uint32_t>(
reinterpret_cast<Address>(data_) + offset);
}
void AllocateData(uint32_t size);
void SetMagicNumber() { SetHeaderValue(kMagicNumberOffset, kMagicNumber); }
byte* data_;
uint32_t size_;
bool owns_data_;
private:
DISALLOW_COPY_AND_ASSIGN(SerializedData);
};
V8_EXPORT_PRIVATE uint32_t Checksum(Vector<const byte> payload);
} // namespace internal

View File

@ -339,58 +339,6 @@ void Snapshot::CheckVersion(const v8::StartupData* data) {
}
}
SnapshotData::SnapshotData(const Serializer* serializer) {
DisallowHeapAllocation no_gc;
std::vector<Reservation> reservations = serializer->EncodeReservations();
const std::vector<byte>* payload = serializer->Payload();
// Calculate sizes.
uint32_t reservation_size =
static_cast<uint32_t>(reservations.size()) * kUInt32Size;
uint32_t payload_offset = kHeaderSize + reservation_size;
uint32_t padded_payload_offset = POINTER_SIZE_ALIGN(payload_offset);
uint32_t size =
padded_payload_offset + static_cast<uint32_t>(payload->size());
// Allocate backing store and create result data.
AllocateData(size);
// Zero out pre-payload data. Part of that is only used for padding.
memset(data_, 0, padded_payload_offset);
// Set header values.
SetMagicNumber();
SetHeaderValue(kNumReservationsOffset, static_cast<int>(reservations.size()));
SetHeaderValue(kPayloadLengthOffset, static_cast<int>(payload->size()));
// Copy reservation chunk sizes.
CopyBytes(data_ + kHeaderSize, reinterpret_cast<byte*>(reservations.data()),
reservation_size);
// Copy serialized data.
CopyBytes(data_ + padded_payload_offset, payload->data(),
static_cast<size_t>(payload->size()));
}
std::vector<SerializedData::Reservation> SnapshotData::Reservations() const {
uint32_t size = GetHeaderValue(kNumReservationsOffset);
std::vector<SerializedData::Reservation> reservations(size);
memcpy(reservations.data(), data_ + kHeaderSize,
size * sizeof(SerializedData::Reservation));
return reservations;
}
Vector<const byte> SnapshotData::Payload() const {
uint32_t reservations_size =
GetHeaderValue(kNumReservationsOffset) * kUInt32Size;
uint32_t padded_payload_offset =
POINTER_SIZE_ALIGN(kHeaderSize + reservations_size);
const byte* payload = data_ + padded_payload_offset;
uint32_t length = GetHeaderValue(kPayloadLengthOffset);
DCHECK_EQ(data_ + size_, payload + length);
return Vector<const byte>(payload, length);
}
namespace {
bool RunExtraCode(v8::Isolate* isolate, v8::Local<v8::Context> context,

View File

@ -0,0 +1,80 @@
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/snapshot/snapshot-data.h"
#include "src/common/assert-scope.h"
#include "src/snapshot/serializer.h"
#ifdef V8_SNAPSHOT_COMPRESSION
#include "src/snapshot/snapshot-compression.h"
#endif
namespace v8 {
namespace internal {
void SerializedData::AllocateData(uint32_t size) {
DCHECK(!owns_data_);
data_ = NewArray<byte>(size);
size_ = size;
owns_data_ = true;
}
// static
constexpr uint32_t SerializedData::kMagicNumber;
SnapshotData::SnapshotData(const Serializer* serializer) {
DisallowHeapAllocation no_gc;
std::vector<Reservation> reservations = serializer->EncodeReservations();
const std::vector<byte>* payload = serializer->Payload();
// Calculate sizes.
uint32_t reservation_size =
static_cast<uint32_t>(reservations.size()) * kUInt32Size;
uint32_t payload_offset = kHeaderSize + reservation_size;
uint32_t padded_payload_offset = POINTER_SIZE_ALIGN(payload_offset);
uint32_t size =
padded_payload_offset + static_cast<uint32_t>(payload->size());
// Allocate backing store and create result data.
AllocateData(size);
// Zero out pre-payload data. Part of that is only used for padding.
memset(data_, 0, padded_payload_offset);
// Set header values.
SetMagicNumber();
SetHeaderValue(kNumReservationsOffset, static_cast<int>(reservations.size()));
SetHeaderValue(kPayloadLengthOffset, static_cast<int>(payload->size()));
// Copy reservation chunk sizes.
CopyBytes(data_ + kHeaderSize, reinterpret_cast<byte*>(reservations.data()),
reservation_size);
// Copy serialized data.
CopyBytes(data_ + padded_payload_offset, payload->data(),
static_cast<size_t>(payload->size()));
}
std::vector<SerializedData::Reservation> SnapshotData::Reservations() const {
uint32_t size = GetHeaderValue(kNumReservationsOffset);
std::vector<SerializedData::Reservation> reservations(size);
memcpy(reservations.data(), data_ + kHeaderSize,
size * sizeof(SerializedData::Reservation));
return reservations;
}
Vector<const byte> SnapshotData::Payload() const {
uint32_t reservations_size =
GetHeaderValue(kNumReservationsOffset) * kUInt32Size;
uint32_t padded_payload_offset =
POINTER_SIZE_ALIGN(kHeaderSize + reservations_size);
const byte* payload = data_ + padded_payload_offset;
uint32_t length = GetHeaderValue(kPayloadLengthOffset);
DCHECK_EQ(data_ + size_, payload + length);
return Vector<const byte>(payload, length);
}
} // namespace internal
} // namespace v8

View File

@ -0,0 +1,129 @@
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_SNAPSHOT_SNAPSHOT_DATA_H_
#define V8_SNAPSHOT_SNAPSHOT_DATA_H_
#include "src/base/bit-field.h"
#include "src/base/memory.h"
#include "src/codegen/external-reference-table.h"
#include "src/utils/memcopy.h"
#include "src/utils/vector.h"
namespace v8 {
namespace internal {
// Forward declarations.
class Isolate;
class Serializer;
class SerializedData {
public:
class Reservation {
public:
Reservation() : reservation_(0) {}
explicit Reservation(uint32_t size)
: reservation_(ChunkSizeBits::encode(size)) {}
uint32_t chunk_size() const { return ChunkSizeBits::decode(reservation_); }
bool is_last() const { return IsLastChunkBits::decode(reservation_); }
void mark_as_last() { reservation_ |= IsLastChunkBits::encode(true); }
private:
uint32_t reservation_;
};
SerializedData(byte* data, int size)
: data_(data), size_(size), owns_data_(false) {}
SerializedData() : data_(nullptr), size_(0), owns_data_(false) {}
SerializedData(SerializedData&& other) V8_NOEXCEPT
: data_(other.data_),
size_(other.size_),
owns_data_(other.owns_data_) {
// Ensure |other| will not attempt to destroy our data in destructor.
other.owns_data_ = false;
}
virtual ~SerializedData() {
if (owns_data_) DeleteArray<byte>(data_);
}
uint32_t GetMagicNumber() const { return GetHeaderValue(kMagicNumberOffset); }
using ChunkSizeBits = base::BitField<uint32_t, 0, 31>;
using IsLastChunkBits = base::BitField<bool, 31, 1>;
static constexpr uint32_t kMagicNumberOffset = 0;
static constexpr uint32_t kMagicNumber =
0xC0DE0000 ^ ExternalReferenceTable::kSize;
protected:
void SetHeaderValue(uint32_t offset, uint32_t value) {
base::WriteLittleEndianValue(reinterpret_cast<Address>(data_) + offset,
value);
}
uint32_t GetHeaderValue(uint32_t offset) const {
return base::ReadLittleEndianValue<uint32_t>(
reinterpret_cast<Address>(data_) + offset);
}
void AllocateData(uint32_t size);
void SetMagicNumber() { SetHeaderValue(kMagicNumberOffset, kMagicNumber); }
byte* data_;
uint32_t size_;
bool owns_data_;
private:
DISALLOW_COPY_AND_ASSIGN(SerializedData);
};
// Wrapper around reservation sizes and the serialization payload.
class V8_EXPORT_PRIVATE SnapshotData : public SerializedData {
public:
// Used when producing.
explicit SnapshotData(const Serializer* serializer);
// Used when consuming.
explicit SnapshotData(const Vector<const byte> snapshot)
: SerializedData(const_cast<byte*>(snapshot.begin()), snapshot.length()) {
}
std::vector<Reservation> Reservations() const;
virtual Vector<const byte> Payload() const;
Vector<const byte> RawData() const {
return Vector<const byte>(data_, size_);
}
protected:
// Empty constructor used by SnapshotCompression so it can manually allocate
// memory.
SnapshotData() : SerializedData() {}
friend class SnapshotCompression;
// Resize used by SnapshotCompression so it can shrink the compressed
// SnapshotData.
void Resize(uint32_t size) { size_ = size; }
// The data header consists of uint32_t-sized entries:
// [0] magic number and (internal) external reference count
// [1] number of reservation size entries
// [2] payload length
// ... reservations
// ... serialized payload
static const uint32_t kNumReservationsOffset =
kMagicNumberOffset + kUInt32Size;
static const uint32_t kPayloadLengthOffset =
kNumReservationsOffset + kUInt32Size;
static const uint32_t kHeaderSize = kPayloadLengthOffset + kUInt32Size;
};
} // namespace internal
} // namespace v8
#endif // V8_SNAPSHOT_SNAPSHOT_DATA_H_

View File

@ -5,60 +5,17 @@
#ifndef V8_SNAPSHOT_SNAPSHOT_H_
#define V8_SNAPSHOT_SNAPSHOT_H_
#include "src/snapshot/partial-serializer.h"
#include "src/snapshot/startup-serializer.h"
#include "include/v8.h"
#include "src/utils/utils.h"
#include "src/base/memory.h"
#include "src/utils/vector.h"
namespace v8 {
namespace internal {
// Forward declarations.
class Isolate;
class PartialSerializer;
class SnapshotCompression;
class StartupSerializer;
// Wrapper around reservation sizes and the serialization payload.
class V8_EXPORT_PRIVATE SnapshotData : public SerializedData {
public:
// Used when producing.
explicit SnapshotData(const Serializer* serializer);
// Used when consuming.
explicit SnapshotData(const Vector<const byte> snapshot)
: SerializedData(const_cast<byte*>(snapshot.begin()), snapshot.length()) {
}
std::vector<Reservation> Reservations() const;
virtual Vector<const byte> Payload() const;
Vector<const byte> RawData() const {
return Vector<const byte>(data_, size_);
}
protected:
// Empty constructor used by SnapshotCompression so it can manually allocate
// memory.
SnapshotData() : SerializedData() {}
friend class SnapshotCompression;
// Resize used by SnapshotCompression so it can shrink the compressed
// SnapshotData.
void Resize(uint32_t size) { size_ = size; }
// The data header consists of uint32_t-sized entries:
// [0] magic number and (internal) external reference count
// [1] number of reservation size entries
// [2] payload length
// ... reservations
// ... serialized payload
static const uint32_t kNumReservationsOffset =
kMagicNumberOffset + kUInt32Size;
static const uint32_t kPayloadLengthOffset =
kNumReservationsOffset + kUInt32Size;
static const uint32_t kHeaderSize = kPayloadLengthOffset + kUInt32Size;
};
class SnapshotData;
class JSGlobalProxy;
class Snapshot : public AllStatic {
public:

View File

@ -8,6 +8,7 @@
#include "src/codegen/assembler-inl.h"
#include "src/execution/v8threads.h"
#include "src/heap/heap-inl.h"
#include "src/logging/log.h"
#include "src/snapshot/snapshot.h"
namespace v8 {