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

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: 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
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 if (this->length() == 0 || this->group() > group) {
13740 // There is no such group.
13741 return;
13742 }
13743 if (this->group() < group) {
13744 // The group comes later in the list.
13745 next_link()->UpdateToFinishedCode(group, info, code_cell);
13746 return;
13747 }
13748 DCHECK_EQ(group, this->group());
13749 DisallowHeapAllocation no_gc; 13749 DisallowHeapAllocation no_gc;
13750 GroupStartIndexes starts(this); 13750 int count = this->count();
13751 int start = starts.at(group); 13751 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) { 13752 if (object_at(i) == info) {
13755 set_object_at(i, code_cell); 13753 set_object_at(i, code_cell);
13756 break; 13754 break;
13757 } 13755 }
13758 } 13756 }
13759
13760 #ifdef DEBUG 13757 #ifdef DEBUG
13761 for (int i = start; i < end; i++) { 13758 for (int i = 0; i < count; i++) {
13762 DCHECK(object_at(i) != info); 13759 DCHECK(object_at(i) != info);
13763 } 13760 }
13764 #endif 13761 #endif
13765 } 13762 }
13766 13763
13767 13764
13768 void DependentCode::RemoveCompilationDependencies( 13765 void DependentCode::RemoveCompilationDependencies(
13769 DependentCode::DependencyGroup group, Foreign* info) { 13766 DependentCode::DependencyGroup group, Foreign* info) {
13767 if (this->length() == 0 || this->group() > group) {
13768 // There is no such group.
13769 return;
13770 }
13771 if (this->group() < group) {
13772 // The group comes later in the list.
13773 next_link()->RemoveCompilationDependencies(group, info);
13774 return;
13775 }
13776 DCHECK_EQ(group, this->group());
13770 DisallowHeapAllocation no_allocation; 13777 DisallowHeapAllocation no_allocation;
13771 GroupStartIndexes starts(this); 13778 int old_count = count();
13772 int start = starts.at(group);
13773 int end = starts.at(group + 1);
13774 // Find compilation info wrapper. 13779 // Find compilation info wrapper.
13775 int info_pos = -1; 13780 int info_pos = -1;
13776 for (int i = start; i < end; i++) { 13781 for (int i = 0; i < old_count; i++) {
13777 if (object_at(i) == info) { 13782 if (object_at(i) == info) {
13778 info_pos = i; 13783 info_pos = i;
13779 break; 13784 break;
13780 } 13785 }
13781 } 13786 }
13782 if (info_pos == -1) return; // Not found. 13787 if (info_pos == -1) return; // Not found.
13783 int gap = info_pos; 13788 // Use the last code to fill the gap.
13784 // Use the last of each group to fill the gap in the previous group. 13789 if (info_pos < old_count - 1) {
13785 for (int i = group; i < kGroupCount; i++) { 13790 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 } 13791 }
13792 DCHECK(gap == starts.number_of_entries() - 1); 13792 clear_at(old_count - 1);
13793 clear_at(gap); // Clear last gap. 13793 set_count(old_count - 1);
13794 set_number_of_entries(group, end - start - 1);
13795 13794
13796 #ifdef DEBUG 13795 #ifdef DEBUG
13797 for (int i = start; i < end - 1; i++) { 13796 for (int i = 0; i < old_count - 1; i++) {
13798 DCHECK(object_at(i) != info); 13797 DCHECK(object_at(i) != info);
13799 } 13798 }
13800 #endif 13799 #endif
13801 } 13800 }
13802 13801
13803 13802
13804 bool DependentCode::Contains(DependencyGroup group, WeakCell* code_cell) { 13803 bool DependentCode::Contains(DependencyGroup group, WeakCell* code_cell) {
13805 GroupStartIndexes starts(this); 13804 if (this->length() == 0 || this->group() > group) {
13806 int start = starts.at(group); 13805 // There is no such group.
13807 int end = starts.at(group + 1); 13806 return false;
13808 for (int i = start; i < end; i++) { 13807 }
13808 if (this->group() < group) {
13809 // The group comes later in the list.
13810 return next_link()->Contains(group, code_cell);
13811 }
13812 DCHECK_EQ(group, this->group());
13813 int count = this->count();
13814 for (int i = 0; i < count; i++) {
13809 if (object_at(i) == code_cell) return true; 13815 if (object_at(i) == code_cell) return true;
13810 } 13816 }
13811 return false; 13817 return false;
13812 } 13818 }
13813 13819
13814 13820
13821 bool DependentCode::IsEmpty(DependencyGroup group) {
13822 if (this->length() == 0 || this->group() > group) {
13823 // There is no such group.
13824 return true;
13825 }
13826 if (this->group() < group) {
13827 // The group comes later in the list.
13828 return next_link()->IsEmpty(group);
13829 }
13830 DCHECK_EQ(group, this->group());
13831 return count() == 0;
13832 }
13833
13834
13815 bool DependentCode::MarkCodeForDeoptimization( 13835 bool DependentCode::MarkCodeForDeoptimization(
13816 Isolate* isolate, 13836 Isolate* isolate,
13817 DependentCode::DependencyGroup group) { 13837 DependentCode::DependencyGroup group) {
13838 if (this->length() == 0 || this->group() > group) {
13839 // There is no such group.
13840 return false;
13841 }
13842 if (this->group() < group) {
13843 // The group comes later in the list.
13844 return next_link()->MarkCodeForDeoptimization(isolate, group);
13845 }
13846 DCHECK_EQ(group, this->group());
13818 DisallowHeapAllocation no_allocation_scope; 13847 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. 13848 // Mark all the code that needs to be deoptimized.
13826 bool marked = false; 13849 bool marked = false;
13827 bool invalidate_embedded_objects = group == kWeakCodeGroup; 13850 bool invalidate_embedded_objects = group == kWeakCodeGroup;
13828 for (int i = start; i < end; i++) { 13851 int count = this->count();
13852 for (int i = 0; i < count; i++) {
13829 Object* obj = object_at(i); 13853 Object* obj = object_at(i);
13830 if (obj->IsWeakCell()) { 13854 if (obj->IsWeakCell()) {
13831 WeakCell* cell = WeakCell::cast(obj); 13855 WeakCell* cell = WeakCell::cast(obj);
13832 if (cell->cleared()) continue; 13856 if (cell->cleared()) continue;
13833 Code* code = Code::cast(cell->value()); 13857 Code* code = Code::cast(cell->value());
13834 if (!code->marked_for_deoptimization()) { 13858 if (!code->marked_for_deoptimization()) {
13835 SetMarkedForDeoptimization(code, group); 13859 SetMarkedForDeoptimization(code, group);
13836 if (invalidate_embedded_objects) { 13860 if (invalidate_embedded_objects) {
13837 code->InvalidateEmbeddedObjects(); 13861 code->InvalidateEmbeddedObjects();
13838 } 13862 }
13839 marked = true; 13863 marked = true;
13840 } 13864 }
13841 } else { 13865 } else {
13842 DCHECK(obj->IsForeign()); 13866 DCHECK(obj->IsForeign());
13843 CompilationDependencies* info = 13867 CompilationDependencies* info =
13844 reinterpret_cast<CompilationDependencies*>( 13868 reinterpret_cast<CompilationDependencies*>(
13845 Foreign::cast(obj)->foreign_address()); 13869 Foreign::cast(obj)->foreign_address());
13846 info->Abort(); 13870 info->Abort();
13847 } 13871 }
13848 } 13872 }
13849 // Compact the array by moving all subsequent groups to fill in the new holes. 13873 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); 13874 clear_at(i);
13857 } 13875 }
13858 set_number_of_entries(group, 0); 13876 set_count(0);
13859 return marked; 13877 return marked;
13860 } 13878 }
13861 13879
13862 13880
13863 void DependentCode::DeoptimizeDependentCodeGroup( 13881 void DependentCode::DeoptimizeDependentCodeGroup(
13864 Isolate* isolate, 13882 Isolate* isolate,
13865 DependentCode::DependencyGroup group) { 13883 DependentCode::DependencyGroup group) {
13866 DCHECK(AllowCodeDependencyChange::IsAllowed()); 13884 DCHECK(AllowCodeDependencyChange::IsAllowed());
13867 DisallowHeapAllocation no_allocation_scope; 13885 DisallowHeapAllocation no_allocation_scope;
13868 bool marked = MarkCodeForDeoptimization(isolate, group); 13886 bool marked = MarkCodeForDeoptimization(isolate, group);
(...skipping 4032 matching lines...) Expand 10 before | Expand all | Expand 10 after
17901 if (cell->value() != *new_value) { 17919 if (cell->value() != *new_value) {
17902 cell->set_value(*new_value); 17920 cell->set_value(*new_value);
17903 Isolate* isolate = cell->GetIsolate(); 17921 Isolate* isolate = cell->GetIsolate();
17904 cell->dependent_code()->DeoptimizeDependentCodeGroup( 17922 cell->dependent_code()->DeoptimizeDependentCodeGroup(
17905 isolate, DependentCode::kPropertyCellChangedGroup); 17923 isolate, DependentCode::kPropertyCellChangedGroup);
17906 } 17924 }
17907 } 17925 }
17908 17926
17909 } // namespace internal 17927 } // namespace internal
17910 } // namespace v8 17928 } // namespace v8
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698