| OLD | NEW |
| 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 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 116 Address Decode(uint32_t key) const { | 116 Address Decode(uint32_t key) const { |
| 117 if (key == 0) return NULL; | 117 if (key == 0) return NULL; |
| 118 return *Lookup(key); | 118 return *Lookup(key); |
| 119 } | 119 } |
| 120 | 120 |
| 121 private: | 121 private: |
| 122 Address** encodings_; | 122 Address** encodings_; |
| 123 | 123 |
| 124 Address* Lookup(uint32_t key) const { | 124 Address* Lookup(uint32_t key) const { |
| 125 int type = key >> kReferenceTypeShift; | 125 int type = key >> kReferenceTypeShift; |
| 126 ASSERT(kFirstTypeCode <= type && type < kTypeCodeCount); | 126 DCHECK(kFirstTypeCode <= type && type < kTypeCodeCount); |
| 127 int id = key & kReferenceIdMask; | 127 int id = key & kReferenceIdMask; |
| 128 return &encodings_[type][id]; | 128 return &encodings_[type][id]; |
| 129 } | 129 } |
| 130 | 130 |
| 131 void Put(uint32_t key, Address value) { | 131 void Put(uint32_t key, Address value) { |
| 132 *Lookup(key) = value; | 132 *Lookup(key) = value; |
| 133 } | 133 } |
| 134 | 134 |
| 135 Isolate* isolate_; | 135 Isolate* isolate_; |
| 136 }; | 136 }; |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 201 // mismatches. | 201 // mismatches. |
| 202 static const int kSynchronize = 0x70; | 202 static const int kSynchronize = 0x70; |
| 203 // Used for the source code of the natives, which is in the executable, but | 203 // Used for the source code of the natives, which is in the executable, but |
| 204 // is referred to from external strings in the snapshot. | 204 // is referred to from external strings in the snapshot. |
| 205 static const int kNativesStringResource = 0x71; | 205 static const int kNativesStringResource = 0x71; |
| 206 static const int kRepeat = 0x72; | 206 static const int kRepeat = 0x72; |
| 207 static const int kConstantRepeat = 0x73; | 207 static const int kConstantRepeat = 0x73; |
| 208 // 0x73-0x7f Repeat last word (subtract 0x72 to get the count). | 208 // 0x73-0x7f Repeat last word (subtract 0x72 to get the count). |
| 209 static const int kMaxRepeats = 0x7f - 0x72; | 209 static const int kMaxRepeats = 0x7f - 0x72; |
| 210 static int CodeForRepeats(int repeats) { | 210 static int CodeForRepeats(int repeats) { |
| 211 ASSERT(repeats >= 1 && repeats <= kMaxRepeats); | 211 DCHECK(repeats >= 1 && repeats <= kMaxRepeats); |
| 212 return 0x72 + repeats; | 212 return 0x72 + repeats; |
| 213 } | 213 } |
| 214 static int RepeatsForCode(int byte_code) { | 214 static int RepeatsForCode(int byte_code) { |
| 215 ASSERT(byte_code >= kConstantRepeat && byte_code <= 0x7f); | 215 DCHECK(byte_code >= kConstantRepeat && byte_code <= 0x7f); |
| 216 return byte_code - 0x72; | 216 return byte_code - 0x72; |
| 217 } | 217 } |
| 218 static const int kRootArrayConstants = 0xa0; | 218 static const int kRootArrayConstants = 0xa0; |
| 219 // 0xa0-0xbf Things from the first 32 elements of the root array. | 219 // 0xa0-0xbf Things from the first 32 elements of the root array. |
| 220 static const int kRootArrayNumberOfConstantEncodings = 0x20; | 220 static const int kRootArrayNumberOfConstantEncodings = 0x20; |
| 221 static int RootArrayConstantFromByteCode(int byte_code) { | 221 static int RootArrayConstantFromByteCode(int byte_code) { |
| 222 return byte_code & 0x1f; | 222 return byte_code & 0x1f; |
| 223 } | 223 } |
| 224 | 224 |
| 225 static const int kNumberOfSpaces = LO_SPACE; | 225 static const int kNumberOfSpaces = LO_SPACE; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 238 | 238 |
| 239 virtual ~Deserializer(); | 239 virtual ~Deserializer(); |
| 240 | 240 |
| 241 // Deserialize the snapshot into an empty heap. | 241 // Deserialize the snapshot into an empty heap. |
| 242 void Deserialize(Isolate* isolate); | 242 void Deserialize(Isolate* isolate); |
| 243 | 243 |
| 244 // Deserialize a single object and the objects reachable from it. | 244 // Deserialize a single object and the objects reachable from it. |
| 245 void DeserializePartial(Isolate* isolate, Object** root); | 245 void DeserializePartial(Isolate* isolate, Object** root); |
| 246 | 246 |
| 247 void set_reservation(int space_number, int reservation) { | 247 void set_reservation(int space_number, int reservation) { |
| 248 ASSERT(space_number >= 0); | 248 DCHECK(space_number >= 0); |
| 249 ASSERT(space_number <= LAST_SPACE); | 249 DCHECK(space_number <= LAST_SPACE); |
| 250 reservations_[space_number] = reservation; | 250 reservations_[space_number] = reservation; |
| 251 } | 251 } |
| 252 | 252 |
| 253 void FlushICacheForNewCodeObjects(); | 253 void FlushICacheForNewCodeObjects(); |
| 254 | 254 |
| 255 // Serialized user code reference certain objects that are provided in a list | 255 // Serialized user code reference certain objects that are provided in a list |
| 256 // By calling this method, we assume that we are deserializing user code. | 256 // By calling this method, we assume that we are deserializing user code. |
| 257 void SetAttachedObjects(Vector<Object*>* attached_objects) { | 257 void SetAttachedObjects(Vector<Object*>* attached_objects) { |
| 258 attached_objects_ = attached_objects; | 258 attached_objects_ = attached_objects; |
| 259 } | 259 } |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 331 | 331 |
| 332 ~SerializationAddressMapper() { | 332 ~SerializationAddressMapper() { |
| 333 delete serialization_map_; | 333 delete serialization_map_; |
| 334 } | 334 } |
| 335 | 335 |
| 336 bool IsMapped(HeapObject* obj) { | 336 bool IsMapped(HeapObject* obj) { |
| 337 return serialization_map_->Lookup(Key(obj), Hash(obj), false) != NULL; | 337 return serialization_map_->Lookup(Key(obj), Hash(obj), false) != NULL; |
| 338 } | 338 } |
| 339 | 339 |
| 340 int MappedTo(HeapObject* obj) { | 340 int MappedTo(HeapObject* obj) { |
| 341 ASSERT(IsMapped(obj)); | 341 DCHECK(IsMapped(obj)); |
| 342 return static_cast<int>(reinterpret_cast<intptr_t>( | 342 return static_cast<int>(reinterpret_cast<intptr_t>( |
| 343 serialization_map_->Lookup(Key(obj), Hash(obj), false)->value)); | 343 serialization_map_->Lookup(Key(obj), Hash(obj), false)->value)); |
| 344 } | 344 } |
| 345 | 345 |
| 346 void AddMapping(HeapObject* obj, int to) { | 346 void AddMapping(HeapObject* obj, int to) { |
| 347 ASSERT(!IsMapped(obj)); | 347 DCHECK(!IsMapped(obj)); |
| 348 HashMap::Entry* entry = | 348 HashMap::Entry* entry = |
| 349 serialization_map_->Lookup(Key(obj), Hash(obj), true); | 349 serialization_map_->Lookup(Key(obj), Hash(obj), true); |
| 350 entry->value = Value(to); | 350 entry->value = Value(to); |
| 351 } | 351 } |
| 352 | 352 |
| 353 private: | 353 private: |
| 354 static uint32_t Hash(HeapObject* obj) { | 354 static uint32_t Hash(HeapObject* obj) { |
| 355 return static_cast<int32_t>(reinterpret_cast<intptr_t>(obj->address())); | 355 return static_cast<int32_t>(reinterpret_cast<intptr_t>(obj->address())); |
| 356 } | 356 } |
| 357 | 357 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 373 | 373 |
| 374 // There can be only one serializer per V8 process. | 374 // There can be only one serializer per V8 process. |
| 375 class Serializer : public SerializerDeserializer { | 375 class Serializer : public SerializerDeserializer { |
| 376 public: | 376 public: |
| 377 Serializer(Isolate* isolate, SnapshotByteSink* sink); | 377 Serializer(Isolate* isolate, SnapshotByteSink* sink); |
| 378 ~Serializer(); | 378 ~Serializer(); |
| 379 void VisitPointers(Object** start, Object** end); | 379 void VisitPointers(Object** start, Object** end); |
| 380 // You can call this after serialization to find out how much space was used | 380 // You can call this after serialization to find out how much space was used |
| 381 // in each space. | 381 // in each space. |
| 382 int CurrentAllocationAddress(int space) const { | 382 int CurrentAllocationAddress(int space) const { |
| 383 ASSERT(space < kNumberOfSpaces); | 383 DCHECK(space < kNumberOfSpaces); |
| 384 return fullness_[space]; | 384 return fullness_[space]; |
| 385 } | 385 } |
| 386 | 386 |
| 387 Isolate* isolate() const { return isolate_; } | 387 Isolate* isolate() const { return isolate_; } |
| 388 | 388 |
| 389 SerializationAddressMapper* address_mapper() { return &address_mapper_; } | 389 SerializationAddressMapper* address_mapper() { return &address_mapper_; } |
| 390 void PutRoot(int index, | 390 void PutRoot(int index, |
| 391 HeapObject* object, | 391 HeapObject* object, |
| 392 HowToCode how, | 392 HowToCode how, |
| 393 WhereToPoint where, | 393 WhereToPoint where, |
| 394 int skip); | 394 int skip); |
| 395 | 395 |
| 396 protected: | 396 protected: |
| 397 static const int kInvalidRootIndex = -1; | 397 static const int kInvalidRootIndex = -1; |
| 398 | 398 |
| 399 int RootIndex(HeapObject* heap_object, HowToCode from); | 399 int RootIndex(HeapObject* heap_object, HowToCode from); |
| 400 intptr_t root_index_wave_front() { return root_index_wave_front_; } | 400 intptr_t root_index_wave_front() { return root_index_wave_front_; } |
| 401 void set_root_index_wave_front(intptr_t value) { | 401 void set_root_index_wave_front(intptr_t value) { |
| 402 ASSERT(value >= root_index_wave_front_); | 402 DCHECK(value >= root_index_wave_front_); |
| 403 root_index_wave_front_ = value; | 403 root_index_wave_front_ = value; |
| 404 } | 404 } |
| 405 | 405 |
| 406 class ObjectSerializer : public ObjectVisitor { | 406 class ObjectSerializer : public ObjectVisitor { |
| 407 public: | 407 public: |
| 408 ObjectSerializer(Serializer* serializer, | 408 ObjectSerializer(Serializer* serializer, |
| 409 Object* o, | 409 Object* o, |
| 410 SnapshotByteSink* sink, | 410 SnapshotByteSink* sink, |
| 411 HowToCode how_to_code, | 411 HowToCode how_to_code, |
| 412 WhereToPoint where_to_point) | 412 WhereToPoint where_to_point) |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 518 WhereToPoint where_to_point, | 518 WhereToPoint where_to_point, |
| 519 int skip); | 519 int skip); |
| 520 | 520 |
| 521 private: | 521 private: |
| 522 int PartialSnapshotCacheIndex(HeapObject* o); | 522 int PartialSnapshotCacheIndex(HeapObject* o); |
| 523 bool ShouldBeInThePartialSnapshotCache(HeapObject* o) { | 523 bool ShouldBeInThePartialSnapshotCache(HeapObject* o) { |
| 524 // Scripts should be referred only through shared function infos. We can't | 524 // Scripts should be referred only through shared function infos. We can't |
| 525 // allow them to be part of the partial snapshot because they contain a | 525 // allow them to be part of the partial snapshot because they contain a |
| 526 // unique ID, and deserializing several partial snapshots containing script | 526 // unique ID, and deserializing several partial snapshots containing script |
| 527 // would cause dupes. | 527 // would cause dupes. |
| 528 ASSERT(!o->IsScript()); | 528 DCHECK(!o->IsScript()); |
| 529 return o->IsName() || o->IsSharedFunctionInfo() || | 529 return o->IsName() || o->IsSharedFunctionInfo() || |
| 530 o->IsHeapNumber() || o->IsCode() || | 530 o->IsHeapNumber() || o->IsCode() || |
| 531 o->IsScopeInfo() || | 531 o->IsScopeInfo() || |
| 532 o->map() == | 532 o->map() == |
| 533 startup_serializer_->isolate()->heap()->fixed_cow_array_map(); | 533 startup_serializer_->isolate()->heap()->fixed_cow_array_map(); |
| 534 } | 534 } |
| 535 | 535 |
| 536 | 536 |
| 537 Serializer* startup_serializer_; | 537 Serializer* startup_serializer_; |
| 538 DISALLOW_COPY_AND_ASSIGN(PartialSerializer); | 538 DISALLOW_COPY_AND_ASSIGN(PartialSerializer); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 586 virtual void SerializeObject(Object* o, HowToCode how_to_code, | 586 virtual void SerializeObject(Object* o, HowToCode how_to_code, |
| 587 WhereToPoint where_to_point, int skip); | 587 WhereToPoint where_to_point, int skip); |
| 588 | 588 |
| 589 static Handle<SharedFunctionInfo> Deserialize(Isolate* isolate, | 589 static Handle<SharedFunctionInfo> Deserialize(Isolate* isolate, |
| 590 ScriptData* data, | 590 ScriptData* data, |
| 591 Handle<String> source); | 591 Handle<String> source); |
| 592 | 592 |
| 593 static const int kSourceObjectIndex = 0; | 593 static const int kSourceObjectIndex = 0; |
| 594 | 594 |
| 595 String* source() { | 595 String* source() { |
| 596 ASSERT(!AllowHeapAllocation::IsAllowed()); | 596 DCHECK(!AllowHeapAllocation::IsAllowed()); |
| 597 return source_; | 597 return source_; |
| 598 } | 598 } |
| 599 | 599 |
| 600 private: | 600 private: |
| 601 void SerializeBuiltin(Code* builtin, HowToCode how_to_code, | 601 void SerializeBuiltin(Code* builtin, HowToCode how_to_code, |
| 602 WhereToPoint where_to_point, int skip); | 602 WhereToPoint where_to_point, int skip); |
| 603 void SerializeSourceObject(HowToCode how_to_code, WhereToPoint where_to_point, | 603 void SerializeSourceObject(HowToCode how_to_code, WhereToPoint where_to_point, |
| 604 int skip); | 604 int skip); |
| 605 | 605 |
| 606 DisallowHeapAllocation no_gc_; | 606 DisallowHeapAllocation no_gc_; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 623 SerializedCodeData(List<byte>* payload, CodeSerializer* cs); | 623 SerializedCodeData(List<byte>* payload, CodeSerializer* cs); |
| 624 | 624 |
| 625 ~SerializedCodeData() { | 625 ~SerializedCodeData() { |
| 626 if (owns_script_data_) delete script_data_; | 626 if (owns_script_data_) delete script_data_; |
| 627 } | 627 } |
| 628 | 628 |
| 629 // Return ScriptData object and relinquish ownership over it to the caller. | 629 // Return ScriptData object and relinquish ownership over it to the caller. |
| 630 ScriptData* GetScriptData() { | 630 ScriptData* GetScriptData() { |
| 631 ScriptData* result = script_data_; | 631 ScriptData* result = script_data_; |
| 632 script_data_ = NULL; | 632 script_data_ = NULL; |
| 633 ASSERT(owns_script_data_); | 633 DCHECK(owns_script_data_); |
| 634 owns_script_data_ = false; | 634 owns_script_data_ = false; |
| 635 return result; | 635 return result; |
| 636 } | 636 } |
| 637 | 637 |
| 638 const byte* Payload() const { | 638 const byte* Payload() const { |
| 639 return script_data_->data() + kHeaderEntries * kIntSize; | 639 return script_data_->data() + kHeaderEntries * kIntSize; |
| 640 } | 640 } |
| 641 | 641 |
| 642 int PayloadLength() const { | 642 int PayloadLength() const { |
| 643 return script_data_->length() - kHeaderEntries * kIntSize; | 643 return script_data_->length() - kHeaderEntries * kIntSize; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 667 static const int kCheckSumOffset = 0; | 667 static const int kCheckSumOffset = 0; |
| 668 static const int kReservationsOffset = 1; | 668 static const int kReservationsOffset = 1; |
| 669 static const int kHeaderEntries = 8; | 669 static const int kHeaderEntries = 8; |
| 670 | 670 |
| 671 ScriptData* script_data_; | 671 ScriptData* script_data_; |
| 672 bool owns_script_data_; | 672 bool owns_script_data_; |
| 673 }; | 673 }; |
| 674 } } // namespace v8::internal | 674 } } // namespace v8::internal |
| 675 | 675 |
| 676 #endif // V8_SERIALIZE_H_ | 676 #endif // V8_SERIALIZE_H_ |
| OLD | NEW |