Chromium Code Reviews| 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 557 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 568 { | 568 { |
| 569 DisallowHeapAllocation no_gc; | 569 DisallowHeapAllocation no_gc; |
| 570 isolate_->heap()->IterateSmiRoots(this); | 570 isolate_->heap()->IterateSmiRoots(this); |
| 571 isolate_->heap()->IterateStrongRoots(this, VISIT_ONLY_STRONG); | 571 isolate_->heap()->IterateStrongRoots(this, VISIT_ONLY_STRONG); |
| 572 isolate_->heap()->RepairFreeListsAfterDeserialization(); | 572 isolate_->heap()->RepairFreeListsAfterDeserialization(); |
| 573 isolate_->heap()->IterateWeakRoots(this, VISIT_ALL); | 573 isolate_->heap()->IterateWeakRoots(this, VISIT_ALL); |
| 574 DeserializeDeferredObjects(); | 574 DeserializeDeferredObjects(); |
| 575 } | 575 } |
| 576 | 576 |
| 577 isolate_->heap()->set_native_contexts_list( | 577 isolate_->heap()->set_native_contexts_list( |
| 578 isolate_->heap()->undefined_value()); | 578 isolate_->heap()->code_stub_context()); |
| 579 | 579 |
| 580 // The allocation site list is build during root iteration, but if no sites | 580 // The allocation site list is build during root iteration, but if no sites |
| 581 // were encountered then it needs to be initialized to undefined. | 581 // were encountered then it needs to be initialized to undefined. |
| 582 if (isolate_->heap()->allocation_sites_list() == Smi::FromInt(0)) { | 582 if (isolate_->heap()->allocation_sites_list() == Smi::FromInt(0)) { |
| 583 isolate_->heap()->set_allocation_sites_list( | 583 isolate_->heap()->set_allocation_sites_list( |
| 584 isolate_->heap()->undefined_value()); | 584 isolate_->heap()->undefined_value()); |
| 585 } | 585 } |
| 586 | 586 |
| 587 // Update data pointers to the external strings containing natives sources. | 587 // Update data pointers to the external strings containing natives sources. |
| 588 for (int i = 0; i < Natives::GetBuiltinsCount(); i++) { | 588 for (int i = 0; i < Natives::GetBuiltinsCount(); i++) { |
| 589 Object* source = isolate_->heap()->natives_source_cache()->get(i); | 589 Object* source = isolate_->heap()->natives_source_cache()->get(i); |
| 590 if (!source->IsUndefined()) { | 590 if (!source->IsUndefined()) { |
| 591 ExternalOneByteString::cast(source)->update_data_cache(); | 591 ExternalOneByteString::cast(source)->update_data_cache(); |
| 592 } | 592 } |
| 593 } | 593 } |
| 594 | 594 |
| 595 for (int i = 0; i < CodeStubNatives::GetBuiltinsCount(); i++) { | |
| 596 Object* source = isolate_->heap()->code_stub_natives_source_cache()->get(i); | |
| 597 if (!source->IsUndefined()) { | |
| 598 ExternalOneByteString::cast(source)->update_data_cache(); | |
| 599 } | |
| 600 } | |
| 601 | |
| 595 FlushICacheForNewCodeObjects(); | 602 FlushICacheForNewCodeObjects(); |
| 596 | 603 |
| 597 // Issue code events for newly deserialized code objects. | 604 // Issue code events for newly deserialized code objects. |
| 598 LOG_CODE_EVENT(isolate_, LogCodeObjects()); | 605 LOG_CODE_EVENT(isolate_, LogCodeObjects()); |
| 599 LOG_CODE_EVENT(isolate_, LogCompiledFunctions()); | 606 LOG_CODE_EVENT(isolate_, LogCompiledFunctions()); |
| 600 } | 607 } |
| 601 | 608 |
| 602 | 609 |
| 603 MaybeHandle<Object> Deserializer::DeserializePartial( | 610 MaybeHandle<Object> Deserializer::DeserializePartial( |
| 604 Isolate* isolate, Handle<JSGlobalProxy> global_proxy, | 611 Isolate* isolate, Handle<JSGlobalProxy> global_proxy, |
| (...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 900 // Assert that the current reserved chunk is still big enough. | 907 // Assert that the current reserved chunk is still big enough. |
| 901 const Heap::Reservation& reservation = reservations_[space_index]; | 908 const Heap::Reservation& reservation = reservations_[space_index]; |
| 902 int chunk_index = current_chunk_[space_index]; | 909 int chunk_index = current_chunk_[space_index]; |
| 903 CHECK_LE(high_water_[space_index], reservation[chunk_index].end); | 910 CHECK_LE(high_water_[space_index], reservation[chunk_index].end); |
| 904 #endif | 911 #endif |
| 905 return address; | 912 return address; |
| 906 } | 913 } |
| 907 } | 914 } |
| 908 | 915 |
| 909 | 916 |
| 917 Object** Deserializer::CopyInNativesSource(Vector<const char> source_vector, | |
| 918 Object** current) { | |
| 919 DCHECK(!isolate_->heap()->deserialization_complete()); | |
| 920 NativesExternalStringResource* resource = new NativesExternalStringResource( | |
| 921 source_vector.start(), source_vector.length()); | |
| 922 Object* resource_obj = reinterpret_cast<Object*>(resource); | |
| 923 UnalignedCopy(current++, &resource_obj); | |
| 924 return current; | |
| 925 } | |
| 926 | |
| 927 | |
| 910 bool Deserializer::ReadData(Object** current, Object** limit, int source_space, | 928 bool Deserializer::ReadData(Object** current, Object** limit, int source_space, |
| 911 Address current_object_address) { | 929 Address current_object_address) { |
| 912 Isolate* const isolate = isolate_; | 930 Isolate* const isolate = isolate_; |
| 913 // Write barrier support costs around 1% in startup time. In fact there | 931 // Write barrier support costs around 1% in startup time. In fact there |
| 914 // are no new space objects in current boot snapshots, so it's not needed, | 932 // are no new space objects in current boot snapshots, so it's not needed, |
| 915 // but that may change. | 933 // but that may change. |
| 916 bool write_barrier_needed = | 934 bool write_barrier_needed = |
| 917 (current_object_address != NULL && source_space != NEW_SPACE && | 935 (current_object_address != NULL && source_space != NEW_SPACE && |
| 918 source_space != CODE_SPACE); | 936 source_space != CODE_SPACE); |
| 919 while (current < limit) { | 937 while (current < limit) { |
| (...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1166 current = limit; | 1184 current = limit; |
| 1167 return false; | 1185 return false; |
| 1168 } | 1186 } |
| 1169 | 1187 |
| 1170 case kSynchronize: | 1188 case kSynchronize: |
| 1171 // If we get here then that indicates that you have a mismatch between | 1189 // If we get here then that indicates that you have a mismatch between |
| 1172 // the number of GC roots when serializing and deserializing. | 1190 // the number of GC roots when serializing and deserializing. |
| 1173 CHECK(false); | 1191 CHECK(false); |
| 1174 break; | 1192 break; |
| 1175 | 1193 |
| 1176 case kNativesStringResource: { | 1194 case kNativesStringResource: { |
|
Yang
2015/07/10 08:18:57
no need for the scoping brackets anymore.
danno
2015/07/13 09:43:37
Done
| |
| 1177 DCHECK(!isolate_->heap()->deserialization_complete()); | 1195 current = CopyInNativesSource(Natives::GetScriptSource(source_.Get()), |
| 1178 int index = source_.Get(); | 1196 current); |
| 1179 Vector<const char> source_vector = Natives::GetScriptSource(index); | |
| 1180 NativesExternalStringResource* resource = | |
| 1181 new NativesExternalStringResource(source_vector.start(), | |
| 1182 source_vector.length()); | |
| 1183 Object* resource_obj = reinterpret_cast<Object*>(resource); | |
| 1184 UnalignedCopy(current++, &resource_obj); | |
| 1185 break; | 1197 break; |
| 1186 } | 1198 } |
| 1187 | 1199 |
| 1200 case kCodeStubNativesStringResource: { | |
| 1201 current = CopyInNativesSource( | |
| 1202 CodeStubNatives::GetScriptSource(source_.Get()), current); | |
| 1203 break; | |
| 1204 } | |
| 1205 | |
| 1188 // Deserialize raw data of variable length. | 1206 // Deserialize raw data of variable length. |
| 1189 case kVariableRawData: { | 1207 case kVariableRawData: { |
| 1190 int size_in_bytes = source_.GetInt(); | 1208 int size_in_bytes = source_.GetInt(); |
| 1191 byte* raw_data_out = reinterpret_cast<byte*>(current); | 1209 byte* raw_data_out = reinterpret_cast<byte*>(current); |
| 1192 source_.CopyRaw(raw_data_out, size_in_bytes); | 1210 source_.CopyRaw(raw_data_out, size_in_bytes); |
| 1193 break; | 1211 break; |
| 1194 } | 1212 } |
| 1195 | 1213 |
| 1196 case kVariableRepeat: { | 1214 case kVariableRepeat: { |
| 1197 int repeats = source_.GetInt(); | 1215 int repeats = source_.GetInt(); |
| (...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1412 } | 1430 } |
| 1413 } | 1431 } |
| 1414 } | 1432 } |
| 1415 | 1433 |
| 1416 | 1434 |
| 1417 void PartialSerializer::Serialize(Object** o) { | 1435 void PartialSerializer::Serialize(Object** o) { |
| 1418 if ((*o)->IsContext()) { | 1436 if ((*o)->IsContext()) { |
| 1419 Context* context = Context::cast(*o); | 1437 Context* context = Context::cast(*o); |
| 1420 global_object_ = context->global_object(); | 1438 global_object_ = context->global_object(); |
| 1421 back_reference_map()->AddGlobalProxy(context->global_proxy()); | 1439 back_reference_map()->AddGlobalProxy(context->global_proxy()); |
| 1440 // The bootstrap already snapshot has a code-stub context, when serializing | |
|
Yang
2015/07/10 08:18:57
weird sentence...
danno
2015/07/13 09:43:37
Done
| |
| 1441 // the partial snapshot, it is chained into the weak context list on the | |
| 1442 // isolate and it's next context pointer may point to the code-stub context. | |
| 1443 // Clear it before serializing, it will get re-added to the context list | |
| 1444 // explicitly when it's loaded. | |
| 1445 if (context->IsNativeContext()) { | |
| 1446 context->set(Context::NEXT_CONTEXT_LINK, | |
| 1447 isolate_->heap()->undefined_value()); | |
| 1448 DCHECK(!context->global_object()->IsUndefined()); | |
| 1449 DCHECK(!context->builtins()->IsUndefined()); | |
| 1450 } | |
| 1422 } | 1451 } |
| 1423 VisitPointer(o); | 1452 VisitPointer(o); |
| 1424 SerializeDeferredObjects(); | 1453 SerializeDeferredObjects(); |
| 1425 SerializeOutdatedContextsAsFixedArray(); | 1454 SerializeOutdatedContextsAsFixedArray(); |
| 1426 Pad(); | 1455 Pad(); |
| 1427 } | 1456 } |
| 1428 | 1457 |
| 1429 | 1458 |
| 1430 void PartialSerializer::SerializeOutdatedContextsAsFixedArray() { | 1459 void PartialSerializer::SerializeOutdatedContextsAsFixedArray() { |
| 1431 int length = outdated_contexts_.length(); | 1460 int length = outdated_contexts_.length(); |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1616 PutBackReference(obj, back_reference); | 1645 PutBackReference(obj, back_reference); |
| 1617 } | 1646 } |
| 1618 return true; | 1647 return true; |
| 1619 } | 1648 } |
| 1620 return false; | 1649 return false; |
| 1621 } | 1650 } |
| 1622 | 1651 |
| 1623 | 1652 |
| 1624 void StartupSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code, | 1653 void StartupSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code, |
| 1625 WhereToPoint where_to_point, int skip) { | 1654 WhereToPoint where_to_point, int skip) { |
| 1626 DCHECK(!obj->IsJSFunction()); | 1655 // Make sure that all functions are derived from the code-stub context |
| 1656 DCHECK(!obj->IsJSFunction() || | |
| 1657 JSFunction::cast(obj)->GetCreationContext() == | |
| 1658 isolate()->heap()->code_stub_context()); | |
| 1627 | 1659 |
| 1628 int root_index = root_index_map_.Lookup(obj); | 1660 int root_index = root_index_map_.Lookup(obj); |
| 1629 // We can only encode roots as such if it has already been serialized. | 1661 // We can only encode roots as such if it has already been serialized. |
| 1630 // That applies to root indices below the wave front. | 1662 // That applies to root indices below the wave front. |
| 1631 if (root_index != RootIndexMap::kInvalidRootIndex && | 1663 if (root_index != RootIndexMap::kInvalidRootIndex && |
| 1632 root_index < root_index_wave_front_) { | 1664 root_index < root_index_wave_front_) { |
| 1633 PutRoot(root_index, obj, how_to_code, where_to_point, skip); | 1665 PutRoot(root_index, obj, how_to_code, where_to_point, skip); |
| 1634 return; | 1666 return; |
| 1635 } | 1667 } |
| 1636 | 1668 |
| (...skipping 483 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2120 | 2152 |
| 2121 | 2153 |
| 2122 void Serializer::ObjectSerializer::VisitCell(RelocInfo* rinfo) { | 2154 void Serializer::ObjectSerializer::VisitCell(RelocInfo* rinfo) { |
| 2123 int skip = OutputRawData(rinfo->pc(), kCanReturnSkipInsteadOfSkipping); | 2155 int skip = OutputRawData(rinfo->pc(), kCanReturnSkipInsteadOfSkipping); |
| 2124 Cell* object = Cell::cast(rinfo->target_cell()); | 2156 Cell* object = Cell::cast(rinfo->target_cell()); |
| 2125 serializer_->SerializeObject(object, kPlain, kInnerPointer, skip); | 2157 serializer_->SerializeObject(object, kPlain, kInnerPointer, skip); |
| 2126 bytes_processed_so_far_ += kPointerSize; | 2158 bytes_processed_so_far_ += kPointerSize; |
| 2127 } | 2159 } |
| 2128 | 2160 |
| 2129 | 2161 |
| 2162 bool Serializer::ObjectSerializer::SerializeExternalNativeSourceString( | |
| 2163 int builtin_count, | |
| 2164 v8::String::ExternalOneByteStringResource** resource_pointer, | |
| 2165 FixedArray* source_cache, int resource_index, const char* begin_string, | |
| 2166 const char* end_string) { | |
| 2167 for (int i = 0; i < builtin_count; i++) { | |
| 2168 Object* source = source_cache->get(i); | |
| 2169 if (!source->IsUndefined()) { | |
| 2170 ExternalOneByteString* string = ExternalOneByteString::cast(source); | |
| 2171 typedef v8::String::ExternalOneByteStringResource Resource; | |
| 2172 const Resource* resource = string->resource(); | |
| 2173 if (resource == *resource_pointer) { | |
| 2174 sink_->Put(resource_index, begin_string); | |
| 2175 sink_->PutSection(i, end_string); | |
| 2176 bytes_processed_so_far_ += sizeof(resource); | |
| 2177 return true; | |
| 2178 } | |
| 2179 } | |
| 2180 } | |
| 2181 return false; | |
| 2182 } | |
| 2183 | |
| 2184 | |
| 2130 void Serializer::ObjectSerializer::VisitExternalOneByteString( | 2185 void Serializer::ObjectSerializer::VisitExternalOneByteString( |
| 2131 v8::String::ExternalOneByteStringResource** resource_pointer) { | 2186 v8::String::ExternalOneByteStringResource** resource_pointer) { |
| 2132 Address references_start = reinterpret_cast<Address>(resource_pointer); | 2187 Address references_start = reinterpret_cast<Address>(resource_pointer); |
| 2133 OutputRawData(references_start); | 2188 OutputRawData(references_start); |
| 2134 for (int i = 0; i < Natives::GetBuiltinsCount(); i++) { | 2189 if (SerializeExternalNativeSourceString( |
| 2135 Object* source = | 2190 Natives::GetBuiltinsCount(), resource_pointer, |
| 2136 serializer_->isolate()->heap()->natives_source_cache()->get(i); | 2191 serializer_->isolate()->heap()->natives_source_cache(), |
| 2137 if (!source->IsUndefined()) { | 2192 kNativesStringResource, "NativesStringResource", |
|
Yang
2015/07/10 08:18:57
Those string arguments are really just for documen
danno
2015/07/13 09:43:37
Done
| |
| 2138 ExternalOneByteString* string = ExternalOneByteString::cast(source); | 2193 "NativesStringResourceEnd")) { |
| 2139 typedef v8::String::ExternalOneByteStringResource Resource; | 2194 return; |
| 2140 const Resource* resource = string->resource(); | 2195 } |
| 2141 if (resource == *resource_pointer) { | 2196 if (SerializeExternalNativeSourceString( |
| 2142 sink_->Put(kNativesStringResource, "NativesStringResource"); | 2197 CodeStubNatives::GetBuiltinsCount(), resource_pointer, |
| 2143 sink_->PutSection(i, "NativesStringResourceEnd"); | 2198 serializer_->isolate()->heap()->code_stub_natives_source_cache(), |
| 2144 bytes_processed_so_far_ += sizeof(resource); | 2199 kCodeStubNativesStringResource, "CodeStubNativesStringResource", |
| 2145 return; | 2200 "CodeStubNativesStringResourceEnd")) { |
| 2146 } | 2201 return; |
| 2147 } | |
| 2148 } | 2202 } |
| 2149 // One of the strings in the natives cache should match the resource. We | 2203 // One of the strings in the natives cache should match the resource. We |
| 2150 // don't expect any other kinds of external strings here. | 2204 // don't expect any other kinds of external strings here. |
| 2151 UNREACHABLE(); | 2205 UNREACHABLE(); |
| 2152 } | 2206 } |
| 2153 | 2207 |
| 2154 | 2208 |
| 2155 Address Serializer::ObjectSerializer::PrepareCode() { | 2209 Address Serializer::ObjectSerializer::PrepareCode() { |
| 2156 // To make snapshots reproducible, we make a copy of the code object | 2210 // To make snapshots reproducible, we make a copy of the code object |
| 2157 // and wipe all pointers in the copy, which we then serialize. | 2211 // and wipe all pointers in the copy, which we then serialize. |
| (...skipping 591 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2749 SerializedCodeData* scd = new SerializedCodeData(cached_data); | 2803 SerializedCodeData* scd = new SerializedCodeData(cached_data); |
| 2750 SanityCheckResult r = scd->SanityCheck(isolate, source); | 2804 SanityCheckResult r = scd->SanityCheck(isolate, source); |
| 2751 if (r == CHECK_SUCCESS) return scd; | 2805 if (r == CHECK_SUCCESS) return scd; |
| 2752 cached_data->Reject(); | 2806 cached_data->Reject(); |
| 2753 source->GetIsolate()->counters()->code_cache_reject_reason()->AddSample(r); | 2807 source->GetIsolate()->counters()->code_cache_reject_reason()->AddSample(r); |
| 2754 delete scd; | 2808 delete scd; |
| 2755 return NULL; | 2809 return NULL; |
| 2756 } | 2810 } |
| 2757 } // namespace internal | 2811 } // namespace internal |
| 2758 } // namespace v8 | 2812 } // namespace v8 |
| OLD | NEW |