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

Side by Side Diff: src/serialize.h

Issue 581223004: Support large objects in the serializer/deserializer. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 3 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 | Annotate | Revision Log
« no previous file with comments | « src/mksnapshot.cc ('k') | src/serialize.cc » ('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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 #ifndef V8_SERIALIZE_H_ 5 #ifndef V8_SERIALIZE_H_
6 #define V8_SERIALIZE_H_ 6 #define V8_SERIALIZE_H_
7 7
8 #include "src/compiler.h" 8 #include "src/compiler.h"
9 #include "src/hashmap.h" 9 #include "src/hashmap.h"
10 #include "src/heap-profiler.h" 10 #include "src/heap-profiler.h"
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
141 141
142 // The Serializer/Deserializer class is a common superclass for Serializer and 142 // The Serializer/Deserializer class is a common superclass for Serializer and
143 // Deserializer which is used to store common constants and methods used by 143 // Deserializer which is used to store common constants and methods used by
144 // both. 144 // both.
145 class SerializerDeserializer: public ObjectVisitor { 145 class SerializerDeserializer: public ObjectVisitor {
146 public: 146 public:
147 static void Iterate(Isolate* isolate, ObjectVisitor* visitor); 147 static void Iterate(Isolate* isolate, ObjectVisitor* visitor);
148 148
149 static int nop() { return kNop; } 149 static int nop() { return kNop; }
150 150
151 // No reservation for large object space necessary.
152 static const int kNumberOfReservedSpaces = LO_SPACE;
153 static const int kNumberOfSpaces = INVALID_SPACE;
154
151 protected: 155 protected:
152 // Where the pointed-to object can be found: 156 // Where the pointed-to object can be found:
153 enum Where { 157 enum Where {
154 kNewObject = 0, // Object is next in snapshot. 158 kNewObject = 0, // Object is next in snapshot.
155 // 1-6 One per space. 159 // 1-7 One per space.
156 kRootArray = 0x9, // Object is found in root array. 160 kRootArray = 0x9, // Object is found in root array.
157 kPartialSnapshotCache = 0xa, // Object is in the cache. 161 kPartialSnapshotCache = 0xa, // Object is in the cache.
158 kExternalReference = 0xb, // Pointer to an external reference. 162 kExternalReference = 0xb, // Pointer to an external reference.
159 kSkip = 0xc, // Skip n bytes. 163 kSkip = 0xc, // Skip n bytes.
160 kBuiltin = 0xd, // Builtin code object. 164 kBuiltin = 0xd, // Builtin code object.
161 kAttachedReference = 0xe, // Object is described in an attached list. 165 kAttachedReference = 0xe, // Object is described in an attached list.
162 kNop = 0xf, // Does nothing, used to pad. 166 kNop = 0xf, // Does nothing, used to pad.
163 kBackref = 0x10, // Object is described relative to end. 167 kBackref = 0x10, // Object is described relative to end.
164 // 0x11-0x16 One per space. 168 // 0x11-0x17 One per space.
165 kBackrefWithSkip = 0x18, // Object is described relative to end. 169 kBackrefWithSkip = 0x18, // Object is described relative to end.
166 // 0x19-0x1e One per space. 170 // 0x19-0x1f One per space.
167 // 0x20-0x3f Used by misc. tags below. 171 // 0x20-0x3f Used by misc. tags below.
168 kPointedToMask = 0x3f 172 kPointedToMask = 0x3f
169 }; 173 };
170 174
171 // How to code the pointer to the object. 175 // How to code the pointer to the object.
172 enum HowToCode { 176 enum HowToCode {
173 kPlain = 0, // Straight pointer. 177 kPlain = 0, // Straight pointer.
174 // What this means depends on the architecture: 178 // What this means depends on the architecture:
175 kFromCode = 0x40, // A pointer inlined in code. 179 kFromCode = 0x40, // A pointer inlined in code.
176 kHowToCodeMask = 0x40 180 kHowToCodeMask = 0x40
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
218 DCHECK(byte_code >= kConstantRepeat && byte_code <= 0x7f); 222 DCHECK(byte_code >= kConstantRepeat && byte_code <= 0x7f);
219 return byte_code - 0x72; 223 return byte_code - 0x72;
220 } 224 }
221 static const int kRootArrayConstants = 0xa0; 225 static const int kRootArrayConstants = 0xa0;
222 // 0xa0-0xbf Things from the first 32 elements of the root array. 226 // 0xa0-0xbf Things from the first 32 elements of the root array.
223 static const int kRootArrayNumberOfConstantEncodings = 0x20; 227 static const int kRootArrayNumberOfConstantEncodings = 0x20;
224 static int RootArrayConstantFromByteCode(int byte_code) { 228 static int RootArrayConstantFromByteCode(int byte_code) {
225 return byte_code & 0x1f; 229 return byte_code & 0x1f;
226 } 230 }
227 231
228 static const int kNumberOfSpaces = LO_SPACE;
229 static const int kAnyOldSpace = -1; 232 static const int kAnyOldSpace = -1;
230 233
231 // A bitmask for getting the space out of an instruction. 234 // A bitmask for getting the space out of an instruction.
232 static const int kSpaceMask = 7; 235 static const int kSpaceMask = 7;
236 STATIC_ASSERT(kNumberOfSpaces <= kSpaceMask + 1);
233 }; 237 };
234 238
235 239
236 // A Deserializer reads a snapshot and reconstructs the Object graph it defines. 240 // A Deserializer reads a snapshot and reconstructs the Object graph it defines.
237 class Deserializer: public SerializerDeserializer { 241 class Deserializer: public SerializerDeserializer {
238 public: 242 public:
239 // Create a deserializer from a snapshot byte source. 243 // Create a deserializer from a snapshot byte source.
240 explicit Deserializer(SnapshotByteSource* source); 244 explicit Deserializer(SnapshotByteSource* source);
241 245
242 virtual ~Deserializer(); 246 virtual ~Deserializer();
243 247
244 // Deserialize the snapshot into an empty heap. 248 // Deserialize the snapshot into an empty heap.
245 void Deserialize(Isolate* isolate); 249 void Deserialize(Isolate* isolate);
246 250
247 // Deserialize a single object and the objects reachable from it. 251 // Deserialize a single object and the objects reachable from it.
248 void DeserializePartial(Isolate* isolate, Object** root); 252 void DeserializePartial(Isolate* isolate, Object** root);
249 253
250 void set_reservation(int space_number, int reservation) { 254 void set_reservation(int space_number, int reservation) {
251 DCHECK(space_number >= 0); 255 DCHECK(space_number >= 0);
252 DCHECK(space_number <= LAST_SPACE); 256 DCHECK(space_number < kNumberOfReservedSpaces);
253 reservations_[space_number] = reservation; 257 reservations_[space_number] = reservation;
254 } 258 }
255 259
260 void set_large_objects_total_size(int size) {
261 large_objects_total_size_ = size;
262 }
263
256 void FlushICacheForNewCodeObjects(); 264 void FlushICacheForNewCodeObjects();
257 265
258 // Serialized user code reference certain objects that are provided in a list 266 // Serialized user code reference certain objects that are provided in a list
259 // By calling this method, we assume that we are deserializing user code. 267 // By calling this method, we assume that we are deserializing user code.
260 void SetAttachedObjects(Vector<Handle<Object> >* attached_objects) { 268 void SetAttachedObjects(Vector<Handle<Object> >* attached_objects) {
261 attached_objects_ = attached_objects; 269 attached_objects_ = attached_objects;
262 } 270 }
263 271
264 bool deserializing_user_code() { return attached_objects_ != NULL; } 272 bool deserializing_user_code() { return attached_objects_ != NULL; }
265 273
(...skipping 14 matching lines...) Expand all
280 // object, i.e. if we are writing a series of tagged values that are not on 288 // object, i.e. if we are writing a series of tagged values that are not on
281 // the heap. 289 // the heap.
282 void ReadChunk( 290 void ReadChunk(
283 Object** start, Object** end, int space, Address object_address); 291 Object** start, Object** end, int space, Address object_address);
284 void ReadObject(int space_number, Object** write_back); 292 void ReadObject(int space_number, Object** write_back);
285 293
286 // Special handling for serialized code like hooking up internalized strings. 294 // Special handling for serialized code like hooking up internalized strings.
287 HeapObject* ProcessNewObjectFromSerializedCode(HeapObject* obj); 295 HeapObject* ProcessNewObjectFromSerializedCode(HeapObject* obj);
288 Object* ProcessBackRefInSerializedCode(Object* obj); 296 Object* ProcessBackRefInSerializedCode(Object* obj);
289 297
290 // This routine both allocates a new object, and also keeps 298 // We know the space requirements before deserialization and can
291 // track of where objects have been allocated so that we can 299 // pre-allocate that reserved space. During deserialization, all we need
292 // fix back references when deserializing. 300 // to do is to bump up the pointer for each space in the reserved
301 // space. This is also used for fixing back references.
302 // Since multiple large objects cannot be folded into one large object
303 // space allocation, we have to do an actual allocation when deserializing
304 // each allocation. Instead of tracking offset for back references, we
305 // reference large objects by index.
293 Address Allocate(int space_index, int size) { 306 Address Allocate(int space_index, int size) {
294 Address address = high_water_[space_index]; 307 if (space_index == LO_SPACE) {
295 high_water_[space_index] = address + size; 308 Executability exec = static_cast<Executability>(source_->GetInt());
296 return address; 309 HeapObject* obj = isolate_->heap()->ForceAllocateLargeObject(size, exec);
310 deserialized_large_objects_.Add(obj);
311 return obj->address();
312 } else {
313 DCHECK(space_index < kNumberOfReservedSpaces);
314 Address address = high_water_[space_index];
315 high_water_[space_index] = address + size;
316 return address;
317 }
297 } 318 }
298 319
299 // This returns the address of an object that has been described in the 320 // This returns the address of an object that has been described in the
300 // snapshot as being offset bytes back in a particular space. 321 // snapshot as being offset bytes back in a particular space.
301 HeapObject* GetAddressFromEnd(int space) { 322 HeapObject* GetAddressFromEnd(int space) {
302 int offset = source_->GetInt(); 323 int offset = source_->GetInt();
324 if (space == LO_SPACE) return deserialized_large_objects_[offset];
303 offset <<= kObjectAlignmentBits; 325 offset <<= kObjectAlignmentBits;
304 return HeapObject::FromAddress(high_water_[space] - offset); 326 return HeapObject::FromAddress(high_water_[space] - offset);
305 } 327 }
306 328
307 // Cached current isolate. 329 // Cached current isolate.
308 Isolate* isolate_; 330 Isolate* isolate_;
309 331
310 // Objects from the attached object descriptions in the serialized user code. 332 // Objects from the attached object descriptions in the serialized user code.
311 Vector<Handle<Object> >* attached_objects_; 333 Vector<Handle<Object> >* attached_objects_;
312 334
313 SnapshotByteSource* source_; 335 SnapshotByteSource* source_;
314 // This is the address of the next object that will be allocated in each 336 // This is the address of the next object that will be allocated in each
315 // space. It is used to calculate the addresses of back-references. 337 // space. It is used to calculate the addresses of back-references.
316 Address high_water_[LAST_SPACE + 1]; 338 Address high_water_[kNumberOfReservedSpaces];
317 339
318 int reservations_[LAST_SPACE + 1]; 340 int reservations_[kNumberOfReservedSpaces];
319 static const intptr_t kUninitializedReservation = -1; 341 static const intptr_t kUninitializedReservation = -1;
320 342
321 ExternalReferenceDecoder* external_reference_decoder_; 343 ExternalReferenceDecoder* external_reference_decoder_;
322 344
345 List<HeapObject*> deserialized_large_objects_;
346 int large_objects_total_size_;
347
323 DISALLOW_COPY_AND_ASSIGN(Deserializer); 348 DISALLOW_COPY_AND_ASSIGN(Deserializer);
324 }; 349 };
325 350
326 351
327 // Mapping objects to their location after deserialization. 352 // Mapping objects to their location after deserialization.
328 // This is used during building, but not at runtime by V8. 353 // This is used during building, but not at runtime by V8.
329 class SerializationAddressMapper { 354 class SerializationAddressMapper {
330 public: 355 public:
331 SerializationAddressMapper() 356 SerializationAddressMapper()
332 : no_allocation_(), 357 : no_allocation_(),
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
376 401
377 // There can be only one serializer per V8 process. 402 // There can be only one serializer per V8 process.
378 class Serializer : public SerializerDeserializer { 403 class Serializer : public SerializerDeserializer {
379 public: 404 public:
380 Serializer(Isolate* isolate, SnapshotByteSink* sink); 405 Serializer(Isolate* isolate, SnapshotByteSink* sink);
381 ~Serializer(); 406 ~Serializer();
382 void VisitPointers(Object** start, Object** end); 407 void VisitPointers(Object** start, Object** end);
383 // You can call this after serialization to find out how much space was used 408 // You can call this after serialization to find out how much space was used
384 // in each space. 409 // in each space.
385 int CurrentAllocationAddress(int space) const { 410 int CurrentAllocationAddress(int space) const {
386 DCHECK(space < kNumberOfSpaces); 411 if (space == LO_SPACE) return 0;
412 DCHECK(space < kNumberOfReservedSpaces);
387 return fullness_[space]; 413 return fullness_[space];
388 } 414 }
389 415
390 Isolate* isolate() const { return isolate_; } 416 Isolate* isolate() const { return isolate_; }
391 417
392 SerializationAddressMapper* address_mapper() { return &address_mapper_; } 418 SerializationAddressMapper* address_mapper() { return &address_mapper_; }
393 void PutRoot(int index, 419 void PutRoot(int index,
394 HeapObject* object, 420 HeapObject* object,
395 HowToCode how, 421 HowToCode how,
396 WhereToPoint where, 422 WhereToPoint where,
397 int skip); 423 int skip);
398 424
425 int large_objects_total_size() const { return large_objects_total_size_; }
426
399 protected: 427 protected:
400 static const int kInvalidRootIndex = -1; 428 static const int kInvalidRootIndex = -1;
401 429
402 int RootIndex(HeapObject* heap_object, HowToCode from); 430 int RootIndex(HeapObject* heap_object, HowToCode from);
403 intptr_t root_index_wave_front() { return root_index_wave_front_; } 431 intptr_t root_index_wave_front() { return root_index_wave_front_; }
404 void set_root_index_wave_front(intptr_t value) { 432 void set_root_index_wave_front(intptr_t value) {
405 DCHECK(value >= root_index_wave_front_); 433 DCHECK(value >= root_index_wave_front_);
406 root_index_wave_front_ = value; 434 root_index_wave_front_ = value;
407 } 435 }
408 436
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
459 HowToCode how_to_code, 487 HowToCode how_to_code,
460 WhereToPoint where_to_point, 488 WhereToPoint where_to_point,
461 int skip) = 0; 489 int skip) = 0;
462 void SerializeReferenceToPreviousObject(HeapObject* heap_object, 490 void SerializeReferenceToPreviousObject(HeapObject* heap_object,
463 HowToCode how_to_code, 491 HowToCode how_to_code,
464 WhereToPoint where_to_point, 492 WhereToPoint where_to_point,
465 int skip); 493 int skip);
466 void InitializeAllocators(); 494 void InitializeAllocators();
467 // This will return the space for an object. 495 // This will return the space for an object.
468 static int SpaceOfObject(HeapObject* object); 496 static int SpaceOfObject(HeapObject* object);
497 int AllocateLargeObject(int size);
469 int Allocate(int space, int size); 498 int Allocate(int space, int size);
470 int EncodeExternalReference(Address addr) { 499 int EncodeExternalReference(Address addr) {
471 return external_reference_encoder_->Encode(addr); 500 return external_reference_encoder_->Encode(addr);
472 } 501 }
473 502
474 int SpaceAreaSize(int space); 503 int SpaceAreaSize(int space);
475 504
476 // Some roots should not be serialized, because their actual value depends on 505 // Some roots should not be serialized, because their actual value depends on
477 // absolute addresses and they are reset after deserialization, anyway. 506 // absolute addresses and they are reset after deserialization, anyway.
478 bool ShouldBeSkipped(Object** current); 507 bool ShouldBeSkipped(Object** current);
479 508
480 Isolate* isolate_; 509 Isolate* isolate_;
481 // Keep track of the fullness of each space in order to generate 510 // Keep track of the fullness of each space in order to generate
482 // relative addresses for back references. 511 // relative addresses for back references.
483 int fullness_[LAST_SPACE + 1]; 512 int fullness_[kNumberOfReservedSpaces];
484 SnapshotByteSink* sink_; 513 SnapshotByteSink* sink_;
485 ExternalReferenceEncoder* external_reference_encoder_; 514 ExternalReferenceEncoder* external_reference_encoder_;
486 515
487 SerializationAddressMapper address_mapper_; 516 SerializationAddressMapper address_mapper_;
488 intptr_t root_index_wave_front_; 517 intptr_t root_index_wave_front_;
489 void Pad(); 518 void Pad();
490 519
491 friend class ObjectSerializer; 520 friend class ObjectSerializer;
492 friend class Deserializer; 521 friend class Deserializer;
493 522
494 // We may not need the code address map for logging for every instance 523 // We may not need the code address map for logging for every instance
495 // of the serializer. Initialize it on demand. 524 // of the serializer. Initialize it on demand.
496 void InitializeCodeAddressMap(); 525 void InitializeCodeAddressMap();
497 526
498 private: 527 private:
499 CodeAddressMap* code_address_map_; 528 CodeAddressMap* code_address_map_;
529 int seen_large_objects_index_;
mvstanton 2014/09/22 14:32:14 A comment on the meaning of seen_large_objects_ind
530 int large_objects_total_size_;
500 DISALLOW_COPY_AND_ASSIGN(Serializer); 531 DISALLOW_COPY_AND_ASSIGN(Serializer);
501 }; 532 };
502 533
503 534
504 class PartialSerializer : public Serializer { 535 class PartialSerializer : public Serializer {
505 public: 536 public:
506 PartialSerializer(Isolate* isolate, 537 PartialSerializer(Isolate* isolate,
507 Serializer* startup_snapshot_serializer, 538 Serializer* startup_snapshot_serializer,
508 SnapshotByteSink* sink) 539 SnapshotByteSink* sink)
509 : Serializer(isolate, sink), 540 : Serializer(isolate, sink),
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
660 int payload_length = GetHeaderValue(kPayloadLengthOffset); 691 int payload_length = GetHeaderValue(kPayloadLengthOffset);
661 DCHECK_EQ(script_data_->data() + script_data_->length(), 692 DCHECK_EQ(script_data_->data() + script_data_->length(),
662 Payload() + payload_length); 693 Payload() + payload_length);
663 return payload_length; 694 return payload_length;
664 } 695 }
665 696
666 int GetReservation(int space) const { 697 int GetReservation(int space) const {
667 return GetHeaderValue(kReservationsOffset + space); 698 return GetHeaderValue(kReservationsOffset + space);
668 } 699 }
669 700
701 int GetLargeObjectsTotalSize() const {
702 return GetHeaderValue(kLargeObjectsTotalSizeOffset);
703 }
704
670 private: 705 private:
671 void SetHeaderValue(int offset, int value) { 706 void SetHeaderValue(int offset, int value) {
672 reinterpret_cast<int*>(const_cast<byte*>(script_data_->data()))[offset] = 707 reinterpret_cast<int*>(const_cast<byte*>(script_data_->data()))[offset] =
673 value; 708 value;
674 } 709 }
675 710
676 int GetHeaderValue(int offset) const { 711 int GetHeaderValue(int offset) const {
677 return reinterpret_cast<const int*>(script_data_->data())[offset]; 712 return reinterpret_cast<const int*>(script_data_->data())[offset];
678 } 713 }
679 714
680 bool IsSane(String* source); 715 bool IsSane(String* source);
681 716
682 int CheckSum(String* source); 717 int CheckSum(String* source);
683 718
684 // The data header consists of int-sized entries: 719 // The data header consists of int-sized entries:
685 // [0] version hash 720 // [0] version hash
686 // [1] number of code stub keys 721 // [1] number of code stub keys
687 // [2] payload length 722 // [2] payload length
688 // [3..9] reservation sizes for spaces from NEW_SPACE to PROPERTY_CELL_SPACE. 723 // [3..9] reservation sizes for spaces from NEW_SPACE to PROPERTY_CELL_SPACE.
689 static const int kCheckSumOffset = 0; 724 static const int kCheckSumOffset = 0;
690 static const int kNumCodeStubKeysOffset = 1; 725 static const int kNumCodeStubKeysOffset = 1;
691 static const int kPayloadLengthOffset = 2; 726 static const int kPayloadLengthOffset = 2;
692 static const int kReservationsOffset = 3; 727 static const int kLargeObjectsTotalSizeOffset = 3;
728 static const int kReservationsOffset = 4;
693 729
694 static const int kNumSpaces = PROPERTY_CELL_SPACE - NEW_SPACE + 1; 730 static const int kHeaderEntries =
695 static const int kHeaderEntries = kReservationsOffset + kNumSpaces; 731 kReservationsOffset + SerializerDeserializer::kNumberOfReservedSpaces;
696 static const int kHeaderSize = kHeaderEntries * kIntSize; 732 static const int kHeaderSize = kHeaderEntries * kIntSize;
697 733
698 // Following the header, we store, in sequential order 734 // Following the header, we store, in sequential order
699 // - code stub keys 735 // - code stub keys
700 // - serialization payload 736 // - serialization payload
701 737
702 ScriptData* script_data_; 738 ScriptData* script_data_;
703 bool owns_script_data_; 739 bool owns_script_data_;
704 }; 740 };
705 } } // namespace v8::internal 741 } } // namespace v8::internal
706 742
707 #endif // V8_SERIALIZE_H_ 743 #endif // V8_SERIALIZE_H_
OLDNEW
« no previous file with comments | « src/mksnapshot.cc ('k') | src/serialize.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698