| 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 "v8.h" | 5 #include "v8.h" |
| 6 | 6 |
| 7 #include "accessors.h" | 7 #include "accessors.h" |
| 8 #include "api.h" | 8 #include "api.h" |
| 9 #include "bootstrapper.h" | 9 #include "bootstrapper.h" |
| 10 #include "deoptimizer.h" | 10 #include "deoptimizer.h" |
| (...skipping 595 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 606 } | 606 } |
| 607 | 607 |
| 608 | 608 |
| 609 ExternalReferenceDecoder::~ExternalReferenceDecoder() { | 609 ExternalReferenceDecoder::~ExternalReferenceDecoder() { |
| 610 for (int type = kFirstTypeCode; type < kTypeCodeCount; ++type) { | 610 for (int type = kFirstTypeCode; type < kTypeCodeCount; ++type) { |
| 611 DeleteArray(encodings_[type]); | 611 DeleteArray(encodings_[type]); |
| 612 } | 612 } |
| 613 DeleteArray(encodings_); | 613 DeleteArray(encodings_); |
| 614 } | 614 } |
| 615 | 615 |
| 616 AtomicWord Serializer::serialization_state_ = SERIALIZER_STATE_UNINITIALIZED; | |
| 617 | 616 |
| 618 class CodeAddressMap: public CodeEventLogger { | 617 class CodeAddressMap: public CodeEventLogger { |
| 619 public: | 618 public: |
| 620 explicit CodeAddressMap(Isolate* isolate) | 619 explicit CodeAddressMap(Isolate* isolate) |
| 621 : isolate_(isolate) { | 620 : isolate_(isolate) { |
| 622 isolate->logger()->addCodeEventListener(this); | 621 isolate->logger()->addCodeEventListener(this); |
| 623 } | 622 } |
| 624 | 623 |
| 625 virtual ~CodeAddressMap() { | 624 virtual ~CodeAddressMap() { |
| 626 isolate_->logger()->removeCodeEventListener(this); | 625 isolate_->logger()->removeCodeEventListener(this); |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 716 const char* name, | 715 const char* name, |
| 717 int length) { | 716 int length) { |
| 718 address_to_name_map_.Insert(code->address(), name, length); | 717 address_to_name_map_.Insert(code->address(), name, length); |
| 719 } | 718 } |
| 720 | 719 |
| 721 NameMap address_to_name_map_; | 720 NameMap address_to_name_map_; |
| 722 Isolate* isolate_; | 721 Isolate* isolate_; |
| 723 }; | 722 }; |
| 724 | 723 |
| 725 | 724 |
| 726 CodeAddressMap* Serializer::code_address_map_ = NULL; | |
| 727 | |
| 728 | |
| 729 void Serializer::RequestEnable(Isolate* isolate) { | |
| 730 isolate->InitializeLoggingAndCounters(); | |
| 731 code_address_map_ = new CodeAddressMap(isolate); | |
| 732 } | |
| 733 | |
| 734 | |
| 735 void Serializer::InitializeOncePerProcess() { | |
| 736 // InitializeOncePerProcess is called by V8::InitializeOncePerProcess, a | |
| 737 // method guaranteed to be called only once in a process lifetime. | |
| 738 // serialization_state_ is read by many threads, hence the use of | |
| 739 // Atomic primitives. Here, we don't need a barrier or mutex to | |
| 740 // write it because V8 initialization is done by one thread, and gates | |
| 741 // all reads of serialization_state_. | |
| 742 ASSERT(NoBarrier_Load(&serialization_state_) == | |
| 743 SERIALIZER_STATE_UNINITIALIZED); | |
| 744 SerializationState state = code_address_map_ | |
| 745 ? SERIALIZER_STATE_ENABLED | |
| 746 : SERIALIZER_STATE_DISABLED; | |
| 747 NoBarrier_Store(&serialization_state_, state); | |
| 748 } | |
| 749 | |
| 750 | |
| 751 void Serializer::TearDown() { | |
| 752 // TearDown is called by V8::TearDown() for the default isolate. It's safe | |
| 753 // to shut down the serializer by that point. Just to be safe, we restore | |
| 754 // serialization_state_ to uninitialized. | |
| 755 ASSERT(NoBarrier_Load(&serialization_state_) != | |
| 756 SERIALIZER_STATE_UNINITIALIZED); | |
| 757 if (code_address_map_) { | |
| 758 ASSERT(NoBarrier_Load(&serialization_state_) == | |
| 759 SERIALIZER_STATE_ENABLED); | |
| 760 delete code_address_map_; | |
| 761 code_address_map_ = NULL; | |
| 762 } | |
| 763 | |
| 764 NoBarrier_Store(&serialization_state_, SERIALIZER_STATE_UNINITIALIZED); | |
| 765 } | |
| 766 | |
| 767 | |
| 768 Deserializer::Deserializer(SnapshotByteSource* source) | 725 Deserializer::Deserializer(SnapshotByteSource* source) |
| 769 : isolate_(NULL), | 726 : isolate_(NULL), |
| 770 source_(source), | 727 source_(source), |
| 771 external_reference_decoder_(NULL) { | 728 external_reference_decoder_(NULL) { |
| 772 for (int i = 0; i < LAST_SPACE + 1; i++) { | 729 for (int i = 0; i < LAST_SPACE + 1; i++) { |
| 773 reservations_[i] = kUninitializedReservation; | 730 reservations_[i] = kUninitializedReservation; |
| 774 } | 731 } |
| 775 } | 732 } |
| 776 | 733 |
| 777 | 734 |
| (...skipping 477 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1255 Put(static_cast<int>(integer & 0xff), "IntPart1"); | 1212 Put(static_cast<int>(integer & 0xff), "IntPart1"); |
| 1256 if (bytes > 1) Put(static_cast<int>((integer >> 8) & 0xff), "IntPart2"); | 1213 if (bytes > 1) Put(static_cast<int>((integer >> 8) & 0xff), "IntPart2"); |
| 1257 if (bytes > 2) Put(static_cast<int>((integer >> 16) & 0xff), "IntPart3"); | 1214 if (bytes > 2) Put(static_cast<int>((integer >> 16) & 0xff), "IntPart3"); |
| 1258 } | 1215 } |
| 1259 | 1216 |
| 1260 | 1217 |
| 1261 Serializer::Serializer(Isolate* isolate, SnapshotByteSink* sink) | 1218 Serializer::Serializer(Isolate* isolate, SnapshotByteSink* sink) |
| 1262 : isolate_(isolate), | 1219 : isolate_(isolate), |
| 1263 sink_(sink), | 1220 sink_(sink), |
| 1264 external_reference_encoder_(new ExternalReferenceEncoder(isolate)), | 1221 external_reference_encoder_(new ExternalReferenceEncoder(isolate)), |
| 1265 root_index_wave_front_(0) { | 1222 root_index_wave_front_(0), |
| 1223 code_address_map_(NULL) { |
| 1266 // The serializer is meant to be used only to generate initial heap images | 1224 // The serializer is meant to be used only to generate initial heap images |
| 1267 // from a context in which there is only one isolate. | 1225 // from a context in which there is only one isolate. |
| 1268 for (int i = 0; i <= LAST_SPACE; i++) { | 1226 for (int i = 0; i <= LAST_SPACE; i++) { |
| 1269 fullness_[i] = 0; | 1227 fullness_[i] = 0; |
| 1270 } | 1228 } |
| 1271 } | 1229 } |
| 1272 | 1230 |
| 1273 | 1231 |
| 1274 Serializer::~Serializer() { | 1232 Serializer::~Serializer() { |
| 1275 delete external_reference_encoder_; | 1233 delete external_reference_encoder_; |
| 1234 if (code_address_map_ != NULL) delete code_address_map_; |
| 1276 } | 1235 } |
| 1277 | 1236 |
| 1278 | 1237 |
| 1279 void StartupSerializer::SerializeStrongReferences() { | 1238 void StartupSerializer::SerializeStrongReferences() { |
| 1280 Isolate* isolate = this->isolate(); | 1239 Isolate* isolate = this->isolate(); |
| 1281 // No active threads. | 1240 // No active threads. |
| 1282 CHECK_EQ(NULL, isolate->thread_manager()->FirstThreadStateInUse()); | 1241 CHECK_EQ(NULL, isolate->thread_manager()->FirstThreadStateInUse()); |
| 1283 // No active or weak handles. | 1242 // No active or weak handles. |
| 1284 CHECK(isolate->handle_scope_implementer()->blocks()->is_empty()); | 1243 CHECK(isolate->handle_scope_implementer()->blocks()->is_empty()); |
| 1285 CHECK_EQ(0, isolate->global_handles()->NumberOfWeakHandles()); | 1244 CHECK_EQ(0, isolate->global_handles()->NumberOfWeakHandles()); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1331 // This ensures that the partial snapshot cache keeps things alive during GC and | 1290 // This ensures that the partial snapshot cache keeps things alive during GC and |
| 1332 // tracks their movement. When it is called during serialization of the startup | 1291 // tracks their movement. When it is called during serialization of the startup |
| 1333 // snapshot nothing happens. When the partial (context) snapshot is created, | 1292 // snapshot nothing happens. When the partial (context) snapshot is created, |
| 1334 // this array is populated with the pointers that the partial snapshot will | 1293 // this array is populated with the pointers that the partial snapshot will |
| 1335 // need. As that happens we emit serialized objects to the startup snapshot | 1294 // need. As that happens we emit serialized objects to the startup snapshot |
| 1336 // that correspond to the elements of this cache array. On deserialization we | 1295 // that correspond to the elements of this cache array. On deserialization we |
| 1337 // therefore need to visit the cache array. This fills it up with pointers to | 1296 // therefore need to visit the cache array. This fills it up with pointers to |
| 1338 // deserialized objects. | 1297 // deserialized objects. |
| 1339 void SerializerDeserializer::Iterate(Isolate* isolate, | 1298 void SerializerDeserializer::Iterate(Isolate* isolate, |
| 1340 ObjectVisitor* visitor) { | 1299 ObjectVisitor* visitor) { |
| 1341 if (Serializer::enabled(isolate)) return; | 1300 if (isolate->serializer_enabled()) return; |
| 1342 for (int i = 0; ; i++) { | 1301 for (int i = 0; ; i++) { |
| 1343 if (isolate->serialize_partial_snapshot_cache_length() <= i) { | 1302 if (isolate->serialize_partial_snapshot_cache_length() <= i) { |
| 1344 // Extend the array ready to get a value from the visitor when | 1303 // Extend the array ready to get a value from the visitor when |
| 1345 // deserializing. | 1304 // deserializing. |
| 1346 isolate->PushToPartialSnapshotCache(Smi::FromInt(0)); | 1305 isolate->PushToPartialSnapshotCache(Smi::FromInt(0)); |
| 1347 } | 1306 } |
| 1348 Object** cache = isolate->serialize_partial_snapshot_cache(); | 1307 Object** cache = isolate->serialize_partial_snapshot_cache(); |
| 1349 visitor->VisitPointers(&cache[i], &cache[i + 1]); | 1308 visitor->VisitPointers(&cache[i], &cache[i + 1]); |
| 1350 // Sentinel is the undefined object, which is a root so it will not normally | 1309 // Sentinel is the undefined object, which is a root so it will not normally |
| 1351 // be found in the cache. | 1310 // be found in the cache. |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1571 | 1530 |
| 1572 | 1531 |
| 1573 void Serializer::ObjectSerializer::Serialize() { | 1532 void Serializer::ObjectSerializer::Serialize() { |
| 1574 int space = Serializer::SpaceOfObject(object_); | 1533 int space = Serializer::SpaceOfObject(object_); |
| 1575 int size = object_->Size(); | 1534 int size = object_->Size(); |
| 1576 | 1535 |
| 1577 sink_->Put(kNewObject + reference_representation_ + space, | 1536 sink_->Put(kNewObject + reference_representation_ + space, |
| 1578 "ObjectSerialization"); | 1537 "ObjectSerialization"); |
| 1579 sink_->PutInt(size >> kObjectAlignmentBits, "Size in words"); | 1538 sink_->PutInt(size >> kObjectAlignmentBits, "Size in words"); |
| 1580 | 1539 |
| 1581 ASSERT(code_address_map_); | 1540 if (serializer_->code_address_map_) { |
| 1582 const char* code_name = code_address_map_->Lookup(object_->address()); | 1541 const char* code_name = |
| 1583 LOG(serializer_->isolate_, | 1542 serializer_->code_address_map_->Lookup(object_->address()); |
| 1584 CodeNameEvent(object_->address(), sink_->Position(), code_name)); | 1543 LOG(serializer_->isolate_, |
| 1585 LOG(serializer_->isolate_, | 1544 CodeNameEvent(object_->address(), sink_->Position(), code_name)); |
| 1586 SnapshotPositionEvent(object_->address(), sink_->Position())); | 1545 LOG(serializer_->isolate_, |
| 1546 SnapshotPositionEvent(object_->address(), sink_->Position())); |
| 1547 } |
| 1587 | 1548 |
| 1588 // Mark this object as already serialized. | 1549 // Mark this object as already serialized. |
| 1589 int offset = serializer_->Allocate(space, size); | 1550 int offset = serializer_->Allocate(space, size); |
| 1590 serializer_->address_mapper()->AddMapping(object_, offset); | 1551 serializer_->address_mapper()->AddMapping(object_, offset); |
| 1591 | 1552 |
| 1592 // Serialize the map (first word of the object). | 1553 // Serialize the map (first word of the object). |
| 1593 serializer_->SerializeObject(object_->map(), kPlain, kStartOfObject, 0); | 1554 serializer_->SerializeObject(object_->map(), kPlain, kStartOfObject, 0); |
| 1594 | 1555 |
| 1595 // Serialize the rest of the object. | 1556 // Serialize the rest of the object. |
| 1596 CHECK_EQ(0, bytes_processed_so_far_); | 1557 CHECK_EQ(0, bytes_processed_so_far_); |
| (...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1856 | 1817 |
| 1857 void Serializer::Pad() { | 1818 void Serializer::Pad() { |
| 1858 // The non-branching GetInt will read up to 3 bytes too far, so we need | 1819 // The non-branching GetInt will read up to 3 bytes too far, so we need |
| 1859 // to pad the snapshot to make sure we don't read over the end. | 1820 // to pad the snapshot to make sure we don't read over the end. |
| 1860 for (unsigned i = 0; i < sizeof(int32_t) - 1; i++) { | 1821 for (unsigned i = 0; i < sizeof(int32_t) - 1; i++) { |
| 1861 sink_->Put(kNop, "Padding"); | 1822 sink_->Put(kNop, "Padding"); |
| 1862 } | 1823 } |
| 1863 } | 1824 } |
| 1864 | 1825 |
| 1865 | 1826 |
| 1827 void Serializer::InitializeCodeAddressMap() { |
| 1828 isolate_->InitializeLoggingAndCounters(); |
| 1829 code_address_map_ = new CodeAddressMap(isolate_); |
| 1830 } |
| 1831 |
| 1832 |
| 1866 bool SnapshotByteSource::AtEOF() { | 1833 bool SnapshotByteSource::AtEOF() { |
| 1867 if (0u + length_ - position_ > 2 * sizeof(uint32_t)) return false; | 1834 if (0u + length_ - position_ > 2 * sizeof(uint32_t)) return false; |
| 1868 for (int x = position_; x < length_; x++) { | 1835 for (int x = position_; x < length_; x++) { |
| 1869 if (data_[x] != SerializerDeserializer::nop()) return false; | 1836 if (data_[x] != SerializerDeserializer::nop()) return false; |
| 1870 } | 1837 } |
| 1871 return true; | 1838 return true; |
| 1872 } | 1839 } |
| 1873 | 1840 |
| 1874 } } // namespace v8::internal | 1841 } } // namespace v8::internal |
| OLD | NEW |