Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(283)

Side by Side Diff: src/snapshot/serialize.cc

Issue 1173013002: Deserializer: flush code objects in large object space. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/snapshot/serialize.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 498 matching lines...) Expand 10 before | Expand all | Expand 10 after
509 for (auto& r : res) { 509 for (auto& r : res) {
510 reservations_[current_space].Add({r.chunk_size(), NULL, NULL}); 510 reservations_[current_space].Add({r.chunk_size(), NULL, NULL});
511 if (r.is_last()) current_space++; 511 if (r.is_last()) current_space++;
512 } 512 }
513 DCHECK_EQ(kNumberOfSpaces, current_space); 513 DCHECK_EQ(kNumberOfSpaces, current_space);
514 for (int i = 0; i < kNumberOfPreallocatedSpaces; i++) current_chunk_[i] = 0; 514 for (int i = 0; i < kNumberOfPreallocatedSpaces; i++) current_chunk_[i] = 0;
515 } 515 }
516 516
517 517
518 void Deserializer::FlushICacheForNewCodeObjects() { 518 void Deserializer::FlushICacheForNewCodeObjects() {
519 PageIterator it(isolate_->heap()->code_space()); 519 if (!deserializing_user_code_) {
520 while (it.has_next()) { 520 // The entire isolate is newly deserialized. Simply flush all code pages.
521 Page* p = it.next(); 521 PageIterator it(isolate_->heap()->code_space());
522 CpuFeatures::FlushICache(p->area_start(), p->area_end() - p->area_start()); 522 while (it.has_next()) {
523 Page* p = it.next();
524 CpuFeatures::FlushICache(p->area_start(),
525 p->area_end() - p->area_start());
526 }
527 }
528 for (Code* code : new_code_objects_) {
529 CpuFeatures::FlushICache(code->instruction_start(),
530 code->instruction_size());
523 } 531 }
524 } 532 }
525 533
526 534
527 bool Deserializer::ReserveSpace() { 535 bool Deserializer::ReserveSpace() {
528 #ifdef DEBUG 536 #ifdef DEBUG
529 for (int i = NEW_SPACE; i < kNumberOfSpaces; ++i) { 537 for (int i = NEW_SPACE; i < kNumberOfSpaces; ++i) {
530 CHECK(reservations_[i].length() > 0); 538 CHECK(reservations_[i].length() > 0);
531 } 539 }
532 #endif // DEBUG 540 #endif // DEBUG
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
605 // Keep track of the code space start and end pointers in case new 613 // Keep track of the code space start and end pointers in case new
606 // code objects were unserialized 614 // code objects were unserialized
607 OldSpace* code_space = isolate_->heap()->code_space(); 615 OldSpace* code_space = isolate_->heap()->code_space();
608 Address start_address = code_space->top(); 616 Address start_address = code_space->top();
609 Object* root; 617 Object* root;
610 Object* outdated_contexts; 618 Object* outdated_contexts;
611 VisitPointer(&root); 619 VisitPointer(&root);
612 VisitPointer(&outdated_contexts); 620 VisitPointer(&outdated_contexts);
613 DeserializeDeferredObjects(); 621 DeserializeDeferredObjects();
614 622
615 // There's no code deserialized here. If this assert fires 623 // There's no code deserialized here. If this assert fires then that's
616 // then that's changed and logging should be added to notify 624 // changed and logging should be added to notify the profiler et al of the
617 // the profiler et al of the new code. 625 // new code, which also has to be flushed from instruction cache.
618 CHECK_EQ(start_address, code_space->top()); 626 CHECK_EQ(start_address, code_space->top());
619 CHECK(outdated_contexts->IsFixedArray()); 627 CHECK(outdated_contexts->IsFixedArray());
620 *outdated_contexts_out = 628 *outdated_contexts_out =
621 Handle<FixedArray>(FixedArray::cast(outdated_contexts), isolate); 629 Handle<FixedArray>(FixedArray::cast(outdated_contexts), isolate);
622 return Handle<Object>(root, isolate); 630 return Handle<Object>(root, isolate);
623 } 631 }
624 632
625 633
626 MaybeHandle<SharedFunctionInfo> Deserializer::DeserializeCode( 634 MaybeHandle<SharedFunctionInfo> Deserializer::DeserializeCode(
627 Isolate* isolate) { 635 Isolate* isolate) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
660 int space = code & kSpaceMask; 668 int space = code & kSpaceMask;
661 DCHECK(space <= kNumberOfSpaces); 669 DCHECK(space <= kNumberOfSpaces);
662 DCHECK(code - space == kNewObject); 670 DCHECK(code - space == kNewObject);
663 HeapObject* object = GetBackReferencedObject(space); 671 HeapObject* object = GetBackReferencedObject(space);
664 int size = source_.GetInt() << kPointerSizeLog2; 672 int size = source_.GetInt() << kPointerSizeLog2;
665 Address obj_address = object->address(); 673 Address obj_address = object->address();
666 Object** start = reinterpret_cast<Object**>(obj_address + kPointerSize); 674 Object** start = reinterpret_cast<Object**>(obj_address + kPointerSize);
667 Object** end = reinterpret_cast<Object**>(obj_address + size); 675 Object** end = reinterpret_cast<Object**>(obj_address + size);
668 bool filled = ReadData(start, end, space, obj_address); 676 bool filled = ReadData(start, end, space, obj_address);
669 CHECK(filled); 677 CHECK(filled);
670 if (object->IsAllocationSite()) { 678 DCHECK(CanBeDeferred(object));
671 RelinkAllocationSite(AllocationSite::cast(object)); 679 PostProcessNewObject(object, space);
672 }
673 } 680 }
674 } 681 }
675 682
676 683
677 // Used to insert a deserialized internalized string into the string table. 684 // Used to insert a deserialized internalized string into the string table.
678 class StringTableInsertionKey : public HashTableKey { 685 class StringTableInsertionKey : public HashTableKey {
679 public: 686 public:
680 explicit StringTableInsertionKey(String* string) 687 explicit StringTableInsertionKey(String* string)
681 : string_(string), hash_(HashForObject(string)) { 688 : string_(string), hash_(HashForObject(string)) {
682 DCHECK(string->IsInternalizedString()); 689 DCHECK(string->IsInternalizedString());
(...skipping 15 matching lines...) Expand all
698 705
699 MUST_USE_RESULT virtual Handle<Object> AsHandle(Isolate* isolate) override { 706 MUST_USE_RESULT virtual Handle<Object> AsHandle(Isolate* isolate) override {
700 return handle(string_, isolate); 707 return handle(string_, isolate);
701 } 708 }
702 709
703 String* string_; 710 String* string_;
704 uint32_t hash_; 711 uint32_t hash_;
705 }; 712 };
706 713
707 714
708 HeapObject* Deserializer::PostProcessNewObject(HeapObject* obj) { 715 HeapObject* Deserializer::PostProcessNewObject(HeapObject* obj, int space) {
709 DCHECK(deserializing_user_code()); 716 if (deserializing_user_code()) {
710 if (obj->IsString()) { 717 if (obj->IsString()) {
711 String* string = String::cast(obj); 718 String* string = String::cast(obj);
712 // Uninitialize hash field as the hash seed may have changed. 719 // Uninitialize hash field as the hash seed may have changed.
713 string->set_hash_field(String::kEmptyHashField); 720 string->set_hash_field(String::kEmptyHashField);
714 if (string->IsInternalizedString()) { 721 if (string->IsInternalizedString()) {
715 DisallowHeapAllocation no_gc; 722 // Canonicalize the internalized string. If it already exists in the
716 HandleScope scope(isolate_); 723 // string table, set it to forward to the existing one.
717 StringTableInsertionKey key(string); 724 DisallowHeapAllocation no_gc;
718 String* canonical = *StringTable::LookupKey(isolate_, &key); 725 HandleScope scope(isolate_);
719 string->SetForwardedInternalizedString(canonical); 726 StringTableInsertionKey key(string);
720 return canonical; 727 String* canonical = *StringTable::LookupKey(isolate_, &key);
728 string->SetForwardedInternalizedString(canonical);
729 return canonical;
730 }
731 } else if (obj->IsScript()) {
732 // Assign a new script id to avoid collision.
733 Script::cast(obj)->set_id(isolate_->heap()->NextScriptId());
734 } else {
735 DCHECK(CanBeDeferred(obj));
721 } 736 }
722 } else if (obj->IsScript()) { 737 }
723 Script::cast(obj)->set_id(isolate_->heap()->NextScriptId()); 738 if (obj->IsAllocationSite()) {
724 } else { 739 DCHECK(obj->IsAllocationSite());
725 DCHECK(CanBeDeferred(obj)); 740 // Allocation sites are present in the snapshot, and must be linked into
741 // a list at deserialization time.
742 AllocationSite* site = AllocationSite::cast(obj);
743 // TODO(mvstanton): consider treating the heap()->allocation_sites_list()
744 // as a (weak) root. If this root is relocated correctly, this becomes
745 // unnecessary.
746 if (isolate_->heap()->allocation_sites_list() == Smi::FromInt(0)) {
747 site->set_weak_next(isolate_->heap()->undefined_value());
748 } else {
749 site->set_weak_next(isolate_->heap()->allocation_sites_list());
750 }
751 isolate_->heap()->set_allocation_sites_list(site);
752 } else if (obj->IsCode()) {
753 // We flush all code pages after deserializing the startup snapshot. In that
754 // case, we only need to remember code objects in the large object space.
755 // When deserializing user code, remember each individual code object.
756 if (deserializing_user_code() || space == LO_SPACE) {
757 new_code_objects_.Add(Code::cast(obj));
758 }
726 } 759 }
727 return obj; 760 return obj;
728 } 761 }
729 762
730 763
731 void Deserializer::RelinkAllocationSite(AllocationSite* obj) {
732 DCHECK(obj->IsAllocationSite());
733 // Allocation sites are present in the snapshot, and must be linked into
734 // a list at deserialization time.
735 AllocationSite* site = AllocationSite::cast(obj);
736 // TODO(mvstanton): consider treating the heap()->allocation_sites_list()
737 // as a (weak) root. If this root is relocated correctly,
738 // RelinkAllocationSite() isn't necessary.
739 if (isolate_->heap()->allocation_sites_list() == Smi::FromInt(0)) {
740 site->set_weak_next(isolate_->heap()->undefined_value());
741 } else {
742 site->set_weak_next(isolate_->heap()->allocation_sites_list());
743 }
744 isolate_->heap()->set_allocation_sites_list(site);
745 }
746
747
748 HeapObject* Deserializer::GetBackReferencedObject(int space) { 764 HeapObject* Deserializer::GetBackReferencedObject(int space) {
749 HeapObject* obj; 765 HeapObject* obj;
750 BackReference back_reference(source_.GetInt()); 766 BackReference back_reference(source_.GetInt());
751 if (space == LO_SPACE) { 767 if (space == LO_SPACE) {
752 CHECK(back_reference.chunk_index() == 0); 768 CHECK(back_reference.chunk_index() == 0);
753 uint32_t index = back_reference.large_object_index(); 769 uint32_t index = back_reference.large_object_index();
754 obj = deserialized_large_objects_[index]; 770 obj = deserialized_large_objects_[index];
755 } else { 771 } else {
756 DCHECK(space < kNumberOfPreallocatedSpaces); 772 DCHECK(space < kNumberOfPreallocatedSpaces);
757 uint32_t chunk_index = back_reference.chunk_index(); 773 uint32_t chunk_index = back_reference.chunk_index();
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
796 812
797 isolate_->heap()->OnAllocationEvent(obj, size); 813 isolate_->heap()->OnAllocationEvent(obj, size);
798 Object** current = reinterpret_cast<Object**>(address); 814 Object** current = reinterpret_cast<Object**>(address);
799 Object** limit = current + (size >> kPointerSizeLog2); 815 Object** limit = current + (size >> kPointerSizeLog2);
800 if (FLAG_log_snapshot_positions) { 816 if (FLAG_log_snapshot_positions) {
801 LOG(isolate_, SnapshotPositionEvent(address, source_.position())); 817 LOG(isolate_, SnapshotPositionEvent(address, source_.position()));
802 } 818 }
803 819
804 if (ReadData(current, limit, space_number, address)) { 820 if (ReadData(current, limit, space_number, address)) {
805 // Only post process if object content has not been deferred. 821 // Only post process if object content has not been deferred.
806 if (obj->IsAllocationSite()) { 822 obj = PostProcessNewObject(obj, space_number);
807 RelinkAllocationSite(AllocationSite::cast(obj));
808 }
809
810 if (deserializing_user_code()) obj = PostProcessNewObject(obj);
811 } 823 }
812 824
813 Object* write_back_obj = obj; 825 Object* write_back_obj = obj;
814 UnalignedCopy(write_back, &write_back_obj); 826 UnalignedCopy(write_back, &write_back_obj);
815 #ifdef DEBUG 827 #ifdef DEBUG
816 if (obj->IsCode()) { 828 if (obj->IsCode()) {
817 DCHECK(space_number == CODE_SPACE || space_number == LO_SPACE); 829 DCHECK(space_number == CODE_SPACE || space_number == LO_SPACE);
818 } else { 830 } else {
819 DCHECK(space_number != CODE_SPACE); 831 DCHECK(space_number != CODE_SPACE);
820 } 832 }
(...skipping 1857 matching lines...) Expand 10 before | Expand all | Expand 10 after
2678 SerializedCodeData* scd = new SerializedCodeData(cached_data); 2690 SerializedCodeData* scd = new SerializedCodeData(cached_data);
2679 SanityCheckResult r = scd->SanityCheck(isolate, source); 2691 SanityCheckResult r = scd->SanityCheck(isolate, source);
2680 if (r == CHECK_SUCCESS) return scd; 2692 if (r == CHECK_SUCCESS) return scd;
2681 cached_data->Reject(); 2693 cached_data->Reject();
2682 source->GetIsolate()->counters()->code_cache_reject_reason()->AddSample(r); 2694 source->GetIsolate()->counters()->code_cache_reject_reason()->AddSample(r);
2683 delete scd; 2695 delete scd;
2684 return NULL; 2696 return NULL;
2685 } 2697 }
2686 } // namespace internal 2698 } // namespace internal
2687 } // namespace v8 2699 } // namespace v8
OLDNEW
« no previous file with comments | « src/snapshot/serialize.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698