Commit dc7b2b2b authored by Yang Guo's avatar Yang Guo Committed by Commit Bot

Reland "[snapshot] include version string in the startup snapshot."

This is a reland of 629406d1
Original change's description:
> [snapshot] include version string in the startup snapshot.
> 
> This is to easier diagnose build issues involving the snapshot.
> Sample error message for mismatching snapshot:
> 
> #
> # Fatal error in ../../src/snapshot/snapshot-common.cc, line 286
> # Version mismatch between V8 binary and snapshot.
> #   V8 binary version: 6.3.1 (candidate)
> #    Snapshot version: 6.3.0 (candidate)
> # The snapshot consists of 2820444 bytes and contains 1 contexts.
> #
> 
> 
> R=machenbach@chromium.org
> 
> Bug: chromium:764327
> Change-Id: Icdc7aeac77819b113985b424feda814a072d5406
> Reviewed-on: https://chromium-review.googlesource.com/684295
> Reviewed-by: Michael Achenbach <machenbach@chromium.org>
> Commit-Queue: Yang Guo <yangguo@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#48161}

Bug: chromium:764327
Change-Id: I3721689824e0a6909eede86d0829dc258ae40c4d
Reviewed-on: https://chromium-review.googlesource.com/684494Reviewed-by: 's avatarMichael Achenbach <machenbach@chromium.org>
Commit-Queue: Yang Guo <yangguo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48164}
parent 8f2977a3
...@@ -102,6 +102,7 @@ class SerializedCodeData : public SerializedData { ...@@ -102,6 +102,7 @@ class SerializedCodeData : public SerializedData {
// ... reservations // ... reservations
// ... code stub keys // ... code stub keys
// ... serialized payload // ... serialized payload
static const uint32_t kVersionHashOffset = kMagicNumberOffset + kUInt32Size;
static const uint32_t kSourceHashOffset = kVersionHashOffset + kUInt32Size; static const uint32_t kSourceHashOffset = kVersionHashOffset + kUInt32Size;
static const uint32_t kCpuFeaturesOffset = kSourceHashOffset + kUInt32Size; static const uint32_t kCpuFeaturesOffset = kSourceHashOffset + kUInt32Size;
static const uint32_t kFlagHashOffset = kCpuFeaturesOffset + kUInt32Size; static const uint32_t kFlagHashOffset = kCpuFeaturesOffset + kUInt32Size;
......
...@@ -290,7 +290,6 @@ class SerializedData { ...@@ -290,7 +290,6 @@ class SerializedData {
} }
static const uint32_t kMagicNumberOffset = 0; static const uint32_t kMagicNumberOffset = 0;
static const uint32_t kVersionHashOffset = kMagicNumberOffset + kUInt32Size;
protected: protected:
void SetHeaderValue(uint32_t offset, uint32_t value) { void SetHeaderValue(uint32_t offset, uint32_t value) {
......
...@@ -41,6 +41,7 @@ bool Snapshot::Initialize(Isolate* isolate) { ...@@ -41,6 +41,7 @@ bool Snapshot::Initialize(Isolate* isolate) {
if (FLAG_profile_deserialization) timer.Start(); if (FLAG_profile_deserialization) timer.Start();
const v8::StartupData* blob = isolate->snapshot_blob(); const v8::StartupData* blob = isolate->snapshot_blob();
CheckVersion(blob);
Vector<const byte> startup_data = ExtractStartupData(blob); Vector<const byte> startup_data = ExtractStartupData(blob);
SnapshotData startup_snapshot_data(startup_data); SnapshotData startup_snapshot_data(startup_data);
Vector<const byte> builtin_data = ExtractBuiltinData(blob); Vector<const byte> builtin_data = ExtractBuiltinData(blob);
...@@ -155,6 +156,11 @@ v8::StartupData Snapshot::CreateSnapshotBlob( ...@@ -155,6 +156,11 @@ v8::StartupData Snapshot::CreateSnapshotBlob(
SetHeaderValue(data, kNumberOfContextsOffset, num_contexts); SetHeaderValue(data, kNumberOfContextsOffset, num_contexts);
SetHeaderValue(data, kRehashabilityOffset, can_be_rehashed ? 1 : 0); SetHeaderValue(data, kRehashabilityOffset, can_be_rehashed ? 1 : 0);
// Write version string into snapshot data.
memset(data + kVersionStringOffset, 0, kVersionStringLength);
Version::GetString(
Vector<char>(data + kVersionStringOffset, kVersionStringLength));
// Startup snapshot (isolate-specific data). // Startup snapshot (isolate-specific data).
uint32_t payload_offset = startup_snapshot_offset; uint32_t payload_offset = startup_snapshot_offset;
uint32_t payload_length = uint32_t payload_length =
...@@ -269,6 +275,25 @@ Vector<const byte> Snapshot::ExtractContextData(const v8::StartupData* data, ...@@ -269,6 +275,25 @@ Vector<const byte> Snapshot::ExtractContextData(const v8::StartupData* data,
return Vector<const byte>(context_data, context_length); return Vector<const byte>(context_data, context_length);
} }
void Snapshot::CheckVersion(const v8::StartupData* data) {
char version[kVersionStringLength];
memset(version, 0, kVersionStringLength);
CHECK_LT(kVersionStringOffset + kVersionStringLength,
static_cast<uint32_t>(data->raw_size));
Version::GetString(Vector<char>(version, kVersionStringLength));
if (memcmp(version, data->data + kVersionStringOffset,
kVersionStringLength) != 0) {
V8_Fatal(__FILE__, __LINE__,
"Version mismatch between V8 binary and snapshot.\n"
"# V8 binary version: %.*s\n"
"# Snapshot version: %.*s\n"
"# The snapshot consists of %d bytes and contains %d context(s).",
kVersionStringLength, version, kVersionStringLength,
data->data + kVersionStringOffset, data->raw_size,
ExtractNumContexts(data));
}
}
template <class AllocatorT> template <class AllocatorT>
SnapshotData::SnapshotData(const Serializer<AllocatorT>* serializer) { SnapshotData::SnapshotData(const Serializer<AllocatorT>* serializer) {
DisallowHeapAllocation no_gc; DisallowHeapAllocation no_gc;
...@@ -286,7 +311,6 @@ SnapshotData::SnapshotData(const Serializer<AllocatorT>* serializer) { ...@@ -286,7 +311,6 @@ SnapshotData::SnapshotData(const Serializer<AllocatorT>* serializer) {
// Set header values. // Set header values.
SetMagicNumber(serializer->isolate()); SetMagicNumber(serializer->isolate());
SetHeaderValue(kVersionHashOffset, Version::Hash());
SetHeaderValue(kNumReservationsOffset, static_cast<int>(reservations.size())); SetHeaderValue(kNumReservationsOffset, static_cast<int>(reservations.size()));
SetHeaderValue(kPayloadLengthOffset, static_cast<int>(payload->size())); SetHeaderValue(kPayloadLengthOffset, static_cast<int>(payload->size()));
...@@ -303,10 +327,6 @@ SnapshotData::SnapshotData(const Serializer<AllocatorT>* serializer) { ...@@ -303,10 +327,6 @@ SnapshotData::SnapshotData(const Serializer<AllocatorT>* serializer) {
template SnapshotData::SnapshotData( template SnapshotData::SnapshotData(
const Serializer<DefaultSerializerAllocator>* serializer); const Serializer<DefaultSerializerAllocator>* serializer);
bool SnapshotData::IsSane() {
return GetHeaderValue(kVersionHashOffset) == Version::Hash();
}
Vector<const SerializedData::Reservation> SnapshotData::Reservations() const { Vector<const SerializedData::Reservation> SnapshotData::Reservations() const {
return Vector<const Reservation>( return Vector<const Reservation>(
reinterpret_cast<const Reservation*>(data_ + kHeaderSize), reinterpret_cast<const Reservation*>(data_ + kHeaderSize),
......
...@@ -29,7 +29,6 @@ class SnapshotData : public SerializedData { ...@@ -29,7 +29,6 @@ class SnapshotData : public SerializedData {
// Used when consuming. // Used when consuming.
explicit SnapshotData(const Vector<const byte> snapshot) explicit SnapshotData(const Vector<const byte> snapshot)
: SerializedData(const_cast<byte*>(snapshot.begin()), snapshot.length()) { : SerializedData(const_cast<byte*>(snapshot.begin()), snapshot.length()) {
CHECK(IsSane());
} }
Vector<const Reservation> Reservations() const; Vector<const Reservation> Reservations() const;
...@@ -40,18 +39,14 @@ class SnapshotData : public SerializedData { ...@@ -40,18 +39,14 @@ class SnapshotData : public SerializedData {
} }
protected: protected:
bool IsSane();
// The data header consists of uint32_t-sized entries: // The data header consists of uint32_t-sized entries:
// [0] magic number and (internal) external reference count // [0] magic number and (internal) external reference count
// [1] API-provided external reference count // [1] number of reservation size entries
// [2] version hash // [2] payload length
// [3] number of reservation size entries
// [4] payload length
// ... reservations // ... reservations
// ... serialized payload // ... serialized payload
static const uint32_t kNumReservationsOffset = static const uint32_t kNumReservationsOffset =
kVersionHashOffset + kUInt32Size; kMagicNumberOffset + kUInt32Size;
static const uint32_t kPayloadLengthOffset = static const uint32_t kPayloadLengthOffset =
kNumReservationsOffset + kUInt32Size; kNumReservationsOffset + kUInt32Size;
static const uint32_t kHeaderSize = kPayloadLengthOffset + kUInt32Size; static const uint32_t kHeaderSize = kPayloadLengthOffset + kUInt32Size;
...@@ -67,7 +62,6 @@ class BuiltinSnapshotData final : public SnapshotData { ...@@ -67,7 +62,6 @@ class BuiltinSnapshotData final : public SnapshotData {
// Used when consuming. // Used when consuming.
explicit BuiltinSnapshotData(const Vector<const byte> snapshot) explicit BuiltinSnapshotData(const Vector<const byte> snapshot)
: SnapshotData(snapshot) { : SnapshotData(snapshot) {
CHECK(IsSane());
} }
// Returns the serialized payload without the builtin offsets table. // Returns the serialized payload without the builtin offsets table.
...@@ -141,12 +135,15 @@ class Snapshot : public AllStatic { ...@@ -141,12 +135,15 @@ class Snapshot : public AllStatic {
WriteLittleEndianValue(data + offset, value); WriteLittleEndianValue(data + offset, value);
} }
static void CheckVersion(const v8::StartupData* data);
// Snapshot blob layout: // Snapshot blob layout:
// [0] number of contexts N // [0] number of contexts N
// [1] rehashability // [1] rehashability
// [2] offset to builtins // [2] (128 bytes) version string
// [3] offset to context 0 // [3] offset to builtins
// [4] offset to context 1 // [4] offset to context 0
// [5] offset to context 1
// ... // ...
// ... offset to context N - 1 // ... offset to context N - 1
// ... startup snapshot data // ... startup snapshot data
...@@ -158,7 +155,11 @@ class Snapshot : public AllStatic { ...@@ -158,7 +155,11 @@ class Snapshot : public AllStatic {
// TODO(yangguo): generalize rehashing, and remove this flag. // TODO(yangguo): generalize rehashing, and remove this flag.
static const uint32_t kRehashabilityOffset = static const uint32_t kRehashabilityOffset =
kNumberOfContextsOffset + kUInt32Size; kNumberOfContextsOffset + kUInt32Size;
static const int kBuiltinOffsetOffset = kRehashabilityOffset + kUInt32Size; static const uint32_t kVersionStringOffset =
kRehashabilityOffset + kUInt32Size;
static const uint32_t kVersionStringLength = 64;
static const uint32_t kBuiltinOffsetOffset =
kVersionStringOffset + kVersionStringLength;
static const uint32_t kFirstContextOffsetOffset = static const uint32_t kFirstContextOffsetOffset =
kBuiltinOffsetOffset + kUInt32Size; kBuiltinOffsetOffset + kUInt32Size;
......
...@@ -27,19 +27,11 @@ const char* Version::version_string_ = V8_VERSION_STRING; ...@@ -27,19 +27,11 @@ const char* Version::version_string_ = V8_VERSION_STRING;
// Calculate the V8 version string. // Calculate the V8 version string.
void Version::GetString(Vector<char> str) { void Version::GetString(Vector<char> str) {
const char* candidate = IsCandidate() ? " (candidate)" : ""; const char* candidate = IsCandidate() ? " (candidate)" : "";
#ifdef USE_SIMULATOR
const char* is_simulator = " SIMULATOR";
#else
const char* is_simulator = "";
#endif // USE_SIMULATOR
if (GetPatch() > 0) { if (GetPatch() > 0) {
SNPrintF(str, "%d.%d.%d.%d%s%s", SNPrintF(str, "%d.%d.%d.%d%s", GetMajor(), GetMinor(), GetBuild(),
GetMajor(), GetMinor(), GetBuild(), GetPatch(), candidate, GetPatch(), candidate);
is_simulator);
} else { } else {
SNPrintF(str, "%d.%d.%d%s%s", SNPrintF(str, "%d.%d.%d%s", GetMajor(), GetMinor(), GetBuild(), candidate);
GetMajor(), GetMinor(), GetBuild(), candidate,
is_simulator);
} }
} }
......
...@@ -69,20 +69,6 @@ static void CheckVersion(int major, int minor, int build, ...@@ -69,20 +69,6 @@ static void CheckVersion(int major, int minor, int build,
TEST(VersionString) { TEST(VersionString) {
#ifdef USE_SIMULATOR
CheckVersion(0, 0, 0, 0, false, "0.0.0 SIMULATOR", "libv8-0.0.0.so");
CheckVersion(0, 0, 0, 0, true,
"0.0.0 (candidate) SIMULATOR", "libv8-0.0.0-candidate.so");
CheckVersion(1, 0, 0, 0, false, "1.0.0 SIMULATOR", "libv8-1.0.0.so");
CheckVersion(1, 0, 0, 0, true,
"1.0.0 (candidate) SIMULATOR", "libv8-1.0.0-candidate.so");
CheckVersion(1, 0, 0, 1, false, "1.0.0.1 SIMULATOR", "libv8-1.0.0.1.so");
CheckVersion(1, 0, 0, 1, true,
"1.0.0.1 (candidate) SIMULATOR", "libv8-1.0.0.1-candidate.so");
CheckVersion(2, 5, 10, 7, false, "2.5.10.7 SIMULATOR", "libv8-2.5.10.7.so");
CheckVersion(2, 5, 10, 7, true,
"2.5.10.7 (candidate) SIMULATOR", "libv8-2.5.10.7-candidate.so");
#else
CheckVersion(0, 0, 0, 0, false, "0.0.0", "libv8-0.0.0.so"); CheckVersion(0, 0, 0, 0, false, "0.0.0", "libv8-0.0.0.so");
CheckVersion(0, 0, 0, 0, true, CheckVersion(0, 0, 0, 0, true,
"0.0.0 (candidate)", "libv8-0.0.0-candidate.so"); "0.0.0 (candidate)", "libv8-0.0.0-candidate.so");
...@@ -95,7 +81,6 @@ TEST(VersionString) { ...@@ -95,7 +81,6 @@ TEST(VersionString) {
CheckVersion(2, 5, 10, 7, false, "2.5.10.7", "libv8-2.5.10.7.so"); CheckVersion(2, 5, 10, 7, false, "2.5.10.7", "libv8-2.5.10.7.so");
CheckVersion(2, 5, 10, 7, true, CheckVersion(2, 5, 10, 7, true,
"2.5.10.7 (candidate)", "libv8-2.5.10.7-candidate.so"); "2.5.10.7 (candidate)", "libv8-2.5.10.7-candidate.so");
#endif
} }
} // namespace internal } // namespace internal
......
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