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 816 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
827 deserialized_large_objects_.Add(obj); | 827 deserialized_large_objects_.Add(obj); |
828 return obj->address(); | 828 return obj->address(); |
829 } else { | 829 } else { |
830 DCHECK(space_index < kNumberOfPreallocatedSpaces); | 830 DCHECK(space_index < kNumberOfPreallocatedSpaces); |
831 Address address = high_water_[space_index]; | 831 Address address = high_water_[space_index]; |
832 high_water_[space_index] = address + size; | 832 high_water_[space_index] = address + size; |
833 return address; | 833 return address; |
834 } | 834 } |
835 } | 835 } |
836 | 836 |
| 837 |
837 void Deserializer::ReadChunk(Object** current, | 838 void Deserializer::ReadChunk(Object** current, |
838 Object** limit, | 839 Object** limit, |
839 int source_space, | 840 int source_space, |
840 Address current_object_address) { | 841 Address current_object_address) { |
841 Isolate* const isolate = isolate_; | 842 Isolate* const isolate = isolate_; |
842 // Write barrier support costs around 1% in startup time. In fact there | 843 // Write barrier support costs around 1% in startup time. In fact there |
843 // are no new space objects in current boot snapshots, so it's not needed, | 844 // are no new space objects in current boot snapshots, so it's not needed, |
844 // but that may change. | 845 // but that may change. |
845 bool write_barrier_needed = (current_object_address != NULL && | 846 bool write_barrier_needed = (current_object_address != NULL && |
846 source_space != NEW_SPACE && | 847 source_space != NEW_SPACE && |
(...skipping 660 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1507 ObjectSerializer serializer(this, | 1508 ObjectSerializer serializer(this, |
1508 heap_object, | 1509 heap_object, |
1509 sink_, | 1510 sink_, |
1510 how_to_code, | 1511 how_to_code, |
1511 where_to_point); | 1512 where_to_point); |
1512 serializer.Serialize(); | 1513 serializer.Serialize(); |
1513 } | 1514 } |
1514 } | 1515 } |
1515 | 1516 |
1516 | 1517 |
1517 void Serializer::ObjectSerializer::Serialize() { | 1518 void Serializer::ObjectSerializer::SerializePrologue(int space, int size, |
1518 int space = Serializer::SpaceOfObject(object_); | 1519 Map* map) { |
1519 int size = object_->Size(); | |
1520 | |
1521 sink_->Put(kNewObject + reference_representation_ + space, | 1520 sink_->Put(kNewObject + reference_representation_ + space, |
1522 "ObjectSerialization"); | 1521 "ObjectSerialization"); |
1523 sink_->PutInt(size >> kObjectAlignmentBits, "Size in words"); | 1522 sink_->PutInt(size >> kObjectAlignmentBits, "Size in words"); |
1524 | 1523 |
1525 if (serializer_->code_address_map_) { | 1524 if (serializer_->code_address_map_) { |
1526 const char* code_name = | 1525 const char* code_name = |
1527 serializer_->code_address_map_->Lookup(object_->address()); | 1526 serializer_->code_address_map_->Lookup(object_->address()); |
1528 LOG(serializer_->isolate_, | 1527 LOG(serializer_->isolate_, |
1529 CodeNameEvent(object_->address(), sink_->Position(), code_name)); | 1528 CodeNameEvent(object_->address(), sink_->Position(), code_name)); |
1530 LOG(serializer_->isolate_, | 1529 LOG(serializer_->isolate_, |
1531 SnapshotPositionEvent(object_->address(), sink_->Position())); | 1530 SnapshotPositionEvent(object_->address(), sink_->Position())); |
1532 } | 1531 } |
1533 | 1532 |
1534 // Mark this object as already serialized. | 1533 // Mark this object as already serialized. |
1535 if (space == LO_SPACE) { | 1534 if (space == LO_SPACE) { |
1536 if (object_->IsCode()) { | 1535 if (object_->IsCode()) { |
1537 sink_->PutInt(EXECUTABLE, "executable large object"); | 1536 sink_->PutInt(EXECUTABLE, "executable large object"); |
1538 } else { | 1537 } else { |
1539 sink_->PutInt(NOT_EXECUTABLE, "not executable large object"); | 1538 sink_->PutInt(NOT_EXECUTABLE, "not executable large object"); |
1540 } | 1539 } |
1541 int index = serializer_->AllocateLargeObject(size); | 1540 int index = serializer_->AllocateLargeObject(size); |
1542 serializer_->address_mapper()->AddMapping(object_, index); | 1541 serializer_->address_mapper()->AddMapping(object_, index); |
1543 } else { | 1542 } else { |
1544 int offset = serializer_->Allocate(space, size); | 1543 int offset = serializer_->Allocate(space, size); |
1545 serializer_->address_mapper()->AddMapping(object_, offset); | 1544 serializer_->address_mapper()->AddMapping(object_, offset); |
1546 } | 1545 } |
1547 | 1546 |
1548 // Serialize the map (first word of the object). | 1547 // Serialize the map (first word of the object). |
1549 serializer_->SerializeObject(object_->map(), kPlain, kStartOfObject, 0); | 1548 serializer_->SerializeObject(map, kPlain, kStartOfObject, 0); |
1550 | |
1551 // Serialize the rest of the object. | |
1552 CHECK_EQ(0, bytes_processed_so_far_); | |
1553 bytes_processed_so_far_ = kPointerSize; | |
1554 object_->IterateBody(object_->map()->instance_type(), size, this); | |
1555 OutputRawData(object_->address() + size); | |
1556 } | 1549 } |
1557 | 1550 |
1558 | 1551 |
| 1552 void Serializer::ObjectSerializer::SerializeExternalString() { |
| 1553 // Instead of serializing this as an external string, we serialize |
| 1554 // an imaginary sequential string with the same content. |
| 1555 DCHECK(object_->IsExternalString() && object_->IsInternalizedString()); |
| 1556 Isolate* isolate = serializer_->isolate(); |
| 1557 ExternalString* string = ExternalString::cast(object_); |
| 1558 int length = string->length(); |
| 1559 Map* map; |
| 1560 int size; |
| 1561 const char* resource; |
| 1562 // Find the map and size for the imaginary sequential string. |
| 1563 if (object_->IsExternalOneByteString()) { |
| 1564 map = isolate->heap()->one_byte_internalized_string_map(); |
| 1565 size = SeqOneByteString::SizeFor(length); |
| 1566 resource = ExternalOneByteString::cast(string)->resource()->data(); |
| 1567 } else { |
| 1568 map = isolate->heap()->internalized_string_map(); |
| 1569 size = SeqTwoByteString::SizeFor(length); |
| 1570 resource = reinterpret_cast<const char*>( |
| 1571 ExternalTwoByteString::cast(string)->resource()->data()); |
| 1572 } |
| 1573 |
| 1574 int space = |
| 1575 (size > Page::kMaxRegularHeapObjectSize) ? LO_SPACE : OLD_DATA_SPACE; |
| 1576 SerializePrologue(space, size, map); |
| 1577 |
| 1578 // Output the rest of the imaginary string. |
| 1579 int bytes_to_output = size - HeapObject::kHeaderSize; |
| 1580 |
| 1581 // Output raw data header. Do not bother with common raw length cases here. |
| 1582 sink_->Put(kRawData, "RawDataForString"); |
| 1583 sink_->PutInt(bytes_to_output, "length"); |
| 1584 |
| 1585 // Serialize string header (except for map). |
| 1586 Address string_start = string->address(); |
| 1587 for (int i = HeapObject::kHeaderSize; i < SeqString::kHeaderSize; i++) { |
| 1588 sink_->PutSection(string_start[i], "StringHeader"); |
| 1589 } |
| 1590 |
| 1591 // Serialize string content. |
| 1592 int content_length = size - SeqString::kHeaderSize; |
| 1593 for (int i = 0; i < content_length; i++) { |
| 1594 sink_->PutSection(resource[i], "StringContent"); |
| 1595 } |
| 1596 |
| 1597 sink_->Put(kSkip, "SkipAfterString"); |
| 1598 sink_->PutInt(bytes_to_output, "SkipDistance"); |
| 1599 } |
| 1600 |
| 1601 |
| 1602 void Serializer::ObjectSerializer::Serialize() { |
| 1603 if (object_->IsExternalString() && object_->IsInternalizedString()) { |
| 1604 // Native source code strings are not internalized and are handled in |
| 1605 // VisitExternalOneByteString. We deal with embedded external strings |
| 1606 // by serializing them as sequential strings on the heap. |
| 1607 // This can only happen with CodeSerializer. |
| 1608 SerializeExternalString(); |
| 1609 } else { |
| 1610 int size = object_->Size(); |
| 1611 Map* map = object_->map(); |
| 1612 SerializePrologue(Serializer::SpaceOfObject(object_), size, map); |
| 1613 |
| 1614 // Serialize the rest of the object. |
| 1615 CHECK_EQ(0, bytes_processed_so_far_); |
| 1616 bytes_processed_so_far_ = kPointerSize; |
| 1617 |
| 1618 object_->IterateBody(map->instance_type(), size, this); |
| 1619 OutputRawData(object_->address() + size); |
| 1620 } |
| 1621 } |
| 1622 |
| 1623 |
1559 void Serializer::ObjectSerializer::VisitPointers(Object** start, | 1624 void Serializer::ObjectSerializer::VisitPointers(Object** start, |
1560 Object** end) { | 1625 Object** end) { |
1561 Object** current = start; | 1626 Object** current = start; |
1562 while (current < end) { | 1627 while (current < end) { |
1563 while (current < end && (*current)->IsSmi()) current++; | 1628 while (current < end && (*current)->IsSmi()) current++; |
1564 if (current < end) OutputRawData(reinterpret_cast<Address>(current)); | 1629 if (current < end) OutputRawData(reinterpret_cast<Address>(current)); |
1565 | 1630 |
1566 while (current < end && !(*current)->IsSmi()) { | 1631 while (current < end && !(*current)->IsSmi()) { |
1567 HeapObject* current_contents = HeapObject::cast(*current); | 1632 HeapObject* current_contents = HeapObject::cast(*current); |
1568 int root_index = serializer_->RootIndex(current_contents, kPlain); | 1633 int root_index = serializer_->RootIndex(current_contents, kPlain); |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1690 const Resource* resource = string->resource(); | 1755 const Resource* resource = string->resource(); |
1691 if (resource == *resource_pointer) { | 1756 if (resource == *resource_pointer) { |
1692 sink_->Put(kNativesStringResource, "NativesStringResource"); | 1757 sink_->Put(kNativesStringResource, "NativesStringResource"); |
1693 sink_->PutSection(i, "NativesStringResourceEnd"); | 1758 sink_->PutSection(i, "NativesStringResourceEnd"); |
1694 bytes_processed_so_far_ += sizeof(resource); | 1759 bytes_processed_so_far_ += sizeof(resource); |
1695 return; | 1760 return; |
1696 } | 1761 } |
1697 } | 1762 } |
1698 } | 1763 } |
1699 // One of the strings in the natives cache should match the resource. We | 1764 // One of the strings in the natives cache should match the resource. We |
1700 // can't serialize any other kinds of external strings. | 1765 // don't expect any other kinds of external strings here. |
1701 UNREACHABLE(); | 1766 UNREACHABLE(); |
1702 } | 1767 } |
1703 | 1768 |
1704 | 1769 |
1705 static Code* CloneCodeObject(HeapObject* code) { | 1770 static Code* CloneCodeObject(HeapObject* code) { |
1706 Address copy = new byte[code->Size()]; | 1771 Address copy = new byte[code->Size()]; |
1707 MemCopy(copy, code->address(), code->Size()); | 1772 MemCopy(copy, code->address(), code->Size()); |
1708 return Code::cast(HeapObject::FromAddress(copy)); | 1773 return Code::cast(HeapObject::FromAddress(copy)); |
1709 } | 1774 } |
1710 | 1775 |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1869 WhereToPoint where_to_point, int skip) { | 1934 WhereToPoint where_to_point, int skip) { |
1870 HeapObject* heap_object = HeapObject::cast(o); | 1935 HeapObject* heap_object = HeapObject::cast(o); |
1871 | 1936 |
1872 int root_index; | 1937 int root_index; |
1873 if ((root_index = RootIndex(heap_object, how_to_code)) != kInvalidRootIndex) { | 1938 if ((root_index = RootIndex(heap_object, how_to_code)) != kInvalidRootIndex) { |
1874 PutRoot(root_index, heap_object, how_to_code, where_to_point, skip); | 1939 PutRoot(root_index, heap_object, how_to_code, where_to_point, skip); |
1875 return; | 1940 return; |
1876 } | 1941 } |
1877 | 1942 |
1878 if (address_mapper_.IsMapped(heap_object)) { | 1943 if (address_mapper_.IsMapped(heap_object)) { |
| 1944 if (FLAG_trace_code_serializer) { |
| 1945 PrintF("Encoding back reference to: "); |
| 1946 heap_object->ShortPrint(); |
| 1947 PrintF("\n"); |
| 1948 } |
1879 SerializeReferenceToPreviousObject(heap_object, how_to_code, where_to_point, | 1949 SerializeReferenceToPreviousObject(heap_object, how_to_code, where_to_point, |
1880 skip); | 1950 skip); |
1881 return; | 1951 return; |
1882 } | 1952 } |
1883 | 1953 |
1884 if (skip != 0) { | 1954 if (skip != 0) { |
1885 sink_->Put(kSkip, "SkipFromSerializeObject"); | 1955 sink_->Put(kSkip, "SkipFromSerializeObject"); |
1886 sink_->PutInt(skip, "SkipDistanceFromSerializeObject"); | 1956 sink_->PutInt(skip, "SkipDistanceFromSerializeObject"); |
1887 } | 1957 } |
1888 | 1958 |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2108 | 2178 |
2109 int SerializedCodeData::CheckSum(String* string) { | 2179 int SerializedCodeData::CheckSum(String* string) { |
2110 int checksum = Version::Hash(); | 2180 int checksum = Version::Hash(); |
2111 #ifdef DEBUG | 2181 #ifdef DEBUG |
2112 uint32_t seed = static_cast<uint32_t>(checksum); | 2182 uint32_t seed = static_cast<uint32_t>(checksum); |
2113 checksum = static_cast<int>(IteratingStringHasher::Hash(string, seed)); | 2183 checksum = static_cast<int>(IteratingStringHasher::Hash(string, seed)); |
2114 #endif // DEBUG | 2184 #endif // DEBUG |
2115 return checksum; | 2185 return checksum; |
2116 } | 2186 } |
2117 } } // namespace v8::internal | 2187 } } // namespace v8::internal |
OLD | NEW |