Commit b39de69a authored by Leszek Swirski's avatar Leszek Swirski Committed by Commit Bot

[serializer] Clean up deserializer case macros

Rewrite the deserializer case macros to look, to formatters, more like
a single case value, and clean up some of the repetition to be more
explicit, e.g. replace

  SIXTEEN_CASES(kFoo)
    impl()

with

  case CASE_REPEAT(kFoo, 16):
    impl()

This should help with auto-formatting issues when modifying the big
deserializer switch statement.

As a drive-by, also clean up the per-space case macros to use a
function rather than a macro for specifying the bytecode, and add
helpers for encoding fixed raw data size in the bytecode (similar to
the existing helper for fixed repeat counts).

Change-Id: I885ba79afef03b95ad64cd78bdfba5dffc82be1e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2367853
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Auto-Submit: Leszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/master@{#69635}
parent 5d471ee6
This diff is collapsed.
......@@ -142,8 +142,7 @@ class V8_EXPORT_PRIVATE Deserializer : public SerializerDeserializer {
// A helper function for ReadData, templatized on the bytecode for efficiency.
// Returns the new value of {current}.
template <typename TSlot, Bytecode bytecode,
SnapshotSpace space_number_if_any>
template <typename TSlot, Bytecode bytecode>
inline TSlot ReadDataCase(TSlot current, Address current_object_address,
byte data, bool write_barrier_needed);
......
......@@ -5,6 +5,7 @@
#ifndef V8_SNAPSHOT_SERIALIZER_DESERIALIZER_H_
#define V8_SNAPSHOT_SERIALIZER_DESERIALIZER_H_
#include "src/base/logging.h"
#include "src/objects/visitors.h"
#include "src/snapshot/references.h"
......@@ -110,21 +111,23 @@ class SerializerDeserializer : public RootVisitor {
STATIC_ASSERT(kNumberOfSpaces <= kSpaceMask + 1);
// First 32 root array items.
static const int kNumberOfRootArrayConstants = 0x20;
static const int kRootArrayConstantsCount = 0x20;
static const int kRootArrayConstantsMask = 0x1f;
// 32 common raw data lengths.
static const int kNumberOfFixedRawData = 0x20;
static const int kFixedRawDataCount = 0x20;
// 16 repeats lengths.
static const int kNumberOfFixedRepeat = 0x10;
static const int kFixedRepeatCount = 0x10;
// 8 hot (recently seen or back-referenced) objects with optional skip.
static const int kNumberOfHotObjects = 8;
STATIC_ASSERT(kNumberOfHotObjects == HotObjectsList::kSize);
static const int kHotObjectCount = 8;
STATIC_ASSERT(kHotObjectCount == HotObjectsList::kSize);
static const int kHotObjectMask = 0x07;
enum Bytecode {
// 3 alignment prefixes
static const int kAlignmentPrefixCount = 3;
enum Bytecode : byte {
//
// ---------- byte code range 0x00..0x0f ----------
//
......@@ -196,7 +199,6 @@ class SerializerDeserializer : public RootVisitor {
// 0x60..0x7f
kFixedRawData = 0x60,
kFixedRawDataStart = kFixedRawData - 1,
//
// ---------- byte code range 0x80..0x9f ----------
......@@ -209,6 +211,14 @@ class SerializerDeserializer : public RootVisitor {
kHotObject = 0x90,
};
template <SnapshotSpace space>
static constexpr byte BytecodeWithSpace(Bytecode bytecode) {
STATIC_ASSERT(
(static_cast<int>(space) & ~SerializerDeserializer::kSpaceMask) == 0);
CONSTEXPR_DCHECK((bytecode & kSpaceMask) == 0);
return bytecode + static_cast<int>(space);
}
//
// Some other constants.
//
......@@ -217,36 +227,57 @@ class SerializerDeserializer : public RootVisitor {
// Sentinel after a new object to indicate that double alignment is needed.
static const int kDoubleAlignmentSentinel = 0;
// Raw data size encoding helpers.
static const int kFirstEncodableFixedRawDataSize = 1;
static const int kLastEncodableFixedRawDataSize =
kFirstEncodableFixedRawDataSize + kFixedRawDataCount - 1;
// Encodes raw data size into a fixed raw data bytecode.
static constexpr byte EncodeFixedRawDataSize(int size_in_tagged) {
CONSTEXPR_DCHECK(base::IsInRange(size_in_tagged,
kFirstEncodableFixedRawDataSize,
kLastEncodableFixedRawDataSize));
return kFixedRawData + size_in_tagged - kFirstEncodableFixedRawDataSize;
}
// Decodes raw data size from a fixed raw data bytecode.
static constexpr int DecodeFixedRawDataSize(byte bytecode) {
CONSTEXPR_DCHECK(base::IsInRange(static_cast<int>(bytecode),
kFixedRawData + 0,
kFixedRawData + kFixedRawDataCount));
return bytecode - kFixedRawData + kFirstEncodableFixedRawDataSize;
}
// Repeat count encoding helpers.
static const int kFirstEncodableRepeatCount = 2;
static const int kLastEncodableFixedRepeatCount =
kFirstEncodableRepeatCount + kNumberOfFixedRepeat - 1;
kFirstEncodableRepeatCount + kFixedRepeatCount - 1;
static const int kFirstEncodableVariableRepeatCount =
kLastEncodableFixedRepeatCount + 1;
// Encodes repeat count into a fixed repeat bytecode.
static int EncodeFixedRepeat(int repeat_count) {
DCHECK(base::IsInRange(repeat_count, kFirstEncodableRepeatCount,
kLastEncodableFixedRepeatCount));
static constexpr byte EncodeFixedRepeat(int repeat_count) {
CONSTEXPR_DCHECK(base::IsInRange(repeat_count, kFirstEncodableRepeatCount,
kLastEncodableFixedRepeatCount));
return kFixedRepeat + repeat_count - kFirstEncodableRepeatCount;
}
// Decodes repeat count from a fixed repeat bytecode.
static int DecodeFixedRepeatCount(int bytecode) {
DCHECK(base::IsInRange(bytecode, kFixedRepeat + 0,
kFixedRepeat + kNumberOfFixedRepeat));
static constexpr int DecodeFixedRepeatCount(int bytecode) {
CONSTEXPR_DCHECK(base::IsInRange(bytecode, kFixedRepeat + 0,
kFixedRepeat + kFixedRepeatCount));
return bytecode - kFixedRepeat + kFirstEncodableRepeatCount;
}
// Encodes repeat count into a serialized variable repeat count value.
static int EncodeVariableRepeatCount(int repeat_count) {
DCHECK_LE(kFirstEncodableVariableRepeatCount, repeat_count);
static constexpr int EncodeVariableRepeatCount(int repeat_count) {
CONSTEXPR_DCHECK(kFirstEncodableVariableRepeatCount <= repeat_count);
return repeat_count - kFirstEncodableVariableRepeatCount;
}
// Decodes repeat count from a serialized variable repeat count value.
static int DecodeVariableRepeatCount(int value) {
DCHECK_LE(0, value);
static constexpr int DecodeVariableRepeatCount(int value) {
CONSTEXPR_DCHECK(0 <= value);
return value + kFirstEncodableVariableRepeatCount;
}
......
......@@ -5,6 +5,7 @@
#include "src/snapshot/serializer.h"
#include "src/codegen/assembler-inl.h"
#include "src/common/globals.h"
#include "src/heap/heap-inl.h" // For Space::identity().
#include "src/heap/memory-chunk-inl.h"
#include "src/heap/read-only-heap.h"
......@@ -123,7 +124,7 @@ bool Serializer::SerializeHotObject(HeapObject obj) {
// Encode a reference to a hot object by its index in the working set.
int index = hot_objects_.Find(obj);
if (index == HotObjectsList::kNotFound) return false;
DCHECK(index >= 0 && index < kNumberOfHotObjects);
DCHECK(index >= 0 && index < kHotObjectCount);
if (FLAG_trace_serializer) {
PrintF(" Encoding hot object %d:", index);
obj.ShortPrint();
......@@ -179,10 +180,10 @@ void Serializer::PutRoot(RootIndex root, HeapObject object) {
// Assert that the first 32 root array items are a conscious choice. They are
// chosen so that the most common ones can be encoded more efficiently.
STATIC_ASSERT(static_cast<int>(RootIndex::kArgumentsMarker) ==
kNumberOfRootArrayConstants - 1);
kRootArrayConstantsCount - 1);
// TODO(ulan): Check that it works with young large objects.
if (root_index < kNumberOfRootArrayConstants &&
if (root_index < kRootArrayConstantsCount &&
!Heap::InYoungGeneration(object)) {
sink_.Put(kRootArrayConstants + root_index, "RootConstant");
} else {
......@@ -200,13 +201,11 @@ void Serializer::PutSmiRoot(FullObjectSlot slot) {
STATIC_ASSERT(decltype(slot)::kSlotDataSize == kSystemPointerSize);
static constexpr int bytes_to_output = decltype(slot)::kSlotDataSize;
static constexpr int size_in_tagged = bytes_to_output >> kTaggedSizeLog2;
sink_.PutSection(kFixedRawDataStart + size_in_tagged, "Smi");
sink_.PutSection(EncodeFixedRawDataSize(size_in_tagged), "Smi");
Address raw_value = Smi::cast(*slot).ptr();
const byte* raw_value_as_bytes = reinterpret_cast<const byte*>(&raw_value);
for (size_t i = 0; i < bytes_to_output; i++) {
sink_.Put(raw_value_as_bytes[i], "Byte");
}
sink_.PutRaw(raw_value_as_bytes, bytes_to_output, "Bytes");
}
void Serializer::PutBackReference(HeapObject object,
......@@ -464,9 +463,9 @@ void Serializer::ObjectSerializer::SerializeExternalStringAsSequentialString() {
sink_->PutInt(bytes_to_output, "length");
// Serialize string header (except for map).
uint8_t* string_start = reinterpret_cast<uint8_t*>(string.address());
byte* string_start = reinterpret_cast<byte*>(string.address());
for (int i = HeapObject::kHeaderSize; i < SeqString::kHeaderSize; i++) {
sink_->PutSection(string_start[i], "StringHeader");
sink_->Put(string_start[i], "StringHeader");
}
// Serialize string content.
......@@ -741,9 +740,9 @@ void Serializer::ObjectSerializer::OutputExternalReference(Address target,
// references verbatim.
CHECK(serializer_->allow_unknown_external_references_for_testing());
CHECK(IsAligned(target_size, kObjectAlignment));
CHECK_LE(target_size, kNumberOfFixedRawData * kTaggedSize);
CHECK_LE(target_size, kFixedRawDataCount * kTaggedSize);
int size_in_tagged = target_size >> kTaggedSizeLog2;
sink_->PutSection(kFixedRawDataStart + size_in_tagged, "FixedRawData");
sink_->PutSection(EncodeFixedRawDataSize(size_in_tagged), "FixedRawData");
sink_->PutRaw(reinterpret_cast<byte*>(&target), target_size, "Bytes");
} else if (encoded_reference.is_from_api()) {
if (V8_HEAP_SANDBOX_BOOL && sandboxify) {
......@@ -856,9 +855,9 @@ void Serializer::ObjectSerializer::OutputRawData(Address up_to) {
if (bytes_to_output != 0) {
DCHECK(to_skip == bytes_to_output);
if (IsAligned(bytes_to_output, kObjectAlignment) &&
bytes_to_output <= kNumberOfFixedRawData * kTaggedSize) {
bytes_to_output <= kFixedRawDataCount * kTaggedSize) {
int size_in_tagged = bytes_to_output >> kTaggedSizeLog2;
sink_->PutSection(kFixedRawDataStart + size_in_tagged, "FixedRawData");
sink_->PutSection(EncodeFixedRawDataSize(size_in_tagged), "FixedRawData");
} else {
sink_->Put(kVariableRawData, "VariableRawData");
sink_->PutInt(bytes_to_output, "length");
......
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