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

Side by Side Diff: src/serialize.cc

Issue 387343002: Fix up internalized strings after deserializing user code. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: remove TODO 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
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 700 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/serialize.h ('k') | test/cctest/test-serialize.cc » ('j') | test/cctest/test-serialize.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698