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 |