Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(48)

Side by Side Diff: src/serialize.cc

Issue 623453003: Serialize external strings in the code serializer. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/serialize.h ('k') | test/cctest/test-serialize.cc » ('j') | test/cctest/test-serialize.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698