Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(907)

Side by Side Diff: src/snapshot/serializer.cc

Issue 2229583003: [serializer] reserve maps one by one to avoid fragmentation. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: fix build Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/snapshot/serializer.h ('k') | src/snapshot/serializer-common.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/snapshot/serializer.h" 5 #include "src/snapshot/serializer.h"
6 6
7 #include "src/macro-assembler.h" 7 #include "src/macro-assembler.h"
8 #include "src/snapshot/natives.h" 8 #include "src/snapshot/natives.h"
9 9
10 namespace v8 { 10 namespace v8 {
11 namespace internal { 11 namespace internal {
12 12
13 Serializer::Serializer(Isolate* isolate) 13 Serializer::Serializer(Isolate* isolate)
14 : isolate_(isolate), 14 : isolate_(isolate),
15 external_reference_encoder_(isolate), 15 external_reference_encoder_(isolate),
16 root_index_map_(isolate), 16 root_index_map_(isolate),
17 recursion_depth_(0), 17 recursion_depth_(0),
18 code_address_map_(NULL), 18 code_address_map_(NULL),
19 num_maps_(0),
19 large_objects_total_size_(0), 20 large_objects_total_size_(0),
20 seen_large_objects_index_(0) { 21 seen_large_objects_index_(0) {
21 // The serializer is meant to be used only to generate initial heap images 22 // The serializer is meant to be used only to generate initial heap images
22 // from a context in which there is only one isolate. 23 // from a context in which there is only one isolate.
23 for (int i = 0; i < kNumberOfPreallocatedSpaces; i++) { 24 for (int i = 0; i < kNumberOfPreallocatedSpaces; i++) {
24 pending_chunk_[i] = 0; 25 pending_chunk_[i] = 0;
25 max_chunk_size_[i] = static_cast<uint32_t>( 26 max_chunk_size_[i] = static_cast<uint32_t>(
26 MemoryAllocator::PageAreaSize(static_cast<AllocationSpace>(i))); 27 MemoryAllocator::PageAreaSize(static_cast<AllocationSpace>(i)));
27 } 28 }
28 29
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
110 for (int i = 0; i < kNumberOfPreallocatedSpaces; i++) { 111 for (int i = 0; i < kNumberOfPreallocatedSpaces; i++) {
111 for (int j = 0; j < completed_chunks_[i].length(); j++) { 112 for (int j = 0; j < completed_chunks_[i].length(); j++) {
112 out->Add(SerializedData::Reservation(completed_chunks_[i][j])); 113 out->Add(SerializedData::Reservation(completed_chunks_[i][j]));
113 } 114 }
114 115
115 if (pending_chunk_[i] > 0 || completed_chunks_[i].length() == 0) { 116 if (pending_chunk_[i] > 0 || completed_chunks_[i].length() == 0) {
116 out->Add(SerializedData::Reservation(pending_chunk_[i])); 117 out->Add(SerializedData::Reservation(pending_chunk_[i]));
117 } 118 }
118 out->last().mark_as_last(); 119 out->last().mark_as_last();
119 } 120 }
120 121 out->Add(SerializedData::Reservation(num_maps_ * Map::kSize));
122 out->last().mark_as_last();
121 out->Add(SerializedData::Reservation(large_objects_total_size_)); 123 out->Add(SerializedData::Reservation(large_objects_total_size_));
122 out->last().mark_as_last(); 124 out->last().mark_as_last();
123 } 125 }
124 126
125 #ifdef DEBUG 127 #ifdef DEBUG
126 bool Serializer::BackReferenceIsAlreadyAllocated( 128 bool Serializer::BackReferenceIsAlreadyAllocated(
127 SerializerReference reference) { 129 SerializerReference reference) {
128 DCHECK(reference.is_back_reference()); 130 DCHECK(reference.is_back_reference());
129 AllocationSpace space = reference.space(); 131 AllocationSpace space = reference.space();
130 int chunk_index = reference.chunk_index();
131 if (space == LO_SPACE) { 132 if (space == LO_SPACE) {
132 return chunk_index == 0 && 133 return reference.large_object_index() < seen_large_objects_index_;
133 reference.large_object_index() < seen_large_objects_index_; 134 } else if (space == MAP_SPACE) {
134 } else if (chunk_index == completed_chunks_[space].length()) { 135 return reference.map_index() < num_maps_;
135 return reference.chunk_offset() < pending_chunk_[space];
136 } else { 136 } else {
137 return chunk_index < completed_chunks_[space].length() && 137 int chunk_index = reference.chunk_index();
138 reference.chunk_offset() < completed_chunks_[space][chunk_index]; 138 if (chunk_index == completed_chunks_[space].length()) {
139 return reference.chunk_offset() < pending_chunk_[space];
140 } else {
141 return chunk_index < completed_chunks_[space].length() &&
142 reference.chunk_offset() < completed_chunks_[space][chunk_index];
143 }
139 } 144 }
140 } 145 }
141 #endif // DEBUG 146 #endif // DEBUG
142 147
143 bool Serializer::SerializeHotObject(HeapObject* obj, HowToCode how_to_code, 148 bool Serializer::SerializeHotObject(HeapObject* obj, HowToCode how_to_code,
144 WhereToPoint where_to_point, int skip) { 149 WhereToPoint where_to_point, int skip) {
145 if (how_to_code != kPlain || where_to_point != kStartOfObject) return false; 150 if (how_to_code != kPlain || where_to_point != kStartOfObject) return false;
146 // Encode a reference to a hot object by its index in the working set. 151 // Encode a reference to a hot object by its index in the working set.
147 int index = hot_objects_.Find(obj); 152 int index = hot_objects_.Find(obj);
148 if (index == HotObjectsList::kNotFound) return false; 153 if (index == HotObjectsList::kNotFound) return false;
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
259 return 0; 264 return 0;
260 } 265 }
261 266
262 SerializerReference Serializer::AllocateLargeObject(int size) { 267 SerializerReference Serializer::AllocateLargeObject(int size) {
263 // Large objects are allocated one-by-one when deserializing. We do not 268 // Large objects are allocated one-by-one when deserializing. We do not
264 // have to keep track of multiple chunks. 269 // have to keep track of multiple chunks.
265 large_objects_total_size_ += size; 270 large_objects_total_size_ += size;
266 return SerializerReference::LargeObjectReference(seen_large_objects_index_++); 271 return SerializerReference::LargeObjectReference(seen_large_objects_index_++);
267 } 272 }
268 273
274 SerializerReference Serializer::AllocateMap() {
275 // Maps are allocated one-by-one when deserializing.
276 return SerializerReference::MapReference(num_maps_++);
277 }
278
269 SerializerReference Serializer::Allocate(AllocationSpace space, int size) { 279 SerializerReference Serializer::Allocate(AllocationSpace space, int size) {
270 DCHECK(space >= 0 && space < kNumberOfPreallocatedSpaces); 280 DCHECK(space >= 0 && space < kNumberOfPreallocatedSpaces);
271 DCHECK(size > 0 && size <= static_cast<int>(max_chunk_size(space))); 281 DCHECK(size > 0 && size <= static_cast<int>(max_chunk_size(space)));
272 uint32_t new_chunk_size = pending_chunk_[space] + size; 282 uint32_t new_chunk_size = pending_chunk_[space] + size;
273 if (new_chunk_size > max_chunk_size(space)) { 283 if (new_chunk_size > max_chunk_size(space)) {
274 // The new chunk size would not fit onto a single page. Complete the 284 // The new chunk size would not fit onto a single page. Complete the
275 // current chunk and start a new one. 285 // current chunk and start a new one.
276 sink_.Put(kNextChunk, "NextChunk"); 286 sink_.Put(kNextChunk, "NextChunk");
277 sink_.Put(space, "NextChunkSpace"); 287 sink_.Put(space, "NextChunkSpace");
278 completed_chunks_[space].Add(pending_chunk_[space]); 288 completed_chunks_[space].Add(pending_chunk_[space]);
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
329 if (space == LO_SPACE) { 339 if (space == LO_SPACE) {
330 sink_->Put(kNewObject + reference_representation_ + space, 340 sink_->Put(kNewObject + reference_representation_ + space,
331 "NewLargeObject"); 341 "NewLargeObject");
332 sink_->PutInt(size >> kObjectAlignmentBits, "ObjectSizeInWords"); 342 sink_->PutInt(size >> kObjectAlignmentBits, "ObjectSizeInWords");
333 if (object_->IsCode()) { 343 if (object_->IsCode()) {
334 sink_->Put(EXECUTABLE, "executable large object"); 344 sink_->Put(EXECUTABLE, "executable large object");
335 } else { 345 } else {
336 sink_->Put(NOT_EXECUTABLE, "not executable large object"); 346 sink_->Put(NOT_EXECUTABLE, "not executable large object");
337 } 347 }
338 back_reference = serializer_->AllocateLargeObject(size); 348 back_reference = serializer_->AllocateLargeObject(size);
349 } else if (space == MAP_SPACE) {
350 DCHECK_EQ(Map::kSize, size);
351 back_reference = serializer_->AllocateMap();
352 sink_->Put(kNewObject + reference_representation_ + space, "NewMap");
353 // This is redundant, but we include it anyways.
354 sink_->PutInt(size >> kObjectAlignmentBits, "ObjectSizeInWords");
339 } else { 355 } else {
340 int fill = serializer_->PutAlignmentPrefix(object_); 356 int fill = serializer_->PutAlignmentPrefix(object_);
341 back_reference = serializer_->Allocate(space, size + fill); 357 back_reference = serializer_->Allocate(space, size + fill);
342 sink_->Put(kNewObject + reference_representation_ + space, "NewObject"); 358 sink_->Put(kNewObject + reference_representation_ + space, "NewObject");
343 sink_->PutInt(size >> kObjectAlignmentBits, "ObjectSizeInWords"); 359 sink_->PutInt(size >> kObjectAlignmentBits, "ObjectSizeInWords");
344 } 360 }
345 361
346 #ifdef OBJECT_PRINT 362 #ifdef OBJECT_PRINT
347 if (FLAG_serialization_statistics) { 363 if (FLAG_serialization_statistics) {
348 serializer_->CountInstanceType(map, size); 364 serializer_->CountInstanceType(map, size);
(...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after
774 if (to_skip != 0 && return_skip == kIgnoringReturn) { 790 if (to_skip != 0 && return_skip == kIgnoringReturn) {
775 sink_->Put(kSkip, "Skip"); 791 sink_->Put(kSkip, "Skip");
776 sink_->PutInt(to_skip, "SkipDistance"); 792 sink_->PutInt(to_skip, "SkipDistance");
777 to_skip = 0; 793 to_skip = 0;
778 } 794 }
779 return to_skip; 795 return to_skip;
780 } 796 }
781 797
782 } // namespace internal 798 } // namespace internal
783 } // namespace v8 799 } // namespace v8
OLDNEW
« no previous file with comments | « src/snapshot/serializer.h ('k') | src/snapshot/serializer-common.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698