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 #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 700 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
711 address_to_name_map_.Insert(code->address(), name, length); | 711 address_to_name_map_.Insert(code->address(), name, length); |
712 } | 712 } |
713 | 713 |
714 NameMap address_to_name_map_; | 714 NameMap address_to_name_map_; |
715 Isolate* isolate_; | 715 Isolate* isolate_; |
716 }; | 716 }; |
717 | 717 |
718 | 718 |
719 Deserializer::Deserializer(SnapshotByteSource* source) | 719 Deserializer::Deserializer(SnapshotByteSource* source) |
720 : isolate_(NULL), | 720 : isolate_(NULL), |
721 deserialize_code_(false), | 721 attached_objects_(NULL), |
722 source_(source), | 722 source_(source), |
723 external_reference_decoder_(NULL) { | 723 external_reference_decoder_(NULL) { |
724 for (int i = 0; i < LAST_SPACE + 1; i++) { | 724 for (int i = 0; i < LAST_SPACE + 1; i++) { |
725 reservations_[i] = kUninitializedReservation; | 725 reservations_[i] = kUninitializedReservation; |
726 } | 726 } |
727 } | 727 } |
728 | 728 |
729 | 729 |
730 void Deserializer::FlushICacheForNewCodeObjects() { | 730 void Deserializer::FlushICacheForNewCodeObjects() { |
731 PageIterator it(isolate_->heap()->code_space()); | 731 PageIterator it(isolate_->heap()->code_space()); |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
898 LOG(isolate_, SnapshotPositionEvent(address, source_->position())); | 898 LOG(isolate_, SnapshotPositionEvent(address, source_->position())); |
899 } | 899 } |
900 ReadChunk(current, limit, space_number, address); | 900 ReadChunk(current, limit, space_number, address); |
901 | 901 |
902 // TODO(mvstanton): consider treating the heap()->allocation_sites_list() | 902 // TODO(mvstanton): consider treating the heap()->allocation_sites_list() |
903 // as a (weak) root. If this root is relocated correctly, | 903 // as a (weak) root. If this root is relocated correctly, |
904 // RelinkAllocationSite() isn't necessary. | 904 // RelinkAllocationSite() isn't necessary. |
905 if (obj->IsAllocationSite()) RelinkAllocationSite(AllocationSite::cast(obj)); | 905 if (obj->IsAllocationSite()) RelinkAllocationSite(AllocationSite::cast(obj)); |
906 | 906 |
907 // Fix up strings from serialized user code. | 907 // Fix up strings from serialized user code. |
908 if (deserialize_code_) obj = ProcessObjectFromSerializedCode(obj); | 908 if (deserializing_user_code()) obj = ProcessObjectFromSerializedCode(obj); |
909 | 909 |
910 *write_back = obj; | 910 *write_back = obj; |
911 #ifdef DEBUG | 911 #ifdef DEBUG |
912 bool is_codespace = (space_number == CODE_SPACE); | 912 bool is_codespace = (space_number == CODE_SPACE); |
913 ASSERT(obj->IsCode() == is_codespace); | 913 ASSERT(obj->IsCode() == is_codespace); |
914 #endif | 914 #endif |
915 } | 915 } |
916 | 916 |
917 void Deserializer::ReadChunk(Object** current, | 917 void Deserializer::ReadChunk(Object** current, |
918 Object** limit, | 918 Object** limit, |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
964 int skip = source_->GetInt(); \ | 964 int skip = source_->GetInt(); \ |
965 current = reinterpret_cast<Object**>( \ | 965 current = reinterpret_cast<Object**>( \ |
966 reinterpret_cast<Address>(current) + skip); \ | 966 reinterpret_cast<Address>(current) + skip); \ |
967 int reference_id = source_->GetInt(); \ | 967 int reference_id = source_->GetInt(); \ |
968 Address address = external_reference_decoder_->Decode(reference_id); \ | 968 Address address = external_reference_decoder_->Decode(reference_id); \ |
969 new_object = reinterpret_cast<Object*>(address); \ | 969 new_object = reinterpret_cast<Object*>(address); \ |
970 } else if (where == kBackref) { \ | 970 } else if (where == kBackref) { \ |
971 emit_write_barrier = (space_number == NEW_SPACE); \ | 971 emit_write_barrier = (space_number == NEW_SPACE); \ |
972 new_object = GetAddressFromEnd(data & kSpaceMask); \ | 972 new_object = GetAddressFromEnd(data & kSpaceMask); \ |
973 } else if (where == kBuiltin) { \ | 973 } else if (where == kBuiltin) { \ |
974 ASSERT(deserialize_code_); \ | 974 ASSERT(deserializing_user_code()); \ |
975 int builtin_id = source_->GetInt(); \ | 975 int builtin_id = source_->GetInt(); \ |
976 ASSERT_LE(0, builtin_id); \ | 976 ASSERT_LE(0, builtin_id); \ |
977 ASSERT_LT(builtin_id, Builtins::builtin_count); \ | 977 ASSERT_LT(builtin_id, Builtins::builtin_count); \ |
978 Builtins::Name name = static_cast<Builtins::Name>(builtin_id); \ | 978 Builtins::Name name = static_cast<Builtins::Name>(builtin_id); \ |
979 new_object = isolate->builtins()->builtin(name); \ | 979 new_object = isolate->builtins()->builtin(name); \ |
980 emit_write_barrier = false; \ | 980 emit_write_barrier = false; \ |
| 981 } else if (where == kAttachedReference) { \ |
| 982 ASSERT(deserializing_user_code()); \ |
| 983 int index = source_->GetInt(); \ |
| 984 new_object = attached_objects_->at(index); \ |
| 985 emit_write_barrier = isolate->heap()->InNewSpace(new_object); \ |
981 } else { \ | 986 } else { \ |
982 ASSERT(where == kBackrefWithSkip); \ | 987 ASSERT(where == kBackrefWithSkip); \ |
983 int skip = source_->GetInt(); \ | 988 int skip = source_->GetInt(); \ |
984 current = reinterpret_cast<Object**>( \ | 989 current = reinterpret_cast<Object**>( \ |
985 reinterpret_cast<Address>(current) + skip); \ | 990 reinterpret_cast<Address>(current) + skip); \ |
986 emit_write_barrier = (space_number == NEW_SPACE); \ | 991 emit_write_barrier = (space_number == NEW_SPACE); \ |
987 new_object = GetAddressFromEnd(data & kSpaceMask); \ | 992 new_object = GetAddressFromEnd(data & kSpaceMask); \ |
988 } \ | 993 } \ |
989 if (within == kInnerPointer) { \ | 994 if (within == kInnerPointer) { \ |
990 if (space_number != CODE_SPACE || new_object->IsCode()) { \ | 995 if (space_number != CODE_SPACE || new_object->IsCode()) { \ |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1215 CASE_BODY(kExternalReference, | 1220 CASE_BODY(kExternalReference, |
1216 kFromCode, | 1221 kFromCode, |
1217 kStartOfObject, | 1222 kStartOfObject, |
1218 0) | 1223 0) |
1219 // Find a builtin and write a pointer to it to the current object. | 1224 // Find a builtin and write a pointer to it to the current object. |
1220 CASE_STATEMENT(kBuiltin, kPlain, kStartOfObject, 0) | 1225 CASE_STATEMENT(kBuiltin, kPlain, kStartOfObject, 0) |
1221 CASE_BODY(kBuiltin, kPlain, kStartOfObject, 0) | 1226 CASE_BODY(kBuiltin, kPlain, kStartOfObject, 0) |
1222 // Find a builtin and write a pointer to it in the current code object. | 1227 // Find a builtin and write a pointer to it in the current code object. |
1223 CASE_STATEMENT(kBuiltin, kFromCode, kInnerPointer, 0) | 1228 CASE_STATEMENT(kBuiltin, kFromCode, kInnerPointer, 0) |
1224 CASE_BODY(kBuiltin, kFromCode, kInnerPointer, 0) | 1229 CASE_BODY(kBuiltin, kFromCode, kInnerPointer, 0) |
| 1230 // Find an object in the attached references and write a pointer to it to |
| 1231 // the current object. |
| 1232 CASE_STATEMENT(kAttachedReference, kPlain, kStartOfObject, 0) |
| 1233 CASE_BODY(kAttachedReference, kPlain, kStartOfObject, 0) |
1225 | 1234 |
1226 #undef CASE_STATEMENT | 1235 #undef CASE_STATEMENT |
1227 #undef CASE_BODY | 1236 #undef CASE_BODY |
1228 #undef ALL_SPACES | 1237 #undef ALL_SPACES |
1229 | 1238 |
1230 case kSkip: { | 1239 case kSkip: { |
1231 int size = source_->GetInt(); | 1240 int size = source_->GetInt(); |
1232 current = reinterpret_cast<Object**>( | 1241 current = reinterpret_cast<Object**>( |
1233 reinterpret_cast<intptr_t>(current) + size); | 1242 reinterpret_cast<intptr_t>(current) + size); |
1234 break; | 1243 break; |
(...skipping 633 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1868 } | 1877 } |
1869 } | 1878 } |
1870 | 1879 |
1871 | 1880 |
1872 void Serializer::InitializeCodeAddressMap() { | 1881 void Serializer::InitializeCodeAddressMap() { |
1873 isolate_->InitializeLoggingAndCounters(); | 1882 isolate_->InitializeLoggingAndCounters(); |
1874 code_address_map_ = new CodeAddressMap(isolate_); | 1883 code_address_map_ = new CodeAddressMap(isolate_); |
1875 } | 1884 } |
1876 | 1885 |
1877 | 1886 |
1878 ScriptData* CodeSerializer::Serialize(Handle<SharedFunctionInfo> info) { | 1887 ScriptData* CodeSerializer::Serialize(Isolate* isolate, |
| 1888 Handle<SharedFunctionInfo> info, |
| 1889 Handle<String> source) { |
1879 // Serialize code object. | 1890 // Serialize code object. |
1880 List<byte> payload; | 1891 List<byte> payload; |
1881 ListSnapshotSink list_sink(&payload); | 1892 ListSnapshotSink list_sink(&payload); |
1882 CodeSerializer cs(info->GetIsolate(), &list_sink); | 1893 CodeSerializer cs(isolate, &list_sink, *source); |
1883 DisallowHeapAllocation no_gc; | |
1884 Object** location = Handle<Object>::cast(info).location(); | 1894 Object** location = Handle<Object>::cast(info).location(); |
1885 cs.VisitPointer(location); | 1895 cs.VisitPointer(location); |
1886 cs.Pad(); | 1896 cs.Pad(); |
1887 | 1897 |
1888 SerializedCodeData data(&payload, &cs); | 1898 SerializedCodeData data(&payload, &cs); |
1889 return data.GetScriptData(); | 1899 return data.GetScriptData(); |
1890 } | 1900 } |
1891 | 1901 |
1892 | 1902 |
1893 void CodeSerializer::SerializeObject(Object* o, HowToCode how_to_code, | 1903 void CodeSerializer::SerializeObject(Object* o, HowToCode how_to_code, |
1894 WhereToPoint where_to_point, int skip) { | 1904 WhereToPoint where_to_point, int skip) { |
1895 CHECK(o->IsHeapObject()); | 1905 CHECK(o->IsHeapObject()); |
1896 HeapObject* heap_object = HeapObject::cast(o); | 1906 HeapObject* heap_object = HeapObject::cast(o); |
1897 | 1907 |
1898 // The code-caches link to context-specific code objects, which | 1908 // The code-caches link to context-specific code objects, which |
1899 // the startup and context serializes cannot currently handle. | 1909 // the startup and context serializes cannot currently handle. |
1900 ASSERT(!heap_object->IsMap() || | 1910 ASSERT(!heap_object->IsMap() || |
1901 Map::cast(heap_object)->code_cache() == | 1911 Map::cast(heap_object)->code_cache() == |
1902 heap_object->GetHeap()->empty_fixed_array()); | 1912 heap_object->GetHeap()->empty_fixed_array()); |
1903 | 1913 |
1904 int root_index; | 1914 int root_index; |
1905 if ((root_index = RootIndex(heap_object, how_to_code)) != kInvalidRootIndex) { | 1915 if ((root_index = RootIndex(heap_object, how_to_code)) != kInvalidRootIndex) { |
1906 PutRoot(root_index, heap_object, how_to_code, where_to_point, skip); | 1916 PutRoot(root_index, heap_object, how_to_code, where_to_point, skip); |
1907 return; | 1917 return; |
1908 } | 1918 } |
1909 | 1919 |
1910 // TODO(yangguo) wire up stubs from stub cache. | 1920 // TODO(yangguo) wire up stubs from stub cache. |
1911 // TODO(yangguo) wire up script source. | 1921 // TODO(yangguo) wire up global object. |
1912 // TODO(yangguo) We cannot deal with different hash seeds yet. | 1922 // TODO(yangguo) We cannot deal with different hash seeds yet. |
1913 ASSERT(!heap_object->IsHashTable()); | 1923 ASSERT(!heap_object->IsHashTable()); |
1914 | 1924 |
| 1925 if (address_mapper_.IsMapped(heap_object)) { |
| 1926 int space = SpaceOfObject(heap_object); |
| 1927 int address = address_mapper_.MappedTo(heap_object); |
| 1928 SerializeReferenceToPreviousObject(space, address, how_to_code, |
| 1929 where_to_point, skip); |
| 1930 return; |
| 1931 } |
| 1932 |
1915 if (heap_object->IsCode()) { | 1933 if (heap_object->IsCode()) { |
1916 Code* code_object = Code::cast(heap_object); | 1934 Code* code_object = Code::cast(heap_object); |
1917 if (code_object->kind() == Code::BUILTIN) { | 1935 if (code_object->kind() == Code::BUILTIN) { |
1918 SerializeBuiltin(code_object, how_to_code, where_to_point, skip); | 1936 SerializeBuiltin(code_object, how_to_code, where_to_point, skip); |
1919 return; | 1937 return; |
1920 } | 1938 } |
1921 } | 1939 } |
1922 | 1940 |
1923 if (address_mapper_.IsMapped(heap_object)) { | 1941 if (heap_object == source_) { |
1924 int space = SpaceOfObject(heap_object); | 1942 SerializeSourceObject(how_to_code, where_to_point, skip); |
1925 int address = address_mapper_.MappedTo(heap_object); | |
1926 SerializeReferenceToPreviousObject(space, address, how_to_code, | |
1927 where_to_point, skip); | |
1928 return; | 1943 return; |
1929 } | 1944 } |
1930 | 1945 |
1931 if (skip != 0) { | 1946 if (skip != 0) { |
1932 sink_->Put(kSkip, "SkipFromSerializeObject"); | 1947 sink_->Put(kSkip, "SkipFromSerializeObject"); |
1933 sink_->PutInt(skip, "SkipDistanceFromSerializeObject"); | 1948 sink_->PutInt(skip, "SkipDistanceFromSerializeObject"); |
1934 } | 1949 } |
1935 // Object has not yet been serialized. Serialize it here. | 1950 // Object has not yet been serialized. Serialize it here. |
1936 ObjectSerializer serializer(this, heap_object, sink_, how_to_code, | 1951 ObjectSerializer serializer(this, heap_object, sink_, how_to_code, |
1937 where_to_point); | 1952 where_to_point); |
(...skipping 15 matching lines...) Expand all Loading... |
1953 Code* b = isolate()->builtins()->builtin(static_cast<Builtins::Name>(id)); | 1968 Code* b = isolate()->builtins()->builtin(static_cast<Builtins::Name>(id)); |
1954 if (builtin == b) break; | 1969 if (builtin == b) break; |
1955 } while (++id < Builtins::builtin_count); | 1970 } while (++id < Builtins::builtin_count); |
1956 ASSERT(id < Builtins::builtin_count); // We must have found a one. | 1971 ASSERT(id < Builtins::builtin_count); // We must have found a one. |
1957 | 1972 |
1958 sink_->Put(kBuiltin + how_to_code + where_to_point, "Builtin"); | 1973 sink_->Put(kBuiltin + how_to_code + where_to_point, "Builtin"); |
1959 sink_->PutInt(id, "builtin_index"); | 1974 sink_->PutInt(id, "builtin_index"); |
1960 } | 1975 } |
1961 | 1976 |
1962 | 1977 |
1963 Object* CodeSerializer::Deserialize(Isolate* isolate, ScriptData* data) { | 1978 void CodeSerializer::SerializeSourceObject(HowToCode how_to_code, |
| 1979 WhereToPoint where_to_point, |
| 1980 int skip) { |
| 1981 if (skip != 0) { |
| 1982 sink_->Put(kSkip, "SkipFromSerializeSourceObject"); |
| 1983 sink_->PutInt(skip, "SkipDistanceFromSerializeSourceObject"); |
| 1984 } |
| 1985 |
| 1986 ASSERT(how_to_code == kPlain && where_to_point == kStartOfObject); |
| 1987 sink_->Put(kAttachedReference + how_to_code + where_to_point, "Source"); |
| 1988 sink_->PutInt(kSourceObjectIndex, "kSourceObjectIndex"); |
| 1989 } |
| 1990 |
| 1991 |
| 1992 Handle<SharedFunctionInfo> CodeSerializer::Deserialize(Isolate* isolate, |
| 1993 ScriptData* data, |
| 1994 Handle<String> source) { |
1964 SerializedCodeData scd(data); | 1995 SerializedCodeData scd(data); |
1965 SnapshotByteSource payload(scd.Payload(), scd.PayloadLength()); | 1996 SnapshotByteSource payload(scd.Payload(), scd.PayloadLength()); |
1966 Deserializer deserializer(&payload); | 1997 Deserializer deserializer(&payload); |
1967 deserializer.ExpectSerializedCode(); | |
1968 STATIC_ASSERT(NEW_SPACE == 0); | 1998 STATIC_ASSERT(NEW_SPACE == 0); |
1969 // TODO(yangguo) what happens if remaining new space is too small? | 1999 // TODO(yangguo) what happens if remaining new space is too small? |
1970 for (int i = NEW_SPACE; i <= PROPERTY_CELL_SPACE; i++) { | 2000 for (int i = NEW_SPACE; i <= PROPERTY_CELL_SPACE; i++) { |
1971 deserializer.set_reservation(i, scd.GetReservation(i)); | 2001 deserializer.set_reservation(i, scd.GetReservation(i)); |
1972 } | 2002 } |
| 2003 DisallowHeapAllocation no_gc; |
| 2004 |
| 2005 // Prepare and register list of attached objects. |
| 2006 List<Object*> attached_objects(1); |
| 2007 attached_objects.Set(kSourceObjectIndex, *source); |
| 2008 deserializer.SetAttachedObjects(&attached_objects); |
| 2009 |
1973 Object* root; | 2010 Object* root; |
1974 deserializer.DeserializePartial(isolate, &root); | 2011 deserializer.DeserializePartial(isolate, &root); |
1975 deserializer.FlushICacheForNewCodeObjects(); | 2012 deserializer.FlushICacheForNewCodeObjects(); |
1976 ASSERT(root->IsSharedFunctionInfo()); | 2013 return Handle<SharedFunctionInfo>(SharedFunctionInfo::cast(root), isolate); |
1977 return root; | |
1978 } | 2014 } |
1979 | 2015 |
1980 | 2016 |
1981 SerializedCodeData::SerializedCodeData(List<byte>* payload, CodeSerializer* cs) | 2017 SerializedCodeData::SerializedCodeData(List<byte>* payload, CodeSerializer* cs) |
1982 : owns_script_data_(true) { | 2018 : owns_script_data_(true) { |
1983 int data_length = payload->length() + kHeaderEntries * kIntSize; | 2019 int data_length = payload->length() + kHeaderEntries * kIntSize; |
1984 byte* data = NewArray<byte>(data_length); | 2020 byte* data = NewArray<byte>(data_length); |
1985 ASSERT(IsAligned(reinterpret_cast<intptr_t>(data), kPointerAlignment)); | 2021 ASSERT(IsAligned(reinterpret_cast<intptr_t>(data), kPointerAlignment)); |
1986 CopyBytes(data + kHeaderEntries * kIntSize, payload->begin(), | 2022 CopyBytes(data + kHeaderEntries * kIntSize, payload->begin(), |
1987 static_cast<size_t>(payload->length())); | 2023 static_cast<size_t>(payload->length())); |
1988 script_data_ = new ScriptData(data, data_length); | 2024 script_data_ = new ScriptData(data, data_length); |
1989 script_data_->AcquireDataOwnership(); | 2025 script_data_->AcquireDataOwnership(); |
1990 SetHeaderValue(kVersionHashOffset, Version::Hash()); | 2026 SetHeaderValue(kVersionHashOffset, Version::Hash()); |
1991 STATIC_ASSERT(NEW_SPACE == 0); | 2027 STATIC_ASSERT(NEW_SPACE == 0); |
1992 for (int i = NEW_SPACE; i <= PROPERTY_CELL_SPACE; i++) { | 2028 for (int i = NEW_SPACE; i <= PROPERTY_CELL_SPACE; i++) { |
1993 SetHeaderValue(kReservationsOffset + i, cs->CurrentAllocationAddress(i)); | 2029 SetHeaderValue(kReservationsOffset + i, cs->CurrentAllocationAddress(i)); |
1994 } | 2030 } |
1995 } | 2031 } |
1996 | 2032 |
1997 | 2033 |
1998 bool SerializedCodeData::IsSane() { | 2034 bool SerializedCodeData::IsSane() { |
1999 return GetHeaderValue(kVersionHashOffset) == Version::Hash() && | 2035 return GetHeaderValue(kVersionHashOffset) == Version::Hash() && |
2000 PayloadLength() >= SharedFunctionInfo::kSize; | 2036 PayloadLength() >= SharedFunctionInfo::kSize; |
2001 } | 2037 } |
2002 } } // namespace v8::internal | 2038 } } // namespace v8::internal |
OLD | NEW |