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