5 #include "src/snapshot/serializer-allocator.h" 7 #include "src/heap/heap-inl.h" 8 #include "src/snapshot/references.h" 9 #include "src/snapshot/serializer.h" 10 #include "src/snapshot/snapshot-source-sink.h" 15 SerializerAllocator::SerializerAllocator(Serializer* serializer)
16 : serializer_(serializer) {
17 for (
int i = 0;
i < kNumberOfPreallocatedSpaces;
i++) {
18 pending_chunk_[
i] = 0;
22 void SerializerAllocator::UseCustomChunkSize(
uint32_t chunk_size) {
23 custom_chunk_size_ = chunk_size;
26 static uint32_t PageSizeOfSpace(
int space) {
28 MemoryChunkLayout::AllocatableMemoryInMemoryChunk(
29 static_cast<AllocationSpace>(space)));
32 uint32_t SerializerAllocator::TargetChunkSize(
int space) {
33 if (custom_chunk_size_ == 0)
return PageSizeOfSpace(space);
34 DCHECK_LE(custom_chunk_size_, PageSizeOfSpace(space));
35 return custom_chunk_size_;
38 SerializerReference SerializerAllocator::Allocate(AllocationSpace space,
40 DCHECK(space >= 0 && space < kNumberOfPreallocatedSpaces);
41 DCHECK(size > 0 && size <= PageSizeOfSpace(space));
44 DCHECK_NE(MAP_SPACE, space);
46 DCHECK_NE(NEW_LO_SPACE, space);
48 uint32_t old_chunk_size = pending_chunk_[space];
49 uint32_t new_chunk_size = old_chunk_size + size;
52 if (new_chunk_size > TargetChunkSize(space) && old_chunk_size != 0) {
53 serializer_->PutNextChunk(space);
54 completed_chunks_[space].push_back(pending_chunk_[space]);
55 pending_chunk_[space] = 0;
56 new_chunk_size = size;
58 uint32_t offset = pending_chunk_[space];
59 pending_chunk_[space] = new_chunk_size;
60 return SerializerReference::BackReference(
61 space, static_cast<uint32_t>(completed_chunks_[space].size()), offset);
64 SerializerReference SerializerAllocator::AllocateMap() {
66 return SerializerReference::MapReference(num_maps_++);
69 SerializerReference SerializerAllocator::AllocateLargeObject(
uint32_t size) {
72 large_objects_total_size_ += size;
73 return SerializerReference::LargeObjectReference(seen_large_objects_index_++);
76 SerializerReference SerializerAllocator::AllocateOffHeapBackingStore() {
77 DCHECK_NE(0, seen_backing_stores_index_);
78 return SerializerReference::OffHeapBackingStoreReference(
79 seen_backing_stores_index_++);
83 bool SerializerAllocator::BackReferenceIsAlreadyAllocated(
84 SerializerReference reference)
const {
85 DCHECK(reference.is_back_reference());
86 AllocationSpace space = reference.space();
87 if (space == LO_SPACE) {
88 return reference.large_object_index() < seen_large_objects_index_;
89 }
else if (space == MAP_SPACE) {
90 return reference.map_index() < num_maps_;
91 }
else if (space == RO_SPACE &&
92 serializer_->isolate()->heap()->deserialization_complete()) {
97 size_t chunk_index = reference.chunk_index();
98 if (chunk_index == completed_chunks_[space].size()) {
99 return reference.chunk_offset() < pending_chunk_[space];
101 return chunk_index < completed_chunks_[space].size() &&
102 reference.chunk_offset() < completed_chunks_[space][chunk_index];
108 std::vector<SerializedData::Reservation>
109 SerializerAllocator::EncodeReservations()
const {
110 std::vector<SerializedData::Reservation> out;
112 for (
int i = FIRST_SPACE;
i < kNumberOfPreallocatedSpaces;
i++) {
113 for (
size_t j = 0; j < completed_chunks_[
i].size(); j++) {
114 out.emplace_back(completed_chunks_[
i][j]);
117 if (pending_chunk_[
i] > 0 || completed_chunks_[
i].size() == 0) {
118 out.emplace_back(pending_chunk_[
i]);
120 out.back().mark_as_last();
123 STATIC_ASSERT(MAP_SPACE == kNumberOfPreallocatedSpaces);
124 out.emplace_back(num_maps_ * Map::kSize);
125 out.back().mark_as_last();
127 STATIC_ASSERT(LO_SPACE == MAP_SPACE + 1);
128 out.emplace_back(large_objects_total_size_);
129 out.back().mark_as_last();
134 void SerializerAllocator::OutputStatistics() {
135 DCHECK(FLAG_serialization_statistics);
137 PrintF(
" Spaces (bytes):\n");
139 for (
int space = FIRST_SPACE; space < kNumberOfSpaces; space++) {
140 PrintF(
"%16s", AllocationSpaceName(static_cast<AllocationSpace>(space)));
144 for (
int space = FIRST_SPACE; space < kNumberOfPreallocatedSpaces; space++) {
145 size_t s = pending_chunk_[space];
146 for (
uint32_t chunk_size : completed_chunks_[space]) s += chunk_size;
147 PrintF(
"%16" PRIuS, s);
150 STATIC_ASSERT(MAP_SPACE == kNumberOfPreallocatedSpaces);
151 PrintF(
"%16d", num_maps_ * Map::kSize);
153 STATIC_ASSERT(LO_SPACE == MAP_SPACE + 1);
154 PrintF(
"%16d\n", large_objects_total_size_);