| 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 682 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 693 | 693 |
| 694 FlushICacheForNewCodeObjects(); | 694 FlushICacheForNewCodeObjects(); |
| 695 | 695 |
| 696 // Issue code events for newly deserialized code objects. | 696 // Issue code events for newly deserialized code objects. |
| 697 LOG_CODE_EVENT(isolate_, LogCodeObjects()); | 697 LOG_CODE_EVENT(isolate_, LogCodeObjects()); |
| 698 LOG_CODE_EVENT(isolate_, LogCompiledFunctions()); | 698 LOG_CODE_EVENT(isolate_, LogCompiledFunctions()); |
| 699 } | 699 } |
| 700 | 700 |
| 701 | 701 |
| 702 MaybeHandle<Object> Deserializer::DeserializePartial( | 702 MaybeHandle<Object> Deserializer::DeserializePartial( |
| 703 Isolate* isolate, Handle<FixedArray>* outdated_contexts_out) { | 703 Isolate* isolate, Handle<JSGlobalProxy> global_proxy, |
| 704 Handle<FixedArray>* outdated_contexts_out) { |
| 704 Initialize(isolate); | 705 Initialize(isolate); |
| 705 if (!ReserveSpace()) { | 706 if (!ReserveSpace()) { |
| 706 FatalProcessOutOfMemory("deserialize context"); | 707 FatalProcessOutOfMemory("deserialize context"); |
| 707 return MaybeHandle<Object>(); | 708 return MaybeHandle<Object>(); |
| 708 } | 709 } |
| 709 | 710 |
| 711 Vector<Handle<Object> > attached_objects = Vector<Handle<Object> >::New(1); |
| 712 attached_objects[kGlobalProxyReference] = global_proxy; |
| 713 SetAttachedObjects(attached_objects); |
| 714 |
| 710 DisallowHeapAllocation no_gc; | 715 DisallowHeapAllocation no_gc; |
| 711 // Keep track of the code space start and end pointers in case new | 716 // Keep track of the code space start and end pointers in case new |
| 712 // code objects were unserialized | 717 // code objects were unserialized |
| 713 OldSpace* code_space = isolate_->heap()->code_space(); | 718 OldSpace* code_space = isolate_->heap()->code_space(); |
| 714 Address start_address = code_space->top(); | 719 Address start_address = code_space->top(); |
| 715 Object* root; | 720 Object* root; |
| 716 Object* outdated_contexts; | 721 Object* outdated_contexts; |
| 717 VisitPointer(&root); | 722 VisitPointer(&root); |
| 718 VisitPointer(&outdated_contexts); | 723 VisitPointer(&outdated_contexts); |
| 719 | 724 |
| 720 // There's no code deserialized here. If this assert fires | 725 // There's no code deserialized here. If this assert fires |
| 721 // then that's changed and logging should be added to notify | 726 // then that's changed and logging should be added to notify |
| 722 // the profiler et al of the new code. | 727 // the profiler et al of the new code. |
| 723 CHECK_EQ(start_address, code_space->top()); | 728 CHECK_EQ(start_address, code_space->top()); |
| 724 CHECK(outdated_contexts->IsFixedArray()); | 729 CHECK(outdated_contexts->IsFixedArray()); |
| 725 *outdated_contexts_out = | 730 *outdated_contexts_out = |
| 726 Handle<FixedArray>(FixedArray::cast(outdated_contexts), isolate); | 731 Handle<FixedArray>(FixedArray::cast(outdated_contexts), isolate); |
| 727 return Handle<Object>(root, isolate); | 732 return Handle<Object>(root, isolate); |
| 728 } | 733 } |
| 729 | 734 |
| 730 | 735 |
| 731 MaybeHandle<SharedFunctionInfo> Deserializer::DeserializeCode( | 736 MaybeHandle<SharedFunctionInfo> Deserializer::DeserializeCode( |
| 732 Isolate* isolate) { | 737 Isolate* isolate) { |
| 733 Initialize(isolate); | 738 Initialize(isolate); |
| 734 if (!ReserveSpace()) { | 739 if (!ReserveSpace()) { |
| 735 return Handle<SharedFunctionInfo>(); | 740 return Handle<SharedFunctionInfo>(); |
| 736 } else { | 741 } else { |
| 742 deserializing_user_code_ = true; |
| 737 DisallowHeapAllocation no_gc; | 743 DisallowHeapAllocation no_gc; |
| 738 Object* root; | 744 Object* root; |
| 739 VisitPointer(&root); | 745 VisitPointer(&root); |
| 740 return Handle<SharedFunctionInfo>(SharedFunctionInfo::cast(root)); | 746 return Handle<SharedFunctionInfo>(SharedFunctionInfo::cast(root)); |
| 741 } | 747 } |
| 742 } | 748 } |
| 743 | 749 |
| 744 | 750 |
| 745 Deserializer::~Deserializer() { | 751 Deserializer::~Deserializer() { |
| 746 // TODO(svenpanne) Re-enable this assertion when v8 initialization is fixed. | 752 // TODO(svenpanne) Re-enable this assertion when v8 initialization is fixed. |
| 747 // DCHECK(source_.AtEOF()); | 753 // DCHECK(source_.AtEOF()); |
| 748 if (external_reference_decoder_) { | 754 if (external_reference_decoder_) { |
| 749 delete external_reference_decoder_; | 755 delete external_reference_decoder_; |
| 750 external_reference_decoder_ = NULL; | 756 external_reference_decoder_ = NULL; |
| 751 } | 757 } |
| 752 if (attached_objects_) attached_objects_->Dispose(); | 758 attached_objects_.Dispose(); |
| 753 } | 759 } |
| 754 | 760 |
| 755 | 761 |
| 756 // This is called on the roots. It is the driver of the deserialization | 762 // This is called on the roots. It is the driver of the deserialization |
| 757 // process. It is also called on the body of each function. | 763 // process. It is also called on the body of each function. |
| 758 void Deserializer::VisitPointers(Object** start, Object** end) { | 764 void Deserializer::VisitPointers(Object** start, Object** end) { |
| 759 // The space must be new space. Any other space would cause ReadChunk to try | 765 // The space must be new space. Any other space would cause ReadChunk to try |
| 760 // to update the remembered using NULL as the address. | 766 // to update the remembered using NULL as the address. |
| 761 ReadData(start, end, NEW_SPACE, NULL); | 767 ReadData(start, end, NEW_SPACE, NULL); |
| 762 } | 768 } |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 990 new_object = GetBackReferencedObject(data & kSpaceMask); \ | 996 new_object = GetBackReferencedObject(data & kSpaceMask); \ |
| 991 } else if (where == kBuiltin) { \ | 997 } else if (where == kBuiltin) { \ |
| 992 DCHECK(deserializing_user_code()); \ | 998 DCHECK(deserializing_user_code()); \ |
| 993 int builtin_id = source_.GetInt(); \ | 999 int builtin_id = source_.GetInt(); \ |
| 994 DCHECK_LE(0, builtin_id); \ | 1000 DCHECK_LE(0, builtin_id); \ |
| 995 DCHECK_LT(builtin_id, Builtins::builtin_count); \ | 1001 DCHECK_LT(builtin_id, Builtins::builtin_count); \ |
| 996 Builtins::Name name = static_cast<Builtins::Name>(builtin_id); \ | 1002 Builtins::Name name = static_cast<Builtins::Name>(builtin_id); \ |
| 997 new_object = isolate->builtins()->builtin(name); \ | 1003 new_object = isolate->builtins()->builtin(name); \ |
| 998 emit_write_barrier = false; \ | 1004 emit_write_barrier = false; \ |
| 999 } else if (where == kAttachedReference) { \ | 1005 } else if (where == kAttachedReference) { \ |
| 1000 DCHECK(deserializing_user_code()); \ | |
| 1001 int index = source_.GetInt(); \ | 1006 int index = source_.GetInt(); \ |
| 1002 new_object = *attached_objects_->at(index); \ | 1007 DCHECK(deserializing_user_code() || index == kGlobalProxyReference); \ |
| 1008 new_object = *attached_objects_[index]; \ |
| 1003 emit_write_barrier = isolate->heap()->InNewSpace(new_object); \ | 1009 emit_write_barrier = isolate->heap()->InNewSpace(new_object); \ |
| 1004 } else { \ | 1010 } else { \ |
| 1005 DCHECK(where == kBackrefWithSkip); \ | 1011 DCHECK(where == kBackrefWithSkip); \ |
| 1006 int skip = source_.GetInt(); \ | 1012 int skip = source_.GetInt(); \ |
| 1007 current = reinterpret_cast<Object**>( \ | 1013 current = reinterpret_cast<Object**>( \ |
| 1008 reinterpret_cast<Address>(current) + skip); \ | 1014 reinterpret_cast<Address>(current) + skip); \ |
| 1009 emit_write_barrier = (space_number == NEW_SPACE); \ | 1015 emit_write_barrier = (space_number == NEW_SPACE); \ |
| 1010 new_object = GetBackReferencedObject(data & kSpaceMask); \ | 1016 new_object = GetBackReferencedObject(data & kSpaceMask); \ |
| 1011 } \ | 1017 } \ |
| 1012 if (within == kInnerPointer) { \ | 1018 if (within == kInnerPointer) { \ |
| (...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1389 sink_->Put(reinterpret_cast<byte*>(current)[i], "Byte"); | 1395 sink_->Put(reinterpret_cast<byte*>(current)[i], "Byte"); |
| 1390 } | 1396 } |
| 1391 } else { | 1397 } else { |
| 1392 SerializeObject(HeapObject::cast(*current), kPlain, kStartOfObject, 0); | 1398 SerializeObject(HeapObject::cast(*current), kPlain, kStartOfObject, 0); |
| 1393 } | 1399 } |
| 1394 } | 1400 } |
| 1395 } | 1401 } |
| 1396 | 1402 |
| 1397 | 1403 |
| 1398 void PartialSerializer::Serialize(Object** o) { | 1404 void PartialSerializer::Serialize(Object** o) { |
| 1399 if ((*o)->IsContext()) global_object_ = Context::cast(*o)->global_object(); | 1405 if ((*o)->IsContext()) { |
| 1406 Context* context = Context::cast(*o); |
| 1407 global_object_ = context->global_object(); |
| 1408 global_proxy_ = context->global_proxy(); |
| 1409 } |
| 1400 VisitPointer(o); | 1410 VisitPointer(o); |
| 1401 SerializeOutdatedContextsAsFixedArray(); | 1411 SerializeOutdatedContextsAsFixedArray(); |
| 1402 Pad(); | 1412 Pad(); |
| 1403 } | 1413 } |
| 1404 | 1414 |
| 1405 | 1415 |
| 1406 void PartialSerializer::SerializeOutdatedContextsAsFixedArray() { | 1416 void PartialSerializer::SerializeOutdatedContextsAsFixedArray() { |
| 1407 int length = outdated_contexts_.length(); | 1417 int length = outdated_contexts_.length(); |
| 1408 if (length == 0) { | 1418 if (length == 0) { |
| 1409 FixedArray* empty = isolate_->heap()->empty_fixed_array(); | 1419 FixedArray* empty = isolate_->heap()->empty_fixed_array(); |
| (...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1676 // If this is not the case you may have to add something to the root array. | 1686 // If this is not the case you may have to add something to the root array. |
| 1677 DCHECK(!startup_serializer_->back_reference_map()->Lookup(obj).is_valid()); | 1687 DCHECK(!startup_serializer_->back_reference_map()->Lookup(obj).is_valid()); |
| 1678 // All the internalized strings that the partial snapshot needs should be | 1688 // All the internalized strings that the partial snapshot needs should be |
| 1679 // either in the root table or in the partial snapshot cache. | 1689 // either in the root table or in the partial snapshot cache. |
| 1680 DCHECK(!obj->IsInternalizedString()); | 1690 DCHECK(!obj->IsInternalizedString()); |
| 1681 | 1691 |
| 1682 if (SerializeKnownObject(obj, how_to_code, where_to_point, skip)) return; | 1692 if (SerializeKnownObject(obj, how_to_code, where_to_point, skip)) return; |
| 1683 | 1693 |
| 1684 FlushSkip(skip); | 1694 FlushSkip(skip); |
| 1685 | 1695 |
| 1696 if (obj == global_proxy_) { |
| 1697 FlushSkip(skip); |
| 1698 DCHECK(how_to_code == kPlain && where_to_point == kStartOfObject); |
| 1699 sink_->Put(kAttachedReference + how_to_code + where_to_point, "Reference"); |
| 1700 sink_->PutInt(kGlobalProxyReference, "kGlobalProxyReferenceIndex"); |
| 1701 return; |
| 1702 } |
| 1703 |
| 1686 // Object has not yet been serialized. Serialize it here. | 1704 // Object has not yet been serialized. Serialize it here. |
| 1687 ObjectSerializer serializer(this, obj, sink_, how_to_code, where_to_point); | 1705 ObjectSerializer serializer(this, obj, sink_, how_to_code, where_to_point); |
| 1688 serializer.Serialize(); | 1706 serializer.Serialize(); |
| 1689 | 1707 |
| 1690 if (obj->IsContext() && | 1708 if (obj->IsContext() && |
| 1691 Context::cast(obj)->global_object() == global_object_) { | 1709 Context::cast(obj)->global_object() == global_object_) { |
| 1692 // Context refers to the current global object. This reference will | 1710 // Context refers to the current global object. This reference will |
| 1693 // become outdated after deserialization. | 1711 // become outdated after deserialization. |
| 1694 BackReference back_reference = back_reference_map_.Lookup(obj); | 1712 BackReference back_reference = back_reference_map_.Lookup(obj); |
| 1695 DCHECK(back_reference.is_valid()); | 1713 DCHECK(back_reference.is_valid()); |
| (...skipping 620 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2316 int index = 0; | 2334 int index = 0; |
| 2317 while (index < stub_keys_.length()) { | 2335 while (index < stub_keys_.length()) { |
| 2318 if (stub_keys_[index] == stub_key) return index; | 2336 if (stub_keys_[index] == stub_key) return index; |
| 2319 index++; | 2337 index++; |
| 2320 } | 2338 } |
| 2321 stub_keys_.Add(stub_key); | 2339 stub_keys_.Add(stub_key); |
| 2322 return index; | 2340 return index; |
| 2323 } | 2341 } |
| 2324 | 2342 |
| 2325 | 2343 |
| 2326 void CodeSerializer::SerializeSourceObject(HowToCode how_to_code, | |
| 2327 WhereToPoint where_to_point) { | |
| 2328 if (FLAG_trace_serializer) PrintF(" Encoding source object\n"); | |
| 2329 | |
| 2330 DCHECK(how_to_code == kPlain && where_to_point == kStartOfObject); | |
| 2331 sink_->Put(kAttachedReference + how_to_code + where_to_point, "Source"); | |
| 2332 sink_->PutInt(kSourceObjectIndex, "kSourceObjectIndex"); | |
| 2333 } | |
| 2334 | |
| 2335 | |
| 2336 MaybeHandle<SharedFunctionInfo> CodeSerializer::Deserialize( | 2344 MaybeHandle<SharedFunctionInfo> CodeSerializer::Deserialize( |
| 2337 Isolate* isolate, ScriptData* cached_data, Handle<String> source) { | 2345 Isolate* isolate, ScriptData* cached_data, Handle<String> source) { |
| 2338 base::ElapsedTimer timer; | 2346 base::ElapsedTimer timer; |
| 2339 if (FLAG_profile_deserialization) timer.Start(); | 2347 if (FLAG_profile_deserialization) timer.Start(); |
| 2340 | 2348 |
| 2341 HandleScope scope(isolate); | 2349 HandleScope scope(isolate); |
| 2342 | 2350 |
| 2343 SmartPointer<SerializedCodeData> scd( | 2351 SmartPointer<SerializedCodeData> scd( |
| 2344 SerializedCodeData::FromCachedData(cached_data, *source)); | 2352 SerializedCodeData::FromCachedData(cached_data, *source)); |
| 2345 if (scd.is_empty()) { | 2353 if (scd.is_empty()) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 2356 Vector<const uint32_t> code_stub_keys = scd->CodeStubKeys(); | 2364 Vector<const uint32_t> code_stub_keys = scd->CodeStubKeys(); |
| 2357 Vector<Handle<Object> > attached_objects = Vector<Handle<Object> >::New( | 2365 Vector<Handle<Object> > attached_objects = Vector<Handle<Object> >::New( |
| 2358 code_stub_keys.length() + kCodeStubsBaseIndex); | 2366 code_stub_keys.length() + kCodeStubsBaseIndex); |
| 2359 attached_objects[kSourceObjectIndex] = source; | 2367 attached_objects[kSourceObjectIndex] = source; |
| 2360 for (int i = 0; i < code_stub_keys.length(); i++) { | 2368 for (int i = 0; i < code_stub_keys.length(); i++) { |
| 2361 attached_objects[i + kCodeStubsBaseIndex] = | 2369 attached_objects[i + kCodeStubsBaseIndex] = |
| 2362 CodeStub::GetCode(isolate, code_stub_keys[i]).ToHandleChecked(); | 2370 CodeStub::GetCode(isolate, code_stub_keys[i]).ToHandleChecked(); |
| 2363 } | 2371 } |
| 2364 | 2372 |
| 2365 Deserializer deserializer(scd.get()); | 2373 Deserializer deserializer(scd.get()); |
| 2366 deserializer.SetAttachedObjects(&attached_objects); | 2374 deserializer.SetAttachedObjects(attached_objects); |
| 2367 | 2375 |
| 2368 // Deserialize. | 2376 // Deserialize. |
| 2369 Handle<SharedFunctionInfo> result; | 2377 Handle<SharedFunctionInfo> result; |
| 2370 if (!deserializer.DeserializeCode(isolate).ToHandle(&result)) { | 2378 if (!deserializer.DeserializeCode(isolate).ToHandle(&result)) { |
| 2371 // Deserializing may fail if the reservations cannot be fulfilled. | 2379 // Deserializing may fail if the reservations cannot be fulfilled. |
| 2372 if (FLAG_profile_deserialization) PrintF("[Deserializing failed]\n"); | 2380 if (FLAG_profile_deserialization) PrintF("[Deserializing failed]\n"); |
| 2373 return MaybeHandle<SharedFunctionInfo>(); | 2381 return MaybeHandle<SharedFunctionInfo>(); |
| 2374 } | 2382 } |
| 2375 deserializer.FlushICacheForNewCodeObjects(); | 2383 deserializer.FlushICacheForNewCodeObjects(); |
| 2376 | 2384 |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2538 return GetHeaderValue(kNumInternalizedStringsOffset); | 2546 return GetHeaderValue(kNumInternalizedStringsOffset); |
| 2539 } | 2547 } |
| 2540 | 2548 |
| 2541 Vector<const uint32_t> SerializedCodeData::CodeStubKeys() const { | 2549 Vector<const uint32_t> SerializedCodeData::CodeStubKeys() const { |
| 2542 int reservations_size = GetHeaderValue(kReservationsOffset) * kInt32Size; | 2550 int reservations_size = GetHeaderValue(kReservationsOffset) * kInt32Size; |
| 2543 const byte* start = data_ + kHeaderSize + reservations_size; | 2551 const byte* start = data_ + kHeaderSize + reservations_size; |
| 2544 return Vector<const uint32_t>(reinterpret_cast<const uint32_t*>(start), | 2552 return Vector<const uint32_t>(reinterpret_cast<const uint32_t*>(start), |
| 2545 GetHeaderValue(kNumCodeStubKeysOffset)); | 2553 GetHeaderValue(kNumCodeStubKeysOffset)); |
| 2546 } | 2554 } |
| 2547 } } // namespace v8::internal | 2555 } } // namespace v8::internal |
| OLD | NEW |