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

Side by Side Diff: src/serialize.cc

Issue 383173002: Serialize builtins by referencing canonical ones. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 5 months 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') | test/cctest/test-compiler.cc » ('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 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 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/accessors.h" 7 #include "src/accessors.h"
8 #include "src/api.h" 8 #include "src/api.h"
9 #include "src/base/platform/platform.h" 9 #include "src/base/platform/platform.h"
10 #include "src/bootstrapper.h" 10 #include "src/bootstrapper.h"
(...skipping 871 matching lines...) Expand 10 before | Expand all | Expand 10 after
882 int data = source_->Get(); 882 int data = source_->Get();
883 switch (data) { 883 switch (data) {
884 #define CASE_STATEMENT(where, how, within, space_number) \ 884 #define CASE_STATEMENT(where, how, within, space_number) \
885 case where + how + within + space_number: \ 885 case where + how + within + space_number: \
886 STATIC_ASSERT((where & ~kPointedToMask) == 0); \ 886 STATIC_ASSERT((where & ~kPointedToMask) == 0); \
887 STATIC_ASSERT((how & ~kHowToCodeMask) == 0); \ 887 STATIC_ASSERT((how & ~kHowToCodeMask) == 0); \
888 STATIC_ASSERT((within & ~kWhereToPointMask) == 0); \ 888 STATIC_ASSERT((within & ~kWhereToPointMask) == 0); \
889 STATIC_ASSERT((space_number & ~kSpaceMask) == 0); 889 STATIC_ASSERT((space_number & ~kSpaceMask) == 0);
890 890
891 #define CASE_BODY(where, how, within, space_number_if_any) \ 891 #define CASE_BODY(where, how, within, space_number_if_any) \
892 { \ 892 { \
893 bool emit_write_barrier = false; \ 893 bool emit_write_barrier = false; \
894 bool current_was_incremented = false; \ 894 bool current_was_incremented = false; \
895 int space_number = space_number_if_any == kAnyOldSpace ? \ 895 int space_number = space_number_if_any == kAnyOldSpace \
896 (data & kSpaceMask) : space_number_if_any; \ 896 ? (data & kSpaceMask) \
897 if (where == kNewObject && how == kPlain && within == kStartOfObject) {\ 897 : space_number_if_any; \
898 ReadObject(space_number, current); \ 898 if (where == kNewObject && how == kPlain && within == kStartOfObject) { \
899 emit_write_barrier = (space_number == NEW_SPACE); \ 899 ReadObject(space_number, current); \
900 emit_write_barrier = (space_number == NEW_SPACE); \
901 } else { \
902 Object* new_object = NULL; /* May not be a real Object pointer. */ \
903 if (where == kNewObject) { \
904 ReadObject(space_number, &new_object); \
905 } else if (where == kRootArray) { \
906 int root_id = source_->GetInt(); \
907 new_object = isolate->heap()->roots_array_start()[root_id]; \
908 emit_write_barrier = isolate->heap()->InNewSpace(new_object); \
909 } else if (where == kPartialSnapshotCache) { \
910 int cache_index = source_->GetInt(); \
911 new_object = isolate->serialize_partial_snapshot_cache()[cache_index]; \
912 emit_write_barrier = isolate->heap()->InNewSpace(new_object); \
913 } else if (where == kExternalReference) { \
914 int skip = source_->GetInt(); \
915 current = reinterpret_cast<Object**>( \
916 reinterpret_cast<Address>(current) + skip); \
917 int reference_id = source_->GetInt(); \
918 Address address = external_reference_decoder_->Decode(reference_id); \
919 new_object = reinterpret_cast<Object*>(address); \
920 } else if (where == kBackref) { \
921 emit_write_barrier = (space_number == NEW_SPACE); \
922 new_object = GetAddressFromEnd(data & kSpaceMask); \
923 } else if (where == kBuiltin) { \
924 int builtin_id = source_->GetInt(); \
925 ASSERT_LE(0, builtin_id); \
926 ASSERT_LT(builtin_id, Builtins::builtin_count); \
927 Builtins::Name name = static_cast<Builtins::Name>(builtin_id); \
928 new_object = isolate->builtins()->builtin(name); \
929 emit_write_barrier = false; \
930 PrintF("BUILTIN how within %d, %d\n", how, within); \
931 } else { \
932 ASSERT(where == kBackrefWithSkip); \
933 int skip = source_->GetInt(); \
934 current = reinterpret_cast<Object**>( \
935 reinterpret_cast<Address>(current) + skip); \
936 emit_write_barrier = (space_number == NEW_SPACE); \
937 new_object = GetAddressFromEnd(data & kSpaceMask); \
938 } \
939 if (within == kInnerPointer) { \
940 if (space_number != CODE_SPACE || new_object->IsCode()) { \
941 Code* new_code_object = reinterpret_cast<Code*>(new_object); \
942 new_object = \
943 reinterpret_cast<Object*>(new_code_object->instruction_start()); \
900 } else { \ 944 } else { \
901 Object* new_object = NULL; /* May not be a real Object pointer. */ \ 945 ASSERT(space_number == CODE_SPACE); \
902 if (where == kNewObject) { \ 946 Cell* cell = Cell::cast(new_object); \
903 ReadObject(space_number, &new_object); \ 947 new_object = reinterpret_cast<Object*>(cell->ValueAddress()); \
904 } else if (where == kRootArray) { \
905 int root_id = source_->GetInt(); \
906 new_object = isolate->heap()->roots_array_start()[root_id]; \
907 emit_write_barrier = isolate->heap()->InNewSpace(new_object); \
908 } else if (where == kPartialSnapshotCache) { \
909 int cache_index = source_->GetInt(); \
910 new_object = isolate->serialize_partial_snapshot_cache() \
911 [cache_index]; \
912 emit_write_barrier = isolate->heap()->InNewSpace(new_object); \
913 } else if (where == kExternalReference) { \
914 int skip = source_->GetInt(); \
915 current = reinterpret_cast<Object**>(reinterpret_cast<Address>( \
916 current) + skip); \
917 int reference_id = source_->GetInt(); \
918 Address address = external_reference_decoder_-> \
919 Decode(reference_id); \
920 new_object = reinterpret_cast<Object*>(address); \
921 } else if (where == kBackref) { \
922 emit_write_barrier = (space_number == NEW_SPACE); \
923 new_object = GetAddressFromEnd(data & kSpaceMask); \
924 } else { \
925 ASSERT(where == kBackrefWithSkip); \
926 int skip = source_->GetInt(); \
927 current = reinterpret_cast<Object**>( \
928 reinterpret_cast<Address>(current) + skip); \
929 emit_write_barrier = (space_number == NEW_SPACE); \
930 new_object = GetAddressFromEnd(data & kSpaceMask); \
931 } \
932 if (within == kInnerPointer) { \
933 if (space_number != CODE_SPACE || new_object->IsCode()) { \
934 Code* new_code_object = reinterpret_cast<Code*>(new_object); \
935 new_object = reinterpret_cast<Object*>( \
936 new_code_object->instruction_start()); \
937 } else { \
938 ASSERT(space_number == CODE_SPACE); \
939 Cell* cell = Cell::cast(new_object); \
940 new_object = reinterpret_cast<Object*>( \
941 cell->ValueAddress()); \
942 } \
943 } \
944 if (how == kFromCode) { \
945 Address location_of_branch_data = \
946 reinterpret_cast<Address>(current); \
947 Assembler::deserialization_set_special_target_at( \
948 location_of_branch_data, \
949 Code::cast(HeapObject::FromAddress(current_object_address)), \
950 reinterpret_cast<Address>(new_object)); \
951 location_of_branch_data += Assembler::kSpecialTargetSize; \
952 current = reinterpret_cast<Object**>(location_of_branch_data); \
953 current_was_incremented = true; \
954 } else { \
955 *current = new_object; \
956 } \
957 } \ 948 } \
958 if (emit_write_barrier && write_barrier_needed) { \
959 Address current_address = reinterpret_cast<Address>(current); \
960 isolate->heap()->RecordWrite( \
961 current_object_address, \
962 static_cast<int>(current_address - current_object_address)); \
963 } \
964 if (!current_was_incremented) { \
965 current++; \
966 } \
967 break; \
968 } \ 949 } \
950 if (how == kFromCode) { \
951 Address location_of_branch_data = reinterpret_cast<Address>(current); \
952 Assembler::deserialization_set_special_target_at( \
953 location_of_branch_data, \
954 Code::cast(HeapObject::FromAddress(current_object_address)), \
955 reinterpret_cast<Address>(new_object)); \
956 location_of_branch_data += Assembler::kSpecialTargetSize; \
957 current = reinterpret_cast<Object**>(location_of_branch_data); \
958 current_was_incremented = true; \
959 } else { \
960 *current = new_object; \
961 } \
962 } \
963 if (emit_write_barrier && write_barrier_needed) { \
964 Address current_address = reinterpret_cast<Address>(current); \
965 isolate->heap()->RecordWrite( \
966 current_object_address, \
967 static_cast<int>(current_address - current_object_address)); \
968 } \
969 if (!current_was_incremented) { \
970 current++; \
971 } \
972 break; \
973 }
969 974
970 // This generates a case and a body for the new space (which has to do extra 975 // This generates a case and a body for the new space (which has to do extra
971 // write barrier handling) and handles the other spaces with 8 fall-through 976 // write barrier handling) and handles the other spaces with 8 fall-through
972 // cases and one body. 977 // cases and one body.
973 #define ALL_SPACES(where, how, within) \ 978 #define ALL_SPACES(where, how, within) \
974 CASE_STATEMENT(where, how, within, NEW_SPACE) \ 979 CASE_STATEMENT(where, how, within, NEW_SPACE) \
975 CASE_BODY(where, how, within, NEW_SPACE) \ 980 CASE_BODY(where, how, within, NEW_SPACE) \
976 CASE_STATEMENT(where, how, within, OLD_DATA_SPACE) \ 981 CASE_STATEMENT(where, how, within, OLD_DATA_SPACE) \
977 CASE_STATEMENT(where, how, within, OLD_POINTER_SPACE) \ 982 CASE_STATEMENT(where, how, within, OLD_POINTER_SPACE) \
978 CASE_STATEMENT(where, how, within, CODE_SPACE) \ 983 CASE_STATEMENT(where, how, within, CODE_SPACE) \
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
1154 kPlain, 1159 kPlain,
1155 kStartOfObject, 1160 kStartOfObject,
1156 0) 1161 0)
1157 // Find an external reference and write a pointer to it in the current 1162 // Find an external reference and write a pointer to it in the current
1158 // code object. 1163 // code object.
1159 CASE_STATEMENT(kExternalReference, kFromCode, kStartOfObject, 0) 1164 CASE_STATEMENT(kExternalReference, kFromCode, kStartOfObject, 0)
1160 CASE_BODY(kExternalReference, 1165 CASE_BODY(kExternalReference,
1161 kFromCode, 1166 kFromCode,
1162 kStartOfObject, 1167 kStartOfObject,
1163 0) 1168 0)
1169 // Find a builtin and write a pointer to it to the current object.
1170 CASE_STATEMENT(kBuiltin, kPlain, kStartOfObject, 0)
1171 CASE_BODY(kBuiltin, kPlain, kStartOfObject, 0)
1172 // Find a builtin and write a pointer to it in the current code object.
1173 CASE_STATEMENT(kBuiltin, kFromCode, kInnerPointer, 0)
1174 CASE_BODY(kBuiltin, kFromCode, kInnerPointer, 0)
1164 1175
1165 #undef CASE_STATEMENT 1176 #undef CASE_STATEMENT
1166 #undef CASE_BODY 1177 #undef CASE_BODY
1167 #undef ALL_SPACES 1178 #undef ALL_SPACES
1168 1179
1169 case kSkip: { 1180 case kSkip: {
1170 int size = source_->GetInt(); 1181 int size = source_->GetInt();
1171 current = reinterpret_cast<Object**>( 1182 current = reinterpret_cast<Object**>(
1172 reinterpret_cast<intptr_t>(current) + size); 1183 reinterpret_cast<intptr_t>(current) + size);
1173 break; 1184 break;
(...skipping 536 matching lines...) Expand 10 before | Expand all | Expand 10 after
1710 } 1721 }
1711 1722
1712 1723
1713 int Serializer::ObjectSerializer::OutputRawData( 1724 int Serializer::ObjectSerializer::OutputRawData(
1714 Address up_to, Serializer::ObjectSerializer::ReturnSkip return_skip) { 1725 Address up_to, Serializer::ObjectSerializer::ReturnSkip return_skip) {
1715 Address object_start = object_->address(); 1726 Address object_start = object_->address();
1716 int base = bytes_processed_so_far_; 1727 int base = bytes_processed_so_far_;
1717 int up_to_offset = static_cast<int>(up_to - object_start); 1728 int up_to_offset = static_cast<int>(up_to - object_start);
1718 int to_skip = up_to_offset - bytes_processed_so_far_; 1729 int to_skip = up_to_offset - bytes_processed_so_far_;
1719 int bytes_to_output = to_skip; 1730 int bytes_to_output = to_skip;
1720 bytes_processed_so_far_ += to_skip; 1731 bytes_processed_so_far_ += to_skip;
1721 // This assert will fail if the reloc info gives us the target_address_address 1732 // This assert will fail if the reloc info gives us the target_address_address
1722 // locations in a non-ascending order. Luckily that doesn't happen. 1733 // locations in a non-ascending order. Luckily that doesn't happen.
1723 ASSERT(to_skip >= 0); 1734 ASSERT(to_skip >= 0);
1724 bool outputting_code = false; 1735 bool outputting_code = false;
1725 if (to_skip != 0 && code_object_ && !code_has_been_output_) { 1736 if (to_skip != 0 && code_object_ && !code_has_been_output_) {
1726 // Output the code all at once and fix later. 1737 // Output the code all at once and fix later.
1727 bytes_to_output = object_->Size() + to_skip - bytes_processed_so_far_; 1738 bytes_to_output = object_->Size() + to_skip - bytes_processed_so_far_;
1728 outputting_code = true; 1739 outputting_code = true;
1729 code_has_been_output_ = true; 1740 code_has_been_output_ = true;
1730 } 1741 }
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
1839 ASSERT(!heap_object->IsMap() || 1850 ASSERT(!heap_object->IsMap() ||
1840 Map::cast(heap_object)->code_cache() == 1851 Map::cast(heap_object)->code_cache() ==
1841 heap_object->GetHeap()->empty_fixed_array()); 1852 heap_object->GetHeap()->empty_fixed_array());
1842 1853
1843 int root_index; 1854 int root_index;
1844 if ((root_index = RootIndex(heap_object, how_to_code)) != kInvalidRootIndex) { 1855 if ((root_index = RootIndex(heap_object, how_to_code)) != kInvalidRootIndex) {
1845 PutRoot(root_index, heap_object, how_to_code, where_to_point, skip); 1856 PutRoot(root_index, heap_object, how_to_code, where_to_point, skip);
1846 return; 1857 return;
1847 } 1858 }
1848 1859
1849 // TODO(yangguo) wire up builtins.
1850 // TODO(yangguo) wire up stubs from stub cache. 1860 // TODO(yangguo) wire up stubs from stub cache.
1851 // TODO(yangguo) wire up script source. 1861 // TODO(yangguo) wire up script source.
1852 // TODO(yangguo) wire up internalized strings 1862 // TODO(yangguo) wire up internalized strings
1853 ASSERT(!heap_object->IsInternalizedString()); 1863 ASSERT(!heap_object->IsInternalizedString());
1854 // TODO(yangguo) We cannot deal with different hash seeds yet. 1864 // TODO(yangguo) We cannot deal with different hash seeds yet.
1855 ASSERT(!heap_object->IsHashTable()); 1865 ASSERT(!heap_object->IsHashTable());
1856 1866
1867 if (heap_object->IsCode()) {
1868 Code* code_object = Code::cast(heap_object);
1869 if (code_object->kind() == Code::BUILTIN) {
1870 SerializeBuiltin(code_object, how_to_code, where_to_point, skip);
1871 return;
1872 }
1873 }
1874
1857 if (address_mapper_.IsMapped(heap_object)) { 1875 if (address_mapper_.IsMapped(heap_object)) {
1858 int space = SpaceOfObject(heap_object); 1876 int space = SpaceOfObject(heap_object);
1859 int address = address_mapper_.MappedTo(heap_object); 1877 int address = address_mapper_.MappedTo(heap_object);
1860 SerializeReferenceToPreviousObject(space, address, how_to_code, 1878 SerializeReferenceToPreviousObject(space, address, how_to_code,
1861 where_to_point, skip); 1879 where_to_point, skip);
1862 return; 1880 return;
1863 } 1881 }
1864 1882
1865 if (skip != 0) { 1883 if (skip != 0) {
1866 sink_->Put(kSkip, "SkipFromSerializeObject"); 1884 sink_->Put(kSkip, "SkipFromSerializeObject");
1867 sink_->PutInt(skip, "SkipDistanceFromSerializeObject"); 1885 sink_->PutInt(skip, "SkipDistanceFromSerializeObject");
1868 } 1886 }
1869 // Object has not yet been serialized. Serialize it here. 1887 // Object has not yet been serialized. Serialize it here.
1870 ObjectSerializer serializer(this, heap_object, sink_, how_to_code, 1888 ObjectSerializer serializer(this, heap_object, sink_, how_to_code,
1871 where_to_point); 1889 where_to_point);
1872 serializer.Serialize(); 1890 serializer.Serialize();
1873 } 1891 }
1874 1892
1875 1893
1894 void CodeSerializer::SerializeBuiltin(Code* builtin, HowToCode how_to_code,
1895 WhereToPoint where_to_point, int skip) {
1896 if (skip != 0) {
1897 sink_->Put(kSkip, "SkipFromSerializeBuiltin");
1898 sink_->PutInt(skip, "SkipDistanceFromSerializeBuiltin");
1899 }
1900
1901 ASSERT((how_to_code == kPlain && where_to_point == kStartOfObject) ||
1902 (how_to_code == kFromCode && where_to_point == kInnerPointer));
1903 int id = 0;
1904 do { // Look for existing builtins in the list.
1905 Code* b = isolate()->builtins()->builtin(static_cast<Builtins::Name>(id));
1906 if (builtin == b) break;
1907 } while (++id < Builtins::builtin_count);
1908 ASSERT(id < Builtins::builtin_count); // We must have found a one.
1909
1910 sink_->Put(kBuiltin + how_to_code + where_to_point, "Builtin");
1911 sink_->PutInt(id, "builtin_index");
1912 }
1913
1914
1876 Object* CodeSerializer::Deserialize(Isolate* isolate, ScriptData* data) { 1915 Object* CodeSerializer::Deserialize(Isolate* isolate, ScriptData* data) {
1877 SerializedCodeData scd(data); 1916 SerializedCodeData scd(data);
1878 SnapshotByteSource payload(scd.Payload(), scd.PayloadLength()); 1917 SnapshotByteSource payload(scd.Payload(), scd.PayloadLength());
1879 Deserializer deserializer(&payload); 1918 Deserializer deserializer(&payload);
1880 STATIC_ASSERT(NEW_SPACE == 0); 1919 STATIC_ASSERT(NEW_SPACE == 0);
1881 // TODO(yangguo) what happens if remaining new space is too small? 1920 // TODO(yangguo) what happens if remaining new space is too small?
1882 for (int i = NEW_SPACE; i <= PROPERTY_CELL_SPACE; i++) { 1921 for (int i = NEW_SPACE; i <= PROPERTY_CELL_SPACE; i++) {
1883 deserializer.set_reservation(i, scd.GetReservation(i)); 1922 deserializer.set_reservation(i, scd.GetReservation(i));
1884 } 1923 }
1885 Object* root; 1924 Object* root;
(...skipping 19 matching lines...) Expand all
1905 SetHeaderValue(kReservationsOffset + i, cs->CurrentAllocationAddress(i)); 1944 SetHeaderValue(kReservationsOffset + i, cs->CurrentAllocationAddress(i));
1906 } 1945 }
1907 } 1946 }
1908 1947
1909 1948
1910 bool SerializedCodeData::IsSane() { 1949 bool SerializedCodeData::IsSane() {
1911 return GetHeaderValue(kVersionHashOffset) == Version::Hash() && 1950 return GetHeaderValue(kVersionHashOffset) == Version::Hash() &&
1912 PayloadLength() >= SharedFunctionInfo::kSize; 1951 PayloadLength() >= SharedFunctionInfo::kSize;
1913 } 1952 }
1914 } } // namespace v8::internal 1953 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/serialize.h ('k') | test/cctest/test-compiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698