mirror of
https://github.com/zebrajr/node.git
synced 2026-01-15 12:15:26 +00:00
src: split BlobSerializer/BlobDeserializer
This patch splits BlobSerializer and BlobDeserializer out of SnapshotSerializer and SnapshotDeserializer. The child classes can implement serialization methods for custom types on top of BlobSerializer/BlobDeserializer for conversions between native types and binary blobs. This allows us to reuse the classes for other cases (e.g. SEA blobs). PR-URL: https://github.com/nodejs/node/pull/47458 Reviewed-By: Darshan Sen <raisinten@gmail.com>
This commit is contained in:
@@ -534,6 +534,7 @@ struct SnapshotData {
|
||||
bool Check() const;
|
||||
static bool FromFile(SnapshotData* out, FILE* in);
|
||||
static bool FromBlob(SnapshotData* out, const std::vector<char>& in);
|
||||
static bool FromBlob(SnapshotData* out, std::string_view in);
|
||||
static const SnapshotData* FromEmbedderWrapper(
|
||||
const EmbedderSnapshotData* data);
|
||||
EmbedderSnapshotData::Pointer AsEmbedderWrapper() const;
|
||||
|
||||
@@ -140,16 +140,15 @@ std::ostream& operator<<(std::ostream& output, const EnvSerializeInfo& i) {
|
||||
return output;
|
||||
}
|
||||
|
||||
class SnapshotSerializerDeserializer {
|
||||
class BlobSerializerDeserializer {
|
||||
public:
|
||||
SnapshotSerializerDeserializer()
|
||||
: is_debug(per_process::enabled_debug_list.enabled(
|
||||
DebugCategory::MKSNAPSHOT)) {}
|
||||
explicit BlobSerializerDeserializer(bool is_debug_v) : is_debug(is_debug_v) {}
|
||||
|
||||
template <typename... Args>
|
||||
void Debug(const char* format, Args&&... args) const {
|
||||
per_process::Debug(
|
||||
DebugCategory::MKSNAPSHOT, format, std::forward<Args>(args)...);
|
||||
if (is_debug) {
|
||||
FPrintF(stderr, format, std::forward<Args>(args)...);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@@ -185,18 +184,28 @@ class SnapshotSerializerDeserializer {
|
||||
bool is_debug = false;
|
||||
};
|
||||
|
||||
class SnapshotDeserializer : public SnapshotSerializerDeserializer {
|
||||
// TODO(joyeecheung): move it to the separate header file.
|
||||
// Child classes are expected to implement T Read<T>() where
|
||||
// !std::is_arithmetic_v<T> && !std::is_same_v<T, std::string>
|
||||
template <typename Impl>
|
||||
class BlobDeserializer : public BlobSerializerDeserializer {
|
||||
public:
|
||||
explicit SnapshotDeserializer(const std::vector<char>& s)
|
||||
: SnapshotSerializerDeserializer(), sink(s) {}
|
||||
~SnapshotDeserializer() {}
|
||||
explicit BlobDeserializer(bool is_debug_v, std::string_view s)
|
||||
: BlobSerializerDeserializer(is_debug_v), sink(s) {}
|
||||
~BlobDeserializer() {}
|
||||
|
||||
size_t read_total = 0;
|
||||
std::string_view sink;
|
||||
|
||||
Impl* impl() { return static_cast<Impl*>(this); }
|
||||
const Impl* impl() const { return static_cast<const Impl*>(this); }
|
||||
|
||||
// Helper for reading numeric types.
|
||||
template <typename T>
|
||||
T Read() {
|
||||
T ReadArithmetic() {
|
||||
static_assert(std::is_arithmetic_v<T>, "Not an arithmetic type");
|
||||
T result;
|
||||
Read(&result, 1);
|
||||
ReadArithmetic(&result, 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -209,14 +218,19 @@ class SnapshotDeserializer : public SnapshotSerializerDeserializer {
|
||||
std::string name = GetName<T>();
|
||||
Debug("\nReadVector<%s>()(%d-byte)\n", name.c_str(), sizeof(T));
|
||||
}
|
||||
size_t count = static_cast<size_t>(Read<size_t>());
|
||||
size_t count = static_cast<size_t>(ReadArithmetic<size_t>());
|
||||
if (count == 0) {
|
||||
return std::vector<T>();
|
||||
}
|
||||
if (is_debug) {
|
||||
Debug("Reading %d vector elements...\n", count);
|
||||
}
|
||||
std::vector<T> result = ReadVector<T>(count, std::is_arithmetic<T>{});
|
||||
std::vector<T> result;
|
||||
if constexpr (std::is_arithmetic_v<T>) {
|
||||
result = ReadArithmeticVector<T>(count);
|
||||
} else {
|
||||
result = ReadNonArithmeticVector<T>(count);
|
||||
}
|
||||
if (is_debug) {
|
||||
std::string str = std::is_arithmetic_v<T> ? "" : ToStr(result);
|
||||
std::string name = GetName<T>();
|
||||
@@ -226,7 +240,7 @@ class SnapshotDeserializer : public SnapshotSerializerDeserializer {
|
||||
}
|
||||
|
||||
std::string ReadString() {
|
||||
size_t length = Read<size_t>();
|
||||
size_t length = ReadArithmetic<size_t>();
|
||||
|
||||
if (is_debug) {
|
||||
Debug("ReadString(), length=%d: ", length);
|
||||
@@ -245,13 +259,9 @@ class SnapshotDeserializer : public SnapshotSerializerDeserializer {
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t read_total = 0;
|
||||
const std::vector<char>& sink;
|
||||
|
||||
private:
|
||||
// Helper for reading an array of numeric types.
|
||||
template <typename T>
|
||||
void Read(T* out, size_t count) {
|
||||
void ReadArithmetic(T* out, size_t count) {
|
||||
static_assert(std::is_arithmetic_v<T>, "Not an arithmetic type");
|
||||
DCHECK_GT(count, 0); // Should not read contents for vectors of size 0.
|
||||
if (is_debug) {
|
||||
@@ -272,17 +282,18 @@ class SnapshotDeserializer : public SnapshotSerializerDeserializer {
|
||||
|
||||
// Helper for reading numeric vectors.
|
||||
template <typename Number>
|
||||
std::vector<Number> ReadVector(size_t count, std::true_type) {
|
||||
std::vector<Number> ReadArithmeticVector(size_t count) {
|
||||
static_assert(std::is_arithmetic_v<Number>, "Not an arithmetic type");
|
||||
DCHECK_GT(count, 0); // Should not read contents for vectors of size 0.
|
||||
std::vector<Number> result(count);
|
||||
Read(result.data(), count);
|
||||
ReadArithmetic(result.data(), count);
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
// Helper for reading non-numeric vectors.
|
||||
template <typename T>
|
||||
std::vector<T> ReadVector(size_t count, std::false_type) {
|
||||
std::vector<T> ReadNonArithmeticVector(size_t count) {
|
||||
static_assert(!std::is_arithmetic_v<T>, "Arithmetic type");
|
||||
DCHECK_GT(count, 0); // Should not read contents for vectors of size 0.
|
||||
std::vector<T> result;
|
||||
@@ -293,29 +304,49 @@ class SnapshotDeserializer : public SnapshotSerializerDeserializer {
|
||||
if (is_debug) {
|
||||
Debug("\n[%d] ", i);
|
||||
}
|
||||
result.push_back(Read<T>());
|
||||
result.push_back(ReadElement<T>());
|
||||
}
|
||||
is_debug = original_is_debug;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T ReadElement() {
|
||||
if constexpr (std::is_arithmetic_v<T>) {
|
||||
return ReadArithmetic<T>();
|
||||
} else if constexpr (std::is_same_v<T, std::string>) {
|
||||
return ReadString();
|
||||
} else {
|
||||
return impl()->template Read<T>();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class SnapshotSerializer : public SnapshotSerializerDeserializer {
|
||||
// TODO(joyeecheung): move it to the separate header file.
|
||||
// Child classes are expected to implement size_t Write<T>(const T&) where
|
||||
// !std::is_arithmetic_v<T> && !std::is_same_v<T, std::string>
|
||||
template <typename Impl>
|
||||
class BlobSerializer : public BlobSerializerDeserializer {
|
||||
public:
|
||||
SnapshotSerializer() : SnapshotSerializerDeserializer() {
|
||||
explicit BlobSerializer(bool is_debug_v)
|
||||
: BlobSerializerDeserializer(is_debug_v) {
|
||||
// Currently the snapshot blob built with an empty script is around 4MB.
|
||||
// So use that as the default sink size.
|
||||
sink.reserve(4 * 1024 * 1024);
|
||||
}
|
||||
~SnapshotSerializer() {}
|
||||
~BlobSerializer() {}
|
||||
|
||||
Impl* impl() { return static_cast<Impl*>(this); }
|
||||
const Impl* impl() const { return static_cast<const Impl*>(this); }
|
||||
|
||||
std::vector<char> sink;
|
||||
|
||||
// Helper for writing numeric types.
|
||||
template <typename T>
|
||||
size_t Write(const T& data) {
|
||||
size_t WriteArithmetic(const T& data) {
|
||||
static_assert(std::is_arithmetic_v<T>, "Not an arithmetic type");
|
||||
return Write(&data, 1);
|
||||
return WriteArithmetic(&data, 1);
|
||||
}
|
||||
|
||||
// Layout of vectors:
|
||||
@@ -333,11 +364,16 @@ class SnapshotSerializer : public SnapshotSerializerDeserializer {
|
||||
str.c_str());
|
||||
}
|
||||
|
||||
size_t written_total = Write<size_t>(data.size());
|
||||
size_t written_total = WriteArithmetic<size_t>(data.size());
|
||||
if (data.size() == 0) {
|
||||
return written_total;
|
||||
}
|
||||
written_total += WriteVector<T>(data, std::is_arithmetic<T>{});
|
||||
|
||||
if constexpr (std::is_arithmetic_v<T>) {
|
||||
written_total += WriteArithmeticVector<T>(data);
|
||||
} else {
|
||||
written_total += WriteNonArithmeticVector<T>(data);
|
||||
}
|
||||
|
||||
if (is_debug) {
|
||||
std::string name = GetName<T>();
|
||||
@@ -352,7 +388,7 @@ class SnapshotSerializer : public SnapshotSerializerDeserializer {
|
||||
// [ |length| bytes ] contents
|
||||
size_t WriteString(const std::string& data) {
|
||||
CHECK_GT(data.size(), 0); // No empty strings should be written.
|
||||
size_t written_total = Write<size_t>(data.size());
|
||||
size_t written_total = WriteArithmetic<size_t>(data.size());
|
||||
if (is_debug) {
|
||||
std::string str = ToStr(data);
|
||||
Debug("WriteString(), length=%zu: \"%s\"\n", data.size(), data.c_str());
|
||||
@@ -370,10 +406,10 @@ class SnapshotSerializer : public SnapshotSerializerDeserializer {
|
||||
return written_total;
|
||||
}
|
||||
|
||||
private:
|
||||
// Helper for writing an array of numeric types.
|
||||
template <typename T>
|
||||
size_t Write(const T* data, size_t count) {
|
||||
size_t WriteArithmetic(const T* data, size_t count) {
|
||||
static_assert(std::is_arithmetic_v<T>, "Arithmetic type");
|
||||
DCHECK_GT(count, 0); // Should not write contents for vectors of size 0.
|
||||
if (is_debug) {
|
||||
std::string str =
|
||||
@@ -398,13 +434,16 @@ class SnapshotSerializer : public SnapshotSerializerDeserializer {
|
||||
|
||||
// Helper for writing numeric vectors.
|
||||
template <typename Number>
|
||||
size_t WriteVector(const std::vector<Number>& data, std::true_type) {
|
||||
return Write(data.data(), data.size());
|
||||
size_t WriteArithmeticVector(const std::vector<Number>& data) {
|
||||
static_assert(std::is_arithmetic_v<Number>, "Arithmetic type");
|
||||
return WriteArithmetic(data.data(), data.size());
|
||||
}
|
||||
|
||||
private:
|
||||
// Helper for writing non-numeric vectors.
|
||||
template <typename T>
|
||||
size_t WriteVector(const std::vector<T>& data, std::false_type) {
|
||||
size_t WriteNonArithmeticVector(const std::vector<T>& data) {
|
||||
static_assert(!std::is_arithmetic_v<T>, "Arithmetic type");
|
||||
DCHECK_GT(data.size(),
|
||||
0); // Should not write contents for vectors of size 0.
|
||||
size_t written_total = 0;
|
||||
@@ -414,25 +453,50 @@ class SnapshotSerializer : public SnapshotSerializerDeserializer {
|
||||
if (is_debug) {
|
||||
Debug("\n[%d] ", i);
|
||||
}
|
||||
written_total += Write<T>(data[i]);
|
||||
written_total += WriteElement<T>(data[i]);
|
||||
}
|
||||
is_debug = original_is_debug;
|
||||
|
||||
return written_total;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
size_t WriteElement(const T& data) {
|
||||
if constexpr (std::is_arithmetic_v<T>) {
|
||||
return WriteArithmetic<T>(data);
|
||||
} else if constexpr (std::is_same_v<T, std::string>) {
|
||||
return WriteString(data);
|
||||
} else {
|
||||
return impl()->template Write<T>(data);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Layout of serialized std::string:
|
||||
// [ 4/8 bytes ] length
|
||||
// [ |length| bytes ] contents
|
||||
template <>
|
||||
std::string SnapshotDeserializer::Read() {
|
||||
return ReadString();
|
||||
}
|
||||
template <>
|
||||
size_t SnapshotSerializer::Write(const std::string& data) {
|
||||
return WriteString(data);
|
||||
}
|
||||
class SnapshotDeserializer : public BlobDeserializer<SnapshotDeserializer> {
|
||||
public:
|
||||
explicit SnapshotDeserializer(std::string_view v)
|
||||
: BlobDeserializer<SnapshotDeserializer>(
|
||||
per_process::enabled_debug_list.enabled(DebugCategory::MKSNAPSHOT),
|
||||
v) {}
|
||||
|
||||
template <typename T,
|
||||
std::enable_if_t<!std::is_same<T, std::string>::value>* = nullptr,
|
||||
std::enable_if_t<!std::is_arithmetic<T>::value>* = nullptr>
|
||||
T Read();
|
||||
};
|
||||
|
||||
class SnapshotSerializer : public BlobSerializer<SnapshotSerializer> {
|
||||
public:
|
||||
SnapshotSerializer()
|
||||
: BlobSerializer<SnapshotSerializer>(
|
||||
per_process::enabled_debug_list.enabled(
|
||||
DebugCategory::MKSNAPSHOT)) {}
|
||||
|
||||
template <typename T,
|
||||
std::enable_if_t<!std::is_same<T, std::string>::value>* = nullptr,
|
||||
std::enable_if_t<!std::is_arithmetic<T>::value>* = nullptr>
|
||||
size_t Write(const T& data);
|
||||
};
|
||||
|
||||
// Layout of v8::StartupData
|
||||
// [ 4/8 bytes ] raw_size
|
||||
@@ -441,13 +505,13 @@ template <>
|
||||
v8::StartupData SnapshotDeserializer::Read() {
|
||||
Debug("Read<v8::StartupData>()\n");
|
||||
|
||||
int raw_size = Read<int>();
|
||||
int raw_size = ReadArithmetic<int>();
|
||||
Debug("size=%d\n", raw_size);
|
||||
|
||||
CHECK_GT(raw_size, 0); // There should be no startup data of size 0.
|
||||
// The data pointer of v8::StartupData would be deleted so it must be new'ed.
|
||||
std::unique_ptr<char> buf = std::unique_ptr<char>(new char[raw_size]);
|
||||
Read<char>(buf.get(), raw_size);
|
||||
ReadArithmetic<char>(buf.get(), raw_size);
|
||||
|
||||
return v8::StartupData{buf.release(), raw_size};
|
||||
}
|
||||
@@ -457,8 +521,9 @@ size_t SnapshotSerializer::Write(const v8::StartupData& data) {
|
||||
Debug("\nWrite<v8::StartupData>() size=%d\n", data.raw_size);
|
||||
|
||||
CHECK_GT(data.raw_size, 0); // There should be no startup data of size 0.
|
||||
size_t written_total = Write<int>(data.raw_size);
|
||||
written_total += Write<char>(data.data, static_cast<size_t>(data.raw_size));
|
||||
size_t written_total = WriteArithmetic<int>(data.raw_size);
|
||||
written_total +=
|
||||
WriteArithmetic<char>(data.data, static_cast<size_t>(data.raw_size));
|
||||
|
||||
Debug("Write<v8::StartupData>() wrote %d bytes\n\n", written_total);
|
||||
return written_total;
|
||||
@@ -508,8 +573,8 @@ PropInfo SnapshotDeserializer::Read() {
|
||||
|
||||
PropInfo result;
|
||||
result.name = ReadString();
|
||||
result.id = Read<uint32_t>();
|
||||
result.index = Read<SnapshotIndex>();
|
||||
result.id = ReadArithmetic<uint32_t>();
|
||||
result.index = ReadArithmetic<SnapshotIndex>();
|
||||
|
||||
if (is_debug) {
|
||||
std::string str = ToStr(result);
|
||||
@@ -527,8 +592,8 @@ size_t SnapshotSerializer::Write(const PropInfo& data) {
|
||||
}
|
||||
|
||||
size_t written_total = WriteString(data.name);
|
||||
written_total += Write<uint32_t>(data.id);
|
||||
written_total += Write<SnapshotIndex>(data.index);
|
||||
written_total += WriteArithmetic<uint32_t>(data.id);
|
||||
written_total += WriteArithmetic<SnapshotIndex>(data.index);
|
||||
|
||||
Debug("Write<PropInfo>() wrote %d bytes\n", written_total);
|
||||
return written_total;
|
||||
@@ -547,10 +612,10 @@ AsyncHooks::SerializeInfo SnapshotDeserializer::Read() {
|
||||
Debug("Read<AsyncHooks::SerializeInfo>()\n");
|
||||
|
||||
AsyncHooks::SerializeInfo result;
|
||||
result.async_ids_stack = Read<AliasedBufferIndex>();
|
||||
result.fields = Read<AliasedBufferIndex>();
|
||||
result.async_id_fields = Read<AliasedBufferIndex>();
|
||||
result.js_execution_async_resources = Read<SnapshotIndex>();
|
||||
result.async_ids_stack = ReadArithmetic<AliasedBufferIndex>();
|
||||
result.fields = ReadArithmetic<AliasedBufferIndex>();
|
||||
result.async_id_fields = ReadArithmetic<AliasedBufferIndex>();
|
||||
result.js_execution_async_resources = ReadArithmetic<SnapshotIndex>();
|
||||
result.native_execution_async_resources = ReadVector<SnapshotIndex>();
|
||||
|
||||
if (is_debug) {
|
||||
@@ -567,10 +632,12 @@ size_t SnapshotSerializer::Write(const AsyncHooks::SerializeInfo& data) {
|
||||
Debug("Write<AsyncHooks::SerializeInfo>() %s\n", str.c_str());
|
||||
}
|
||||
|
||||
size_t written_total = Write<AliasedBufferIndex>(data.async_ids_stack);
|
||||
written_total += Write<AliasedBufferIndex>(data.fields);
|
||||
written_total += Write<AliasedBufferIndex>(data.async_id_fields);
|
||||
written_total += Write<SnapshotIndex>(data.js_execution_async_resources);
|
||||
size_t written_total =
|
||||
WriteArithmetic<AliasedBufferIndex>(data.async_ids_stack);
|
||||
written_total += WriteArithmetic<AliasedBufferIndex>(data.fields);
|
||||
written_total += WriteArithmetic<AliasedBufferIndex>(data.async_id_fields);
|
||||
written_total +=
|
||||
WriteArithmetic<SnapshotIndex>(data.js_execution_async_resources);
|
||||
written_total +=
|
||||
WriteVector<SnapshotIndex>(data.native_execution_async_resources);
|
||||
|
||||
@@ -585,7 +652,7 @@ TickInfo::SerializeInfo SnapshotDeserializer::Read() {
|
||||
Debug("Read<TickInfo::SerializeInfo>()\n");
|
||||
|
||||
TickInfo::SerializeInfo result;
|
||||
result.fields = Read<AliasedBufferIndex>();
|
||||
result.fields = ReadArithmetic<AliasedBufferIndex>();
|
||||
|
||||
if (is_debug) {
|
||||
std::string str = ToStr(result);
|
||||
@@ -602,7 +669,7 @@ size_t SnapshotSerializer::Write(const TickInfo::SerializeInfo& data) {
|
||||
Debug("Write<TickInfo::SerializeInfo>() %s\n", str.c_str());
|
||||
}
|
||||
|
||||
size_t written_total = Write<AliasedBufferIndex>(data.fields);
|
||||
size_t written_total = WriteArithmetic<AliasedBufferIndex>(data.fields);
|
||||
|
||||
Debug("Write<TickInfo::SerializeInfo>() wrote %d bytes\n", written_total);
|
||||
return written_total;
|
||||
@@ -612,11 +679,10 @@ size_t SnapshotSerializer::Write(const TickInfo::SerializeInfo& data) {
|
||||
// [ 4/8 bytes ] snapshot index of fields
|
||||
template <>
|
||||
ImmediateInfo::SerializeInfo SnapshotDeserializer::Read() {
|
||||
per_process::Debug(DebugCategory::MKSNAPSHOT,
|
||||
"Read<ImmediateInfo::SerializeInfo>()\n");
|
||||
Debug("Read<ImmediateInfo::SerializeInfo>()\n");
|
||||
|
||||
ImmediateInfo::SerializeInfo result;
|
||||
result.fields = Read<AliasedBufferIndex>();
|
||||
result.fields = ReadArithmetic<AliasedBufferIndex>();
|
||||
if (is_debug) {
|
||||
std::string str = ToStr(result);
|
||||
Debug("Read<ImmediateInfo::SerializeInfo>() %s\n", str.c_str());
|
||||
@@ -631,7 +697,7 @@ size_t SnapshotSerializer::Write(const ImmediateInfo::SerializeInfo& data) {
|
||||
Debug("Write<ImmediateInfo::SerializeInfo>() %s\n", str.c_str());
|
||||
}
|
||||
|
||||
size_t written_total = Write<AliasedBufferIndex>(data.fields);
|
||||
size_t written_total = WriteArithmetic<AliasedBufferIndex>(data.fields);
|
||||
|
||||
Debug("Write<ImmediateInfo::SerializeInfo>() wrote %d bytes\n",
|
||||
written_total);
|
||||
@@ -644,13 +710,12 @@ size_t SnapshotSerializer::Write(const ImmediateInfo::SerializeInfo& data) {
|
||||
// [ 4/8 bytes ] snapshot index of observers
|
||||
template <>
|
||||
performance::PerformanceState::SerializeInfo SnapshotDeserializer::Read() {
|
||||
per_process::Debug(DebugCategory::MKSNAPSHOT,
|
||||
"Read<PerformanceState::SerializeInfo>()\n");
|
||||
Debug("Read<PerformanceState::SerializeInfo>()\n");
|
||||
|
||||
performance::PerformanceState::SerializeInfo result;
|
||||
result.root = Read<AliasedBufferIndex>();
|
||||
result.milestones = Read<AliasedBufferIndex>();
|
||||
result.observers = Read<AliasedBufferIndex>();
|
||||
result.root = ReadArithmetic<AliasedBufferIndex>();
|
||||
result.milestones = ReadArithmetic<AliasedBufferIndex>();
|
||||
result.observers = ReadArithmetic<AliasedBufferIndex>();
|
||||
if (is_debug) {
|
||||
std::string str = ToStr(result);
|
||||
Debug("Read<PerformanceState::SerializeInfo>() %s\n", str.c_str());
|
||||
@@ -666,9 +731,9 @@ size_t SnapshotSerializer::Write(
|
||||
Debug("Write<PerformanceState::SerializeInfo>() %s\n", str.c_str());
|
||||
}
|
||||
|
||||
size_t written_total = Write<AliasedBufferIndex>(data.root);
|
||||
written_total += Write<AliasedBufferIndex>(data.milestones);
|
||||
written_total += Write<AliasedBufferIndex>(data.observers);
|
||||
size_t written_total = WriteArithmetic<AliasedBufferIndex>(data.root);
|
||||
written_total += WriteArithmetic<AliasedBufferIndex>(data.milestones);
|
||||
written_total += WriteArithmetic<AliasedBufferIndex>(data.observers);
|
||||
|
||||
Debug("Write<PerformanceState::SerializeInfo>() wrote %d bytes\n",
|
||||
written_total);
|
||||
@@ -682,8 +747,7 @@ size_t SnapshotSerializer::Write(
|
||||
// [ ... ] |length| of PropInfo data
|
||||
template <>
|
||||
IsolateDataSerializeInfo SnapshotDeserializer::Read() {
|
||||
per_process::Debug(DebugCategory::MKSNAPSHOT,
|
||||
"Read<IsolateDataSerializeInfo>()\n");
|
||||
Debug("Read<IsolateDataSerializeInfo>()\n");
|
||||
|
||||
IsolateDataSerializeInfo result;
|
||||
result.primitive_values = ReadVector<SnapshotIndex>();
|
||||
@@ -711,12 +775,12 @@ size_t SnapshotSerializer::Write(const IsolateDataSerializeInfo& data) {
|
||||
|
||||
template <>
|
||||
RealmSerializeInfo SnapshotDeserializer::Read() {
|
||||
per_process::Debug(DebugCategory::MKSNAPSHOT, "Read<RealmSerializeInfo>()\n");
|
||||
Debug("Read<RealmSerializeInfo>()\n");
|
||||
RealmSerializeInfo result;
|
||||
result.builtins = ReadVector<std::string>();
|
||||
result.persistent_values = ReadVector<PropInfo>();
|
||||
result.native_objects = ReadVector<PropInfo>();
|
||||
result.context = Read<SnapshotIndex>();
|
||||
result.context = ReadArithmetic<SnapshotIndex>();
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -731,7 +795,7 @@ size_t SnapshotSerializer::Write(const RealmSerializeInfo& data) {
|
||||
size_t written_total = WriteVector<std::string>(data.builtins);
|
||||
written_total += WriteVector<PropInfo>(data.persistent_values);
|
||||
written_total += WriteVector<PropInfo>(data.native_objects);
|
||||
written_total += Write<SnapshotIndex>(data.context);
|
||||
written_total += WriteArithmetic<SnapshotIndex>(data.context);
|
||||
|
||||
Debug("Write<RealmSerializeInfo>() wrote %d bytes\n", written_total);
|
||||
return written_total;
|
||||
@@ -739,17 +803,17 @@ size_t SnapshotSerializer::Write(const RealmSerializeInfo& data) {
|
||||
|
||||
template <>
|
||||
EnvSerializeInfo SnapshotDeserializer::Read() {
|
||||
per_process::Debug(DebugCategory::MKSNAPSHOT, "Read<EnvSerializeInfo>()\n");
|
||||
Debug("Read<EnvSerializeInfo>()\n");
|
||||
EnvSerializeInfo result;
|
||||
result.async_hooks = Read<AsyncHooks::SerializeInfo>();
|
||||
result.tick_info = Read<TickInfo::SerializeInfo>();
|
||||
result.immediate_info = Read<ImmediateInfo::SerializeInfo>();
|
||||
result.timeout_info = Read<AliasedBufferIndex>();
|
||||
result.timeout_info = ReadArithmetic<AliasedBufferIndex>();
|
||||
result.performance_state =
|
||||
Read<performance::PerformanceState::SerializeInfo>();
|
||||
result.exit_info = Read<AliasedBufferIndex>();
|
||||
result.stream_base_state = Read<AliasedBufferIndex>();
|
||||
result.should_abort_on_uncaught_toggle = Read<AliasedBufferIndex>();
|
||||
result.exit_info = ReadArithmetic<AliasedBufferIndex>();
|
||||
result.stream_base_state = ReadArithmetic<AliasedBufferIndex>();
|
||||
result.should_abort_on_uncaught_toggle = ReadArithmetic<AliasedBufferIndex>();
|
||||
result.principal_realm = Read<RealmSerializeInfo>();
|
||||
return result;
|
||||
}
|
||||
@@ -765,13 +829,13 @@ size_t SnapshotSerializer::Write(const EnvSerializeInfo& data) {
|
||||
size_t written_total = Write<AsyncHooks::SerializeInfo>(data.async_hooks);
|
||||
written_total += Write<TickInfo::SerializeInfo>(data.tick_info);
|
||||
written_total += Write<ImmediateInfo::SerializeInfo>(data.immediate_info);
|
||||
written_total += Write<AliasedBufferIndex>(data.timeout_info);
|
||||
written_total += WriteArithmetic<AliasedBufferIndex>(data.timeout_info);
|
||||
written_total += Write<performance::PerformanceState::SerializeInfo>(
|
||||
data.performance_state);
|
||||
written_total += Write<AliasedBufferIndex>(data.exit_info);
|
||||
written_total += Write<AliasedBufferIndex>(data.stream_base_state);
|
||||
written_total += WriteArithmetic<AliasedBufferIndex>(data.exit_info);
|
||||
written_total += WriteArithmetic<AliasedBufferIndex>(data.stream_base_state);
|
||||
written_total +=
|
||||
Write<AliasedBufferIndex>(data.should_abort_on_uncaught_toggle);
|
||||
WriteArithmetic<AliasedBufferIndex>(data.should_abort_on_uncaught_toggle);
|
||||
written_total += Write<RealmSerializeInfo>(data.principal_realm);
|
||||
|
||||
Debug("Write<EnvSerializeInfo>() wrote %d bytes\n", written_total);
|
||||
@@ -789,14 +853,14 @@ size_t SnapshotSerializer::Write(const EnvSerializeInfo& data) {
|
||||
// [ 4 bytes ] v8 cache version tag
|
||||
template <>
|
||||
SnapshotMetadata SnapshotDeserializer::Read() {
|
||||
per_process::Debug(DebugCategory::MKSNAPSHOT, "Read<SnapshotMetadata>()\n");
|
||||
Debug("Read<SnapshotMetadata>()\n");
|
||||
|
||||
SnapshotMetadata result;
|
||||
result.type = static_cast<SnapshotMetadata::Type>(Read<uint8_t>());
|
||||
result.type = static_cast<SnapshotMetadata::Type>(ReadArithmetic<uint8_t>());
|
||||
result.node_version = ReadString();
|
||||
result.node_arch = ReadString();
|
||||
result.node_platform = ReadString();
|
||||
result.v8_cache_version_tag = Read<uint32_t>();
|
||||
result.v8_cache_version_tag = ReadArithmetic<uint32_t>();
|
||||
|
||||
if (is_debug) {
|
||||
std::string str = ToStr(result);
|
||||
@@ -816,7 +880,7 @@ size_t SnapshotSerializer::Write(const SnapshotMetadata& data) {
|
||||
// Node.js may perform synchronizations that are platform-specific and they
|
||||
// can be changed in semver-patches.
|
||||
Debug("Write snapshot type %" PRIu8 "\n", static_cast<uint8_t>(data.type));
|
||||
written_total += Write<uint8_t>(static_cast<uint8_t>(data.type));
|
||||
written_total += WriteArithmetic<uint8_t>(static_cast<uint8_t>(data.type));
|
||||
Debug("Write Node.js version %s\n", data.node_version.c_str());
|
||||
written_total += WriteString(data.node_version);
|
||||
Debug("Write Node.js arch %s\n", data.node_arch);
|
||||
@@ -825,7 +889,7 @@ size_t SnapshotSerializer::Write(const SnapshotMetadata& data) {
|
||||
written_total += WriteString(data.node_platform);
|
||||
Debug("Write V8 cached data version tag %" PRIx32 "\n",
|
||||
data.v8_cache_version_tag);
|
||||
written_total += Write<uint32_t>(data.v8_cache_version_tag);
|
||||
written_total += WriteArithmetic<uint32_t>(data.v8_cache_version_tag);
|
||||
return written_total;
|
||||
}
|
||||
|
||||
@@ -848,7 +912,7 @@ std::vector<char> SnapshotData::ToBlob() const {
|
||||
|
||||
// Metadata
|
||||
w.Debug("Write magic %" PRIx32 "\n", kMagic);
|
||||
written_total += w.Write<uint32_t>(kMagic);
|
||||
written_total += w.WriteArithmetic<uint32_t>(kMagic);
|
||||
w.Debug("Write metadata\n");
|
||||
written_total += w.Write<SnapshotMetadata>(metadata);
|
||||
|
||||
@@ -883,13 +947,17 @@ bool SnapshotData::FromFile(SnapshotData* out, FILE* in) {
|
||||
}
|
||||
|
||||
bool SnapshotData::FromBlob(SnapshotData* out, const std::vector<char>& in) {
|
||||
return FromBlob(out, std::string_view(in.data(), in.size()));
|
||||
}
|
||||
|
||||
bool SnapshotData::FromBlob(SnapshotData* out, std::string_view in) {
|
||||
SnapshotDeserializer r(in);
|
||||
r.Debug("SnapshotData::FromBlob()\n");
|
||||
|
||||
DCHECK_EQ(out->data_ownership, SnapshotData::DataOwnership::kOwned);
|
||||
|
||||
// Metadata
|
||||
uint32_t magic = r.Read<uint32_t>();
|
||||
uint32_t magic = r.ReadArithmetic<uint32_t>();
|
||||
r.Debug("Read magic %" PRIx32 "\n", magic);
|
||||
CHECK_EQ(magic, kMagic);
|
||||
out->metadata = r.Read<SnapshotMetadata>();
|
||||
|
||||
Reference in New Issue
Block a user