| 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 |