Commit 2b9a6d89 authored by jgruber's avatar jgruber Committed by Commit Bot

[snapshot] Add BuiltinDeserializerAllocator

Encapsulates special reservation / allocation behavior for builtin
deserialization.

Bug: v8:6624
Change-Id: Ic784ed43b607c881b356c6e535c9dbe185e1d4cd
Reviewed-on: https://chromium-review.googlesource.com/716229
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarYang Guo <yangguo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48638}
parent 3a20e450
...@@ -1962,6 +1962,8 @@ v8_source_set("v8_base") { ...@@ -1962,6 +1962,8 @@ v8_source_set("v8_base") {
"src/setup-isolate.h", "src/setup-isolate.h",
"src/signature.h", "src/signature.h",
"src/simulator.h", "src/simulator.h",
"src/snapshot/builtin-deserializer-allocator.cc",
"src/snapshot/builtin-deserializer-allocator.h",
"src/snapshot/builtin-deserializer.cc", "src/snapshot/builtin-deserializer.cc",
"src/snapshot/builtin-deserializer.h", "src/snapshot/builtin-deserializer.h",
"src/snapshot/builtin-serializer.cc", "src/snapshot/builtin-serializer.cc",
......
// 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-deserializer-allocator.h"
#include "src/heap/heap-inl.h"
#include "src/snapshot/builtin-deserializer.h"
#include "src/snapshot/deserializer.h"
namespace v8 {
namespace internal {
BuiltinDeserializerAllocator::BuiltinDeserializerAllocator(
Deserializer<BuiltinDeserializerAllocator>* deserializer)
: deserializer_(static_cast<BuiltinDeserializer*>(deserializer)) {}
Address BuiltinDeserializerAllocator::Allocate(AllocationSpace space,
int size) {
const int builtin_id = deserializer_->CurrentBuiltinId();
DCHECK_EQ(CODE_SPACE, space);
DCHECK_EQ(deserializer_->ExtractBuiltinSize(builtin_id), size);
#ifdef DEBUG
RegisterBuiltinAllocation(builtin_id);
#endif
Object* obj = isolate()->builtins()->builtin(builtin_id);
DCHECK(Internals::HasHeapObjectTag(obj));
return HeapObject::cast(obj)->address();
}
Heap::Reservation
BuiltinDeserializerAllocator::CreateReservationsForEagerBuiltins() {
Heap::Reservation result;
// DeserializeLazy is always the first reservation (to simplify logic in
// InitializeBuiltinsTable).
{
DCHECK(!Builtins::IsLazy(Builtins::kDeserializeLazy));
uint32_t builtin_size =
deserializer_->ExtractBuiltinSize(Builtins::kDeserializeLazy);
DCHECK_LE(builtin_size, MemoryAllocator::PageAreaSize(CODE_SPACE));
result.push_back({builtin_size, nullptr, nullptr});
}
for (int i = 0; i < Builtins::builtin_count; i++) {
if (i == Builtins::kDeserializeLazy) continue;
// Skip lazy builtins. These will be replaced by the DeserializeLazy code
// object in InitializeBuiltinsTable and thus require no reserved space.
if (deserializer_->IsLazyDeserializationEnabled() && Builtins::IsLazy(i)) {
continue;
}
uint32_t builtin_size = deserializer_->ExtractBuiltinSize(i);
DCHECK_LE(builtin_size, MemoryAllocator::PageAreaSize(CODE_SPACE));
result.push_back({builtin_size, nullptr, nullptr});
}
return result;
}
void BuiltinDeserializerAllocator::InitializeBuiltinFromReservation(
const Heap::Chunk& chunk, int builtin_id) {
DCHECK_EQ(deserializer_->ExtractBuiltinSize(builtin_id), chunk.size);
DCHECK_EQ(chunk.size, chunk.end - chunk.start);
SkipList::Update(chunk.start, chunk.size);
isolate()->builtins()->set_builtin(builtin_id,
HeapObject::FromAddress(chunk.start));
#ifdef DEBUG
RegisterBuiltinReservation(builtin_id);
#endif
}
void BuiltinDeserializerAllocator::InitializeBuiltinsTable(
const Heap::Reservation& reservation) {
DCHECK(!AllowHeapAllocation::IsAllowed());
Builtins* builtins = isolate()->builtins();
int reservation_index = 0;
// Other builtins can be replaced by DeserializeLazy so it may not be lazy.
// It always occupies the first reservation slot.
{
DCHECK(!Builtins::IsLazy(Builtins::kDeserializeLazy));
InitializeBuiltinFromReservation(reservation[reservation_index],
Builtins::kDeserializeLazy);
reservation_index++;
}
Code* deserialize_lazy = builtins->builtin(Builtins::kDeserializeLazy);
for (int i = 0; i < Builtins::builtin_count; i++) {
if (i == Builtins::kDeserializeLazy) continue;
if (deserializer_->IsLazyDeserializationEnabled() && Builtins::IsLazy(i)) {
builtins->set_builtin(i, deserialize_lazy);
} else {
InitializeBuiltinFromReservation(reservation[reservation_index], i);
reservation_index++;
}
}
DCHECK_EQ(reservation.size(), reservation_index);
}
void BuiltinDeserializerAllocator::ReserveAndInitializeBuiltinsTableForBuiltin(
int builtin_id) {
DCHECK(AllowHeapAllocation::IsAllowed());
DCHECK(isolate()->builtins()->is_initialized());
DCHECK(Builtins::IsBuiltinId(builtin_id));
DCHECK_NE(Builtins::kDeserializeLazy, builtin_id);
DCHECK_EQ(Builtins::kDeserializeLazy,
isolate()->builtins()->builtin(builtin_id)->builtin_index());
const uint32_t builtin_size = deserializer_->ExtractBuiltinSize(builtin_id);
DCHECK_LE(builtin_size, MemoryAllocator::PageAreaSize(CODE_SPACE));
Handle<HeapObject> o =
isolate()->factory()->NewCodeForDeserialization(builtin_size);
// Note: After this point and until deserialization finishes, heap allocation
// is disallowed. We currently can't safely assert this since we'd need to
// pass the DisallowHeapAllocation scope out of this function.
// Write the allocated filler object into the builtins table. It will be
// returned by our custom Allocate method below once needed.
isolate()->builtins()->set_builtin(builtin_id, *o);
#ifdef DEBUG
RegisterBuiltinReservation(builtin_id);
#endif
}
#ifdef DEBUG
void BuiltinDeserializerAllocator::RegisterBuiltinReservation(int builtin_id) {
const auto result = unused_reservations_.emplace(builtin_id);
CHECK(result.second); // False, iff builtin_id was already present in set.
}
void BuiltinDeserializerAllocator::RegisterBuiltinAllocation(int builtin_id) {
const size_t removed_elems = unused_reservations_.erase(builtin_id);
CHECK_EQ(removed_elems, 1);
}
bool BuiltinDeserializerAllocator::ReservationsAreFullyUsed() const {
// Not 100% precise but should be good enough.
return unused_reservations_.empty();
}
#endif // DEBUG
Isolate* BuiltinDeserializerAllocator::isolate() const {
return deserializer_->isolate();
}
} // 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_DESERIALIZER_ALLOCATOR_H_
#define V8_SNAPSHOT_BUILTIN_DESERIALIZER_ALLOCATOR_H_
#include <unordered_set>
#include "src/globals.h"
#include "src/heap/heap.h"
#include "src/snapshot/serializer-common.h"
namespace v8 {
namespace internal {
template <class AllocatorT>
class Deserializer;
class BuiltinDeserializer;
class BuiltinDeserializerAllocator final {
public:
BuiltinDeserializerAllocator(
Deserializer<BuiltinDeserializerAllocator>* deserializer);
// ------- Allocation Methods -------
// Methods related to memory allocation during deserialization.
// Allocation works differently here than in other deserializers. Instead of
// a statically-known memory area determined at serialization-time, our
// memory requirements here are determined at runtime. Another major
// difference is that we create builtin Code objects up-front (before
// deserialization) in order to avoid having to patch builtin references
// later on. See also the kBuiltin case in deserializer.cc.
//
// Allocate simply returns the pre-allocated object prepared by
// InitializeBuiltinsTable.
Address Allocate(AllocationSpace space, int size);
void MoveToNextChunk(AllocationSpace space) { UNREACHABLE(); }
void SetAlignment(AllocationAlignment alignment) { UNREACHABLE(); }
HeapObject* GetMap(uint32_t index) { UNREACHABLE(); }
HeapObject* GetLargeObject(uint32_t index) { UNREACHABLE(); }
HeapObject* GetObject(AllocationSpace space, uint32_t chunk_index,
uint32_t chunk_offset) {
UNREACHABLE();
}
// ------- Reservation Methods -------
// Methods related to memory reservations (prior to deserialization).
// Builtin deserialization does not bake reservations into the snapshot, hence
// this is a nop.
void DecodeReservation(Vector<const SerializedData::Reservation> res) {}
// These methods are used to pre-allocate builtin objects prior to
// deserialization.
// TODO(jgruber): Refactor reservation/allocation logic in deserializers to
// make this less messy.
Heap::Reservation CreateReservationsForEagerBuiltins();
void InitializeBuiltinsTable(const Heap::Reservation& reservation);
// Creates reservations and initializes the builtins table in preparation for
// lazily deserializing a single builtin.
void ReserveAndInitializeBuiltinsTableForBuiltin(int builtin_id);
#ifdef DEBUG
bool ReservationsAreFullyUsed() const;
#endif
// For SortMapDescriptors();
const std::vector<Address>& GetAllocatedMaps() const {
static std::vector<Address> empty_vector(0);
return empty_vector;
}
private:
Isolate* isolate() const;
// Used after memory allocation prior to isolate initialization, to register
// the newly created object in code space and add it to the builtins table.
void InitializeBuiltinFromReservation(const Heap::Chunk& chunk,
int builtin_id);
#ifdef DEBUG
void RegisterBuiltinReservation(int builtin_id);
void RegisterBuiltinAllocation(int builtin_id);
std::unordered_set<int> unused_reservations_;
#endif
private:
// The current deserializer.
BuiltinDeserializer* const deserializer_;
DISALLOW_COPY_AND_ASSIGN(BuiltinDeserializerAllocator)
};
} // namespace internal
} // namespace v8
#endif // V8_SNAPSHOT_BUILTIN_DESERIALIZER_ALLOCATOR_H_
...@@ -36,10 +36,6 @@ class DeserializingBuiltinScope { ...@@ -36,10 +36,6 @@ class DeserializingBuiltinScope {
BuiltinDeserializer::BuiltinDeserializer(Isolate* isolate, BuiltinDeserializer::BuiltinDeserializer(Isolate* isolate,
const BuiltinSnapshotData* data) const BuiltinSnapshotData* data)
: Deserializer(data, false) { : Deserializer(data, false) {
// We may have to relax this at some point to pack reloc infos and handler
// tables into the builtin blob (instead of the partial snapshot cache).
DCHECK(allocator()->ReservesOnlyCodeSpace());
builtin_offsets_ = data->BuiltinOffsets(); builtin_offsets_ = data->BuiltinOffsets();
DCHECK_EQ(Builtins::builtin_count, builtin_offsets_.length()); DCHECK_EQ(Builtins::builtin_count, builtin_offsets_.length());
DCHECK(std::is_sorted(builtin_offsets_.begin(), builtin_offsets_.end())); DCHECK(std::is_sorted(builtin_offsets_.begin(), builtin_offsets_.end()));
...@@ -59,7 +55,7 @@ void BuiltinDeserializer::DeserializeEagerBuiltins() { ...@@ -59,7 +55,7 @@ void BuiltinDeserializer::DeserializeEagerBuiltins() {
DCHECK_EQ(builtins->builtin(Builtins::kDeserializeLazy), DCHECK_EQ(builtins->builtin(Builtins::kDeserializeLazy),
builtins->builtin(i)); builtins->builtin(i));
} else { } else {
builtins->set_builtin(i, DeserializeBuiltin(i)); builtins->set_builtin(i, DeserializeBuiltinRaw(i));
} }
} }
...@@ -72,6 +68,12 @@ void BuiltinDeserializer::DeserializeEagerBuiltins() { ...@@ -72,6 +68,12 @@ void BuiltinDeserializer::DeserializeEagerBuiltins() {
} }
Code* BuiltinDeserializer::DeserializeBuiltin(int builtin_id) { Code* BuiltinDeserializer::DeserializeBuiltin(int builtin_id) {
allocator()->ReserveAndInitializeBuiltinsTableForBuiltin(builtin_id);
DisallowHeapAllocation no_gc;
return DeserializeBuiltinRaw(builtin_id);
}
Code* BuiltinDeserializer::DeserializeBuiltinRaw(int builtin_id) {
DCHECK(!AllowHeapAllocation::IsAllowed()); DCHECK(!AllowHeapAllocation::IsAllowed());
DCHECK(Builtins::IsBuiltinId(builtin_id)); DCHECK(Builtins::IsBuiltinId(builtin_id));
...@@ -135,110 +137,5 @@ uint32_t BuiltinDeserializer::ExtractBuiltinSize(int builtin_id) { ...@@ -135,110 +137,5 @@ uint32_t BuiltinDeserializer::ExtractBuiltinSize(int builtin_id) {
return result; return result;
} }
Heap::Reservation BuiltinDeserializer::CreateReservationsForEagerBuiltins() {
DCHECK(allocator()->ReservesOnlyCodeSpace());
Heap::Reservation result;
// DeserializeLazy is always the first reservation (to simplify logic in
// InitializeBuiltinsTable).
{
DCHECK(!Builtins::IsLazy(Builtins::kDeserializeLazy));
uint32_t builtin_size = ExtractBuiltinSize(Builtins::kDeserializeLazy);
DCHECK_LE(builtin_size, MemoryAllocator::PageAreaSize(CODE_SPACE));
result.push_back({builtin_size, nullptr, nullptr});
}
for (int i = 0; i < Builtins::builtin_count; i++) {
if (i == Builtins::kDeserializeLazy) continue;
// Skip lazy builtins. These will be replaced by the DeserializeLazy code
// object in InitializeBuiltinsTable and thus require no reserved space.
if (IsLazyDeserializationEnabled() && Builtins::IsLazy(i)) continue;
uint32_t builtin_size = ExtractBuiltinSize(i);
DCHECK_LE(builtin_size, MemoryAllocator::PageAreaSize(CODE_SPACE));
result.push_back({builtin_size, nullptr, nullptr});
}
return result;
}
void BuiltinDeserializer::InitializeBuiltinFromReservation(
const Heap::Chunk& chunk, int builtin_id) {
DCHECK_EQ(ExtractBuiltinSize(builtin_id), chunk.size);
DCHECK_EQ(chunk.size, chunk.end - chunk.start);
SkipList::Update(chunk.start, chunk.size);
isolate()->builtins()->set_builtin(builtin_id,
HeapObject::FromAddress(chunk.start));
}
void BuiltinDeserializer::InitializeBuiltinsTable(
const Heap::Reservation& reservation) {
DCHECK(!AllowHeapAllocation::IsAllowed());
Builtins* builtins = isolate()->builtins();
int reservation_index = 0;
// Other builtins can be replaced by DeserializeLazy so it may not be lazy.
// It always occupies the first reservation slot.
{
DCHECK(!Builtins::IsLazy(Builtins::kDeserializeLazy));
InitializeBuiltinFromReservation(reservation[reservation_index],
Builtins::kDeserializeLazy);
reservation_index++;
}
Code* deserialize_lazy = builtins->builtin(Builtins::kDeserializeLazy);
for (int i = 0; i < Builtins::builtin_count; i++) {
if (i == Builtins::kDeserializeLazy) continue;
if (IsLazyDeserializationEnabled() && Builtins::IsLazy(i)) {
builtins->set_builtin(i, deserialize_lazy);
} else {
InitializeBuiltinFromReservation(reservation[reservation_index], i);
reservation_index++;
}
}
DCHECK_EQ(reservation.size(), reservation_index);
}
void BuiltinDeserializer::ReserveAndInitializeBuiltinsTableForBuiltin(
int builtin_id) {
DCHECK(AllowHeapAllocation::IsAllowed());
DCHECK(isolate()->builtins()->is_initialized());
DCHECK(Builtins::IsBuiltinId(builtin_id));
DCHECK_NE(Builtins::kDeserializeLazy, builtin_id);
DCHECK_EQ(Builtins::kDeserializeLazy,
isolate()->builtins()->builtin(builtin_id)->builtin_index());
const uint32_t builtin_size = ExtractBuiltinSize(builtin_id);
DCHECK_LE(builtin_size, MemoryAllocator::PageAreaSize(CODE_SPACE));
Handle<HeapObject> o =
isolate()->factory()->NewCodeForDeserialization(builtin_size);
// Note: After this point and until deserialization finishes, heap allocation
// is disallowed. We currently can't safely assert this since we'd need to
// pass the DisallowHeapAllocation scope out of this function.
// Write the allocated filler object into the builtins table. It will be
// returned by our custom Allocate method below once needed.
isolate()->builtins()->set_builtin(builtin_id, *o);
}
Address BuiltinDeserializer::Allocate(int space_index, int size) {
DCHECK_EQ(CODE_SPACE, space_index);
DCHECK_EQ(ExtractBuiltinSize(current_builtin_id_), size);
Object* obj = isolate()->builtins()->builtin(current_builtin_id_);
DCHECK(Internals::HasHeapObjectTag(obj));
HeapObject* heap_obj = HeapObject::cast(obj);
return heap_obj->address();
}
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
#ifndef V8_SNAPSHOT_BUILTIN_DESERIALIZER_H_ #ifndef V8_SNAPSHOT_BUILTIN_DESERIALIZER_H_
#define V8_SNAPSHOT_BUILTIN_DESERIALIZER_H_ #define V8_SNAPSHOT_BUILTIN_DESERIALIZER_H_
#include "src/heap/heap.h" #include "src/snapshot/builtin-deserializer-allocator.h"
#include "src/snapshot/deserializer.h" #include "src/snapshot/deserializer.h"
namespace v8 { namespace v8 {
...@@ -14,7 +14,8 @@ namespace internal { ...@@ -14,7 +14,8 @@ namespace internal {
class BuiltinSnapshotData; class BuiltinSnapshotData;
// Deserializes the builtins blob. // Deserializes the builtins blob.
class BuiltinDeserializer final : public Deserializer<> { class BuiltinDeserializer final
: public Deserializer<BuiltinDeserializerAllocator> {
public: public:
BuiltinDeserializer(Isolate* isolate, const BuiltinSnapshotData* data); BuiltinDeserializer(Isolate* isolate, const BuiltinSnapshotData* data);
...@@ -27,50 +28,30 @@ class BuiltinDeserializer final : public Deserializer<> { ...@@ -27,50 +28,30 @@ class BuiltinDeserializer final : public Deserializer<> {
// do it ourselves since the startup serializer batch-flushes all code pages). // do it ourselves since the startup serializer batch-flushes all code pages).
void DeserializeEagerBuiltins(); void DeserializeEagerBuiltins();
// Deserializes the single given builtin. Assumes that reservations have // Deserializes the single given builtin. This is used whenever a builtin is
// already been allocated. // lazily deserialized at runtime.
Code* DeserializeBuiltin(int builtin_id); Code* DeserializeBuiltin(int builtin_id);
// These methods are used to pre-allocate builtin objects prior to
// deserialization.
// TODO(jgruber): Refactor reservation/allocation logic in deserializers to
// make this less messy.
Heap::Reservation CreateReservationsForEagerBuiltins();
void InitializeBuiltinsTable(const Heap::Reservation& reservation);
// Creates reservations and initializes the builtins table in preparation for
// lazily deserializing a single builtin.
void ReserveAndInitializeBuiltinsTableForBuiltin(int builtin_id);
private: private:
// Deserializes the single given builtin. Assumes that reservations have
// already been allocated.
Code* DeserializeBuiltinRaw(int builtin_id);
// TODO(jgruber): Remove once allocations have been refactored. // TODO(jgruber): Remove once allocations have been refactored.
void SetPositionToBuiltin(int builtin_id); void SetPositionToBuiltin(int builtin_id);
// Extracts the size builtin Code objects (baked into the snapshot). // Extracts the size builtin Code objects (baked into the snapshot).
uint32_t ExtractBuiltinSize(int builtin_id); uint32_t ExtractBuiltinSize(int builtin_id);
// Used after memory allocation prior to isolate initialization, to register
// the newly created object in code space and add it to the builtins table.
void InitializeBuiltinFromReservation(const Heap::Chunk& chunk,
int builtin_id);
// Allocation works differently here than in other deserializers. Instead of
// a statically-known memory area determined at serialization-time, our
// memory requirements here are determined at runtime. Another major
// difference is that we create builtin Code objects up-front (before
// deserialization) in order to avoid having to patch builtin references
// later on. See also the kBuiltin case in deserializer.cc.
//
// Allocate simply returns the pre-allocated object prepared by
// InitializeBuiltinsTable.
Address Allocate(int space_index, int size) override;
// BuiltinDeserializer implements its own builtin iteration logic. Make sure // BuiltinDeserializer implements its own builtin iteration logic. Make sure
// the RootVisitor API is not used accidentally. // the RootVisitor API is not used accidentally.
void VisitRootPointers(Root root, Object** start, Object** end) override { void VisitRootPointers(Root root, Object** start, Object** end) override {
UNREACHABLE(); UNREACHABLE();
} }
int CurrentBuiltinId() const { return current_builtin_id_; }
private:
// Stores the builtin currently being deserialized. We need this to determine // Stores the builtin currently being deserialized. We need this to determine
// where to 'allocate' from during deserialization. // where to 'allocate' from during deserialization.
static const int kNoBuiltinId = -1; static const int kNoBuiltinId = -1;
...@@ -80,7 +61,12 @@ class BuiltinDeserializer final : public Deserializer<> { ...@@ -80,7 +61,12 @@ class BuiltinDeserializer final : public Deserializer<> {
// BuiltinSerializer::builtin_offsets_ but on the deserialization side. // BuiltinSerializer::builtin_offsets_ but on the deserialization side.
Vector<const uint32_t> builtin_offsets_; Vector<const uint32_t> builtin_offsets_;
// For current_builtin_id_.
friend class DeserializingBuiltinScope; friend class DeserializingBuiltinScope;
// For isolate(), IsLazyDeserializationEnabled(), CurrentBuiltinId() and
// ExtractBuiltinSize().
friend class BuiltinDeserializerAllocator;
}; };
} // namespace internal } // namespace internal
......
...@@ -169,7 +169,7 @@ bool DefaultDeserializerAllocator::ReserveSpace( ...@@ -169,7 +169,7 @@ bool DefaultDeserializerAllocator::ReserveSpace(
} }
Heap::Reservation builtin_reservations = Heap::Reservation builtin_reservations =
builtin_deserializer->CreateReservationsForEagerBuiltins(); builtin_deserializer->allocator()->CreateReservationsForEagerBuiltins();
DCHECK(!builtin_reservations.empty()); DCHECK(!builtin_reservations.empty());
for (const auto& c : builtin_reservations) { for (const auto& c : builtin_reservations) {
...@@ -199,7 +199,8 @@ bool DefaultDeserializerAllocator::ReserveSpace( ...@@ -199,7 +199,8 @@ bool DefaultDeserializerAllocator::ReserveSpace(
merged_reservations[CODE_SPACE].pop_back(); merged_reservations[CODE_SPACE].pop_back();
} }
builtin_deserializer->InitializeBuiltinsTable(builtin_reservations); builtin_deserializer->allocator()->InitializeBuiltinsTable(
builtin_reservations);
} }
// Write back startup reservations. // Write back startup reservations.
...@@ -212,22 +213,11 @@ bool DefaultDeserializerAllocator::ReserveSpace( ...@@ -212,22 +213,11 @@ bool DefaultDeserializerAllocator::ReserveSpace(
for (int i = first_space; i < kNumberOfPreallocatedSpaces; i++) { for (int i = first_space; i < kNumberOfPreallocatedSpaces; i++) {
startup_deserializer->allocator()->high_water_[i] = startup_deserializer->allocator()->high_water_[i] =
startup_deserializer->allocator()->reservations_[i][0].start; startup_deserializer->allocator()->reservations_[i][0].start;
builtin_deserializer->allocator()->high_water_[i] = nullptr;
} }
return true; return true;
} }
bool DefaultDeserializerAllocator::ReservesOnlyCodeSpace() const {
for (int space = NEW_SPACE; space < kNumberOfSpaces; space++) {
if (space == CODE_SPACE) continue;
const auto& r = reservations_[space];
for (const Heap::Chunk& c : r)
if (c.size != 0) return false;
}
return true;
}
bool DefaultDeserializerAllocator::ReservationsAreFullyUsed() const { bool DefaultDeserializerAllocator::ReservationsAreFullyUsed() const {
for (int space = 0; space < kNumberOfPreallocatedSpaces; space++) { for (int space = 0; space < kNumberOfPreallocatedSpaces; space++) {
const uint32_t chunk_index = current_chunk_[space]; const uint32_t chunk_index = current_chunk_[space];
......
...@@ -52,7 +52,6 @@ class DefaultDeserializerAllocator final { ...@@ -52,7 +52,6 @@ class DefaultDeserializerAllocator final {
static bool ReserveSpace(StartupDeserializer* startup_deserializer, static bool ReserveSpace(StartupDeserializer* startup_deserializer,
BuiltinDeserializer* builtin_deserializer); BuiltinDeserializer* builtin_deserializer);
bool ReservesOnlyCodeSpace() const;
bool ReservationsAreFullyUsed() const; bool ReservationsAreFullyUsed() const;
// ------- Misc Utility Methods ------- // ------- Misc Utility Methods -------
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "src/assembler-inl.h" #include "src/assembler-inl.h"
#include "src/isolate.h" #include "src/isolate.h"
#include "src/objects/string.h" #include "src/objects/string.h"
#include "src/snapshot/builtin-deserializer-allocator.h"
#include "src/snapshot/natives.h" #include "src/snapshot/natives.h"
namespace v8 { namespace v8 {
...@@ -272,7 +273,8 @@ void Deserializer<AllocatorT>::ReadObject(int space_number, ...@@ -272,7 +273,8 @@ void Deserializer<AllocatorT>::ReadObject(int space_number,
Object** write_back) { Object** write_back) {
const int size = source_.GetInt() << kObjectAlignmentBits; const int size = source_.GetInt() << kObjectAlignmentBits;
Address address = Allocate(space_number, size); Address address =
allocator()->Allocate(static_cast<AllocationSpace>(space_number), size);
HeapObject* obj = HeapObject::FromAddress(address); HeapObject* obj = HeapObject::FromAddress(address);
isolate_->heap()->OnAllocationEvent(obj, size); isolate_->heap()->OnAllocationEvent(obj, size);
...@@ -295,13 +297,6 @@ void Deserializer<AllocatorT>::ReadObject(int space_number, ...@@ -295,13 +297,6 @@ void Deserializer<AllocatorT>::ReadObject(int space_number,
#endif // DEBUG #endif // DEBUG
} }
template <class AllocatorT>
Address Deserializer<AllocatorT>::Allocate(int space_index, int size) {
// TODO(jgruber): Remove this indirection once we have a
// BuiltinDeserializerAllocator.
return allocator()->Allocate(static_cast<AllocationSpace>(space_index), size);
}
template <class AllocatorT> template <class AllocatorT>
Object* Deserializer<AllocatorT>::ReadDataSingle() { Object* Deserializer<AllocatorT>::ReadDataSingle() {
Object* o; Object* o;
...@@ -718,6 +713,7 @@ Object** Deserializer<AllocatorT>::ReadDataCase(Isolate* isolate, ...@@ -718,6 +713,7 @@ Object** Deserializer<AllocatorT>::ReadDataCase(Isolate* isolate,
} }
// Explicit instantiation. // Explicit instantiation.
template class Deserializer<BuiltinDeserializerAllocator>;
template class Deserializer<DefaultDeserializerAllocator>; template class Deserializer<DefaultDeserializerAllocator>;
} // namespace internal } // namespace internal
......
...@@ -55,8 +55,6 @@ class Deserializer : public SerializerDeserializer { ...@@ -55,8 +55,6 @@ class Deserializer : public SerializerDeserializer {
void Initialize(Isolate* isolate); void Initialize(Isolate* isolate);
void DeserializeDeferredObjects(); void DeserializeDeferredObjects();
virtual Address Allocate(int space_index, int size);
// Deserializes into a single pointer and returns the resulting object. // Deserializes into a single pointer and returns the resulting object.
Object* ReadDataSingle(); Object* ReadDataSingle();
......
...@@ -97,10 +97,6 @@ Code* Snapshot::DeserializeBuiltin(Isolate* isolate, int builtin_id) { ...@@ -97,10 +97,6 @@ Code* Snapshot::DeserializeBuiltin(Isolate* isolate, int builtin_id) {
BuiltinSnapshotData builtin_snapshot_data(builtin_data); BuiltinSnapshotData builtin_snapshot_data(builtin_data);
BuiltinDeserializer builtin_deserializer(isolate, &builtin_snapshot_data); BuiltinDeserializer builtin_deserializer(isolate, &builtin_snapshot_data);
builtin_deserializer.ReserveAndInitializeBuiltinsTableForBuiltin(builtin_id);
DisallowHeapAllocation no_gc;
Code* code = builtin_deserializer.DeserializeBuiltin(builtin_id); Code* code = builtin_deserializer.DeserializeBuiltin(builtin_id);
DCHECK_EQ(code, isolate->builtins()->builtin(builtin_id)); DCHECK_EQ(code, isolate->builtins()->builtin(builtin_id));
......
...@@ -1339,6 +1339,8 @@ ...@@ -1339,6 +1339,8 @@
'setup-isolate.h', 'setup-isolate.h',
'signature.h', 'signature.h',
'simulator.h', 'simulator.h',
'snapshot/builtin-deserializer-allocator.cc',
'snapshot/builtin-deserializer-allocator.h',
'snapshot/builtin-deserializer.cc', 'snapshot/builtin-deserializer.cc',
'snapshot/builtin-deserializer.h', 'snapshot/builtin-deserializer.h',
'snapshot/builtin-serializer.cc', 'snapshot/builtin-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