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