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 624 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
635 } | 635 } |
636 | 636 |
637 | 637 |
638 MaybeHandle<SharedFunctionInfo> Deserializer::DeserializeCode( | 638 MaybeHandle<SharedFunctionInfo> Deserializer::DeserializeCode( |
639 Isolate* isolate) { | 639 Isolate* isolate) { |
640 Initialize(isolate); | 640 Initialize(isolate); |
641 if (!ReserveSpace()) { | 641 if (!ReserveSpace()) { |
642 return Handle<SharedFunctionInfo>(); | 642 return Handle<SharedFunctionInfo>(); |
643 } else { | 643 } else { |
644 deserializing_user_code_ = true; | 644 deserializing_user_code_ = true; |
645 DisallowHeapAllocation no_gc; | 645 HandleScope scope(isolate); |
646 Object* root; | 646 Handle<SharedFunctionInfo> result; |
647 VisitPointer(&root); | 647 { |
648 DeserializeDeferredObjects(); | 648 DisallowHeapAllocation no_gc; |
649 return Handle<SharedFunctionInfo>(SharedFunctionInfo::cast(root)); | 649 Object* root; |
| 650 VisitPointer(&root); |
| 651 DeserializeDeferredObjects(); |
| 652 result = Handle<SharedFunctionInfo>(SharedFunctionInfo::cast(root)); |
| 653 } |
| 654 CommitNewInternalizedStrings(isolate); |
| 655 return scope.CloseAndEscape(result); |
650 } | 656 } |
651 } | 657 } |
652 | 658 |
653 | 659 |
654 Deserializer::~Deserializer() { | 660 Deserializer::~Deserializer() { |
655 // TODO(svenpanne) Re-enable this assertion when v8 initialization is fixed. | 661 // TODO(svenpanne) Re-enable this assertion when v8 initialization is fixed. |
656 // DCHECK(source_.AtEOF()); | 662 // DCHECK(source_.AtEOF()); |
657 attached_objects_.Dispose(); | 663 attached_objects_.Dispose(); |
658 } | 664 } |
659 | 665 |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
704 uint32_t Hash() override { return hash_; } | 710 uint32_t Hash() override { return hash_; } |
705 | 711 |
706 uint32_t HashForObject(Object* key) override { | 712 uint32_t HashForObject(Object* key) override { |
707 return String::cast(key)->Hash(); | 713 return String::cast(key)->Hash(); |
708 } | 714 } |
709 | 715 |
710 MUST_USE_RESULT virtual Handle<Object> AsHandle(Isolate* isolate) override { | 716 MUST_USE_RESULT virtual Handle<Object> AsHandle(Isolate* isolate) override { |
711 return handle(string_, isolate); | 717 return handle(string_, isolate); |
712 } | 718 } |
713 | 719 |
| 720 private: |
714 String* string_; | 721 String* string_; |
715 uint32_t hash_; | 722 uint32_t hash_; |
| 723 DisallowHeapAllocation no_gc; |
716 }; | 724 }; |
717 | 725 |
718 | 726 |
719 HeapObject* Deserializer::PostProcessNewObject(HeapObject* obj, int space) { | 727 HeapObject* Deserializer::PostProcessNewObject(HeapObject* obj, int space) { |
720 if (deserializing_user_code()) { | 728 if (deserializing_user_code()) { |
721 if (obj->IsString()) { | 729 if (obj->IsString()) { |
722 String* string = String::cast(obj); | 730 String* string = String::cast(obj); |
723 // Uninitialize hash field as the hash seed may have changed. | 731 // Uninitialize hash field as the hash seed may have changed. |
724 string->set_hash_field(String::kEmptyHashField); | 732 string->set_hash_field(String::kEmptyHashField); |
725 if (string->IsInternalizedString()) { | 733 if (string->IsInternalizedString()) { |
726 // Canonicalize the internalized string. If it already exists in the | 734 // Canonicalize the internalized string. If it already exists in the |
727 // string table, set it to forward to the existing one. | 735 // string table, set it to forward to the existing one. |
728 DisallowHeapAllocation no_gc; | |
729 HandleScope scope(isolate_); | |
730 StringTableInsertionKey key(string); | 736 StringTableInsertionKey key(string); |
731 String* canonical = *StringTable::LookupKey(isolate_, &key); | 737 String* canonical = StringTable::LookupKeyIfExists(isolate_, &key); |
732 string->SetForwardedInternalizedString(canonical); | 738 if (canonical == NULL) { |
733 return canonical; | 739 new_internalized_strings_.Add(handle(string)); |
| 740 return string; |
| 741 } else { |
| 742 string->SetForwardedInternalizedString(canonical); |
| 743 return canonical; |
| 744 } |
734 } | 745 } |
735 } else if (obj->IsScript()) { | 746 } else if (obj->IsScript()) { |
736 // Assign a new script id to avoid collision. | 747 // Assign a new script id to avoid collision. |
737 Script::cast(obj)->set_id(isolate_->heap()->NextScriptId()); | 748 Script::cast(obj)->set_id(isolate_->heap()->NextScriptId()); |
738 } else { | 749 } else { |
739 DCHECK(CanBeDeferred(obj)); | 750 DCHECK(CanBeDeferred(obj)); |
740 } | 751 } |
741 } | 752 } |
742 if (obj->IsAllocationSite()) { | 753 if (obj->IsAllocationSite()) { |
743 DCHECK(obj->IsAllocationSite()); | 754 DCHECK(obj->IsAllocationSite()); |
(...skipping 16 matching lines...) Expand all Loading... |
760 if (deserializing_user_code() || space == LO_SPACE) { | 771 if (deserializing_user_code() || space == LO_SPACE) { |
761 new_code_objects_.Add(Code::cast(obj)); | 772 new_code_objects_.Add(Code::cast(obj)); |
762 } | 773 } |
763 } | 774 } |
764 // Check alignment. | 775 // Check alignment. |
765 DCHECK_EQ(0, Heap::GetFillToAlign(obj->address(), obj->RequiredAlignment())); | 776 DCHECK_EQ(0, Heap::GetFillToAlign(obj->address(), obj->RequiredAlignment())); |
766 return obj; | 777 return obj; |
767 } | 778 } |
768 | 779 |
769 | 780 |
| 781 void Deserializer::CommitNewInternalizedStrings(Isolate* isolate) { |
| 782 StringTable::EnsureCapacityForDeserialization( |
| 783 isolate, new_internalized_strings_.length()); |
| 784 for (Handle<String> string : new_internalized_strings_) { |
| 785 StringTableInsertionKey key(*string); |
| 786 DCHECK_NULL(StringTable::LookupKeyIfExists(isolate, &key)); |
| 787 StringTable::LookupKey(isolate, &key); |
| 788 } |
| 789 } |
| 790 |
| 791 |
770 HeapObject* Deserializer::GetBackReferencedObject(int space) { | 792 HeapObject* Deserializer::GetBackReferencedObject(int space) { |
771 HeapObject* obj; | 793 HeapObject* obj; |
772 BackReference back_reference(source_.GetInt()); | 794 BackReference back_reference(source_.GetInt()); |
773 if (space == LO_SPACE) { | 795 if (space == LO_SPACE) { |
774 CHECK(back_reference.chunk_index() == 0); | 796 CHECK(back_reference.chunk_index() == 0); |
775 uint32_t index = back_reference.large_object_index(); | 797 uint32_t index = back_reference.large_object_index(); |
776 obj = deserialized_large_objects_[index]; | 798 obj = deserialized_large_objects_[index]; |
777 } else { | 799 } else { |
778 DCHECK(space < kNumberOfPreallocatedSpaces); | 800 DCHECK(space < kNumberOfPreallocatedSpaces); |
779 uint32_t chunk_index = back_reference.chunk_index(); | 801 uint32_t chunk_index = back_reference.chunk_index(); |
(...skipping 1561 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2341 // We expect no instantiated function objects or contexts. | 2363 // We expect no instantiated function objects or contexts. |
2342 CHECK(!obj->IsJSFunction() && !obj->IsContext()); | 2364 CHECK(!obj->IsJSFunction() && !obj->IsContext()); |
2343 | 2365 |
2344 SerializeGeneric(obj, how_to_code, where_to_point); | 2366 SerializeGeneric(obj, how_to_code, where_to_point); |
2345 } | 2367 } |
2346 | 2368 |
2347 | 2369 |
2348 void CodeSerializer::SerializeGeneric(HeapObject* heap_object, | 2370 void CodeSerializer::SerializeGeneric(HeapObject* heap_object, |
2349 HowToCode how_to_code, | 2371 HowToCode how_to_code, |
2350 WhereToPoint where_to_point) { | 2372 WhereToPoint where_to_point) { |
2351 if (heap_object->IsInternalizedString()) num_internalized_strings_++; | |
2352 | |
2353 // Object has not yet been serialized. Serialize it here. | 2373 // Object has not yet been serialized. Serialize it here. |
2354 ObjectSerializer serializer(this, heap_object, sink_, how_to_code, | 2374 ObjectSerializer serializer(this, heap_object, sink_, how_to_code, |
2355 where_to_point); | 2375 where_to_point); |
2356 serializer.Serialize(); | 2376 serializer.Serialize(); |
2357 } | 2377 } |
2358 | 2378 |
2359 | 2379 |
2360 void CodeSerializer::SerializeBuiltin(int builtin_index, HowToCode how_to_code, | 2380 void CodeSerializer::SerializeBuiltin(int builtin_index, HowToCode how_to_code, |
2361 WhereToPoint where_to_point) { | 2381 WhereToPoint where_to_point) { |
2362 DCHECK((how_to_code == kPlain && where_to_point == kStartOfObject) || | 2382 DCHECK((how_to_code == kPlain && where_to_point == kStartOfObject) || |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2464 // Prepare and register list of attached objects. | 2484 // Prepare and register list of attached objects. |
2465 Vector<const uint32_t> code_stub_keys = scd->CodeStubKeys(); | 2485 Vector<const uint32_t> code_stub_keys = scd->CodeStubKeys(); |
2466 Vector<Handle<Object> > attached_objects = Vector<Handle<Object> >::New( | 2486 Vector<Handle<Object> > attached_objects = Vector<Handle<Object> >::New( |
2467 code_stub_keys.length() + kCodeStubsBaseIndex); | 2487 code_stub_keys.length() + kCodeStubsBaseIndex); |
2468 attached_objects[kSourceObjectIndex] = source; | 2488 attached_objects[kSourceObjectIndex] = source; |
2469 for (int i = 0; i < code_stub_keys.length(); i++) { | 2489 for (int i = 0; i < code_stub_keys.length(); i++) { |
2470 attached_objects[i + kCodeStubsBaseIndex] = | 2490 attached_objects[i + kCodeStubsBaseIndex] = |
2471 CodeStub::GetCode(isolate, code_stub_keys[i]).ToHandleChecked(); | 2491 CodeStub::GetCode(isolate, code_stub_keys[i]).ToHandleChecked(); |
2472 } | 2492 } |
2473 | 2493 |
2474 // Eagerly expand string table to avoid allocations during deserialization. | |
2475 StringTable::EnsureCapacityForDeserialization(isolate, | |
2476 scd->NumInternalizedStrings()); | |
2477 | |
2478 Deserializer deserializer(scd.get()); | 2494 Deserializer deserializer(scd.get()); |
2479 deserializer.SetAttachedObjects(attached_objects); | 2495 deserializer.SetAttachedObjects(attached_objects); |
2480 | 2496 |
2481 // Deserialize. | 2497 // Deserialize. |
2482 Handle<SharedFunctionInfo> result; | 2498 Handle<SharedFunctionInfo> result; |
2483 if (!deserializer.DeserializeCode(isolate).ToHandle(&result)) { | 2499 if (!deserializer.DeserializeCode(isolate).ToHandle(&result)) { |
2484 // Deserializing may fail if the reservations cannot be fulfilled. | 2500 // Deserializing may fail if the reservations cannot be fulfilled. |
2485 if (FLAG_profile_deserialization) PrintF("[Deserializing failed]\n"); | 2501 if (FLAG_profile_deserialization) PrintF("[Deserializing failed]\n"); |
2486 return MaybeHandle<SharedFunctionInfo>(); | 2502 return MaybeHandle<SharedFunctionInfo>(); |
2487 } | 2503 } |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2626 // Allocate backing store and create result data. | 2642 // Allocate backing store and create result data. |
2627 AllocateData(size); | 2643 AllocateData(size); |
2628 | 2644 |
2629 // Set header values. | 2645 // Set header values. |
2630 SetMagicNumber(cs.isolate()); | 2646 SetMagicNumber(cs.isolate()); |
2631 SetHeaderValue(kVersionHashOffset, Version::Hash()); | 2647 SetHeaderValue(kVersionHashOffset, Version::Hash()); |
2632 SetHeaderValue(kSourceHashOffset, SourceHash(cs.source())); | 2648 SetHeaderValue(kSourceHashOffset, SourceHash(cs.source())); |
2633 SetHeaderValue(kCpuFeaturesOffset, | 2649 SetHeaderValue(kCpuFeaturesOffset, |
2634 static_cast<uint32_t>(CpuFeatures::SupportedFeatures())); | 2650 static_cast<uint32_t>(CpuFeatures::SupportedFeatures())); |
2635 SetHeaderValue(kFlagHashOffset, FlagList::Hash()); | 2651 SetHeaderValue(kFlagHashOffset, FlagList::Hash()); |
2636 SetHeaderValue(kNumInternalizedStringsOffset, cs.num_internalized_strings()); | |
2637 SetHeaderValue(kNumReservationsOffset, reservations.length()); | 2652 SetHeaderValue(kNumReservationsOffset, reservations.length()); |
2638 SetHeaderValue(kNumCodeStubKeysOffset, num_stub_keys); | 2653 SetHeaderValue(kNumCodeStubKeysOffset, num_stub_keys); |
2639 SetHeaderValue(kPayloadLengthOffset, payload.length()); | 2654 SetHeaderValue(kPayloadLengthOffset, payload.length()); |
2640 | 2655 |
2641 Checksum checksum(payload.ToConstVector()); | 2656 Checksum checksum(payload.ToConstVector()); |
2642 SetHeaderValue(kChecksum1Offset, checksum.a()); | 2657 SetHeaderValue(kChecksum1Offset, checksum.a()); |
2643 SetHeaderValue(kChecksum2Offset, checksum.b()); | 2658 SetHeaderValue(kChecksum2Offset, checksum.b()); |
2644 | 2659 |
2645 // Copy reservation chunk sizes. | 2660 // Copy reservation chunk sizes. |
2646 CopyBytes(data_ + kHeaderSize, reinterpret_cast<byte*>(reservations.begin()), | 2661 CopyBytes(data_ + kHeaderSize, reinterpret_cast<byte*>(reservations.begin()), |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2704 int payload_offset = kHeaderSize + reservations_size + code_stubs_size; | 2719 int payload_offset = kHeaderSize + reservations_size + code_stubs_size; |
2705 int padded_payload_offset = POINTER_SIZE_ALIGN(payload_offset); | 2720 int padded_payload_offset = POINTER_SIZE_ALIGN(payload_offset); |
2706 const byte* payload = data_ + padded_payload_offset; | 2721 const byte* payload = data_ + padded_payload_offset; |
2707 DCHECK(IsAligned(reinterpret_cast<intptr_t>(payload), kPointerAlignment)); | 2722 DCHECK(IsAligned(reinterpret_cast<intptr_t>(payload), kPointerAlignment)); |
2708 int length = GetHeaderValue(kPayloadLengthOffset); | 2723 int length = GetHeaderValue(kPayloadLengthOffset); |
2709 DCHECK_EQ(data_ + size_, payload + length); | 2724 DCHECK_EQ(data_ + size_, payload + length); |
2710 return Vector<const byte>(payload, length); | 2725 return Vector<const byte>(payload, length); |
2711 } | 2726 } |
2712 | 2727 |
2713 | 2728 |
2714 int SerializedCodeData::NumInternalizedStrings() const { | |
2715 return GetHeaderValue(kNumInternalizedStringsOffset); | |
2716 } | |
2717 | |
2718 Vector<const uint32_t> SerializedCodeData::CodeStubKeys() const { | 2729 Vector<const uint32_t> SerializedCodeData::CodeStubKeys() const { |
2719 int reservations_size = GetHeaderValue(kNumReservationsOffset) * kInt32Size; | 2730 int reservations_size = GetHeaderValue(kNumReservationsOffset) * kInt32Size; |
2720 const byte* start = data_ + kHeaderSize + reservations_size; | 2731 const byte* start = data_ + kHeaderSize + reservations_size; |
2721 return Vector<const uint32_t>(reinterpret_cast<const uint32_t*>(start), | 2732 return Vector<const uint32_t>(reinterpret_cast<const uint32_t*>(start), |
2722 GetHeaderValue(kNumCodeStubKeysOffset)); | 2733 GetHeaderValue(kNumCodeStubKeysOffset)); |
2723 } | 2734 } |
2724 | 2735 |
2725 | 2736 |
2726 SerializedCodeData::SerializedCodeData(ScriptData* data) | 2737 SerializedCodeData::SerializedCodeData(ScriptData* data) |
2727 : SerializedData(const_cast<byte*>(data->data()), data->length()) {} | 2738 : SerializedData(const_cast<byte*>(data->data()), data->length()) {} |
2728 | 2739 |
2729 | 2740 |
2730 SerializedCodeData* SerializedCodeData::FromCachedData(Isolate* isolate, | 2741 SerializedCodeData* SerializedCodeData::FromCachedData(Isolate* isolate, |
2731 ScriptData* cached_data, | 2742 ScriptData* cached_data, |
2732 String* source) { | 2743 String* source) { |
2733 DisallowHeapAllocation no_gc; | 2744 DisallowHeapAllocation no_gc; |
2734 SerializedCodeData* scd = new SerializedCodeData(cached_data); | 2745 SerializedCodeData* scd = new SerializedCodeData(cached_data); |
2735 SanityCheckResult r = scd->SanityCheck(isolate, source); | 2746 SanityCheckResult r = scd->SanityCheck(isolate, source); |
2736 if (r == CHECK_SUCCESS) return scd; | 2747 if (r == CHECK_SUCCESS) return scd; |
2737 cached_data->Reject(); | 2748 cached_data->Reject(); |
2738 source->GetIsolate()->counters()->code_cache_reject_reason()->AddSample(r); | 2749 source->GetIsolate()->counters()->code_cache_reject_reason()->AddSample(r); |
2739 delete scd; | 2750 delete scd; |
2740 return NULL; | 2751 return NULL; |
2741 } | 2752 } |
2742 } // namespace internal | 2753 } // namespace internal |
2743 } // namespace v8 | 2754 } // namespace v8 |
OLD | NEW |