OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 904 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
915 } | 915 } |
916 | 916 |
917 | 917 |
918 class ReferenceUpdater: public ObjectVisitor { | 918 class ReferenceUpdater: public ObjectVisitor { |
919 public: | 919 public: |
920 ReferenceUpdater(HeapObject* obj, Serializer* serializer) | 920 ReferenceUpdater(HeapObject* obj, Serializer* serializer) |
921 : obj_address_(obj->address()), | 921 : obj_address_(obj->address()), |
922 serializer_(serializer), | 922 serializer_(serializer), |
923 reference_encoder_(serializer->reference_encoder_), | 923 reference_encoder_(serializer->reference_encoder_), |
924 offsets_(8), | 924 offsets_(8), |
925 addresses_(8) { | 925 addresses_(8), |
| 926 offsets_32_bit_(0), |
| 927 data_32_bit_(0) { |
926 } | 928 } |
927 | 929 |
928 virtual void VisitPointers(Object** start, Object** end) { | 930 virtual void VisitPointers(Object** start, Object** end) { |
929 for (Object** p = start; p < end; ++p) { | 931 for (Object** p = start; p < end; ++p) { |
930 if ((*p)->IsHeapObject()) { | 932 if ((*p)->IsHeapObject()) { |
931 offsets_.Add(reinterpret_cast<Address>(p) - obj_address_); | 933 offsets_.Add(reinterpret_cast<Address>(p) - obj_address_); |
932 Address a = serializer_->GetSavedAddress(HeapObject::cast(*p)); | 934 Address a = serializer_->GetSavedAddress(HeapObject::cast(*p)); |
933 addresses_.Add(a); | 935 addresses_.Add(a); |
934 } | 936 } |
935 } | 937 } |
936 } | 938 } |
937 | 939 |
938 virtual void VisitCodeTarget(RelocInfo* rinfo) { | 940 virtual void VisitCodeTarget(RelocInfo* rinfo) { |
939 ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode())); | 941 ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode())); |
940 Code* target = Code::GetCodeFromTargetAddress(rinfo->target_address()); | 942 Code* target = Code::GetCodeFromTargetAddress(rinfo->target_address()); |
941 Address encoded_target = serializer_->GetSavedAddress(target); | 943 Address encoded_target = serializer_->GetSavedAddress(target); |
942 offsets_.Add(rinfo->target_address_address() - obj_address_); | 944 // All calls and jumps are to code objects that encode into 32 bits. |
943 addresses_.Add(encoded_target); | 945 offsets_32_bit_.Add(rinfo->target_address_address() - obj_address_); |
944 } | 946 uint32_t small_target = |
| 947 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(encoded_target)); |
| 948 ASSERT(reinterpret_cast<uintptr_t>(encoded_target) == small_target); |
| 949 data_32_bit_.Add(small_target); |
| 950 } |
945 | 951 |
946 | 952 |
947 virtual void VisitExternalReferences(Address* start, Address* end) { | 953 virtual void VisitExternalReferences(Address* start, Address* end) { |
948 for (Address* p = start; p < end; ++p) { | 954 for (Address* p = start; p < end; ++p) { |
949 uint32_t code = reference_encoder_->Encode(*p); | 955 uint32_t code = reference_encoder_->Encode(*p); |
950 CHECK(*p == NULL ? code == 0 : code != 0); | 956 CHECK(*p == NULL ? code == 0 : code != 0); |
951 offsets_.Add(reinterpret_cast<Address>(p) - obj_address_); | 957 offsets_.Add(reinterpret_cast<Address>(p) - obj_address_); |
952 addresses_.Add(reinterpret_cast<Address>(code)); | 958 addresses_.Add(reinterpret_cast<Address>(code)); |
953 } | 959 } |
954 } | 960 } |
955 | 961 |
956 virtual void VisitRuntimeEntry(RelocInfo* rinfo) { | 962 virtual void VisitRuntimeEntry(RelocInfo* rinfo) { |
957 Address target = rinfo->target_address(); | 963 Address target = rinfo->target_address(); |
958 uint32_t encoding = reference_encoder_->Encode(target); | 964 uint32_t encoding = reference_encoder_->Encode(target); |
959 CHECK(target == NULL ? encoding == 0 : encoding != 0); | 965 CHECK(target == NULL ? encoding == 0 : encoding != 0); |
960 offsets_.Add(rinfo->target_address_address() - obj_address_); | 966 offsets_.Add(rinfo->target_address_address() - obj_address_); |
961 addresses_.Add(reinterpret_cast<Address>(encoding)); | 967 addresses_.Add(reinterpret_cast<Address>(encoding)); |
962 } | 968 } |
963 | 969 |
964 void Update(Address start_address) { | 970 void Update(Address start_address) { |
965 for (int i = 0; i < offsets_.length(); i++) { | 971 for (int i = 0; i < offsets_.length(); i++) { |
966 memcpy(start_address + offsets_[i], &addresses_[i], sizeof(Address)); | 972 memcpy(start_address + offsets_[i], &addresses_[i], sizeof(Address)); |
967 } | 973 } |
| 974 for (int i = 0; i < offsets_32_bit_.length(); i++) { |
| 975 memcpy(start_address + offsets_32_bit_[i], &data_32_bit_[i], |
| 976 sizeof(uint32_t)); |
| 977 } |
968 } | 978 } |
969 | 979 |
970 private: | 980 private: |
971 Address obj_address_; | 981 Address obj_address_; |
972 Serializer* serializer_; | 982 Serializer* serializer_; |
973 ExternalReferenceEncoder* reference_encoder_; | 983 ExternalReferenceEncoder* reference_encoder_; |
974 List<int> offsets_; | 984 List<int> offsets_; |
975 List<Address> addresses_; | 985 List<Address> addresses_; |
| 986 // Some updates are 32-bit even on a 64-bit platform. |
| 987 // We keep a separate list of them on 64-bit platforms. |
| 988 List<int> offsets_32_bit_; |
| 989 List<uint32_t> data_32_bit_; |
976 }; | 990 }; |
977 | 991 |
978 | 992 |
979 // Helper functions for a map of encoded heap object addresses. | 993 // Helper functions for a map of encoded heap object addresses. |
980 static uint32_t HeapObjectHash(HeapObject* key) { | 994 static uint32_t HeapObjectHash(HeapObject* key) { |
981 uint32_t low32bits = static_cast<uint32_t>(reinterpret_cast<uintptr_t>(key)); | 995 uint32_t low32bits = static_cast<uint32_t>(reinterpret_cast<uintptr_t>(key)); |
982 return low32bits >> 2; | 996 return low32bits >> 2; |
983 } | 997 } |
984 | 998 |
985 | 999 |
(...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1425 // read: resolve it to a true address (or Smi) | 1439 // read: resolve it to a true address (or Smi) |
1426 *p = Resolve(reinterpret_cast<Address>(*p)); | 1440 *p = Resolve(reinterpret_cast<Address>(*p)); |
1427 } | 1441 } |
1428 } | 1442 } |
1429 root_ = root; | 1443 root_ = root; |
1430 } | 1444 } |
1431 | 1445 |
1432 | 1446 |
1433 void Deserializer::VisitCodeTarget(RelocInfo* rinfo) { | 1447 void Deserializer::VisitCodeTarget(RelocInfo* rinfo) { |
1434 ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode())); | 1448 ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode())); |
1435 Address encoded_address = reinterpret_cast<Address>(rinfo->target_object()); | 1449 // On all platforms, the encoded code object address is only 32 bits. |
| 1450 Address encoded_address = reinterpret_cast<Address>(Memory::uint32_at( |
| 1451 reinterpret_cast<Address>(rinfo->target_object_address()))); |
1436 Code* target_object = reinterpret_cast<Code*>(Resolve(encoded_address)); | 1452 Code* target_object = reinterpret_cast<Code*>(Resolve(encoded_address)); |
1437 rinfo->set_target_address(target_object->instruction_start()); | 1453 rinfo->set_target_address(target_object->instruction_start()); |
1438 } | 1454 } |
1439 | 1455 |
1440 | 1456 |
1441 void Deserializer::VisitExternalReferences(Address* start, Address* end) { | 1457 void Deserializer::VisitExternalReferences(Address* start, Address* end) { |
1442 for (Address* p = start; p < end; ++p) { | 1458 for (Address* p = start; p < end; ++p) { |
1443 uint32_t code = static_cast<uint32_t>(reinterpret_cast<uintptr_t>(*p)); | 1459 uint32_t code = static_cast<uint32_t>(reinterpret_cast<uintptr_t>(*p)); |
1444 *p = reference_decoder_->Decode(code); | 1460 *p = reference_decoder_->Decode(code); |
1445 } | 1461 } |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1656 } | 1672 } |
1657 } | 1673 } |
1658 | 1674 |
1659 | 1675 |
1660 Object* Deserializer::Resolve(Address encoded) { | 1676 Object* Deserializer::Resolve(Address encoded) { |
1661 Object* o = reinterpret_cast<Object*>(encoded); | 1677 Object* o = reinterpret_cast<Object*>(encoded); |
1662 if (o->IsSmi()) return o; | 1678 if (o->IsSmi()) return o; |
1663 | 1679 |
1664 // Encoded addresses of HeapObjects always have 'HeapObject' tags. | 1680 // Encoded addresses of HeapObjects always have 'HeapObject' tags. |
1665 ASSERT(o->IsHeapObject()); | 1681 ASSERT(o->IsHeapObject()); |
1666 | |
1667 switch (GetSpace(encoded)) { | 1682 switch (GetSpace(encoded)) { |
1668 // For Map space and Old space, we cache the known Pages in map_pages, | 1683 // For Map space and Old space, we cache the known Pages in map_pages, |
1669 // old_pointer_pages and old_data_pages. Even though MapSpace keeps a list | 1684 // old_pointer_pages and old_data_pages. Even though MapSpace keeps a list |
1670 // of page addresses, we don't rely on it since GetObject uses AllocateRaw, | 1685 // of page addresses, we don't rely on it since GetObject uses AllocateRaw, |
1671 // and that appears not to update the page list. | 1686 // and that appears not to update the page list. |
1672 case MAP_SPACE: | 1687 case MAP_SPACE: |
1673 return ResolvePaged(PageIndex(encoded), PageOffset(encoded), | 1688 return ResolvePaged(PageIndex(encoded), PageOffset(encoded), |
1674 Heap::map_space(), &map_pages_); | 1689 Heap::map_space(), &map_pages_); |
1675 case CELL_SPACE: | 1690 case CELL_SPACE: |
1676 return ResolvePaged(PageIndex(encoded), PageOffset(encoded), | 1691 return ResolvePaged(PageIndex(encoded), PageOffset(encoded), |
(...skipping 30 matching lines...) Expand all Loading... |
1707 ASSERT(index < large_objects_.length()); | 1722 ASSERT(index < large_objects_.length()); |
1708 } | 1723 } |
1709 return large_objects_[index]; // s.page_offset() is ignored. | 1724 return large_objects_[index]; // s.page_offset() is ignored. |
1710 } | 1725 } |
1711 UNREACHABLE(); | 1726 UNREACHABLE(); |
1712 return NULL; | 1727 return NULL; |
1713 } | 1728 } |
1714 | 1729 |
1715 | 1730 |
1716 } } // namespace v8::internal | 1731 } } // namespace v8::internal |
OLD | NEW |