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 1576 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1587 // an imaginary sequential string with the same content. | 1587 // an imaginary sequential string with the same content. |
1588 Isolate* isolate = serializer_->isolate(); | 1588 Isolate* isolate = serializer_->isolate(); |
1589 DCHECK(object_->IsExternalString()); | 1589 DCHECK(object_->IsExternalString()); |
1590 DCHECK(object_->map() != isolate->heap()->native_source_string_map()); | 1590 DCHECK(object_->map() != isolate->heap()->native_source_string_map()); |
1591 ExternalString* string = ExternalString::cast(object_); | 1591 ExternalString* string = ExternalString::cast(object_); |
1592 int length = string->length(); | 1592 int length = string->length(); |
1593 Map* map; | 1593 Map* map; |
1594 int size; | 1594 int size; |
1595 const char* resource; | 1595 const char* resource; |
1596 // Find the map and size for the imaginary sequential string. | 1596 // Find the map and size for the imaginary sequential string. |
| 1597 bool internalized = object_->IsInternalizedString(); |
1597 if (object_->IsExternalOneByteString()) { | 1598 if (object_->IsExternalOneByteString()) { |
1598 map = isolate->heap()->one_byte_internalized_string_map(); | 1599 map = internalized ? isolate->heap()->one_byte_internalized_string_map() |
| 1600 : isolate->heap()->one_byte_string_map(); |
1599 size = SeqOneByteString::SizeFor(length); | 1601 size = SeqOneByteString::SizeFor(length); |
1600 resource = ExternalOneByteString::cast(string)->resource()->data(); | 1602 resource = ExternalOneByteString::cast(string)->resource()->data(); |
1601 } else { | 1603 } else { |
1602 map = isolate->heap()->internalized_string_map(); | 1604 map = internalized ? isolate->heap()->internalized_string_map() |
| 1605 : isolate->heap()->string_map(); |
1603 size = SeqTwoByteString::SizeFor(length); | 1606 size = SeqTwoByteString::SizeFor(length); |
1604 resource = reinterpret_cast<const char*>( | 1607 resource = reinterpret_cast<const char*>( |
1605 ExternalTwoByteString::cast(string)->resource()->data()); | 1608 ExternalTwoByteString::cast(string)->resource()->data()); |
1606 } | 1609 } |
1607 | 1610 |
1608 int space = | 1611 int space = |
1609 (size > Page::kMaxRegularHeapObjectSize) ? LO_SPACE : OLD_DATA_SPACE; | 1612 (size > Page::kMaxRegularHeapObjectSize) ? LO_SPACE : OLD_DATA_SPACE; |
1610 SerializePrologue(space, size, map); | 1613 SerializePrologue(space, size, map); |
1611 | 1614 |
1612 // Output the rest of the imaginary string. | 1615 // Output the rest of the imaginary string. |
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1903 uint32_t Serializer::AllocateLargeObject(int size) { | 1906 uint32_t Serializer::AllocateLargeObject(int size) { |
1904 // Large objects are allocated one-by-one when deserializing. We do not | 1907 // Large objects are allocated one-by-one when deserializing. We do not |
1905 // have to keep track of multiple chunks. | 1908 // have to keep track of multiple chunks. |
1906 pending_chunk_[LO_SPACE] += size; | 1909 pending_chunk_[LO_SPACE] += size; |
1907 return seen_large_objects_index_++; | 1910 return seen_large_objects_index_++; |
1908 } | 1911 } |
1909 | 1912 |
1910 | 1913 |
1911 uint32_t Serializer::Allocate(int space, int size) { | 1914 uint32_t Serializer::Allocate(int space, int size) { |
1912 CHECK(space >= 0 && space < kNumberOfPreallocatedSpaces); | 1915 CHECK(space >= 0 && space < kNumberOfPreallocatedSpaces); |
1913 DCHECK(size > 0 && size < Page::kMaxRegularHeapObjectSize); | 1916 DCHECK(size > 0 && size <= Page::kMaxRegularHeapObjectSize); |
1914 uint32_t new_chunk_size = pending_chunk_[space] + size; | 1917 uint32_t new_chunk_size = pending_chunk_[space] + size; |
1915 uint32_t allocation; | 1918 uint32_t allocation; |
1916 if (new_chunk_size > static_cast<uint32_t>(Page::kMaxRegularHeapObjectSize)) { | 1919 if (new_chunk_size > static_cast<uint32_t>(Page::kMaxRegularHeapObjectSize)) { |
1917 // The new chunk size would not fit onto a single page. Complete the | 1920 // The new chunk size would not fit onto a single page. Complete the |
1918 // current chunk and start a new one. | 1921 // current chunk and start a new one. |
1919 completed_chunks_[space].Add(pending_chunk_[space]); | 1922 completed_chunks_[space].Add(pending_chunk_[space]); |
1920 pending_chunk_[space] = 0; | 1923 pending_chunk_[space] = 0; |
1921 new_chunk_size = size; | 1924 new_chunk_size = size; |
1922 } | 1925 } |
1923 // For back-referencing, each allocation is encoded as a combination | 1926 // For back-referencing, each allocation is encoded as a combination |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2074 | 2077 |
2075 void CodeSerializer::SerializeHeapObject(HeapObject* heap_object, | 2078 void CodeSerializer::SerializeHeapObject(HeapObject* heap_object, |
2076 HowToCode how_to_code, | 2079 HowToCode how_to_code, |
2077 WhereToPoint where_to_point) { | 2080 WhereToPoint where_to_point) { |
2078 if (FLAG_serializer_trace_level > 0) { | 2081 if (FLAG_serializer_trace_level > 0) { |
2079 PrintF(" Encoding heap object: "); | 2082 PrintF(" Encoding heap object: "); |
2080 heap_object->ShortPrint(); | 2083 heap_object->ShortPrint(); |
2081 PrintF("\n"); | 2084 PrintF("\n"); |
2082 } | 2085 } |
2083 | 2086 |
| 2087 if (heap_object->IsInternalizedString()) num_internalized_strings_++; |
| 2088 |
2084 // Object has not yet been serialized. Serialize it here. | 2089 // Object has not yet been serialized. Serialize it here. |
2085 ObjectSerializer serializer(this, heap_object, sink_, how_to_code, | 2090 ObjectSerializer serializer(this, heap_object, sink_, how_to_code, |
2086 where_to_point); | 2091 where_to_point); |
2087 serializer.Serialize(); | 2092 serializer.Serialize(); |
2088 } | 2093 } |
2089 | 2094 |
2090 | 2095 |
2091 void CodeSerializer::SerializeBuiltin(int builtin_index, HowToCode how_to_code, | 2096 void CodeSerializer::SerializeBuiltin(int builtin_index, HowToCode how_to_code, |
2092 WhereToPoint where_to_point) { | 2097 WhereToPoint where_to_point) { |
2093 DCHECK((how_to_code == kPlain && where_to_point == kStartOfObject) || | 2098 DCHECK((how_to_code == kPlain && where_to_point == kStartOfObject) || |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2194 | 2199 |
2195 Object* root; | 2200 Object* root; |
2196 | 2201 |
2197 { | 2202 { |
2198 HandleScope scope(isolate); | 2203 HandleScope scope(isolate); |
2199 | 2204 |
2200 SerializedCodeData scd(data, *source); | 2205 SerializedCodeData scd(data, *source); |
2201 SnapshotByteSource payload(scd.Payload(), scd.PayloadLength()); | 2206 SnapshotByteSource payload(scd.Payload(), scd.PayloadLength()); |
2202 Deserializer deserializer(&payload); | 2207 Deserializer deserializer(&payload); |
2203 | 2208 |
| 2209 // Eagerly expand string table to avoid allocations during deserialization. |
| 2210 StringTable::EnsureCapacityForDeserialization(isolate, |
| 2211 scd.NumInternalizedStrings()); |
| 2212 |
| 2213 // Set reservations. |
2204 STATIC_ASSERT(NEW_SPACE == 0); | 2214 STATIC_ASSERT(NEW_SPACE == 0); |
2205 int current_space = NEW_SPACE; | 2215 int current_space = NEW_SPACE; |
2206 Vector<const SerializedCodeData::Reservation> res = scd.Reservations(); | 2216 Vector<const SerializedCodeData::Reservation> res = scd.Reservations(); |
2207 for (const auto& r : res) { | 2217 for (const auto& r : res) { |
2208 deserializer.AddReservation(current_space, r.chunk_size()); | 2218 deserializer.AddReservation(current_space, r.chunk_size()); |
2209 if (r.is_last_chunk()) current_space++; | 2219 if (r.is_last_chunk()) current_space++; |
2210 } | 2220 } |
2211 DCHECK_EQ(kNumberOfSpaces, current_space); | 2221 DCHECK_EQ(kNumberOfSpaces, current_space); |
2212 | 2222 |
2213 // Prepare and register list of attached objects. | 2223 // Prepare and register list of attached objects. |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2247 DisallowHeapAllocation no_gc; | 2257 DisallowHeapAllocation no_gc; |
2248 List<uint32_t>* stub_keys = cs->stub_keys(); | 2258 List<uint32_t>* stub_keys = cs->stub_keys(); |
2249 | 2259 |
2250 // Gather reservation chunk sizes. | 2260 // Gather reservation chunk sizes. |
2251 List<uint32_t> reservations(SerializerDeserializer::kNumberOfSpaces); | 2261 List<uint32_t> reservations(SerializerDeserializer::kNumberOfSpaces); |
2252 STATIC_ASSERT(NEW_SPACE == 0); | 2262 STATIC_ASSERT(NEW_SPACE == 0); |
2253 for (int i = 0; i < SerializerDeserializer::kNumberOfSpaces; i++) { | 2263 for (int i = 0; i < SerializerDeserializer::kNumberOfSpaces; i++) { |
2254 Vector<const uint32_t> chunks = cs->FinalAllocationChunks(i); | 2264 Vector<const uint32_t> chunks = cs->FinalAllocationChunks(i); |
2255 for (int j = 0; j < chunks.length(); j++) { | 2265 for (int j = 0; j < chunks.length(); j++) { |
2256 DCHECK(i == LO_SPACE || | 2266 DCHECK(i == LO_SPACE || |
2257 chunks[j] < | 2267 chunks[j] <= |
2258 static_cast<uint32_t>(Page::kMaxRegularHeapObjectSize)); | 2268 static_cast<uint32_t>(Page::kMaxRegularHeapObjectSize)); |
2259 uint32_t chunk = ChunkSizeBits::encode(chunks[j]) | | 2269 uint32_t chunk = ChunkSizeBits::encode(chunks[j]) | |
2260 IsLastChunkBits::encode(j == chunks.length() - 1); | 2270 IsLastChunkBits::encode(j == chunks.length() - 1); |
2261 reservations.Add(chunk); | 2271 reservations.Add(chunk); |
2262 } | 2272 } |
2263 } | 2273 } |
2264 | 2274 |
2265 // Calculate sizes. | 2275 // Calculate sizes. |
2266 int reservation_size = reservations.length() * kInt32Size; | 2276 int reservation_size = reservations.length() * kInt32Size; |
2267 int num_stub_keys = stub_keys->length(); | 2277 int num_stub_keys = stub_keys->length(); |
2268 int stub_keys_size = stub_keys->length() * kInt32Size; | 2278 int stub_keys_size = stub_keys->length() * kInt32Size; |
2269 int data_length = | 2279 int data_length = |
2270 kHeaderSize + reservation_size + stub_keys_size + payload->length(); | 2280 kHeaderSize + reservation_size + stub_keys_size + payload->length(); |
2271 | 2281 |
2272 // Allocate backing store and create result data. | 2282 // Allocate backing store and create result data. |
2273 byte* data = NewArray<byte>(data_length); | 2283 byte* data = NewArray<byte>(data_length); |
2274 DCHECK(IsAligned(reinterpret_cast<intptr_t>(data), kPointerAlignment)); | 2284 DCHECK(IsAligned(reinterpret_cast<intptr_t>(data), kPointerAlignment)); |
2275 script_data_ = new ScriptData(data, data_length); | 2285 script_data_ = new ScriptData(data, data_length); |
2276 script_data_->AcquireDataOwnership(); | 2286 script_data_->AcquireDataOwnership(); |
2277 | 2287 |
2278 // Set header values. | 2288 // Set header values. |
2279 SetHeaderValue(kCheckSumOffset, CheckSum(cs->source())); | 2289 SetHeaderValue(kCheckSumOffset, CheckSum(cs->source())); |
| 2290 SetHeaderValue(kNumInternalizedStringsOffset, cs->num_internalized_strings()); |
2280 SetHeaderValue(kReservationsOffset, reservations.length()); | 2291 SetHeaderValue(kReservationsOffset, reservations.length()); |
2281 SetHeaderValue(kNumCodeStubKeysOffset, num_stub_keys); | 2292 SetHeaderValue(kNumCodeStubKeysOffset, num_stub_keys); |
2282 SetHeaderValue(kPayloadLengthOffset, payload->length()); | 2293 SetHeaderValue(kPayloadLengthOffset, payload->length()); |
2283 | 2294 |
2284 // Copy reservation chunk sizes. | 2295 // Copy reservation chunk sizes. |
2285 CopyBytes(data + kHeaderSize, reinterpret_cast<byte*>(reservations.begin()), | 2296 CopyBytes(data + kHeaderSize, reinterpret_cast<byte*>(reservations.begin()), |
2286 reservation_size); | 2297 reservation_size); |
2287 | 2298 |
2288 // Copy code stub keys. | 2299 // Copy code stub keys. |
2289 CopyBytes(data + kHeaderSize + reservation_size, | 2300 CopyBytes(data + kHeaderSize + reservation_size, |
(...skipping 13 matching lines...) Expand all Loading... |
2303 | 2314 |
2304 int SerializedCodeData::CheckSum(String* string) { | 2315 int SerializedCodeData::CheckSum(String* string) { |
2305 int checksum = Version::Hash(); | 2316 int checksum = Version::Hash(); |
2306 #ifdef DEBUG | 2317 #ifdef DEBUG |
2307 uint32_t seed = static_cast<uint32_t>(checksum); | 2318 uint32_t seed = static_cast<uint32_t>(checksum); |
2308 checksum = static_cast<int>(IteratingStringHasher::Hash(string, seed)); | 2319 checksum = static_cast<int>(IteratingStringHasher::Hash(string, seed)); |
2309 #endif // DEBUG | 2320 #endif // DEBUG |
2310 return checksum; | 2321 return checksum; |
2311 } | 2322 } |
2312 } } // namespace v8::internal | 2323 } } // namespace v8::internal |
OLD | NEW |