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

Side by Side Diff: src/serialize.cc

Issue 8404030: Version 3.7.1 (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
Patch Set: Created 9 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
« no previous file with comments | « src/serialize.h ('k') | src/spaces.h » ('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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 300 matching lines...) Expand 10 before | Expand all | Expand 10 after
311 "StoreBuffer::StoreBufferOverflow"); 311 "StoreBuffer::StoreBufferOverflow");
312 Add(ExternalReference:: 312 Add(ExternalReference::
313 incremental_evacuation_record_write_function(isolate).address(), 313 incremental_evacuation_record_write_function(isolate).address(),
314 RUNTIME_ENTRY, 314 RUNTIME_ENTRY,
315 7, 315 7,
316 "IncrementalMarking::RecordWrite"); 316 "IncrementalMarking::RecordWrite");
317 317
318 318
319 319
320 // Miscellaneous 320 // Miscellaneous
321 Add(ExternalReference::roots_address(isolate).address(), 321 Add(ExternalReference::roots_array_start(isolate).address(),
322 UNCLASSIFIED, 322 UNCLASSIFIED,
323 3, 323 3,
324 "Heap::roots_address()"); 324 "Heap::roots_array_start()");
325 Add(ExternalReference::address_of_stack_limit(isolate).address(), 325 Add(ExternalReference::address_of_stack_limit(isolate).address(),
326 UNCLASSIFIED, 326 UNCLASSIFIED,
327 4, 327 4,
328 "StackGuard::address_of_jslimit()"); 328 "StackGuard::address_of_jslimit()");
329 Add(ExternalReference::address_of_real_stack_limit(isolate).address(), 329 Add(ExternalReference::address_of_real_stack_limit(isolate).address(),
330 UNCLASSIFIED, 330 UNCLASSIFIED,
331 5, 331 5,
332 "StackGuard::address_of_real_jslimit()"); 332 "StackGuard::address_of_real_jslimit()");
333 #ifndef V8_INTERPRETED_REGEXP 333 #ifndef V8_INTERPRETED_REGEXP
334 Add(ExternalReference::address_of_regexp_stack_limit(isolate).address(), 334 Add(ExternalReference::address_of_regexp_stack_limit(isolate).address(),
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
483 42, 483 42,
484 "power_double_int_function"); 484 "power_double_int_function");
485 Add(ExternalReference::store_buffer_top(isolate).address(), 485 Add(ExternalReference::store_buffer_top(isolate).address(),
486 UNCLASSIFIED, 486 UNCLASSIFIED,
487 43, 487 43,
488 "store_buffer_top"); 488 "store_buffer_top");
489 Add(ExternalReference::address_of_canonical_non_hole_nan().address(), 489 Add(ExternalReference::address_of_canonical_non_hole_nan().address(),
490 UNCLASSIFIED, 490 UNCLASSIFIED,
491 44, 491 44,
492 "canonical_nan"); 492 "canonical_nan");
493 Add(ExternalReference::address_of_the_hole_nan().address(),
494 UNCLASSIFIED,
495 45,
496 "the_hole_nan");
493 } 497 }
494 498
495 499
496 ExternalReferenceEncoder::ExternalReferenceEncoder() 500 ExternalReferenceEncoder::ExternalReferenceEncoder()
497 : encodings_(Match), 501 : encodings_(Match),
498 isolate_(Isolate::Current()) { 502 isolate_(Isolate::Current()) {
499 ExternalReferenceTable* external_references = 503 ExternalReferenceTable* external_references =
500 ExternalReferenceTable::instance(isolate_); 504 ExternalReferenceTable::instance(isolate_);
501 for (int i = 0; i < external_references->size(); ++i) { 505 for (int i = 0; i < external_references->size(); ++i) {
502 Put(external_references->address(i), i); 506 Put(external_references->address(i), i);
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
746 dest_space = isolate->heap()->lo_space(); \ 750 dest_space = isolate->heap()->lo_space(); \
747 } 751 }
748 752
749 753
750 static const int kUnknownOffsetFromStart = -1; 754 static const int kUnknownOffsetFromStart = -1;
751 755
752 756
753 void Deserializer::ReadChunk(Object** current, 757 void Deserializer::ReadChunk(Object** current,
754 Object** limit, 758 Object** limit,
755 int source_space, 759 int source_space,
756 Address address) { 760 Address current_object_address) {
757 Isolate* const isolate = isolate_; 761 Isolate* const isolate = isolate_;
762 bool write_barrier_needed = (current_object_address != NULL &&
763 source_space != NEW_SPACE &&
764 source_space != CELL_SPACE &&
765 source_space != CODE_SPACE &&
766 source_space != OLD_DATA_SPACE);
758 while (current < limit) { 767 while (current < limit) {
759 int data = source_->Get(); 768 int data = source_->Get();
760 switch (data) { 769 switch (data) {
761 #define CASE_STATEMENT(where, how, within, space_number) \ 770 #define CASE_STATEMENT(where, how, within, space_number) \
762 case where + how + within + space_number: \ 771 case where + how + within + space_number: \
763 ASSERT((where & ~kPointedToMask) == 0); \ 772 ASSERT((where & ~kPointedToMask) == 0); \
764 ASSERT((how & ~kHowToCodeMask) == 0); \ 773 ASSERT((how & ~kHowToCodeMask) == 0); \
765 ASSERT((within & ~kWhereToPointMask) == 0); \ 774 ASSERT((within & ~kWhereToPointMask) == 0); \
766 ASSERT((space_number & ~kSpaceMask) == 0); 775 ASSERT((space_number & ~kSpaceMask) == 0);
767 776
768 #define CASE_BODY(where, how, within, space_number_if_any, offset_from_start) \ 777 #define CASE_BODY(where, how, within, space_number_if_any, offset_from_start) \
769 { \ 778 { \
770 bool emit_write_barrier = false; \ 779 bool emit_write_barrier = false; \
771 bool current_was_incremented = false; \ 780 bool current_was_incremented = false; \
772 int space_number = space_number_if_any == kAnyOldSpace ? \ 781 int space_number = space_number_if_any == kAnyOldSpace ? \
773 (data & kSpaceMask) : space_number_if_any; \ 782 (data & kSpaceMask) : space_number_if_any; \
774 if (where == kNewObject && how == kPlain && within == kStartOfObject) {\ 783 if (where == kNewObject && how == kPlain && within == kStartOfObject) {\
775 ASSIGN_DEST_SPACE(space_number) \ 784 ASSIGN_DEST_SPACE(space_number) \
776 ReadObject(space_number, dest_space, current); \ 785 ReadObject(space_number, dest_space, current); \
777 emit_write_barrier = (space_number == NEW_SPACE && \ 786 emit_write_barrier = (space_number == NEW_SPACE); \
778 source_space != NEW_SPACE && \
779 source_space != CELL_SPACE); \
780 } else { \ 787 } else { \
781 Object* new_object = NULL; /* May not be a real Object pointer. */ \ 788 Object* new_object = NULL; /* May not be a real Object pointer. */ \
782 if (where == kNewObject) { \ 789 if (where == kNewObject) { \
783 ASSIGN_DEST_SPACE(space_number) \ 790 ASSIGN_DEST_SPACE(space_number) \
784 ReadObject(space_number, dest_space, &new_object); \ 791 ReadObject(space_number, dest_space, &new_object); \
785 } else if (where == kRootArray) { \ 792 } else if (where == kRootArray) { \
786 int root_id = source_->GetInt(); \ 793 int root_id = source_->GetInt(); \
787 new_object = isolate->heap()->roots_address()[root_id]; \ 794 new_object = isolate->heap()->roots_array_start()[root_id]; \
795 emit_write_barrier = isolate->heap()->InNewSpace(new_object); \
788 } else if (where == kPartialSnapshotCache) { \ 796 } else if (where == kPartialSnapshotCache) { \
789 int cache_index = source_->GetInt(); \ 797 int cache_index = source_->GetInt(); \
790 new_object = isolate->serialize_partial_snapshot_cache() \ 798 new_object = isolate->serialize_partial_snapshot_cache() \
791 [cache_index]; \ 799 [cache_index]; \
800 emit_write_barrier = isolate->heap()->InNewSpace(new_object); \
792 } else if (where == kExternalReference) { \ 801 } else if (where == kExternalReference) { \
793 int reference_id = source_->GetInt(); \ 802 int reference_id = source_->GetInt(); \
794 Address address = external_reference_decoder_-> \ 803 Address address = external_reference_decoder_-> \
795 Decode(reference_id); \ 804 Decode(reference_id); \
796 new_object = reinterpret_cast<Object*>(address); \ 805 new_object = reinterpret_cast<Object*>(address); \
797 } else if (where == kBackref) { \ 806 } else if (where == kBackref) { \
798 emit_write_barrier = (space_number == NEW_SPACE && \ 807 emit_write_barrier = (space_number == NEW_SPACE); \
799 source_space != NEW_SPACE && \
800 source_space != CELL_SPACE); \
801 new_object = GetAddressFromEnd(data & kSpaceMask); \ 808 new_object = GetAddressFromEnd(data & kSpaceMask); \
802 } else { \ 809 } else { \
803 ASSERT(where == kFromStart); \ 810 ASSERT(where == kFromStart); \
804 if (offset_from_start == kUnknownOffsetFromStart) { \ 811 if (offset_from_start == kUnknownOffsetFromStart) { \
805 emit_write_barrier = (space_number == NEW_SPACE && \ 812 emit_write_barrier = (space_number == NEW_SPACE); \
806 source_space != NEW_SPACE && \
807 source_space != CELL_SPACE); \
808 new_object = GetAddressFromStart(data & kSpaceMask); \ 813 new_object = GetAddressFromStart(data & kSpaceMask); \
809 } else { \ 814 } else { \
810 Address object_address = pages_[space_number][0] + \ 815 Address object_address = pages_[space_number][0] + \
811 (offset_from_start << kObjectAlignmentBits); \ 816 (offset_from_start << kObjectAlignmentBits); \
812 new_object = HeapObject::FromAddress(object_address); \ 817 new_object = HeapObject::FromAddress(object_address); \
813 } \ 818 } \
814 } \ 819 } \
815 if (within == kFirstInstruction) { \ 820 if (within == kFirstInstruction) { \
816 Code* new_code_object = reinterpret_cast<Code*>(new_object); \ 821 Code* new_code_object = reinterpret_cast<Code*>(new_object); \
817 new_object = reinterpret_cast<Object*>( \ 822 new_object = reinterpret_cast<Object*>( \
818 new_code_object->instruction_start()); \ 823 new_code_object->instruction_start()); \
819 } \ 824 } \
820 if (how == kFromCode) { \ 825 if (how == kFromCode) { \
821 Address location_of_branch_data = \ 826 Address location_of_branch_data = \
822 reinterpret_cast<Address>(current); \ 827 reinterpret_cast<Address>(current); \
823 Assembler::set_target_at(location_of_branch_data, \ 828 Assembler::set_target_at(location_of_branch_data, \
824 reinterpret_cast<Address>(new_object)); \ 829 reinterpret_cast<Address>(new_object)); \
825 if (within == kFirstInstruction) { \ 830 if (within == kFirstInstruction) { \
826 location_of_branch_data += Assembler::kCallTargetSize; \ 831 location_of_branch_data += Assembler::kCallTargetSize; \
827 current = reinterpret_cast<Object**>(location_of_branch_data); \ 832 current = reinterpret_cast<Object**>(location_of_branch_data); \
828 current_was_incremented = true; \ 833 current_was_incremented = true; \
829 } \ 834 } \
830 } else { \ 835 } else { \
831 *current = new_object; \ 836 *current = new_object; \
832 } \ 837 } \
833 } \ 838 } \
834 if (emit_write_barrier) { \ 839 if (emit_write_barrier && write_barrier_needed) { \
835 isolate->heap()->RecordWrite(address, static_cast<int>( \ 840 Address current_address = reinterpret_cast<Address>(current); \
836 reinterpret_cast<Address>(current) - address)); \ 841 isolate->heap()->RecordWrite( \
842 current_object_address, \
843 static_cast<int>(current_address - current_object_address)); \
837 } \ 844 } \
838 if (!current_was_incremented) { \ 845 if (!current_was_incremented) { \
839 current++; /* Increment current if it wasn't done above. */ \ 846 current++; \
840 } \ 847 } \
841 break; \ 848 break; \
842 } \ 849 } \
843 850
844 // This generates a case and a body for each space. The large object spaces are 851 // This generates a case and a body for each space. The large object spaces are
845 // very rare in snapshots so they are grouped in one body. 852 // very rare in snapshots so they are grouped in one body.
846 #define ONE_PER_SPACE(where, how, within) \ 853 #define ONE_PER_SPACE(where, how, within) \
847 CASE_STATEMENT(where, how, within, NEW_SPACE) \ 854 CASE_STATEMENT(where, how, within, NEW_SPACE) \
848 CASE_BODY(where, how, within, NEW_SPACE, kUnknownOffsetFromStart) \ 855 CASE_BODY(where, how, within, NEW_SPACE, kUnknownOffsetFromStart) \
849 CASE_STATEMENT(where, how, within, OLD_DATA_SPACE) \ 856 CASE_STATEMENT(where, how, within, OLD_DATA_SPACE) \
(...skipping 26 matching lines...) Expand all
876 CASE_STATEMENT(where, how, within, kLargeCode) \ 883 CASE_STATEMENT(where, how, within, kLargeCode) \
877 CASE_STATEMENT(where, how, within, kLargeFixedArray) \ 884 CASE_STATEMENT(where, how, within, kLargeFixedArray) \
878 CASE_BODY(where, how, within, kAnyOldSpace, kUnknownOffsetFromStart) 885 CASE_BODY(where, how, within, kAnyOldSpace, kUnknownOffsetFromStart)
879 886
880 #define ONE_PER_CODE_SPACE(where, how, within) \ 887 #define ONE_PER_CODE_SPACE(where, how, within) \
881 CASE_STATEMENT(where, how, within, CODE_SPACE) \ 888 CASE_STATEMENT(where, how, within, CODE_SPACE) \
882 CASE_BODY(where, how, within, CODE_SPACE, kUnknownOffsetFromStart) \ 889 CASE_BODY(where, how, within, CODE_SPACE, kUnknownOffsetFromStart) \
883 CASE_STATEMENT(where, how, within, kLargeCode) \ 890 CASE_STATEMENT(where, how, within, kLargeCode) \
884 CASE_BODY(where, how, within, kLargeCode, kUnknownOffsetFromStart) 891 CASE_BODY(where, how, within, kLargeCode, kUnknownOffsetFromStart)
885 892
886 #define EMIT_COMMON_REFERENCE_PATTERNS(pseudo_space_number, \ 893 #define FOUR_CASES(byte_code) \
887 space_number, \ 894 case byte_code: \
888 offset_from_start) \ 895 case byte_code + 1: \
889 CASE_STATEMENT(kFromStart, kPlain, kStartOfObject, pseudo_space_number) \ 896 case byte_code + 2: \
890 CASE_BODY(kFromStart, kPlain, kStartOfObject, space_number, offset_from_start) 897 case byte_code + 3:
898
899 #define SIXTEEN_CASES(byte_code) \
900 FOUR_CASES(byte_code) \
901 FOUR_CASES(byte_code + 4) \
902 FOUR_CASES(byte_code + 8) \
903 FOUR_CASES(byte_code + 12)
891 904
892 // We generate 15 cases and bodies that process special tags that combine 905 // We generate 15 cases and bodies that process special tags that combine
893 // the raw data tag and the length into one byte. 906 // the raw data tag and the length into one byte.
894 #define RAW_CASE(index, size) \ 907 #define RAW_CASE(index, size) \
895 case kRawData + index: { \ 908 case kRawData + index: { \
896 byte* raw_data_out = reinterpret_cast<byte*>(current); \ 909 byte* raw_data_out = reinterpret_cast<byte*>(current); \
897 source_->CopyRaw(raw_data_out, size); \ 910 source_->CopyRaw(raw_data_out, size); \
898 current = reinterpret_cast<Object**>(raw_data_out + size); \ 911 current = reinterpret_cast<Object**>(raw_data_out + size); \
899 break; \ 912 break; \
900 } 913 }
901 COMMON_RAW_LENGTHS(RAW_CASE) 914 COMMON_RAW_LENGTHS(RAW_CASE)
902 #undef RAW_CASE 915 #undef RAW_CASE
903 916
904 // Deserialize a chunk of raw data that doesn't have one of the popular 917 // Deserialize a chunk of raw data that doesn't have one of the popular
905 // lengths. 918 // lengths.
906 case kRawData: { 919 case kRawData: {
907 int size = source_->GetInt(); 920 int size = source_->GetInt();
908 byte* raw_data_out = reinterpret_cast<byte*>(current); 921 byte* raw_data_out = reinterpret_cast<byte*>(current);
909 source_->CopyRaw(raw_data_out, size); 922 source_->CopyRaw(raw_data_out, size);
910 current = reinterpret_cast<Object**>(raw_data_out + size); 923 current = reinterpret_cast<Object**>(raw_data_out + size);
911 break; 924 break;
912 } 925 }
913 926
927 SIXTEEN_CASES(kRootArrayLowConstants)
928 SIXTEEN_CASES(kRootArrayHighConstants) {
929 int root_id = RootArrayConstantFromByteCode(data);
930 Object* object = isolate->heap()->roots_array_start()[root_id];
931 ASSERT(!isolate->heap()->InNewSpace(object));
932 *current++ = object;
933 break;
934 }
935
936 case kRepeat: {
937 int repeats = source_->GetInt();
938 Object* object = current[-1];
939 ASSERT(!isolate->heap()->InNewSpace(object));
940 for (int i = 0; i < repeats; i++) current[i] = object;
941 current += repeats;
942 break;
943 }
944
945 STATIC_ASSERT(kRootArrayNumberOfConstantEncodings ==
946 Heap::kOldSpaceRoots);
947 STATIC_ASSERT(kMaxRepeats == 12);
948 FOUR_CASES(kConstantRepeat)
949 FOUR_CASES(kConstantRepeat + 4)
950 FOUR_CASES(kConstantRepeat + 8) {
951 int repeats = RepeatsForCode(data);
952 Object* object = current[-1];
953 ASSERT(!isolate->heap()->InNewSpace(object));
954 for (int i = 0; i < repeats; i++) current[i] = object;
955 current += repeats;
956 break;
957 }
958
914 // Deserialize a new object and write a pointer to it to the current 959 // Deserialize a new object and write a pointer to it to the current
915 // object. 960 // object.
916 ONE_PER_SPACE(kNewObject, kPlain, kStartOfObject) 961 ONE_PER_SPACE(kNewObject, kPlain, kStartOfObject)
917 // Support for direct instruction pointers in functions 962 // Support for direct instruction pointers in functions
918 ONE_PER_CODE_SPACE(kNewObject, kPlain, kFirstInstruction) 963 ONE_PER_CODE_SPACE(kNewObject, kPlain, kFirstInstruction)
919 // Deserialize a new code object and write a pointer to its first 964 // Deserialize a new code object and write a pointer to its first
920 // instruction to the current code object. 965 // instruction to the current code object.
921 ONE_PER_SPACE(kNewObject, kFromCode, kFirstInstruction) 966 ONE_PER_SPACE(kNewObject, kFromCode, kFirstInstruction)
922 // Find a recently deserialized object using its offset from the current 967 // Find a recently deserialized object using its offset from the current
923 // allocation point and write a pointer to it to the current object. 968 // allocation point and write a pointer to it to the current object.
924 ALL_SPACES(kBackref, kPlain, kStartOfObject) 969 ALL_SPACES(kBackref, kPlain, kStartOfObject)
925 // Find a recently deserialized code object using its offset from the 970 // Find a recently deserialized code object using its offset from the
926 // current allocation point and write a pointer to its first instruction 971 // current allocation point and write a pointer to its first instruction
927 // to the current code object or the instruction pointer in a function 972 // to the current code object or the instruction pointer in a function
928 // object. 973 // object.
929 ALL_SPACES(kBackref, kFromCode, kFirstInstruction) 974 ALL_SPACES(kBackref, kFromCode, kFirstInstruction)
930 ALL_SPACES(kBackref, kPlain, kFirstInstruction) 975 ALL_SPACES(kBackref, kPlain, kFirstInstruction)
931 // Find an already deserialized object using its offset from the start 976 // Find an already deserialized object using its offset from the start
932 // and write a pointer to it to the current object. 977 // and write a pointer to it to the current object.
933 ALL_SPACES(kFromStart, kPlain, kStartOfObject) 978 ALL_SPACES(kFromStart, kPlain, kStartOfObject)
934 ALL_SPACES(kFromStart, kPlain, kFirstInstruction) 979 ALL_SPACES(kFromStart, kPlain, kFirstInstruction)
935 // Find an already deserialized code object using its offset from the 980 // Find an already deserialized code object using its offset from the
936 // start and write a pointer to its first instruction to the current code 981 // start and write a pointer to its first instruction to the current code
937 // object. 982 // object.
938 ALL_SPACES(kFromStart, kFromCode, kFirstInstruction) 983 ALL_SPACES(kFromStart, kFromCode, kFirstInstruction)
939 // Find an already deserialized object at one of the predetermined popular
940 // offsets from the start and write a pointer to it in the current object.
941 COMMON_REFERENCE_PATTERNS(EMIT_COMMON_REFERENCE_PATTERNS)
942 // Find an object in the roots array and write a pointer to it to the 984 // Find an object in the roots array and write a pointer to it to the
943 // current object. 985 // current object.
944 CASE_STATEMENT(kRootArray, kPlain, kStartOfObject, 0) 986 CASE_STATEMENT(kRootArray, kPlain, kStartOfObject, 0)
945 CASE_BODY(kRootArray, kPlain, kStartOfObject, 0, kUnknownOffsetFromStart) 987 CASE_BODY(kRootArray, kPlain, kStartOfObject, 0, kUnknownOffsetFromStart)
946 // Find an object in the partial snapshots cache and write a pointer to it 988 // Find an object in the partial snapshots cache and write a pointer to it
947 // to the current object. 989 // to the current object.
948 CASE_STATEMENT(kPartialSnapshotCache, kPlain, kStartOfObject, 0) 990 CASE_STATEMENT(kPartialSnapshotCache, kPlain, kStartOfObject, 0)
949 CASE_BODY(kPartialSnapshotCache, 991 CASE_BODY(kPartialSnapshotCache,
950 kPlain, 992 kPlain,
951 kStartOfObject, 993 kStartOfObject,
(...skipping 21 matching lines...) Expand all
973 CASE_BODY(kExternalReference, 1015 CASE_BODY(kExternalReference,
974 kFromCode, 1016 kFromCode,
975 kStartOfObject, 1017 kStartOfObject,
976 0, 1018 0,
977 kUnknownOffsetFromStart) 1019 kUnknownOffsetFromStart)
978 1020
979 #undef CASE_STATEMENT 1021 #undef CASE_STATEMENT
980 #undef CASE_BODY 1022 #undef CASE_BODY
981 #undef ONE_PER_SPACE 1023 #undef ONE_PER_SPACE
982 #undef ALL_SPACES 1024 #undef ALL_SPACES
983 #undef EMIT_COMMON_REFERENCE_PATTERNS
984 #undef ASSIGN_DEST_SPACE 1025 #undef ASSIGN_DEST_SPACE
985 1026
986 case kNewPage: { 1027 case kNewPage: {
987 int space = source_->Get(); 1028 int space = source_->Get();
988 pages_[space].Add(last_object_address_); 1029 pages_[space].Add(last_object_address_);
989 if (space == CODE_SPACE) { 1030 if (space == CODE_SPACE) {
990 CPU::FlushICache(last_object_address_, Page::kPageSize); 1031 CPU::FlushICache(last_object_address_, Page::kPageSize);
991 } 1032 }
992 break; 1033 break;
993 } 1034 }
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
1060 sink_->PutSection(character, "TagCharacter"); 1101 sink_->PutSection(character, "TagCharacter");
1061 } while (character != 0); 1102 } while (character != 0);
1062 } 1103 }
1063 1104
1064 #endif 1105 #endif
1065 1106
1066 Serializer::Serializer(SnapshotByteSink* sink) 1107 Serializer::Serializer(SnapshotByteSink* sink)
1067 : sink_(sink), 1108 : sink_(sink),
1068 current_root_index_(0), 1109 current_root_index_(0),
1069 external_reference_encoder_(new ExternalReferenceEncoder), 1110 external_reference_encoder_(new ExternalReferenceEncoder),
1070 large_object_total_(0) { 1111 large_object_total_(0),
1112 root_index_wave_front_(0) {
1071 // The serializer is meant to be used only to generate initial heap images 1113 // The serializer is meant to be used only to generate initial heap images
1072 // from a context in which there is only one isolate. 1114 // from a context in which there is only one isolate.
1073 ASSERT(Isolate::Current()->IsDefaultIsolate()); 1115 ASSERT(Isolate::Current()->IsDefaultIsolate());
1074 for (int i = 0; i <= LAST_SPACE; i++) { 1116 for (int i = 0; i <= LAST_SPACE; i++) {
1075 fullness_[i] = 0; 1117 fullness_[i] = 0;
1076 } 1118 }
1077 } 1119 }
1078 1120
1079 1121
1080 Serializer::~Serializer() { 1122 Serializer::~Serializer() {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1117 } 1159 }
1118 isolate->set_serialize_partial_snapshot_cache_length( 1160 isolate->set_serialize_partial_snapshot_cache_length(
1119 Isolate::kPartialSnapshotCacheCapacity); 1161 Isolate::kPartialSnapshotCacheCapacity);
1120 } 1162 }
1121 1163
1122 1164
1123 void Serializer::VisitPointers(Object** start, Object** end) { 1165 void Serializer::VisitPointers(Object** start, Object** end) {
1124 Isolate* isolate = Isolate::Current(); 1166 Isolate* isolate = Isolate::Current();
1125 1167
1126 for (Object** current = start; current < end; current++) { 1168 for (Object** current = start; current < end; current++) {
1169 if (start == isolate->heap()->roots_array_start()) {
1170 root_index_wave_front_ =
1171 Max(root_index_wave_front_, static_cast<intptr_t>(current - start));
1172 }
1127 if (reinterpret_cast<Address>(current) == 1173 if (reinterpret_cast<Address>(current) ==
1128 isolate->heap()->store_buffer()->TopAddress()) { 1174 isolate->heap()->store_buffer()->TopAddress()) {
1129 sink_->Put(kSkip, "Skip"); 1175 sink_->Put(kSkip, "Skip");
1130 } else if ((*current)->IsSmi()) { 1176 } else if ((*current)->IsSmi()) {
1131 sink_->Put(kRawData, "RawData"); 1177 sink_->Put(kRawData, "RawData");
1132 sink_->PutInt(kPointerSize, "length"); 1178 sink_->PutInt(kPointerSize, "length");
1133 for (int i = 0; i < kPointerSize; i++) { 1179 for (int i = 0; i < kPointerSize; i++) {
1134 sink_->Put(reinterpret_cast<byte*>(current)[i], "Byte"); 1180 sink_->Put(reinterpret_cast<byte*>(current)[i], "Byte");
1135 } 1181 }
1136 } else { 1182 } else {
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1184 startup_serializer_->VisitPointer( 1230 startup_serializer_->VisitPointer(
1185 &isolate->serialize_partial_snapshot_cache()[length]); 1231 &isolate->serialize_partial_snapshot_cache()[length]);
1186 // We don't recurse from the startup snapshot generator into the partial 1232 // We don't recurse from the startup snapshot generator into the partial
1187 // snapshot generator. 1233 // snapshot generator.
1188 ASSERT(length == isolate->serialize_partial_snapshot_cache_length()); 1234 ASSERT(length == isolate->serialize_partial_snapshot_cache_length());
1189 isolate->set_serialize_partial_snapshot_cache_length(length + 1); 1235 isolate->set_serialize_partial_snapshot_cache_length(length + 1);
1190 return length; 1236 return length;
1191 } 1237 }
1192 1238
1193 1239
1194 int PartialSerializer::RootIndex(HeapObject* heap_object) { 1240 int Serializer::RootIndex(HeapObject* heap_object) {
1195 for (int i = 0; i < Heap::kRootListLength; i++) { 1241 Heap* heap = HEAP;
1196 Object* root = HEAP->roots_address()[i]; 1242 if (heap->InNewSpace(heap_object)) return kInvalidRootIndex;
1197 if (root == heap_object) return i; 1243 for (int i = 0; i < root_index_wave_front_; i++) {
1244 Object* root = heap->roots_array_start()[i];
1245 if (!root->IsSmi() && root == heap_object) return i;
1198 } 1246 }
1199 return kInvalidRootIndex; 1247 return kInvalidRootIndex;
1200 } 1248 }
1201 1249
1202 1250
1203 // Encode the location of an already deserialized object in order to write its 1251 // Encode the location of an already deserialized object in order to write its
1204 // location into a later object. We can encode the location as an offset from 1252 // location into a later object. We can encode the location as an offset from
1205 // the start of the deserialized objects or as an offset backwards from the 1253 // the start of the deserialized objects or as an offset backwards from the
1206 // current allocation pointer. 1254 // current allocation pointer.
1207 void Serializer::SerializeReferenceToPreviousObject( 1255 void Serializer::SerializeReferenceToPreviousObject(
(...skipping 15 matching lines...) Expand all
1223 // For new space it is always simple to encode back from current allocation. 1271 // For new space it is always simple to encode back from current allocation.
1224 if (offset < address) { 1272 if (offset < address) {
1225 from_start = false; 1273 from_start = false;
1226 address = offset; 1274 address = offset;
1227 } 1275 }
1228 } 1276 }
1229 // If we are actually dealing with real offsets (and not a numbering of 1277 // If we are actually dealing with real offsets (and not a numbering of
1230 // all objects) then we should shift out the bits that are always 0. 1278 // all objects) then we should shift out the bits that are always 0.
1231 if (!SpaceIsLarge(space)) address >>= kObjectAlignmentBits; 1279 if (!SpaceIsLarge(space)) address >>= kObjectAlignmentBits;
1232 if (from_start) { 1280 if (from_start) {
1233 #define COMMON_REFS_CASE(pseudo_space, actual_space, offset) \ 1281 sink_->Put(kFromStart + how_to_code + where_to_point + space, "RefSer");
1234 if (space == actual_space && address == offset && \ 1282 sink_->PutInt(address, "address");
1235 how_to_code == kPlain && where_to_point == kStartOfObject) { \
1236 sink_->Put(kFromStart + how_to_code + where_to_point + \
1237 pseudo_space, "RefSer"); \
1238 } else /* NOLINT */
1239 COMMON_REFERENCE_PATTERNS(COMMON_REFS_CASE)
1240 #undef COMMON_REFS_CASE
1241 { /* NOLINT */
1242 sink_->Put(kFromStart + how_to_code + where_to_point + space, "RefSer");
1243 sink_->PutInt(address, "address");
1244 }
1245 } else { 1283 } else {
1246 sink_->Put(kBackref + how_to_code + where_to_point + space, "BackRefSer"); 1284 sink_->Put(kBackref + how_to_code + where_to_point + space, "BackRefSer");
1247 sink_->PutInt(address, "address"); 1285 sink_->PutInt(address, "address");
1248 } 1286 }
1249 } 1287 }
1250 1288
1251 1289
1252 void StartupSerializer::SerializeObject( 1290 void StartupSerializer::SerializeObject(
1253 Object* o, 1291 Object* o,
1254 HowToCode how_to_code, 1292 HowToCode how_to_code,
1255 WhereToPoint where_to_point) { 1293 WhereToPoint where_to_point) {
1256 CHECK(o->IsHeapObject()); 1294 CHECK(o->IsHeapObject());
1257 HeapObject* heap_object = HeapObject::cast(o); 1295 HeapObject* heap_object = HeapObject::cast(o);
1258 1296
1297 int root_index;
1298 if ((root_index = RootIndex(heap_object)) != kInvalidRootIndex) {
1299 PutRoot(root_index, heap_object, how_to_code, where_to_point);
1300 return;
1301 }
1302
1259 if (address_mapper_.IsMapped(heap_object)) { 1303 if (address_mapper_.IsMapped(heap_object)) {
1260 int space = SpaceOfAlreadySerializedObject(heap_object); 1304 int space = SpaceOfAlreadySerializedObject(heap_object);
1261 int address = address_mapper_.MappedTo(heap_object); 1305 int address = address_mapper_.MappedTo(heap_object);
1262 SerializeReferenceToPreviousObject(space, 1306 SerializeReferenceToPreviousObject(space,
1263 address, 1307 address,
1264 how_to_code, 1308 how_to_code,
1265 where_to_point); 1309 where_to_point);
1266 } else { 1310 } else {
1267 // Object has not yet been serialized. Serialize it here. 1311 // Object has not yet been serialized. Serialize it here.
1268 ObjectSerializer object_serializer(this, 1312 ObjectSerializer object_serializer(this,
(...skipping 10 matching lines...) Expand all
1279 for (int i = Isolate::Current()->serialize_partial_snapshot_cache_length(); 1323 for (int i = Isolate::Current()->serialize_partial_snapshot_cache_length();
1280 i < Isolate::kPartialSnapshotCacheCapacity; 1324 i < Isolate::kPartialSnapshotCacheCapacity;
1281 i++) { 1325 i++) {
1282 sink_->Put(kRootArray + kPlain + kStartOfObject, "RootSerialization"); 1326 sink_->Put(kRootArray + kPlain + kStartOfObject, "RootSerialization");
1283 sink_->PutInt(Heap::kUndefinedValueRootIndex, "root_index"); 1327 sink_->PutInt(Heap::kUndefinedValueRootIndex, "root_index");
1284 } 1328 }
1285 HEAP->IterateWeakRoots(this, VISIT_ALL); 1329 HEAP->IterateWeakRoots(this, VISIT_ALL);
1286 } 1330 }
1287 1331
1288 1332
1333 void Serializer::PutRoot(int root_index,
1334 HeapObject* object,
1335 SerializerDeserializer::HowToCode how_to_code,
1336 SerializerDeserializer::WhereToPoint where_to_point) {
1337 if (how_to_code == kPlain &&
1338 where_to_point == kStartOfObject &&
1339 root_index < kRootArrayNumberOfConstantEncodings &&
1340 !HEAP->InNewSpace(object)) {
1341 if (root_index < kRootArrayNumberOfLowConstantEncodings) {
1342 sink_->Put(kRootArrayLowConstants + root_index, "RootLoConstant");
1343 } else {
1344 sink_->Put(kRootArrayHighConstants + root_index -
1345 kRootArrayNumberOfLowConstantEncodings,
1346 "RootHiConstant");
1347 }
1348 } else {
1349 sink_->Put(kRootArray + how_to_code + where_to_point, "RootSerialization");
1350 sink_->PutInt(root_index, "root_index");
1351 }
1352 }
1353
1354
1289 void PartialSerializer::SerializeObject( 1355 void PartialSerializer::SerializeObject(
1290 Object* o, 1356 Object* o,
1291 HowToCode how_to_code, 1357 HowToCode how_to_code,
1292 WhereToPoint where_to_point) { 1358 WhereToPoint where_to_point) {
1293 CHECK(o->IsHeapObject()); 1359 CHECK(o->IsHeapObject());
1294 HeapObject* heap_object = HeapObject::cast(o); 1360 HeapObject* heap_object = HeapObject::cast(o);
1295 1361
1296 int root_index; 1362 int root_index;
1297 if ((root_index = RootIndex(heap_object)) != kInvalidRootIndex) { 1363 if ((root_index = RootIndex(heap_object)) != kInvalidRootIndex) {
1298 sink_->Put(kRootArray + how_to_code + where_to_point, "RootSerialization"); 1364 PutRoot(root_index, heap_object, how_to_code, where_to_point);
1299 sink_->PutInt(root_index, "root_index");
1300 return; 1365 return;
1301 } 1366 }
1302 1367
1303 if (ShouldBeInThePartialSnapshotCache(heap_object)) { 1368 if (ShouldBeInThePartialSnapshotCache(heap_object)) {
1304 int cache_index = PartialSnapshotCacheIndex(heap_object); 1369 int cache_index = PartialSnapshotCacheIndex(heap_object);
1305 sink_->Put(kPartialSnapshotCache + how_to_code + where_to_point, 1370 sink_->Put(kPartialSnapshotCache + how_to_code + where_to_point,
1306 "PartialSnapshotCache"); 1371 "PartialSnapshotCache");
1307 sink_->PutInt(cache_index, "partial_snapshot_cache_index"); 1372 sink_->PutInt(cache_index, "partial_snapshot_cache_index");
1308 return; 1373 return;
1309 } 1374 }
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1367 1432
1368 1433
1369 void Serializer::ObjectSerializer::VisitPointers(Object** start, 1434 void Serializer::ObjectSerializer::VisitPointers(Object** start,
1370 Object** end) { 1435 Object** end) {
1371 Object** current = start; 1436 Object** current = start;
1372 while (current < end) { 1437 while (current < end) {
1373 while (current < end && (*current)->IsSmi()) current++; 1438 while (current < end && (*current)->IsSmi()) current++;
1374 if (current < end) OutputRawData(reinterpret_cast<Address>(current)); 1439 if (current < end) OutputRawData(reinterpret_cast<Address>(current));
1375 1440
1376 while (current < end && !(*current)->IsSmi()) { 1441 while (current < end && !(*current)->IsSmi()) {
1377 serializer_->SerializeObject(*current, kPlain, kStartOfObject); 1442 HeapObject* current_contents = HeapObject::cast(*current);
1378 bytes_processed_so_far_ += kPointerSize; 1443 int root_index = serializer_->RootIndex(current_contents);
1379 current++; 1444 // Repeats are not subject to the write barrier so there are only some
1445 // objects that can be used in a repeat encoding. These are the early
1446 // ones in the root array that are never in new space.
1447 if (current != start &&
1448 root_index != kInvalidRootIndex &&
1449 root_index < kRootArrayNumberOfConstantEncodings &&
1450 current_contents == current[-1]) {
1451 ASSERT(!HEAP->InNewSpace(current_contents));
1452 int repeat_count = 1;
1453 while (current < end - 1 && current[repeat_count] == current_contents) {
1454 repeat_count++;
1455 }
1456 current += repeat_count;
1457 bytes_processed_so_far_ += repeat_count * kPointerSize;
1458 if (repeat_count > kMaxRepeats) {
1459 sink_->Put(kRepeat, "SerializeRepeats");
1460 sink_->PutInt(repeat_count, "SerializeRepeats");
1461 } else {
1462 sink_->Put(CodeForRepeats(repeat_count), "SerializeRepeats");
1463 }
1464 } else {
1465 serializer_->SerializeObject(current_contents, kPlain, kStartOfObject);
1466 bytes_processed_so_far_ += kPointerSize;
1467 current++;
1468 }
1380 } 1469 }
1381 } 1470 }
1382 } 1471 }
1383 1472
1384 1473
1385 void Serializer::ObjectSerializer::VisitExternalReferences(Address* start, 1474 void Serializer::ObjectSerializer::VisitExternalReferences(Address* start,
1386 Address* end) { 1475 Address* end) {
1387 Address references_start = reinterpret_cast<Address>(start); 1476 Address references_start = reinterpret_cast<Address>(start);
1388 OutputRawData(references_start); 1477 OutputRawData(references_start);
1389 1478
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
1553 fullness_[space] = RoundUp(fullness_[space], Page::kPageSize); 1642 fullness_[space] = RoundUp(fullness_[space], Page::kPageSize);
1554 } 1643 }
1555 } 1644 }
1556 int allocation_address = fullness_[space]; 1645 int allocation_address = fullness_[space];
1557 fullness_[space] = allocation_address + size; 1646 fullness_[space] = allocation_address + size;
1558 return allocation_address; 1647 return allocation_address;
1559 } 1648 }
1560 1649
1561 1650
1562 } } // namespace v8::internal 1651 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/serialize.h ('k') | src/spaces.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698