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 |