| 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 source_(source), | 722 source_(source), |
| 722 external_reference_decoder_(NULL) { | 723 external_reference_decoder_(NULL) { |
| 723 for (int i = 0; i < LAST_SPACE + 1; i++) { | 724 for (int i = 0; i < LAST_SPACE + 1; i++) { |
| 724 reservations_[i] = kUninitializedReservation; | 725 reservations_[i] = kUninitializedReservation; |
| 725 } | 726 } |
| 726 } | 727 } |
| 727 | 728 |
| 728 | 729 |
| 729 void Deserializer::FlushICacheForNewCodeObjects() { | 730 void Deserializer::FlushICacheForNewCodeObjects() { |
| 730 PageIterator it(isolate_->heap()->code_space()); | 731 PageIterator it(isolate_->heap()->code_space()); |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 825 void Deserializer::RelinkAllocationSite(AllocationSite* site) { | 826 void Deserializer::RelinkAllocationSite(AllocationSite* site) { |
| 826 if (isolate_->heap()->allocation_sites_list() == Smi::FromInt(0)) { | 827 if (isolate_->heap()->allocation_sites_list() == Smi::FromInt(0)) { |
| 827 site->set_weak_next(isolate_->heap()->undefined_value()); | 828 site->set_weak_next(isolate_->heap()->undefined_value()); |
| 828 } else { | 829 } else { |
| 829 site->set_weak_next(isolate_->heap()->allocation_sites_list()); | 830 site->set_weak_next(isolate_->heap()->allocation_sites_list()); |
| 830 } | 831 } |
| 831 isolate_->heap()->set_allocation_sites_list(site); | 832 isolate_->heap()->set_allocation_sites_list(site); |
| 832 } | 833 } |
| 833 | 834 |
| 834 | 835 |
| 836 // Used to insert a deserialized internalized string into the string table. |
| 837 class StringTableInsertionKey : public HashTableKey { |
| 838 public: |
| 839 explicit StringTableInsertionKey(String* string) |
| 840 : string_(string), hash_(HashForObject(string)) { |
| 841 ASSERT(string->IsInternalizedString()); |
| 842 } |
| 843 |
| 844 virtual bool IsMatch(Object* string) { |
| 845 // We know that all entries in a hash table had their hash keys created. |
| 846 // Use that knowledge to have fast failure. |
| 847 if (hash_ != HashForObject(string)) return false; |
| 848 // We want to compare the content of two internalized strings here. |
| 849 return string_->SlowEquals(String::cast(string)); |
| 850 } |
| 851 |
| 852 virtual uint32_t Hash() V8_OVERRIDE { return hash_; } |
| 853 |
| 854 virtual uint32_t HashForObject(Object* key) V8_OVERRIDE { |
| 855 return String::cast(key)->Hash(); |
| 856 } |
| 857 |
| 858 MUST_USE_RESULT virtual Handle<Object> AsHandle(Isolate* isolate) |
| 859 V8_OVERRIDE { |
| 860 return handle(string_, isolate); |
| 861 } |
| 862 |
| 863 String* string_; |
| 864 uint32_t hash_; |
| 865 }; |
| 866 |
| 867 |
| 868 HeapObject* Deserializer::ProcessObjectFromSerializedCode(HeapObject* obj) { |
| 869 if (obj->IsString()) { |
| 870 String* string = String::cast(obj); |
| 871 // Uninitialize hash field as the hash seed may have changed. |
| 872 string->set_hash_field(String::kEmptyHashField); |
| 873 if (string->IsInternalizedString()) { |
| 874 DisallowHeapAllocation no_gc; |
| 875 HandleScope scope(isolate_); |
| 876 StringTableInsertionKey key(string); |
| 877 return *StringTable::LookupKey(isolate_, &key); |
| 878 } |
| 879 } |
| 880 return obj; |
| 881 } |
| 882 |
| 883 |
| 835 // This routine writes the new object into the pointer provided and then | 884 // This routine writes the new object into the pointer provided and then |
| 836 // returns true if the new object was in young space and false otherwise. | 885 // returns true if the new object was in young space and false otherwise. |
| 837 // The reason for this strange interface is that otherwise the object is | 886 // The reason for this strange interface is that otherwise the object is |
| 838 // written very late, which means the FreeSpace map is not set up by the | 887 // written very late, which means the FreeSpace map is not set up by the |
| 839 // time we need to use it to mark the space at the end of a page free. | 888 // time we need to use it to mark the space at the end of a page free. |
| 840 void Deserializer::ReadObject(int space_number, | 889 void Deserializer::ReadObject(int space_number, |
| 841 Object** write_back) { | 890 Object** write_back) { |
| 842 int size = source_->GetInt() << kObjectAlignmentBits; | 891 int size = source_->GetInt() << kObjectAlignmentBits; |
| 843 Address address = Allocate(space_number, size); | 892 Address address = Allocate(space_number, size); |
| 844 HeapObject* obj = HeapObject::FromAddress(address); | 893 HeapObject* obj = HeapObject::FromAddress(address); |
| 845 isolate_->heap()->OnAllocationEvent(obj, size); | 894 isolate_->heap()->OnAllocationEvent(obj, size); |
| 846 *write_back = obj; | |
| 847 Object** current = reinterpret_cast<Object**>(address); | 895 Object** current = reinterpret_cast<Object**>(address); |
| 848 Object** limit = current + (size >> kPointerSizeLog2); | 896 Object** limit = current + (size >> kPointerSizeLog2); |
| 849 if (FLAG_log_snapshot_positions) { | 897 if (FLAG_log_snapshot_positions) { |
| 850 LOG(isolate_, SnapshotPositionEvent(address, source_->position())); | 898 LOG(isolate_, SnapshotPositionEvent(address, source_->position())); |
| 851 } | 899 } |
| 852 ReadChunk(current, limit, space_number, address); | 900 ReadChunk(current, limit, space_number, address); |
| 853 | 901 |
| 854 // TODO(mvstanton): consider treating the heap()->allocation_sites_list() | 902 // TODO(mvstanton): consider treating the heap()->allocation_sites_list() |
| 855 // as a (weak) root. If this root is relocated correctly, | 903 // as a (weak) root. If this root is relocated correctly, |
| 856 // RelinkAllocationSite() isn't necessary. | 904 // RelinkAllocationSite() isn't necessary. |
| 857 if (obj->IsAllocationSite()) { | 905 if (obj->IsAllocationSite()) RelinkAllocationSite(AllocationSite::cast(obj)); |
| 858 RelinkAllocationSite(AllocationSite::cast(obj)); | |
| 859 } | |
| 860 | 906 |
| 907 // Fix up strings from serialized user code. |
| 908 if (deserialize_code_) obj = ProcessObjectFromSerializedCode(obj); |
| 909 |
| 910 *write_back = obj; |
| 861 #ifdef DEBUG | 911 #ifdef DEBUG |
| 862 bool is_codespace = (space_number == CODE_SPACE); | 912 bool is_codespace = (space_number == CODE_SPACE); |
| 863 ASSERT(obj->IsCode() == is_codespace); | 913 ASSERT(obj->IsCode() == is_codespace); |
| 864 #endif | 914 #endif |
| 865 } | 915 } |
| 866 | 916 |
| 867 void Deserializer::ReadChunk(Object** current, | 917 void Deserializer::ReadChunk(Object** current, |
| 868 Object** limit, | 918 Object** limit, |
| 869 int source_space, | 919 int source_space, |
| 870 Address current_object_address) { | 920 Address current_object_address) { |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 914 int skip = source_->GetInt(); \ | 964 int skip = source_->GetInt(); \ |
| 915 current = reinterpret_cast<Object**>( \ | 965 current = reinterpret_cast<Object**>( \ |
| 916 reinterpret_cast<Address>(current) + skip); \ | 966 reinterpret_cast<Address>(current) + skip); \ |
| 917 int reference_id = source_->GetInt(); \ | 967 int reference_id = source_->GetInt(); \ |
| 918 Address address = external_reference_decoder_->Decode(reference_id); \ | 968 Address address = external_reference_decoder_->Decode(reference_id); \ |
| 919 new_object = reinterpret_cast<Object*>(address); \ | 969 new_object = reinterpret_cast<Object*>(address); \ |
| 920 } else if (where == kBackref) { \ | 970 } else if (where == kBackref) { \ |
| 921 emit_write_barrier = (space_number == NEW_SPACE); \ | 971 emit_write_barrier = (space_number == NEW_SPACE); \ |
| 922 new_object = GetAddressFromEnd(data & kSpaceMask); \ | 972 new_object = GetAddressFromEnd(data & kSpaceMask); \ |
| 923 } else if (where == kBuiltin) { \ | 973 } else if (where == kBuiltin) { \ |
| 974 ASSERT(deserialize_code_); \ |
| 924 int builtin_id = source_->GetInt(); \ | 975 int builtin_id = source_->GetInt(); \ |
| 925 ASSERT_LE(0, builtin_id); \ | 976 ASSERT_LE(0, builtin_id); \ |
| 926 ASSERT_LT(builtin_id, Builtins::builtin_count); \ | 977 ASSERT_LT(builtin_id, Builtins::builtin_count); \ |
| 927 Builtins::Name name = static_cast<Builtins::Name>(builtin_id); \ | 978 Builtins::Name name = static_cast<Builtins::Name>(builtin_id); \ |
| 928 new_object = isolate->builtins()->builtin(name); \ | 979 new_object = isolate->builtins()->builtin(name); \ |
| 929 emit_write_barrier = false; \ | 980 emit_write_barrier = false; \ |
| 930 PrintF("BUILTIN how within %d, %d\n", how, within); \ | |
| 931 } else { \ | 981 } else { \ |
| 932 ASSERT(where == kBackrefWithSkip); \ | 982 ASSERT(where == kBackrefWithSkip); \ |
| 933 int skip = source_->GetInt(); \ | 983 int skip = source_->GetInt(); \ |
| 934 current = reinterpret_cast<Object**>( \ | 984 current = reinterpret_cast<Object**>( \ |
| 935 reinterpret_cast<Address>(current) + skip); \ | 985 reinterpret_cast<Address>(current) + skip); \ |
| 936 emit_write_barrier = (space_number == NEW_SPACE); \ | 986 emit_write_barrier = (space_number == NEW_SPACE); \ |
| 937 new_object = GetAddressFromEnd(data & kSpaceMask); \ | 987 new_object = GetAddressFromEnd(data & kSpaceMask); \ |
| 938 } \ | 988 } \ |
| 939 if (within == kInnerPointer) { \ | 989 if (within == kInnerPointer) { \ |
| 940 if (space_number != CODE_SPACE || new_object->IsCode()) { \ | 990 if (space_number != CODE_SPACE || new_object->IsCode()) { \ |
| (...skipping 911 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1852 heap_object->GetHeap()->empty_fixed_array()); | 1902 heap_object->GetHeap()->empty_fixed_array()); |
| 1853 | 1903 |
| 1854 int root_index; | 1904 int root_index; |
| 1855 if ((root_index = RootIndex(heap_object, how_to_code)) != kInvalidRootIndex) { | 1905 if ((root_index = RootIndex(heap_object, how_to_code)) != kInvalidRootIndex) { |
| 1856 PutRoot(root_index, heap_object, how_to_code, where_to_point, skip); | 1906 PutRoot(root_index, heap_object, how_to_code, where_to_point, skip); |
| 1857 return; | 1907 return; |
| 1858 } | 1908 } |
| 1859 | 1909 |
| 1860 // TODO(yangguo) wire up stubs from stub cache. | 1910 // TODO(yangguo) wire up stubs from stub cache. |
| 1861 // TODO(yangguo) wire up script source. | 1911 // TODO(yangguo) wire up script source. |
| 1862 // TODO(yangguo) wire up internalized strings | |
| 1863 ASSERT(!heap_object->IsInternalizedString()); | |
| 1864 // TODO(yangguo) We cannot deal with different hash seeds yet. | 1912 // TODO(yangguo) We cannot deal with different hash seeds yet. |
| 1865 ASSERT(!heap_object->IsHashTable()); | 1913 ASSERT(!heap_object->IsHashTable()); |
| 1866 | 1914 |
| 1867 if (heap_object->IsCode()) { | 1915 if (heap_object->IsCode()) { |
| 1868 Code* code_object = Code::cast(heap_object); | 1916 Code* code_object = Code::cast(heap_object); |
| 1869 if (code_object->kind() == Code::BUILTIN) { | 1917 if (code_object->kind() == Code::BUILTIN) { |
| 1870 SerializeBuiltin(code_object, how_to_code, where_to_point, skip); | 1918 SerializeBuiltin(code_object, how_to_code, where_to_point, skip); |
| 1871 return; | 1919 return; |
| 1872 } | 1920 } |
| 1873 } | 1921 } |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1909 | 1957 |
| 1910 sink_->Put(kBuiltin + how_to_code + where_to_point, "Builtin"); | 1958 sink_->Put(kBuiltin + how_to_code + where_to_point, "Builtin"); |
| 1911 sink_->PutInt(id, "builtin_index"); | 1959 sink_->PutInt(id, "builtin_index"); |
| 1912 } | 1960 } |
| 1913 | 1961 |
| 1914 | 1962 |
| 1915 Object* CodeSerializer::Deserialize(Isolate* isolate, ScriptData* data) { | 1963 Object* CodeSerializer::Deserialize(Isolate* isolate, ScriptData* data) { |
| 1916 SerializedCodeData scd(data); | 1964 SerializedCodeData scd(data); |
| 1917 SnapshotByteSource payload(scd.Payload(), scd.PayloadLength()); | 1965 SnapshotByteSource payload(scd.Payload(), scd.PayloadLength()); |
| 1918 Deserializer deserializer(&payload); | 1966 Deserializer deserializer(&payload); |
| 1967 deserializer.ExpectSerializedCode(); |
| 1919 STATIC_ASSERT(NEW_SPACE == 0); | 1968 STATIC_ASSERT(NEW_SPACE == 0); |
| 1920 // TODO(yangguo) what happens if remaining new space is too small? | 1969 // TODO(yangguo) what happens if remaining new space is too small? |
| 1921 for (int i = NEW_SPACE; i <= PROPERTY_CELL_SPACE; i++) { | 1970 for (int i = NEW_SPACE; i <= PROPERTY_CELL_SPACE; i++) { |
| 1922 deserializer.set_reservation(i, scd.GetReservation(i)); | 1971 deserializer.set_reservation(i, scd.GetReservation(i)); |
| 1923 } | 1972 } |
| 1924 Object* root; | 1973 Object* root; |
| 1925 deserializer.DeserializePartial(isolate, &root); | 1974 deserializer.DeserializePartial(isolate, &root); |
| 1926 deserializer.FlushICacheForNewCodeObjects(); | 1975 deserializer.FlushICacheForNewCodeObjects(); |
| 1927 ASSERT(root->IsSharedFunctionInfo()); | 1976 ASSERT(root->IsSharedFunctionInfo()); |
| 1928 return root; | 1977 return root; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1944 SetHeaderValue(kReservationsOffset + i, cs->CurrentAllocationAddress(i)); | 1993 SetHeaderValue(kReservationsOffset + i, cs->CurrentAllocationAddress(i)); |
| 1945 } | 1994 } |
| 1946 } | 1995 } |
| 1947 | 1996 |
| 1948 | 1997 |
| 1949 bool SerializedCodeData::IsSane() { | 1998 bool SerializedCodeData::IsSane() { |
| 1950 return GetHeaderValue(kVersionHashOffset) == Version::Hash() && | 1999 return GetHeaderValue(kVersionHashOffset) == Version::Hash() && |
| 1951 PayloadLength() >= SharedFunctionInfo::kSize; | 2000 PayloadLength() >= SharedFunctionInfo::kSize; |
| 1952 } | 2001 } |
| 1953 } } // namespace v8::internal | 2002 } } // namespace v8::internal |
| OLD | NEW |