OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 |
(...skipping 540 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
551 ExternalReferenceDecoder::~ExternalReferenceDecoder() { | 551 ExternalReferenceDecoder::~ExternalReferenceDecoder() { |
552 for (int type = kFirstTypeCode; type < kTypeCodeCount; ++type) { | 552 for (int type = kFirstTypeCode; type < kTypeCodeCount; ++type) { |
553 DeleteArray(encodings_[type]); | 553 DeleteArray(encodings_[type]); |
554 } | 554 } |
555 DeleteArray(encodings_); | 555 DeleteArray(encodings_); |
556 } | 556 } |
557 | 557 |
558 | 558 |
559 bool Serializer::serialization_enabled_ = false; | 559 bool Serializer::serialization_enabled_ = false; |
560 bool Serializer::too_late_to_enable_now_ = false; | 560 bool Serializer::too_late_to_enable_now_ = false; |
| 561 ExternalReferenceDecoder* Deserializer::external_reference_decoder_ = NULL; |
561 | 562 |
562 | 563 |
563 Deserializer::Deserializer(SnapshotByteSource* source) | 564 Deserializer::Deserializer(SnapshotByteSource* source) : source_(source) { |
564 : source_(source), | |
565 external_reference_decoder_(NULL) { | |
566 } | 565 } |
567 | 566 |
568 | 567 |
569 // This routine both allocates a new object, and also keeps | 568 // This routine both allocates a new object, and also keeps |
570 // track of where objects have been allocated so that we can | 569 // track of where objects have been allocated so that we can |
571 // fix back references when deserializing. | 570 // fix back references when deserializing. |
572 Address Deserializer::Allocate(int space_index, Space* space, int size) { | 571 Address Deserializer::Allocate(int space_index, Space* space, int size) { |
573 Address address; | 572 Address address; |
574 if (!SpaceIsLarge(space_index)) { | 573 if (!SpaceIsLarge(space_index)) { |
575 ASSERT(!SpaceIsPaged(space_index) || | 574 ASSERT(!SpaceIsPaged(space_index) || |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
645 // Don't use the free lists while deserializing. | 644 // Don't use the free lists while deserializing. |
646 LinearAllocationScope allocate_linearly; | 645 LinearAllocationScope allocate_linearly; |
647 // No active threads. | 646 // No active threads. |
648 ASSERT_EQ(NULL, ThreadState::FirstInUse()); | 647 ASSERT_EQ(NULL, ThreadState::FirstInUse()); |
649 // No active handles. | 648 // No active handles. |
650 ASSERT(HandleScopeImplementer::instance()->blocks()->is_empty()); | 649 ASSERT(HandleScopeImplementer::instance()->blocks()->is_empty()); |
651 ASSERT_EQ(NULL, external_reference_decoder_); | 650 ASSERT_EQ(NULL, external_reference_decoder_); |
652 external_reference_decoder_ = new ExternalReferenceDecoder(); | 651 external_reference_decoder_ = new ExternalReferenceDecoder(); |
653 Heap::IterateRoots(this, VISIT_ONLY_STRONG); | 652 Heap::IterateRoots(this, VISIT_ONLY_STRONG); |
654 ASSERT(source_->AtEOF()); | 653 ASSERT(source_->AtEOF()); |
655 delete external_reference_decoder_; | 654 } |
656 external_reference_decoder_ = NULL; | 655 |
| 656 |
| 657 void Deserializer::DeserializePartial(Object** root) { |
| 658 // Don't GC while deserializing - just expand the heap. |
| 659 AlwaysAllocateScope always_allocate; |
| 660 // Don't use the free lists while deserializing. |
| 661 LinearAllocationScope allocate_linearly; |
| 662 if (external_reference_decoder_ == NULL) { |
| 663 external_reference_decoder_ = new ExternalReferenceDecoder(); |
| 664 } |
| 665 VisitPointer(root); |
| 666 } |
| 667 |
| 668 |
| 669 void Deserializer::TearDown() { |
| 670 if (external_reference_decoder_ != NULL) { |
| 671 delete external_reference_decoder_; |
| 672 external_reference_decoder_ = NULL; |
| 673 } |
657 } | 674 } |
658 | 675 |
659 | 676 |
660 // This is called on the roots. It is the driver of the deserialization | 677 // This is called on the roots. It is the driver of the deserialization |
661 // process. It is also called on the body of each function. | 678 // process. It is also called on the body of each function. |
662 void Deserializer::VisitPointers(Object** start, Object** end) { | 679 void Deserializer::VisitPointers(Object** start, Object** end) { |
663 // The space must be new space. Any other space would cause ReadChunk to try | 680 // The space must be new space. Any other space would cause ReadChunk to try |
664 // to update the remembered using NULL as the address. | 681 // to update the remembered using NULL as the address. |
665 ReadChunk(start, end, NEW_SPACE, NULL); | 682 ReadChunk(start, end, NEW_SPACE, NULL); |
666 } | 683 } |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
859 break; | 876 break; |
860 } | 877 } |
861 case NATIVES_STRING_RESOURCE: { | 878 case NATIVES_STRING_RESOURCE: { |
862 int index = source_->Get(); | 879 int index = source_->Get(); |
863 Vector<const char> source_vector = Natives::GetScriptSource(index); | 880 Vector<const char> source_vector = Natives::GetScriptSource(index); |
864 NativesExternalStringResource* resource = | 881 NativesExternalStringResource* resource = |
865 new NativesExternalStringResource(source_vector.start()); | 882 new NativesExternalStringResource(source_vector.start()); |
866 *current++ = reinterpret_cast<Object*>(resource); | 883 *current++ = reinterpret_cast<Object*>(resource); |
867 break; | 884 break; |
868 } | 885 } |
| 886 case ROOT_SERIALIZATION: { |
| 887 int root_id = source_->GetInt(); |
| 888 *current++ = Heap::roots_address()[root_id]; |
| 889 break; |
| 890 } |
869 default: | 891 default: |
870 UNREACHABLE(); | 892 UNREACHABLE(); |
871 } | 893 } |
872 } | 894 } |
873 ASSERT_EQ(current, limit); | 895 ASSERT_EQ(current, limit); |
874 } | 896 } |
875 | 897 |
876 | 898 |
877 void SnapshotByteSink::PutInt(uintptr_t integer, const char* description) { | 899 void SnapshotByteSink::PutInt(uintptr_t integer, const char* description) { |
878 const int max_shift = ((kPointerSize * kBitsPerByte) / 7) * 7; | 900 const int max_shift = ((kPointerSize * kBitsPerByte) / 7) * 7; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
912 sink_->PutSection(character, "TagCharacter"); | 934 sink_->PutSection(character, "TagCharacter"); |
913 } while (character != 0); | 935 } while (character != 0); |
914 } | 936 } |
915 | 937 |
916 #endif | 938 #endif |
917 | 939 |
918 Serializer::Serializer(SnapshotByteSink* sink) | 940 Serializer::Serializer(SnapshotByteSink* sink) |
919 : sink_(sink), | 941 : sink_(sink), |
920 current_root_index_(0), | 942 current_root_index_(0), |
921 external_reference_encoder_(NULL), | 943 external_reference_encoder_(NULL), |
922 partial_(false) { | 944 partial_(false), |
| 945 large_object_total_(0) { |
923 for (int i = 0; i <= LAST_SPACE; i++) { | 946 for (int i = 0; i <= LAST_SPACE; i++) { |
924 fullness_[i] = 0; | 947 fullness_[i] = 0; |
925 } | 948 } |
926 } | 949 } |
927 | 950 |
928 | 951 |
929 void Serializer::Serialize() { | 952 void Serializer::Serialize() { |
930 // No active threads. | 953 // No active threads. |
931 CHECK_EQ(NULL, ThreadState::FirstInUse()); | 954 CHECK_EQ(NULL, ThreadState::FirstInUse()); |
932 // No active or weak handles. | 955 // No active or weak handles. |
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1223 return 0; | 1246 return 0; |
1224 } | 1247 } |
1225 | 1248 |
1226 | 1249 |
1227 int Serializer::Allocate(int space, int size, bool* new_page) { | 1250 int Serializer::Allocate(int space, int size, bool* new_page) { |
1228 CHECK(space >= 0 && space < kNumberOfSpaces); | 1251 CHECK(space >= 0 && space < kNumberOfSpaces); |
1229 if (SpaceIsLarge(space)) { | 1252 if (SpaceIsLarge(space)) { |
1230 // In large object space we merely number the objects instead of trying to | 1253 // In large object space we merely number the objects instead of trying to |
1231 // determine some sort of address. | 1254 // determine some sort of address. |
1232 *new_page = true; | 1255 *new_page = true; |
| 1256 large_object_total_ += size; |
1233 return fullness_[LO_SPACE]++; | 1257 return fullness_[LO_SPACE]++; |
1234 } | 1258 } |
1235 *new_page = false; | 1259 *new_page = false; |
1236 if (fullness_[space] == 0) { | 1260 if (fullness_[space] == 0) { |
1237 *new_page = true; | 1261 *new_page = true; |
1238 } | 1262 } |
1239 if (SpaceIsPaged(space)) { | 1263 if (SpaceIsPaged(space)) { |
1240 // Paged spaces are a little special. We encode their addresses as if the | 1264 // Paged spaces are a little special. We encode their addresses as if the |
1241 // pages were all contiguous and each page were filled up in the range | 1265 // pages were all contiguous and each page were filled up in the range |
1242 // 0 - Page::kObjectAreaSize. In practice the pages may not be contiguous | 1266 // 0 - Page::kObjectAreaSize. In practice the pages may not be contiguous |
1243 // and allocation does not start at offset 0 in the page, but this scheme | 1267 // and allocation does not start at offset 0 in the page, but this scheme |
1244 // means the deserializer can get the page number quickly by shifting the | 1268 // means the deserializer can get the page number quickly by shifting the |
1245 // serialized address. | 1269 // serialized address. |
1246 CHECK(IsPowerOf2(Page::kPageSize)); | 1270 CHECK(IsPowerOf2(Page::kPageSize)); |
1247 int used_in_this_page = (fullness_[space] & (Page::kPageSize - 1)); | 1271 int used_in_this_page = (fullness_[space] & (Page::kPageSize - 1)); |
1248 CHECK(size <= Page::kObjectAreaSize); | 1272 CHECK(size <= Page::kObjectAreaSize); |
1249 if (used_in_this_page + size > Page::kObjectAreaSize) { | 1273 if (used_in_this_page + size > Page::kObjectAreaSize) { |
1250 *new_page = true; | 1274 *new_page = true; |
1251 fullness_[space] = RoundUp(fullness_[space], Page::kPageSize); | 1275 fullness_[space] = RoundUp(fullness_[space], Page::kPageSize); |
1252 } | 1276 } |
1253 } | 1277 } |
1254 int allocation_address = fullness_[space]; | 1278 int allocation_address = fullness_[space]; |
1255 fullness_[space] = allocation_address + size; | 1279 fullness_[space] = allocation_address + size; |
1256 return allocation_address; | 1280 return allocation_address; |
1257 } | 1281 } |
1258 | 1282 |
1259 | 1283 |
1260 } } // namespace v8::internal | 1284 } } // namespace v8::internal |
OLD | NEW |