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

Side by Side Diff: src/serialize.h

Issue 394007: * Remove old snapshot implementation (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 1 month 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
OLDNEW
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution. 11 // with the distribution.
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
101 int id = key & kReferenceIdMask; 101 int id = key & kReferenceIdMask;
102 return &encodings_[type][id]; 102 return &encodings_[type][id];
103 } 103 }
104 104
105 void Put(uint32_t key, Address value) { 105 void Put(uint32_t key, Address value) {
106 *Lookup(key) = value; 106 *Lookup(key) = value;
107 } 107 }
108 }; 108 };
109 109
110 110
111 // A Serializer recursively visits objects to construct a serialized
112 // representation of the Heap stored in a string. Serialization is
113 // destructive. We use a similar mechanism to the GC to ensure that
114 // each object is visited once, namely, we modify the map pointer of
115 // each visited object to contain the relative address in the
116 // appropriate space where that object will be allocated when the heap
117 // is deserialized.
118
119
120 // Helper classes defined in serialize.cc.
121 class RelativeAddress;
122 class SimulatedHeapSpace;
123 class SnapshotWriter;
124 class ReferenceUpdater;
125
126
127 class Serializer: public ObjectVisitor {
128 public:
129 Serializer();
130
131 virtual ~Serializer();
132
133 // Serialize the current state of the heap. This operation destroys the
134 // heap contents and the contents of the roots into the heap.
135 void Serialize();
136
137 // Returns the serialized buffer. Ownership is transferred to the
138 // caller. Only the destructor and getters may be called after this call.
139 void Finalize(byte** str, int* len);
140
141 int roots() { return roots_; }
142 int objects() { return objects_; }
143
144 #ifdef DEBUG
145 // insert "tag" into the serialized stream
146 virtual void Synchronize(const char* tag);
147 #endif
148
149 static bool enabled() { return serialization_enabled_; }
150
151 static void Enable() {
152 if (!serialization_enabled_) {
153 ASSERT(!too_late_to_enable_now_);
154 }
155 serialization_enabled_ = true;
156 }
157
158 static void Disable() { serialization_enabled_ = false; }
159 // Call this when you have made use of the fact that there is no serialization
160 // going on.
161 static void TooLateToEnableNow() { too_late_to_enable_now_ = true; }
162
163 private:
164 friend class ReferenceUpdater;
165
166 virtual void VisitPointers(Object** start, Object** end);
167 virtual void VisitCodeTarget(RelocInfo* rinfo);
168 bool IsVisited(HeapObject* obj);
169
170 Address GetSavedAddress(HeapObject* obj);
171
172 void SaveAddress(HeapObject* obj, Address addr);
173
174 void PutEncodedAddress(Address addr);
175 // Write the global flags into the file.
176 void PutFlags();
177 // Write global information into the header of the file.
178 void PutHeader();
179 // Write the contents of the log into the file.
180 void PutLog();
181 // Serialize 'obj', and return its encoded RelativeAddress.
182 Address PutObject(HeapObject* obj);
183 // Write a stack of handles to the file bottom first.
184 void PutGlobalHandleStack(const List<Handle<Object> >& stack);
185 // Write the context stack into the file.
186 void PutContextStack();
187
188 // Return the encoded RelativeAddress where this object will be
189 // allocated on deserialization. On the first visit of 'o',
190 // serialize its contents. On return, *serialized will be true iff
191 // 'o' has just been serialized.
192 Address Encode(Object* o, bool* serialized);
193
194 // Simulate the allocation of 'obj', returning the address where it will
195 // be allocated on deserialization
196 RelativeAddress Allocate(HeapObject* obj);
197
198 void InitializeAllocators();
199
200 SnapshotWriter* writer_;
201 bool root_; // serializing a root?
202 int roots_; // number of roots visited
203 int objects_; // number of objects serialized
204
205 static bool serialization_enabled_;
206 // Did we already make use of the fact that serialization was not enabled?
207 static bool too_late_to_enable_now_;
208
209 int flags_end_; // The position right after the flags.
210
211 // An array of per-space SimulatedHeapSpaces used as memory allocators.
212 SimulatedHeapSpace* allocator_[LAST_SPACE+1];
213 // A list of global handles at serialization time.
214 List<Object**> global_handles_;
215
216 ExternalReferenceEncoder* reference_encoder_;
217
218 HashMap saved_addresses_;
219
220 DISALLOW_COPY_AND_ASSIGN(Serializer);
221 };
222
223 // Helper class to read the bytes of the serialized heap.
224
225 class SnapshotReader {
226 public:
227 SnapshotReader(const byte* str, int len): str_(str), end_(str + len) {}
228
229 void ExpectC(char expected) {
230 int c = GetC();
231 USE(c);
232 ASSERT(c == expected);
233 }
234
235 int GetC() {
236 if (str_ >= end_) return EOF;
237 return *str_++;
238 }
239
240 int GetInt() {
241 int result;
242 GetBytes(reinterpret_cast<Address>(&result), sizeof(result));
243 return result;
244 }
245
246 Address GetAddress() {
247 Address result;
248 GetBytes(reinterpret_cast<Address>(&result), sizeof(result));
249 return result;
250 }
251
252 void GetBytes(Address a, int size) {
253 ASSERT(str_ + size <= end_);
254 memcpy(a, str_, size);
255 str_ += size;
256 }
257
258 char* GetString() {
259 ExpectC('[');
260 int size = GetInt();
261 ExpectC(']');
262 char* s = NewArray<char>(size + 1);
263 GetBytes(reinterpret_cast<Address>(s), size);
264 s[size] = 0;
265 return s;
266 }
267
268 private:
269 const byte* str_;
270 const byte* end_;
271 };
272
273
274 // A Deserializer reads a snapshot and reconstructs the Object graph it defines.
275
276
277 // TODO(erikcorry): Get rid of this superclass when we are using the new
278 // snapshot code exclusively.
279 class GenericDeserializer: public ObjectVisitor {
280 public:
281 virtual void GetLog() = 0;
282 virtual void Deserialize() = 0;
283 };
284
285
286 // TODO(erikcorry): Get rid of this class.
287 class Deserializer: public GenericDeserializer {
288 public:
289 // Create a deserializer. The snapshot is held in str and has size len.
290 Deserializer(const byte* str, int len);
291
292 virtual ~Deserializer();
293
294 // Read the flags from the header of the file, and set those that
295 // should be inherited from the snapshot.
296 void GetFlags();
297
298 // Read saved profiling information from the file and log it if required.
299 void GetLog();
300
301 // Deserialize the snapshot into an empty heap.
302 void Deserialize();
303
304 int roots() { return roots_; }
305 int objects() { return objects_; }
306
307 #ifdef DEBUG
308 // Check for the presence of "tag" in the serialized stream
309 virtual void Synchronize(const char* tag);
310 #endif
311
312 private:
313 virtual void VisitPointers(Object** start, Object** end);
314 virtual void VisitCodeTarget(RelocInfo* rinfo);
315 virtual void VisitExternalReferences(Address* start, Address* end);
316 virtual void VisitRuntimeEntry(RelocInfo* rinfo);
317
318 Address GetEncodedAddress();
319
320 // Read other global information (except flags) from the header of the file.
321 void GetHeader();
322 // Read a stack of handles from the file bottom first.
323 void GetGlobalHandleStack(List<Handle<Object> >* stack);
324 // Read the context stack from the file.
325 void GetContextStack();
326
327 Object* GetObject();
328
329 // Get the encoded address. In debug mode we make sure
330 // it matches the given expectations.
331 void ExpectEncodedAddress(Address expected);
332
333 // Given an encoded address (the result of
334 // RelativeAddress::Encode), return the object to which it points,
335 // which will be either an Smi or a HeapObject in the current heap.
336 Object* Resolve(Address encoded_address);
337
338 SnapshotReader reader_;
339 bool root_; // Deserializing a root?
340 int roots_; // number of roots visited
341 int objects_; // number of objects serialized
342
343 bool has_log_; // The file has log information.
344
345 // Resolve caches the following:
346 List<Page*> map_pages_; // All pages in the map space.
347 List<Page*> cell_pages_; // All pages in the cell space.
348 List<Page*> old_pointer_pages_; // All pages in the old pointer space.
349 List<Page*> old_data_pages_; // All pages in the old data space.
350 List<Page*> code_pages_; // All pages in the code space.
351 List<Object*> large_objects_; // All known large objects.
352 // A list of global handles at deserialization time.
353 List<Object**> global_handles_;
354
355 ExternalReferenceDecoder* reference_decoder_;
356
357 #ifdef DEBUG
358 bool expect_debug_information_;
359 #endif
360
361 DISALLOW_COPY_AND_ASSIGN(Deserializer);
362 };
363
364
365 class SnapshotByteSource { 111 class SnapshotByteSource {
366 public: 112 public:
367 SnapshotByteSource(const byte* array, int length) 113 SnapshotByteSource(const byte* array, int length)
368 : data_(array), length_(length), position_(0) { } 114 : data_(array), length_(length), position_(0) { }
369 115
370 bool HasMore() { return position_ < length_; } 116 bool HasMore() { return position_ < length_; }
371 117
372 int Get() { 118 int Get() {
373 ASSERT(position_ < length_); 119 ASSERT(position_ < length_);
374 return data_[position_++]; 120 return data_[position_++];
(...skipping 25 matching lines...) Expand all
400 bool AtEOF() { 146 bool AtEOF() {
401 return position_ == length_; 147 return position_ == length_;
402 } 148 }
403 149
404 private: 150 private:
405 const byte* data_; 151 const byte* data_;
406 int length_; 152 int length_;
407 int position_; 153 int position_;
408 }; 154 };
409 155
156
410 // It is very common to have a reference to the object at word 10 in space 2, 157 // It is very common to have a reference to the object at word 10 in space 2,
411 // the object at word 5 in space 2 and the object at word 28 in space 4. This 158 // the object at word 5 in space 2 and the object at word 28 in space 4. This
412 // only works for objects in the first page of a space. 159 // only works for objects in the first page of a space.
413 #define COMMON_REFERENCE_PATTERNS(f) \ 160 #define COMMON_REFERENCE_PATTERNS(f) \
414 f(kNumberOfSpaces, 2, 10) \ 161 f(kNumberOfSpaces, 2, 10) \
415 f(kNumberOfSpaces + 1, 2, 5) \ 162 f(kNumberOfSpaces + 1, 2, 5) \
416 f(kNumberOfSpaces + 2, 4, 28) \ 163 f(kNumberOfSpaces + 2, 4, 28) \
417 f(kNumberOfSpaces + 3, 2, 21) \ 164 f(kNumberOfSpaces + 3, 2, 21) \
418 f(kNumberOfSpaces + 4, 2, 98) \ 165 f(kNumberOfSpaces + 4, 2, 98) \
419 f(kNumberOfSpaces + 5, 2, 67) \ 166 f(kNumberOfSpaces + 5, 2, 67) \
420 f(kNumberOfSpaces + 6, 4, 132) 167 f(kNumberOfSpaces + 6, 4, 132)
421 168
422 #define COMMON_RAW_LENGTHS(f) \ 169 #define COMMON_RAW_LENGTHS(f) \
423 f(1, 1) \ 170 f(1, 1) \
424 f(2, 2) \ 171 f(2, 2) \
425 f(3, 3) \ 172 f(3, 3) \
426 f(4, 4) \ 173 f(4, 4) \
427 f(5, 5) \ 174 f(5, 5) \
428 f(6, 6) \ 175 f(6, 6) \
429 f(7, 7) \ 176 f(7, 7) \
430 f(8, 8) \ 177 f(8, 8) \
431 f(9, 12) \ 178 f(9, 12) \
432 f(10, 16) \ 179 f(10, 16) \
433 f(11, 20) \ 180 f(11, 20) \
434 f(12, 24) \ 181 f(12, 24) \
435 f(13, 28) \ 182 f(13, 28) \
436 f(14, 32) \ 183 f(14, 32) \
437 f(15, 36) 184 f(15, 36)
438 185
439 // The SerDes class is a common superclass for Serializer2 and Deserializer2 186 // The SerDes class is a common superclass for Serializer and Deserializer
440 // which is used to store common constants and methods used by both. 187 // which is used to store common constants and methods used by both.
441 // TODO(erikcorry): This should inherit from ObjectVisitor. 188 class SerDes: public ObjectVisitor {
442 class SerDes: public GenericDeserializer {
443 protected: 189 protected:
444 enum DataType { 190 enum DataType {
445 RAW_DATA_SERIALIZATION = 0, 191 RAW_DATA_SERIALIZATION = 0,
446 // And 15 common raw lengths. 192 // And 15 common raw lengths.
447 OBJECT_SERIALIZATION = 16, 193 OBJECT_SERIALIZATION = 16,
448 // One variant per space. 194 // One variant per space.
449 CODE_OBJECT_SERIALIZATION = 25, 195 CODE_OBJECT_SERIALIZATION = 25,
450 // One per space (only code spaces in use). 196 // One per space (only code spaces in use).
451 EXTERNAL_REFERENCE_SERIALIZATION = 34, 197 EXTERNAL_REFERENCE_SERIALIZATION = 34,
452 EXTERNAL_BRANCH_TARGET_SERIALIZATION = 35, 198 EXTERNAL_BRANCH_TARGET_SERIALIZATION = 35,
(...skipping 23 matching lines...) Expand all
476 222
477 static inline bool SpaceIsLarge(int space) { return space >= kLargeData; } 223 static inline bool SpaceIsLarge(int space) { return space >= kLargeData; }
478 static inline bool SpaceIsPaged(int space) { 224 static inline bool SpaceIsPaged(int space) {
479 return space >= FIRST_PAGED_SPACE && space <= LAST_PAGED_SPACE; 225 return space >= FIRST_PAGED_SPACE && space <= LAST_PAGED_SPACE;
480 } 226 }
481 }; 227 };
482 228
483 229
484 230
485 // A Deserializer reads a snapshot and reconstructs the Object graph it defines. 231 // A Deserializer reads a snapshot and reconstructs the Object graph it defines.
486 class Deserializer2: public SerDes { 232 class Deserializer: public SerDes {
487 public: 233 public:
488 // Create a deserializer from a snapshot byte source. 234 // Create a deserializer from a snapshot byte source.
489 explicit Deserializer2(SnapshotByteSource* source); 235 explicit Deserializer(SnapshotByteSource* source);
490 236
491 virtual ~Deserializer2() { } 237 virtual ~Deserializer() { }
492 238
493 // Deserialize the snapshot into an empty heap. 239 // Deserialize the snapshot into an empty heap.
494 void Deserialize(); 240 void Deserialize();
495 void GetLog() { } // TODO(erikcorry): Get rid of this.
496 #ifdef DEBUG 241 #ifdef DEBUG
497 virtual void Synchronize(const char* tag); 242 virtual void Synchronize(const char* tag);
498 #endif 243 #endif
499 244
500 private: 245 private:
501 virtual void VisitPointers(Object** start, Object** end); 246 virtual void VisitPointers(Object** start, Object** end);
502 247
503 virtual void VisitExternalReferences(Address* start, Address* end) { 248 virtual void VisitExternalReferences(Address* start, Address* end) {
504 UNREACHABLE(); 249 UNREACHABLE();
505 } 250 }
(...skipping 17 matching lines...) Expand all
523 SnapshotByteSource* source_; 268 SnapshotByteSource* source_;
524 ExternalReferenceDecoder* external_reference_decoder_; 269 ExternalReferenceDecoder* external_reference_decoder_;
525 // This is the address of the next object that will be allocated in each 270 // This is the address of the next object that will be allocated in each
526 // space. It is used to calculate the addresses of back-references. 271 // space. It is used to calculate the addresses of back-references.
527 Address high_water_[LAST_SPACE + 1]; 272 Address high_water_[LAST_SPACE + 1];
528 // This is the address of the most recent object that was allocated. It 273 // This is the address of the most recent object that was allocated. It
529 // is used to set the location of the new page when we encounter a 274 // is used to set the location of the new page when we encounter a
530 // START_NEW_PAGE_SERIALIZATION tag. 275 // START_NEW_PAGE_SERIALIZATION tag.
531 Address last_object_address_; 276 Address last_object_address_;
532 277
533 DISALLOW_COPY_AND_ASSIGN(Deserializer2); 278 DISALLOW_COPY_AND_ASSIGN(Deserializer);
534 }; 279 };
535 280
536 281
537 class SnapshotByteSink { 282 class SnapshotByteSink {
538 public: 283 public:
539 virtual ~SnapshotByteSink() { } 284 virtual ~SnapshotByteSink() { }
540 virtual void Put(int byte, const char* description) = 0; 285 virtual void Put(int byte, const char* description) = 0;
541 virtual void PutSection(int byte, const char* description) { 286 virtual void PutSection(int byte, const char* description) {
542 Put(byte, description); 287 Put(byte, description);
543 } 288 }
544 void PutInt(uintptr_t integer, const char* description); 289 void PutInt(uintptr_t integer, const char* description);
545 }; 290 };
546 291
547 292
548 class Serializer2 : public SerDes { 293 class Serializer : public SerDes {
549 public: 294 public:
550 explicit Serializer2(SnapshotByteSink* sink); 295 explicit Serializer(SnapshotByteSink* sink);
551 // Serialize the current state of the heap. This operation destroys the 296 // Serialize the current state of the heap. This operation destroys the
552 // heap contents. 297 // heap contents.
553 void Serialize(); 298 void Serialize();
554 void VisitPointers(Object** start, Object** end); 299 void VisitPointers(Object** start, Object** end);
555 void GetLog() { } // TODO(erikcorry): Get rid of this. 300
556 void Deserialize() { } // TODO(erikcorry): Get rid of this. 301 static void Enable() {
302 if (!serialization_enabled_) {
303 ASSERT(!too_late_to_enable_now_);
304 }
305 serialization_enabled_ = true;
306 }
307
308 static void Disable() { serialization_enabled_ = false; }
309 // Call this when you have made use of the fact that there is no serialization
310 // going on.
311 static void TooLateToEnableNow() { too_late_to_enable_now_ = true; }
312 static bool enabled() { return serialization_enabled_; }
557 #ifdef DEBUG 313 #ifdef DEBUG
558 virtual void Synchronize(const char* tag); 314 virtual void Synchronize(const char* tag);
559 #endif 315 #endif
560 316
561 private: 317 private:
562 enum ReferenceRepresentation { 318 enum ReferenceRepresentation {
563 TAGGED_REPRESENTATION, // A tagged object reference. 319 TAGGED_REPRESENTATION, // A tagged object reference.
564 CODE_TARGET_REPRESENTATION // A reference to first instruction in target. 320 CODE_TARGET_REPRESENTATION // A reference to first instruction in target.
565 }; 321 };
566 class ObjectSerializer : public ObjectVisitor { 322 class ObjectSerializer : public ObjectVisitor {
567 public: 323 public:
568 ObjectSerializer(Serializer2* serializer, 324 ObjectSerializer(Serializer* serializer,
569 Object* o, 325 Object* o,
570 SnapshotByteSink* sink, 326 SnapshotByteSink* sink,
571 ReferenceRepresentation representation) 327 ReferenceRepresentation representation)
572 : serializer_(serializer), 328 : serializer_(serializer),
573 object_(HeapObject::cast(o)), 329 object_(HeapObject::cast(o)),
574 sink_(sink), 330 sink_(sink),
575 reference_representation_(representation), 331 reference_representation_(representation),
576 bytes_processed_so_far_(0) { } 332 bytes_processed_so_far_(0) { }
577 void Serialize(); 333 void Serialize();
578 void VisitPointers(Object** start, Object** end); 334 void VisitPointers(Object** start, Object** end);
579 void VisitExternalReferences(Address* start, Address* end); 335 void VisitExternalReferences(Address* start, Address* end);
580 void VisitCodeTarget(RelocInfo* target); 336 void VisitCodeTarget(RelocInfo* target);
581 void VisitRuntimeEntry(RelocInfo* reloc); 337 void VisitRuntimeEntry(RelocInfo* reloc);
582 // Used for seralizing the external strings that hold the natives source. 338 // Used for seralizing the external strings that hold the natives source.
583 void VisitExternalAsciiString( 339 void VisitExternalAsciiString(
584 v8::String::ExternalAsciiStringResource** resource); 340 v8::String::ExternalAsciiStringResource** resource);
585 // We can't serialize a heap with external two byte strings. 341 // We can't serialize a heap with external two byte strings.
586 void VisitExternalTwoByteString( 342 void VisitExternalTwoByteString(
587 v8::String::ExternalStringResource** resource) { 343 v8::String::ExternalStringResource** resource) {
588 UNREACHABLE(); 344 UNREACHABLE();
589 } 345 }
590 346
591 private: 347 private:
592 void OutputRawData(Address up_to); 348 void OutputRawData(Address up_to);
593 349
594 Serializer2* serializer_; 350 Serializer* serializer_;
595 HeapObject* object_; 351 HeapObject* object_;
596 SnapshotByteSink* sink_; 352 SnapshotByteSink* sink_;
597 ReferenceRepresentation reference_representation_; 353 ReferenceRepresentation reference_representation_;
598 int bytes_processed_so_far_; 354 int bytes_processed_so_far_;
599 }; 355 };
600 356
601 void SerializeObject(Object* o, ReferenceRepresentation representation); 357 void SerializeObject(Object* o, ReferenceRepresentation representation);
602 void InitializeAllocators(); 358 void InitializeAllocators();
603 // This will return the space for an object. If the object is in large 359 // This will return the space for an object. If the object is in large
604 // object space it may return kLargeCode or kLargeFixedArray in order 360 // object space it may return kLargeCode or kLargeFixedArray in order
(...skipping 14 matching lines...) Expand all
619 } 375 }
620 376
621 // Keep track of the fullness of each space in order to generate 377 // Keep track of the fullness of each space in order to generate
622 // relative addresses for back references. Large objects are 378 // relative addresses for back references. Large objects are
623 // just numbered sequentially since relative addresses make no 379 // just numbered sequentially since relative addresses make no
624 // sense in large object space. 380 // sense in large object space.
625 int fullness_[LAST_SPACE + 1]; 381 int fullness_[LAST_SPACE + 1];
626 SnapshotByteSink* sink_; 382 SnapshotByteSink* sink_;
627 int current_root_index_; 383 int current_root_index_;
628 ExternalReferenceEncoder* external_reference_encoder_; 384 ExternalReferenceEncoder* external_reference_encoder_;
385 static bool serialization_enabled_;
386 // Did we already make use of the fact that serialization was not enabled?
387 static bool too_late_to_enable_now_;
629 388
630 friend class ObjectSerializer; 389 friend class ObjectSerializer;
631 friend class Deserializer2; 390 friend class Deserializer;
632 391
633 DISALLOW_COPY_AND_ASSIGN(Serializer2); 392 DISALLOW_COPY_AND_ASSIGN(Serializer);
634 }; 393 };
635 394
636 } } // namespace v8::internal 395 } } // namespace v8::internal
637 396
638 #endif // V8_SERIALIZE_H_ 397 #endif // V8_SERIALIZE_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698