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