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

Side by Side Diff: src/objects.cc

Issue 1435313002: Refactor dependent code. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix compactions Created 5 years, 1 month 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
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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/objects.h" 5 #include "src/objects.h"
6 6
7 #include <cmath> 7 #include <cmath>
8 #include <iomanip> 8 #include <iomanip>
9 #include <sstream> 9 #include <sstream>
10 10
(...skipping 13625 matching lines...) Expand 10 before | Expand all | Expand 10 after
13636 void Map::AddDependentCode(Handle<Map> map, 13636 void Map::AddDependentCode(Handle<Map> map,
13637 DependentCode::DependencyGroup group, 13637 DependentCode::DependencyGroup group,
13638 Handle<Code> code) { 13638 Handle<Code> code) {
13639 Handle<WeakCell> cell = Code::WeakCellFor(code); 13639 Handle<WeakCell> cell = Code::WeakCellFor(code);
13640 Handle<DependentCode> codes = DependentCode::InsertWeakCode( 13640 Handle<DependentCode> codes = DependentCode::InsertWeakCode(
13641 Handle<DependentCode>(map->dependent_code()), group, cell); 13641 Handle<DependentCode>(map->dependent_code()), group, cell);
13642 if (*codes != map->dependent_code()) map->set_dependent_code(*codes); 13642 if (*codes != map->dependent_code()) map->set_dependent_code(*codes);
13643 } 13643 }
13644 13644
13645 13645
13646 DependentCode::GroupStartIndexes::GroupStartIndexes(DependentCode* entries) {
13647 Recompute(entries);
13648 }
13649
13650
13651 void DependentCode::GroupStartIndexes::Recompute(DependentCode* entries) {
13652 start_indexes_[0] = 0;
13653 for (int g = 1; g <= kGroupCount; g++) {
13654 int count = entries->number_of_entries(static_cast<DependencyGroup>(g - 1));
13655 start_indexes_[g] = start_indexes_[g - 1] + count;
13656 }
13657 }
13658
13659
13660 Handle<DependentCode> DependentCode::InsertCompilationDependencies( 13646 Handle<DependentCode> DependentCode::InsertCompilationDependencies(
13661 Handle<DependentCode> entries, DependencyGroup group, 13647 Handle<DependentCode> entries, DependencyGroup group,
13662 Handle<Foreign> info) { 13648 Handle<Foreign> info) {
13663 return Insert(entries, group, info); 13649 return Insert(entries, group, info);
13664 } 13650 }
13665 13651
13666 13652
13667 Handle<DependentCode> DependentCode::InsertWeakCode( 13653 Handle<DependentCode> DependentCode::InsertWeakCode(
13668 Handle<DependentCode> entries, DependencyGroup group, 13654 Handle<DependentCode> entries, DependencyGroup group,
13669 Handle<WeakCell> code_cell) { 13655 Handle<WeakCell> code_cell) {
13670 return Insert(entries, group, code_cell); 13656 return Insert(entries, group, code_cell);
13671 } 13657 }
13672 13658
13673 13659
13674 Handle<DependentCode> DependentCode::Insert(Handle<DependentCode> entries, 13660 Handle<DependentCode> DependentCode::Insert(Handle<DependentCode> entries,
13675 DependencyGroup group, 13661 DependencyGroup group,
13676 Handle<Object> object) { 13662 Handle<Object> object) {
13677 GroupStartIndexes starts(*entries); 13663 if (entries->length() == 0 || entries->group() > group) {
13678 int start = starts.at(group); 13664 // There is no such group.
13679 int end = starts.at(group + 1); 13665 return DependentCode::New(group, object, entries);
13680 int number_of_entries = starts.number_of_entries(); 13666 }
13667 if (entries->group() < group) {
13668 // The group comes later in the list.
13669 Handle<DependentCode> old_next(entries->next_link());
13670 Handle<DependentCode> new_next = Insert(old_next, group, object);
13671 if (!old_next.is_identical_to(new_next)) {
13672 entries->set_next_link(*new_next);
13673 }
13674 return entries;
13675 }
13676 DCHECK_EQ(group, entries->group());
13677 int count = entries->count();
13681 // Check for existing entry to avoid duplicates. 13678 // Check for existing entry to avoid duplicates.
13682 for (int i = start; i < end; i++) { 13679 for (int i = 0; i < count; i++) {
13683 if (entries->object_at(i) == *object) return entries; 13680 if (entries->object_at(i) == *object) return entries;
13684 } 13681 }
13685 if (entries->length() < kCodesStartIndex + number_of_entries + 1) { 13682 if (entries->length() < kCodesStartIndex + count + 1) {
13686 entries = EnsureSpace(entries); 13683 entries = EnsureSpace(entries);
13687 // The number of codes can change after Compact and GC. 13684 // Count could have changed, reload it.
13688 starts.Recompute(*entries); 13685 count = entries->count();
13689 start = starts.at(group);
13690 end = starts.at(group + 1);
13691 } 13686 }
13687 entries->set_object_at(count, *object);
13688 entries->set_count(count + 1);
13689 return entries;
13690 }
13692 13691
13693 entries->ExtendGroup(group); 13692
13694 entries->set_object_at(end, *object); 13693 Handle<DependentCode> DependentCode::New(DependencyGroup group,
13695 entries->set_number_of_entries(group, end + 1 - start); 13694 Handle<Object> object,
13696 return entries; 13695 Handle<DependentCode> next) {
13696 Isolate* isolate = next->GetIsolate();
13697 Handle<DependentCode> result = Handle<DependentCode>::cast(
13698 isolate->factory()->NewFixedArray(kCodesStartIndex + 1, TENURED));
13699 result->set_next_link(*next);
13700 result->set_flags(GroupField::encode(group) | CountField::encode(1));
13701 result->set_object_at(0, *object);
13702 return result;
13697 } 13703 }
13698 13704
13699 13705
13700 Handle<DependentCode> DependentCode::EnsureSpace( 13706 Handle<DependentCode> DependentCode::EnsureSpace(
13701 Handle<DependentCode> entries) { 13707 Handle<DependentCode> entries) {
13708 if (entries->Compact()) return entries;
13702 Isolate* isolate = entries->GetIsolate(); 13709 Isolate* isolate = entries->GetIsolate();
13703 if (entries->length() == 0) { 13710 int capacity = kCodesStartIndex + DependentCode::Grow(entries->count());
13704 entries = Handle<DependentCode>::cast(
13705 isolate->factory()->NewFixedArray(kCodesStartIndex + 1, TENURED));
13706 for (int g = 0; g < kGroupCount; g++) {
13707 entries->set_number_of_entries(static_cast<DependencyGroup>(g), 0);
13708 }
13709 return entries;
13710 }
13711 if (entries->Compact()) return entries;
13712 GroupStartIndexes starts(*entries);
13713 int capacity =
13714 kCodesStartIndex + DependentCode::Grow(starts.number_of_entries());
13715 int grow_by = capacity - entries->length(); 13711 int grow_by = capacity - entries->length();
13716 return Handle<DependentCode>::cast( 13712 return Handle<DependentCode>::cast(
13717 isolate->factory()->CopyFixedArrayAndGrow(entries, grow_by, TENURED)); 13713 isolate->factory()->CopyFixedArrayAndGrow(entries, grow_by, TENURED));
13718 } 13714 }
13719 13715
13720 13716
13721 bool DependentCode::Compact() { 13717 bool DependentCode::Compact() {
13722 GroupStartIndexes starts(this); 13718 int old_count = count();
13723 int n = 0; 13719 int new_count = 0;
13724 for (int g = 0; g < kGroupCount; g++) { 13720 for (int i = 0; i < old_count; i++) {
13725 int start = starts.at(g); 13721 Object* obj = object_at(i);
13726 int end = starts.at(g + 1); 13722 if (!obj->IsWeakCell() || !WeakCell::cast(obj)->cleared()) {
13727 int count = 0; 13723 if (i != new_count) {
13728 DCHECK(start >= n); 13724 copy(i, new_count);
13729 for (int i = start; i < end; i++) {
13730 Object* obj = object_at(i);
13731 if (!obj->IsWeakCell() || !WeakCell::cast(obj)->cleared()) {
13732 if (i != n + count) {
13733 copy(i, n + count);
13734 }
13735 count++;
13736 } 13725 }
13726 new_count++;
13737 } 13727 }
13738 if (count != end - start) {
13739 set_number_of_entries(static_cast<DependencyGroup>(g), count);
13740 }
13741 n += count;
13742 } 13728 }
13743 return n < starts.number_of_entries(); 13729 set_count(new_count);
13730 for (int i = new_count; i < old_count; i++) {
13731 clear_at(i);
13732 }
13733 return new_count < old_count;
13744 } 13734 }
13745 13735
13746 13736
13747 void DependentCode::UpdateToFinishedCode(DependencyGroup group, Foreign* info, 13737 void DependentCode::UpdateToFinishedCode(DependencyGroup group, Foreign* info,
13748 WeakCell* code_cell) { 13738 WeakCell* code_cell) {
13739 DCHECK_LE(this->group(), group);
Igor Sheludko 2015/11/20 12:35:32 I think this check is redundant, given that we hav
ulan 2015/11/23 09:01:11 Removed, the length is dchecked when accessing the
13740 if (this->group() < group) {
13741 // The group comes later in the list.
13742 next_link()->UpdateToFinishedCode(group, info, code_cell);
13743 return;
13744 }
13745 DCHECK_EQ(group, this->group());
13749 DisallowHeapAllocation no_gc; 13746 DisallowHeapAllocation no_gc;
13750 GroupStartIndexes starts(this); 13747 int count = this->count();
13751 int start = starts.at(group); 13748 for (int i = 0; i < count; i++) {
13752 int end = starts.at(group + 1);
13753 for (int i = start; i < end; i++) {
13754 if (object_at(i) == info) { 13749 if (object_at(i) == info) {
13755 set_object_at(i, code_cell); 13750 set_object_at(i, code_cell);
13756 break; 13751 break;
13757 } 13752 }
13758 } 13753 }
13759
13760 #ifdef DEBUG 13754 #ifdef DEBUG
13761 for (int i = start; i < end; i++) { 13755 for (int i = 0; i < count; i++) {
13762 DCHECK(object_at(i) != info); 13756 DCHECK(object_at(i) != info);
13763 } 13757 }
13764 #endif 13758 #endif
13765 } 13759 }
13766 13760
13767 13761
13768 void DependentCode::RemoveCompilationDependencies( 13762 void DependentCode::RemoveCompilationDependencies(
13769 DependentCode::DependencyGroup group, Foreign* info) { 13763 DependentCode::DependencyGroup group, Foreign* info) {
13764 DCHECK_LE(this->group(), group);
Igor Sheludko 2015/11/20 12:35:32 Ditto.
ulan 2015/11/23 09:01:11 Done.
13765 if (this->group() < group) {
13766 // The group comes later in the list.
13767 next_link()->RemoveCompilationDependencies(group, info);
13768 return;
13769 }
13770 DCHECK_EQ(group, this->group());
13770 DisallowHeapAllocation no_allocation; 13771 DisallowHeapAllocation no_allocation;
13771 GroupStartIndexes starts(this); 13772 int old_count = count();
13772 int start = starts.at(group);
13773 int end = starts.at(group + 1);
13774 // Find compilation info wrapper. 13773 // Find compilation info wrapper.
13775 int info_pos = -1; 13774 int info_pos = -1;
13776 for (int i = start; i < end; i++) { 13775 for (int i = 0; i < old_count; i++) {
13777 if (object_at(i) == info) { 13776 if (object_at(i) == info) {
13778 info_pos = i; 13777 info_pos = i;
13779 break; 13778 break;
13780 } 13779 }
13781 } 13780 }
13782 if (info_pos == -1) return; // Not found. 13781 if (info_pos == -1) return; // Not found.
13783 int gap = info_pos; 13782 // Use the last code to fill the gap.
13784 // Use the last of each group to fill the gap in the previous group. 13783 if (info_pos < old_count - 1) {
13785 for (int i = group; i < kGroupCount; i++) { 13784 copy(old_count - 1, info_pos);
13786 int last_of_group = starts.at(i + 1) - 1;
13787 DCHECK(last_of_group >= gap);
13788 if (last_of_group == gap) continue;
13789 copy(last_of_group, gap);
13790 gap = last_of_group;
13791 } 13785 }
13792 DCHECK(gap == starts.number_of_entries() - 1); 13786 clear_at(old_count - 1);
13793 clear_at(gap); // Clear last gap. 13787 set_count(old_count - 1);
13794 set_number_of_entries(group, end - start - 1);
13795 13788
13796 #ifdef DEBUG 13789 #ifdef DEBUG
13797 for (int i = start; i < end - 1; i++) { 13790 for (int i = 0; i < old_count - 1; i++) {
13798 DCHECK(object_at(i) != info); 13791 DCHECK(object_at(i) != info);
13799 } 13792 }
13800 #endif 13793 #endif
13801 } 13794 }
13802 13795
13803 13796
13804 bool DependentCode::Contains(DependencyGroup group, WeakCell* code_cell) { 13797 bool DependentCode::Contains(DependencyGroup group, WeakCell* code_cell) {
13805 GroupStartIndexes starts(this); 13798 if (this->length() == 0 || this->group() > group) {
13806 int start = starts.at(group); 13799 // There is no such group.
13807 int end = starts.at(group + 1); 13800 return false;
13808 for (int i = start; i < end; i++) { 13801 }
13802 if (this->group() < group) {
13803 // The group comes later in the list.
13804 return next_link()->Contains(group, code_cell);
13805 }
13806 DCHECK_EQ(group, this->group());
13807 int count = this->count();
13808 for (int i = 0; i < count; i++) {
13809 if (object_at(i) == code_cell) return true; 13809 if (object_at(i) == code_cell) return true;
13810 } 13810 }
13811 return false; 13811 return false;
13812 } 13812 }
13813 13813
13814 13814
13815 bool DependentCode::IsEmpty(DependencyGroup group) {
13816 if (this->length() == 0 || this->group() > group) {
13817 // There is no such group.
13818 return true;
13819 }
13820 if (this->group() < group) {
13821 // The group comes later in the list.
13822 return next_link()->IsEmpty(group);
13823 }
13824 DCHECK_EQ(group, this->group());
13825 return count() == 0;
13826 }
13827
13828
13815 bool DependentCode::MarkCodeForDeoptimization( 13829 bool DependentCode::MarkCodeForDeoptimization(
13816 Isolate* isolate, 13830 Isolate* isolate,
13817 DependentCode::DependencyGroup group) { 13831 DependentCode::DependencyGroup group) {
13832 if (this->length() == 0 || this->group() > group) {
13833 // There is no such group.
13834 return false;
13835 }
13836 if (this->group() < group) {
13837 // The group comes later in the list.
13838 return next_link()->MarkCodeForDeoptimization(isolate, group);
13839 }
13840 DCHECK_EQ(group, this->group());
13818 DisallowHeapAllocation no_allocation_scope; 13841 DisallowHeapAllocation no_allocation_scope;
13819 DependentCode::GroupStartIndexes starts(this);
13820 int start = starts.at(group);
13821 int end = starts.at(group + 1);
13822 int code_entries = starts.number_of_entries();
13823 if (start == end) return false;
13824
13825 // Mark all the code that needs to be deoptimized. 13842 // Mark all the code that needs to be deoptimized.
13826 bool marked = false; 13843 bool marked = false;
13827 bool invalidate_embedded_objects = group == kWeakCodeGroup; 13844 bool invalidate_embedded_objects = group == kWeakCodeGroup;
13828 for (int i = start; i < end; i++) { 13845 int count = this->count();
13846 for (int i = 0; i < count; i++) {
13829 Object* obj = object_at(i); 13847 Object* obj = object_at(i);
13830 if (obj->IsWeakCell()) { 13848 if (obj->IsWeakCell()) {
13831 WeakCell* cell = WeakCell::cast(obj); 13849 WeakCell* cell = WeakCell::cast(obj);
13832 if (cell->cleared()) continue; 13850 if (cell->cleared()) continue;
13833 Code* code = Code::cast(cell->value()); 13851 Code* code = Code::cast(cell->value());
13834 if (!code->marked_for_deoptimization()) { 13852 if (!code->marked_for_deoptimization()) {
13835 SetMarkedForDeoptimization(code, group); 13853 SetMarkedForDeoptimization(code, group);
13836 if (invalidate_embedded_objects) { 13854 if (invalidate_embedded_objects) {
13837 code->InvalidateEmbeddedObjects(); 13855 code->InvalidateEmbeddedObjects();
13838 } 13856 }
13839 marked = true; 13857 marked = true;
13840 } 13858 }
13841 } else { 13859 } else {
13842 DCHECK(obj->IsForeign()); 13860 DCHECK(obj->IsForeign());
13843 CompilationDependencies* info = 13861 CompilationDependencies* info =
13844 reinterpret_cast<CompilationDependencies*>( 13862 reinterpret_cast<CompilationDependencies*>(
13845 Foreign::cast(obj)->foreign_address()); 13863 Foreign::cast(obj)->foreign_address());
13846 info->Abort(); 13864 info->Abort();
13847 } 13865 }
13848 } 13866 }
13849 // Compact the array by moving all subsequent groups to fill in the new holes. 13867 for (int i = 0; i < count; i++) {
13850 for (int src = end, dst = start; src < code_entries; src++, dst++) {
13851 copy(src, dst);
13852 }
13853 // Now the holes are at the end of the array, zap them for heap-verifier.
13854 int removed = end - start;
13855 for (int i = code_entries - removed; i < code_entries; i++) {
13856 clear_at(i); 13868 clear_at(i);
13857 } 13869 }
13858 set_number_of_entries(group, 0); 13870 set_count(0);
13859 return marked; 13871 return marked;
13860 } 13872 }
13861 13873
13862 13874
13863 void DependentCode::DeoptimizeDependentCodeGroup( 13875 void DependentCode::DeoptimizeDependentCodeGroup(
13864 Isolate* isolate, 13876 Isolate* isolate,
13865 DependentCode::DependencyGroup group) { 13877 DependentCode::DependencyGroup group) {
13866 DCHECK(AllowCodeDependencyChange::IsAllowed()); 13878 DCHECK(AllowCodeDependencyChange::IsAllowed());
13867 DisallowHeapAllocation no_allocation_scope; 13879 DisallowHeapAllocation no_allocation_scope;
13868 bool marked = MarkCodeForDeoptimization(isolate, group); 13880 bool marked = MarkCodeForDeoptimization(isolate, group);
(...skipping 4032 matching lines...) Expand 10 before | Expand all | Expand 10 after
17901 if (cell->value() != *new_value) { 17913 if (cell->value() != *new_value) {
17902 cell->set_value(*new_value); 17914 cell->set_value(*new_value);
17903 Isolate* isolate = cell->GetIsolate(); 17915 Isolate* isolate = cell->GetIsolate();
17904 cell->dependent_code()->DeoptimizeDependentCodeGroup( 17916 cell->dependent_code()->DeoptimizeDependentCodeGroup(
17905 isolate, DependentCode::kPropertyCellChangedGroup); 17917 isolate, DependentCode::kPropertyCellChangedGroup);
17906 } 17918 }
17907 } 17919 }
17908 17920
17909 } // namespace internal 17921 } // namespace internal
17910 } // namespace v8 17922 } // namespace v8
OLDNEW
« src/objects.h ('K') | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698