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 849 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
860 MUST_USE_RESULT virtual Handle<Object> AsHandle(Isolate* isolate) | 860 MUST_USE_RESULT virtual Handle<Object> AsHandle(Isolate* isolate) |
861 V8_OVERRIDE { | 861 V8_OVERRIDE { |
862 return handle(string_, isolate); | 862 return handle(string_, isolate); |
863 } | 863 } |
864 | 864 |
865 String* string_; | 865 String* string_; |
866 uint32_t hash_; | 866 uint32_t hash_; |
867 }; | 867 }; |
868 | 868 |
869 | 869 |
870 HeapObject* Deserializer::ProcessObjectFromSerializedCode(HeapObject* obj) { | 870 HeapObject* Deserializer::ProcessNewObjectFromSerializedCode(HeapObject* obj) { |
871 if (obj->IsString()) { | 871 if (obj->IsString()) { |
872 String* string = String::cast(obj); | 872 String* string = String::cast(obj); |
873 // Uninitialize hash field as the hash seed may have changed. | 873 // Uninitialize hash field as the hash seed may have changed. |
874 string->set_hash_field(String::kEmptyHashField); | 874 string->set_hash_field(String::kEmptyHashField); |
875 if (string->IsInternalizedString()) { | 875 if (string->IsInternalizedString()) { |
876 DisallowHeapAllocation no_gc; | 876 DisallowHeapAllocation no_gc; |
877 HandleScope scope(isolate_); | 877 HandleScope scope(isolate_); |
878 StringTableInsertionKey key(string); | 878 StringTableInsertionKey key(string); |
879 return *StringTable::LookupKey(isolate_, &key); | 879 String* canonical = *StringTable::LookupKey(isolate_, &key); |
| 880 string->SetForwardedInternalizedString(canonical); |
| 881 return canonical; |
880 } | 882 } |
881 } | 883 } |
882 return obj; | 884 return obj; |
883 } | 885 } |
884 | 886 |
885 | 887 |
| 888 Object* Deserializer::ProcessBackRefInSerializedCode(Object* obj) { |
| 889 if (obj->IsInternalizedString()) { |
| 890 return String::cast(obj)->GetForwardedInternalizedString(); |
| 891 } |
| 892 return obj; |
| 893 } |
| 894 |
| 895 |
886 // This routine writes the new object into the pointer provided and then | 896 // This routine writes the new object into the pointer provided and then |
887 // returns true if the new object was in young space and false otherwise. | 897 // returns true if the new object was in young space and false otherwise. |
888 // The reason for this strange interface is that otherwise the object is | 898 // The reason for this strange interface is that otherwise the object is |
889 // written very late, which means the FreeSpace map is not set up by the | 899 // written very late, which means the FreeSpace map is not set up by the |
890 // time we need to use it to mark the space at the end of a page free. | 900 // time we need to use it to mark the space at the end of a page free. |
891 void Deserializer::ReadObject(int space_number, | 901 void Deserializer::ReadObject(int space_number, |
892 Object** write_back) { | 902 Object** write_back) { |
893 int size = source_->GetInt() << kObjectAlignmentBits; | 903 int size = source_->GetInt() << kObjectAlignmentBits; |
894 Address address = Allocate(space_number, size); | 904 Address address = Allocate(space_number, size); |
895 HeapObject* obj = HeapObject::FromAddress(address); | 905 HeapObject* obj = HeapObject::FromAddress(address); |
896 isolate_->heap()->OnAllocationEvent(obj, size); | 906 isolate_->heap()->OnAllocationEvent(obj, size); |
897 Object** current = reinterpret_cast<Object**>(address); | 907 Object** current = reinterpret_cast<Object**>(address); |
898 Object** limit = current + (size >> kPointerSizeLog2); | 908 Object** limit = current + (size >> kPointerSizeLog2); |
899 if (FLAG_log_snapshot_positions) { | 909 if (FLAG_log_snapshot_positions) { |
900 LOG(isolate_, SnapshotPositionEvent(address, source_->position())); | 910 LOG(isolate_, SnapshotPositionEvent(address, source_->position())); |
901 } | 911 } |
902 ReadChunk(current, limit, space_number, address); | 912 ReadChunk(current, limit, space_number, address); |
903 | 913 |
904 // TODO(mvstanton): consider treating the heap()->allocation_sites_list() | 914 // TODO(mvstanton): consider treating the heap()->allocation_sites_list() |
905 // as a (weak) root. If this root is relocated correctly, | 915 // as a (weak) root. If this root is relocated correctly, |
906 // RelinkAllocationSite() isn't necessary. | 916 // RelinkAllocationSite() isn't necessary. |
907 if (obj->IsAllocationSite()) RelinkAllocationSite(AllocationSite::cast(obj)); | 917 if (obj->IsAllocationSite()) RelinkAllocationSite(AllocationSite::cast(obj)); |
908 | 918 |
909 // Fix up strings from serialized user code. | 919 // Fix up strings from serialized user code. |
910 if (deserializing_user_code()) obj = ProcessObjectFromSerializedCode(obj); | 920 if (deserializing_user_code()) obj = ProcessNewObjectFromSerializedCode(obj); |
911 | 921 |
912 *write_back = obj; | 922 *write_back = obj; |
913 #ifdef DEBUG | 923 #ifdef DEBUG |
914 bool is_codespace = (space_number == CODE_SPACE); | 924 bool is_codespace = (space_number == CODE_SPACE); |
915 ASSERT(obj->IsCode() == is_codespace); | 925 ASSERT(obj->IsCode() == is_codespace); |
916 #endif | 926 #endif |
917 } | 927 } |
918 | 928 |
919 void Deserializer::ReadChunk(Object** current, | 929 void Deserializer::ReadChunk(Object** current, |
920 Object** limit, | 930 Object** limit, |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
965 } else if (where == kExternalReference) { \ | 975 } else if (where == kExternalReference) { \ |
966 int skip = source_->GetInt(); \ | 976 int skip = source_->GetInt(); \ |
967 current = reinterpret_cast<Object**>( \ | 977 current = reinterpret_cast<Object**>( \ |
968 reinterpret_cast<Address>(current) + skip); \ | 978 reinterpret_cast<Address>(current) + skip); \ |
969 int reference_id = source_->GetInt(); \ | 979 int reference_id = source_->GetInt(); \ |
970 Address address = external_reference_decoder_->Decode(reference_id); \ | 980 Address address = external_reference_decoder_->Decode(reference_id); \ |
971 new_object = reinterpret_cast<Object*>(address); \ | 981 new_object = reinterpret_cast<Object*>(address); \ |
972 } else if (where == kBackref) { \ | 982 } else if (where == kBackref) { \ |
973 emit_write_barrier = (space_number == NEW_SPACE); \ | 983 emit_write_barrier = (space_number == NEW_SPACE); \ |
974 new_object = GetAddressFromEnd(data & kSpaceMask); \ | 984 new_object = GetAddressFromEnd(data & kSpaceMask); \ |
| 985 if (deserializing_user_code()) { \ |
| 986 new_object = ProcessBackRefInSerializedCode(new_object); \ |
| 987 } \ |
975 } else if (where == kBuiltin) { \ | 988 } else if (where == kBuiltin) { \ |
976 ASSERT(deserializing_user_code()); \ | 989 ASSERT(deserializing_user_code()); \ |
977 int builtin_id = source_->GetInt(); \ | 990 int builtin_id = source_->GetInt(); \ |
978 ASSERT_LE(0, builtin_id); \ | 991 ASSERT_LE(0, builtin_id); \ |
979 ASSERT_LT(builtin_id, Builtins::builtin_count); \ | 992 ASSERT_LT(builtin_id, Builtins::builtin_count); \ |
980 Builtins::Name name = static_cast<Builtins::Name>(builtin_id); \ | 993 Builtins::Name name = static_cast<Builtins::Name>(builtin_id); \ |
981 new_object = isolate->builtins()->builtin(name); \ | 994 new_object = isolate->builtins()->builtin(name); \ |
982 emit_write_barrier = false; \ | 995 emit_write_barrier = false; \ |
983 } else if (where == kAttachedReference) { \ | 996 } else if (where == kAttachedReference) { \ |
984 ASSERT(deserializing_user_code()); \ | 997 ASSERT(deserializing_user_code()); \ |
985 int index = source_->GetInt(); \ | 998 int index = source_->GetInt(); \ |
986 new_object = attached_objects_->at(index); \ | 999 new_object = attached_objects_->at(index); \ |
987 emit_write_barrier = isolate->heap()->InNewSpace(new_object); \ | 1000 emit_write_barrier = isolate->heap()->InNewSpace(new_object); \ |
988 } else { \ | 1001 } else { \ |
989 ASSERT(where == kBackrefWithSkip); \ | 1002 ASSERT(where == kBackrefWithSkip); \ |
990 int skip = source_->GetInt(); \ | 1003 int skip = source_->GetInt(); \ |
991 current = reinterpret_cast<Object**>( \ | 1004 current = reinterpret_cast<Object**>( \ |
992 reinterpret_cast<Address>(current) + skip); \ | 1005 reinterpret_cast<Address>(current) + skip); \ |
993 emit_write_barrier = (space_number == NEW_SPACE); \ | 1006 emit_write_barrier = (space_number == NEW_SPACE); \ |
994 new_object = GetAddressFromEnd(data & kSpaceMask); \ | 1007 new_object = GetAddressFromEnd(data & kSpaceMask); \ |
| 1008 if (deserializing_user_code()) { \ |
| 1009 new_object = ProcessBackRefInSerializedCode(new_object); \ |
| 1010 } \ |
995 } \ | 1011 } \ |
996 if (within == kInnerPointer) { \ | 1012 if (within == kInnerPointer) { \ |
997 if (space_number != CODE_SPACE || new_object->IsCode()) { \ | 1013 if (space_number != CODE_SPACE || new_object->IsCode()) { \ |
998 Code* new_code_object = reinterpret_cast<Code*>(new_object); \ | 1014 Code* new_code_object = reinterpret_cast<Code*>(new_object); \ |
999 new_object = \ | 1015 new_object = \ |
1000 reinterpret_cast<Object*>(new_code_object->instruction_start()); \ | 1016 reinterpret_cast<Object*>(new_code_object->instruction_start()); \ |
1001 } else { \ | 1017 } else { \ |
1002 ASSERT(space_number == CODE_SPACE); \ | 1018 ASSERT(space_number == CODE_SPACE); \ |
1003 Cell* cell = Cell::cast(new_object); \ | 1019 Cell* cell = Cell::cast(new_object); \ |
1004 new_object = reinterpret_cast<Object*>(cell->ValueAddress()); \ | 1020 new_object = reinterpret_cast<Object*>(cell->ValueAddress()); \ |
(...skipping 1040 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2045 | 2061 |
2046 int SerializedCodeData::CheckSum(String* string) { | 2062 int SerializedCodeData::CheckSum(String* string) { |
2047 int checksum = Version::Hash(); | 2063 int checksum = Version::Hash(); |
2048 #ifdef DEBUG | 2064 #ifdef DEBUG |
2049 uint32_t seed = static_cast<uint32_t>(checksum); | 2065 uint32_t seed = static_cast<uint32_t>(checksum); |
2050 checksum = static_cast<int>(IteratingStringHasher::Hash(string, seed)); | 2066 checksum = static_cast<int>(IteratingStringHasher::Hash(string, seed)); |
2051 #endif // DEBUG | 2067 #endif // DEBUG |
2052 return checksum; | 2068 return checksum; |
2053 } | 2069 } |
2054 } } // namespace v8::internal | 2070 } } // namespace v8::internal |
OLD | NEW |