| 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 |