Commit 8e6d29e3 authored by jgruber's avatar jgruber Committed by Commit Bot

[snapshot] Add BuiltinSerializerAllocator

Encapsulates special reservation / allocation behavior for builtin
serialization.

This allows us to remove special logic around kNextChunk in builtin
deserialization (since we don't generate that bytecode anymore for
builtins).

Bug: v8:6624
Change-Id: Ice7673006cee53b9d11cdfb7f84d4175221c7984
Reviewed-on: https://chromium-review.googlesource.com/720357Reviewed-by: 's avatarPeter Marshall <petermarshall@chromium.org>
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48725}
parent 7a540779
......@@ -1965,6 +1965,8 @@ v8_source_set("v8_base") {
"src/snapshot/builtin-deserializer-allocator.h",
"src/snapshot/builtin-deserializer.cc",
"src/snapshot/builtin-deserializer.h",
"src/snapshot/builtin-serializer-allocator.cc",
"src/snapshot/builtin-serializer-allocator.h",
"src/snapshot/builtin-serializer.cc",
"src/snapshot/builtin-serializer.h",
"src/snapshot/code-serializer.cc",
......
......@@ -80,7 +80,7 @@ Code* BuiltinDeserializer::DeserializeBuiltinRaw(int builtin_id) {
DeserializingBuiltinScope scope(this, builtin_id);
const int initial_position = source()->position();
SetPositionToBuiltin(builtin_id);
source()->set_position(builtin_offsets_[builtin_id]);
Object* o = ReadDataSingle();
DCHECK(o->IsCode() && Code::cast(o)->is_builtin());
......@@ -96,35 +96,13 @@ Code* BuiltinDeserializer::DeserializeBuiltinRaw(int builtin_id) {
return code;
}
void BuiltinDeserializer::SetPositionToBuiltin(int builtin_id) {
DCHECK(Builtins::IsBuiltinId(builtin_id));
const uint32_t offset = builtin_offsets_[builtin_id];
source()->set_position(offset);
// Grab the size of the code object.
byte data = source()->Get();
// The first bytecode can either be kNewObject, or kNextChunk if the current
// chunk has been exhausted. Since we do allocations differently here, we
// don't care about kNextChunk and can simply skip over it.
// TODO(jgruber): When refactoring (de)serializer allocations, ensure we don't
// generate kNextChunk bytecodes anymore for the builtins snapshot. In fact,
// the entire reservations mechanism is unused for the builtins snapshot.
if (data == kNextChunk) {
source()->Get(); // Skip over kNextChunk's {space} parameter.
} else {
source()->set_position(offset); // Rewind.
}
}
uint32_t BuiltinDeserializer::ExtractBuiltinSize(int builtin_id) {
DCHECK(Builtins::IsBuiltinId(builtin_id));
const int initial_position = source()->position();
// Grab the size of the code object.
SetPositionToBuiltin(builtin_id);
source()->set_position(builtin_offsets_[builtin_id]);
byte data = source()->Get();
USE(data);
......
......@@ -37,8 +37,6 @@ class BuiltinDeserializer final
// already been allocated.
Code* DeserializeBuiltinRaw(int builtin_id);
// TODO(jgruber): Remove once allocations have been refactored.
void SetPositionToBuiltin(int builtin_id);
// Extracts the size builtin Code objects (baked into the snapshot).
uint32_t ExtractBuiltinSize(int builtin_id);
......
// Copyright 2017 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/builtin-serializer-allocator.h"
#include "src/heap/heap-inl.h"
namespace v8 {
namespace internal {
SerializerReference BuiltinSerializerAllocator::Allocate(AllocationSpace space,
uint32_t size) {
DCHECK_EQ(space, CODE_SPACE);
DCHECK_GT(size, 0);
// Builtin serialization & deserialization does not use the reservation
// system. Instead of worrying about chunk indices and offsets, we simply
// need to generate unique offsets here.
const uint32_t virtual_chunk_index = 0;
const auto ref = SerializerReference::BackReference(
CODE_SPACE, virtual_chunk_index, virtual_chunk_offset_);
virtual_chunk_size_ += size;
virtual_chunk_offset_ += kObjectAlignment; // Needs to be aligned.
return ref;
}
#ifdef DEBUG
bool BuiltinSerializerAllocator::BackReferenceIsAlreadyAllocated(
SerializerReference reference) const {
DCHECK(reference.is_back_reference());
AllocationSpace space = reference.space();
DCHECK_EQ(space, CODE_SPACE);
DCHECK_EQ(reference.chunk_index(), 0);
return reference.chunk_offset() < virtual_chunk_offset_;
}
#endif // DEBUG
std::vector<SerializedData::Reservation>
BuiltinSerializerAllocator::EncodeReservations() const {
return {};
}
void BuiltinSerializerAllocator::OutputStatistics() {
DCHECK(FLAG_serialization_statistics);
PrintF(" Spaces (bytes):\n");
STATIC_ASSERT(NEW_SPACE == 0);
for (int space = 0; space < kNumberOfSpaces; space++) {
PrintF("%16s", AllocationSpaceName(static_cast<AllocationSpace>(space)));
}
PrintF("\n");
STATIC_ASSERT(NEW_SPACE == 0);
for (int space = 0; space < kNumberOfSpaces; space++) {
uint32_t space_size = (space == CODE_SPACE) ? virtual_chunk_size_ : 0;
PrintF("%16d", space_size);
}
PrintF("\n");
}
} // namespace internal
} // namespace v8
// Copyright 2017 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_BUILTIN_SERIALIZER_ALLOCATOR_H_
#define V8_SNAPSHOT_BUILTIN_SERIALIZER_ALLOCATOR_H_
#include "src/snapshot/serializer-common.h"
namespace v8 {
namespace internal {
template <class AllocatorT>
class Serializer;
class BuiltinSerializerAllocator final {
public:
BuiltinSerializerAllocator(
Serializer<BuiltinSerializerAllocator>* serializer) {}
SerializerReference Allocate(AllocationSpace space, uint32_t size);
SerializerReference AllocateMap() { UNREACHABLE(); }
SerializerReference AllocateLargeObject(uint32_t size) { UNREACHABLE(); }
SerializerReference AllocateOffHeapBackingStore() { UNREACHABLE(); }
#ifdef DEBUG
bool BackReferenceIsAlreadyAllocated(
SerializerReference back_reference) const;
#endif
std::vector<SerializedData::Reservation> EncodeReservations() const;
void OutputStatistics();
private:
static constexpr int kNumberOfPreallocatedSpaces =
SerializerDeserializer::kNumberOfPreallocatedSpaces;
static constexpr int kNumberOfSpaces =
SerializerDeserializer::kNumberOfSpaces;
// We need to track a faked offset to create back-references. The size is
// kept simply to display statistics.
uint32_t virtual_chunk_size_ = 0;
uint32_t virtual_chunk_offset_ = 0;
DISALLOW_COPY_AND_ASSIGN(BuiltinSerializerAllocator)
};
} // namespace internal
} // namespace v8
#endif // V8_SNAPSHOT_BUILTIN_SERIALIZER_ALLOCATOR_H_
......@@ -5,6 +5,7 @@
#ifndef V8_SNAPSHOT_BUILTIN_SERIALIZER_H_
#define V8_SNAPSHOT_BUILTIN_SERIALIZER_H_
#include "src/snapshot/builtin-serializer-allocator.h"
#include "src/snapshot/serializer.h"
namespace v8 {
......@@ -15,7 +16,7 @@ class StartupSerializer;
// Responsible for serializing all builtin objects during startup snapshot
// creation. Builtins are serialized into a dedicated area of the snapshot.
// See snapshot.h for documentation of the snapshot layout.
class BuiltinSerializer : public Serializer<> {
class BuiltinSerializer : public Serializer<BuiltinSerializerAllocator> {
public:
BuiltinSerializer(Isolate* isolate, StartupSerializer* startup_serializer);
~BuiltinSerializer() override;
......
......@@ -6,6 +6,7 @@
#include "src/assembler-inl.h"
#include "src/objects/map.h"
#include "src/snapshot/builtin-serializer-allocator.h"
#include "src/snapshot/natives.h"
namespace v8 {
......@@ -866,6 +867,7 @@ void Serializer<AllocatorT>::ObjectSerializer::OutputCode(int size) {
}
// Explicit instantiation.
template class Serializer<BuiltinSerializerAllocator>;
template class Serializer<DefaultSerializerAllocator>;
} // namespace internal
......
......@@ -1343,6 +1343,8 @@
'snapshot/builtin-deserializer-allocator.h',
'snapshot/builtin-deserializer.cc',
'snapshot/builtin-deserializer.h',
'snapshot/builtin-serializer-allocator.cc',
'snapshot/builtin-serializer-allocator.h',
'snapshot/builtin-serializer.cc',
'snapshot/builtin-serializer.h',
'snapshot/code-serializer.cc',
......
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