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 596 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
607 NameMap address_to_name_map_; | 607 NameMap address_to_name_map_; |
608 Isolate* isolate_; | 608 Isolate* isolate_; |
609 }; | 609 }; |
610 | 610 |
611 | 611 |
612 void Deserializer::DecodeReservation( | 612 void Deserializer::DecodeReservation( |
613 Vector<const SerializedData::Reservation> res) { | 613 Vector<const SerializedData::Reservation> res) { |
614 DCHECK_EQ(0, reservations_[NEW_SPACE].length()); | 614 DCHECK_EQ(0, reservations_[NEW_SPACE].length()); |
615 STATIC_ASSERT(NEW_SPACE == 0); | 615 STATIC_ASSERT(NEW_SPACE == 0); |
616 int current_space = NEW_SPACE; | 616 int current_space = NEW_SPACE; |
617 for (const auto& r : res) { | 617 for (int i = 0; i < res.length(); i++) { |
| 618 SerializedData::Reservation r(0); |
| 619 memcpy(&r, res.start() + i, sizeof(r)); |
618 reservations_[current_space].Add({r.chunk_size(), NULL, NULL}); | 620 reservations_[current_space].Add({r.chunk_size(), NULL, NULL}); |
619 if (r.is_last()) current_space++; | 621 if (r.is_last()) current_space++; |
620 } | 622 } |
621 DCHECK_EQ(kNumberOfSpaces, current_space); | 623 DCHECK_EQ(kNumberOfSpaces, current_space); |
622 for (int i = 0; i < kNumberOfPreallocatedSpaces; i++) current_chunk_[i] = 0; | 624 for (int i = 0; i < kNumberOfPreallocatedSpaces; i++) current_chunk_[i] = 0; |
623 } | 625 } |
624 | 626 |
625 | 627 |
626 void Deserializer::FlushICacheForNewCodeObjects() { | 628 void Deserializer::FlushICacheForNewCodeObjects() { |
627 PageIterator it(isolate_->heap()->code_space()); | 629 PageIterator it(isolate_->heap()->code_space()); |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
853 ReadData(current, limit, space_number, address); | 855 ReadData(current, limit, space_number, address); |
854 | 856 |
855 // TODO(mvstanton): consider treating the heap()->allocation_sites_list() | 857 // TODO(mvstanton): consider treating the heap()->allocation_sites_list() |
856 // as a (weak) root. If this root is relocated correctly, | 858 // as a (weak) root. If this root is relocated correctly, |
857 // RelinkAllocationSite() isn't necessary. | 859 // RelinkAllocationSite() isn't necessary. |
858 if (obj->IsAllocationSite()) RelinkAllocationSite(AllocationSite::cast(obj)); | 860 if (obj->IsAllocationSite()) RelinkAllocationSite(AllocationSite::cast(obj)); |
859 | 861 |
860 // Fix up strings from serialized user code. | 862 // Fix up strings from serialized user code. |
861 if (deserializing_user_code()) obj = ProcessNewObjectFromSerializedCode(obj); | 863 if (deserializing_user_code()) obj = ProcessNewObjectFromSerializedCode(obj); |
862 | 864 |
863 *write_back = obj; | 865 Object* write_back_obj = obj; |
| 866 UnalignedCopy(write_back, &write_back_obj); |
864 #ifdef DEBUG | 867 #ifdef DEBUG |
865 if (obj->IsCode()) { | 868 if (obj->IsCode()) { |
866 DCHECK(space_number == CODE_SPACE || space_number == LO_SPACE); | 869 DCHECK(space_number == CODE_SPACE || space_number == LO_SPACE); |
867 } else { | 870 } else { |
868 DCHECK(space_number != CODE_SPACE); | 871 DCHECK(space_number != CODE_SPACE); |
869 } | 872 } |
870 #endif | 873 #endif |
871 } | 874 } |
872 | 875 |
873 | 876 |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
996 if (how == kFromCode) { \ | 999 if (how == kFromCode) { \ |
997 Address location_of_branch_data = reinterpret_cast<Address>(current); \ | 1000 Address location_of_branch_data = reinterpret_cast<Address>(current); \ |
998 Assembler::deserialization_set_special_target_at( \ | 1001 Assembler::deserialization_set_special_target_at( \ |
999 location_of_branch_data, \ | 1002 location_of_branch_data, \ |
1000 Code::cast(HeapObject::FromAddress(current_object_address)), \ | 1003 Code::cast(HeapObject::FromAddress(current_object_address)), \ |
1001 reinterpret_cast<Address>(new_object)); \ | 1004 reinterpret_cast<Address>(new_object)); \ |
1002 location_of_branch_data += Assembler::kSpecialTargetSize; \ | 1005 location_of_branch_data += Assembler::kSpecialTargetSize; \ |
1003 current = reinterpret_cast<Object**>(location_of_branch_data); \ | 1006 current = reinterpret_cast<Object**>(location_of_branch_data); \ |
1004 current_was_incremented = true; \ | 1007 current_was_incremented = true; \ |
1005 } else { \ | 1008 } else { \ |
1006 *current = new_object; \ | 1009 UnalignedCopy(current, &new_object); \ |
1007 } \ | 1010 } \ |
1008 } \ | 1011 } \ |
1009 if (emit_write_barrier && write_barrier_needed) { \ | 1012 if (emit_write_barrier && write_barrier_needed) { \ |
1010 Address current_address = reinterpret_cast<Address>(current); \ | 1013 Address current_address = reinterpret_cast<Address>(current); \ |
1011 isolate->heap()->RecordWrite( \ | 1014 isolate->heap()->RecordWrite( \ |
1012 current_object_address, \ | 1015 current_object_address, \ |
1013 static_cast<int>(current_address - current_object_address)); \ | 1016 static_cast<int>(current_address - current_object_address)); \ |
1014 } \ | 1017 } \ |
1015 if (!current_was_incremented) { \ | 1018 if (!current_was_incremented) { \ |
1016 current++; \ | 1019 current++; \ |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1097 byte* raw_data_out = reinterpret_cast<byte*>(current); | 1100 byte* raw_data_out = reinterpret_cast<byte*>(current); |
1098 source_.CopyRaw(raw_data_out, size); | 1101 source_.CopyRaw(raw_data_out, size); |
1099 break; | 1102 break; |
1100 } | 1103 } |
1101 | 1104 |
1102 SIXTEEN_CASES(kRootArrayConstants + kNoSkipDistance) | 1105 SIXTEEN_CASES(kRootArrayConstants + kNoSkipDistance) |
1103 SIXTEEN_CASES(kRootArrayConstants + kNoSkipDistance + 16) { | 1106 SIXTEEN_CASES(kRootArrayConstants + kNoSkipDistance + 16) { |
1104 int root_id = RootArrayConstantFromByteCode(data); | 1107 int root_id = RootArrayConstantFromByteCode(data); |
1105 Object* object = isolate->heap()->roots_array_start()[root_id]; | 1108 Object* object = isolate->heap()->roots_array_start()[root_id]; |
1106 DCHECK(!isolate->heap()->InNewSpace(object)); | 1109 DCHECK(!isolate->heap()->InNewSpace(object)); |
1107 *current++ = object; | 1110 UnalignedCopy(current++, &object); |
1108 break; | 1111 break; |
1109 } | 1112 } |
1110 | 1113 |
1111 SIXTEEN_CASES(kRootArrayConstants + kHasSkipDistance) | 1114 SIXTEEN_CASES(kRootArrayConstants + kHasSkipDistance) |
1112 SIXTEEN_CASES(kRootArrayConstants + kHasSkipDistance + 16) { | 1115 SIXTEEN_CASES(kRootArrayConstants + kHasSkipDistance + 16) { |
1113 int root_id = RootArrayConstantFromByteCode(data); | 1116 int root_id = RootArrayConstantFromByteCode(data); |
1114 int skip = source_.GetInt(); | 1117 int skip = source_.GetInt(); |
1115 current = reinterpret_cast<Object**>( | 1118 current = reinterpret_cast<Object**>( |
1116 reinterpret_cast<intptr_t>(current) + skip); | 1119 reinterpret_cast<intptr_t>(current) + skip); |
1117 Object* object = isolate->heap()->roots_array_start()[root_id]; | 1120 Object* object = isolate->heap()->roots_array_start()[root_id]; |
1118 DCHECK(!isolate->heap()->InNewSpace(object)); | 1121 DCHECK(!isolate->heap()->InNewSpace(object)); |
1119 *current++ = object; | 1122 UnalignedCopy(current++, &object); |
1120 break; | 1123 break; |
1121 } | 1124 } |
1122 | 1125 |
1123 case kVariableRepeat: { | 1126 case kVariableRepeat: { |
1124 int repeats = source_.GetInt(); | 1127 int repeats = source_.GetInt(); |
1125 Object* object = current[-1]; | 1128 Object* object = current[-1]; |
1126 DCHECK(!isolate->heap()->InNewSpace(object)); | 1129 DCHECK(!isolate->heap()->InNewSpace(object)); |
1127 for (int i = 0; i < repeats; i++) current[i] = object; | 1130 for (int i = 0; i < repeats; i++) UnalignedCopy(current++, &object); |
1128 current += repeats; | |
1129 break; | 1131 break; |
1130 } | 1132 } |
1131 | 1133 |
1132 STATIC_ASSERT(kRootArrayNumberOfConstantEncodings == | 1134 STATIC_ASSERT(kRootArrayNumberOfConstantEncodings == |
1133 Heap::kOldSpaceRoots); | 1135 Heap::kOldSpaceRoots); |
1134 STATIC_ASSERT(kMaxFixedRepeats == 15); | 1136 STATIC_ASSERT(kMaxFixedRepeats == 15); |
1135 FOUR_CASES(kFixedRepeat) | 1137 FOUR_CASES(kFixedRepeat) |
1136 FOUR_CASES(kFixedRepeat + 4) | 1138 FOUR_CASES(kFixedRepeat + 4) |
1137 FOUR_CASES(kFixedRepeat + 8) | 1139 FOUR_CASES(kFixedRepeat + 8) |
1138 case kFixedRepeat + 12: | 1140 case kFixedRepeat + 12: |
1139 case kFixedRepeat + 13: | 1141 case kFixedRepeat + 13: |
1140 case kFixedRepeat + 14: { | 1142 case kFixedRepeat + 14: { |
1141 int repeats = RepeatsForCode(data); | 1143 int repeats = RepeatsForCode(data); |
1142 Object* object = current[-1]; | 1144 Object* object; |
| 1145 UnalignedCopy(&object, current - 1); |
1143 DCHECK(!isolate->heap()->InNewSpace(object)); | 1146 DCHECK(!isolate->heap()->InNewSpace(object)); |
1144 for (int i = 0; i < repeats; i++) current[i] = object; | 1147 for (int i = 0; i < repeats; i++) UnalignedCopy(current++, &object); |
1145 current += repeats; | |
1146 break; | 1148 break; |
1147 } | 1149 } |
1148 | 1150 |
1149 // Deserialize a new object and write a pointer to it to the current | 1151 // Deserialize a new object and write a pointer to it to the current |
1150 // object. | 1152 // object. |
1151 ALL_SPACES(kNewObject, kPlain, kStartOfObject) | 1153 ALL_SPACES(kNewObject, kPlain, kStartOfObject) |
1152 // Support for direct instruction pointers in functions. It's an inner | 1154 // Support for direct instruction pointers in functions. It's an inner |
1153 // pointer because it points at the entry point, not at the start of the | 1155 // pointer because it points at the entry point, not at the start of the |
1154 // code object. | 1156 // code object. |
1155 CASE_STATEMENT(kNewObject, kPlain, kInnerPointer, CODE_SPACE) | 1157 CASE_STATEMENT(kNewObject, kPlain, kInnerPointer, CODE_SPACE) |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1247 break; | 1249 break; |
1248 } | 1250 } |
1249 | 1251 |
1250 case kNativesStringResource: { | 1252 case kNativesStringResource: { |
1251 int index = source_.Get(); | 1253 int index = source_.Get(); |
1252 Vector<const char> source_vector = Natives::GetScriptSource(index); | 1254 Vector<const char> source_vector = Natives::GetScriptSource(index); |
1253 NativesExternalStringResource* resource = | 1255 NativesExternalStringResource* resource = |
1254 new NativesExternalStringResource(isolate->bootstrapper(), | 1256 new NativesExternalStringResource(isolate->bootstrapper(), |
1255 source_vector.start(), | 1257 source_vector.start(), |
1256 source_vector.length()); | 1258 source_vector.length()); |
1257 *current++ = reinterpret_cast<Object*>(resource); | 1259 Object* resource_obj = reinterpret_cast<Object*>(resource); |
| 1260 UnalignedCopy(current++, &resource_obj); |
1258 break; | 1261 break; |
1259 } | 1262 } |
1260 | 1263 |
1261 case kNextChunk: { | 1264 case kNextChunk: { |
1262 int space = source_.Get(); | 1265 int space = source_.Get(); |
1263 DCHECK(space < kNumberOfPreallocatedSpaces); | 1266 DCHECK(space < kNumberOfPreallocatedSpaces); |
1264 int chunk_index = current_chunk_[space]; | 1267 int chunk_index = current_chunk_[space]; |
1265 const Heap::Reservation& reservation = reservations_[space]; | 1268 const Heap::Reservation& reservation = reservations_[space]; |
1266 // Make sure the current chunk is indeed exhausted. | 1269 // Make sure the current chunk is indeed exhausted. |
1267 CHECK_EQ(reservation[chunk_index].end, high_water_[space]); | 1270 CHECK_EQ(reservation[chunk_index].end, high_water_[space]); |
1268 // Move to next reserved chunk. | 1271 // Move to next reserved chunk. |
1269 chunk_index = ++current_chunk_[space]; | 1272 chunk_index = ++current_chunk_[space]; |
1270 DCHECK_LT(chunk_index, reservation.length()); | 1273 DCHECK_LT(chunk_index, reservation.length()); |
1271 high_water_[space] = reservation[chunk_index].start; | 1274 high_water_[space] = reservation[chunk_index].start; |
1272 break; | 1275 break; |
1273 } | 1276 } |
1274 | 1277 |
1275 FOUR_CASES(kHotObjectWithSkip) | 1278 FOUR_CASES(kHotObjectWithSkip) |
1276 FOUR_CASES(kHotObjectWithSkip + 4) { | 1279 FOUR_CASES(kHotObjectWithSkip + 4) { |
1277 int skip = source_.GetInt(); | 1280 int skip = source_.GetInt(); |
1278 current = reinterpret_cast<Object**>( | 1281 current = reinterpret_cast<Object**>( |
1279 reinterpret_cast<Address>(current) + skip); | 1282 reinterpret_cast<Address>(current) + skip); |
1280 // Fall through. | 1283 // Fall through. |
1281 } | 1284 } |
1282 FOUR_CASES(kHotObject) | 1285 FOUR_CASES(kHotObject) |
1283 FOUR_CASES(kHotObject + 4) { | 1286 FOUR_CASES(kHotObject + 4) { |
1284 int index = data & kHotObjectIndexMask; | 1287 int index = data & kHotObjectIndexMask; |
1285 *current = hot_objects_.Get(index); | 1288 Object* hot_object = hot_objects_.Get(index); |
1286 if (write_barrier_needed && isolate->heap()->InNewSpace(*current)) { | 1289 UnalignedCopy(current, &hot_object); |
| 1290 if (write_barrier_needed && isolate->heap()->InNewSpace(hot_object)) { |
1287 Address current_address = reinterpret_cast<Address>(current); | 1291 Address current_address = reinterpret_cast<Address>(current); |
1288 isolate->heap()->RecordWrite( | 1292 isolate->heap()->RecordWrite( |
1289 current_object_address, | 1293 current_object_address, |
1290 static_cast<int>(current_address - current_object_address)); | 1294 static_cast<int>(current_address - current_object_address)); |
1291 } | 1295 } |
1292 current++; | 1296 current++; |
1293 break; | 1297 break; |
1294 } | 1298 } |
1295 | 1299 |
1296 case kSynchronize: { | 1300 case kSynchronize: { |
(...skipping 1180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2477 return GetHeaderValue(kNumInternalizedStringsOffset); | 2481 return GetHeaderValue(kNumInternalizedStringsOffset); |
2478 } | 2482 } |
2479 | 2483 |
2480 Vector<const uint32_t> SerializedCodeData::CodeStubKeys() const { | 2484 Vector<const uint32_t> SerializedCodeData::CodeStubKeys() const { |
2481 int reservations_size = GetHeaderValue(kReservationsOffset) * kInt32Size; | 2485 int reservations_size = GetHeaderValue(kReservationsOffset) * kInt32Size; |
2482 const byte* start = data_ + kHeaderSize + reservations_size; | 2486 const byte* start = data_ + kHeaderSize + reservations_size; |
2483 return Vector<const uint32_t>(reinterpret_cast<const uint32_t*>(start), | 2487 return Vector<const uint32_t>(reinterpret_cast<const uint32_t*>(start), |
2484 GetHeaderValue(kNumCodeStubKeysOffset)); | 2488 GetHeaderValue(kNumCodeStubKeysOffset)); |
2485 } | 2489 } |
2486 } } // namespace v8::internal | 2490 } } // namespace v8::internal |
OLD | NEW |