OLD | NEW |
---|---|
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 <sstream> | 5 #include <sstream> |
6 | 6 |
7 #include "src/v8.h" | 7 #include "src/v8.h" |
8 | 8 |
9 #include "src/accessors.h" | 9 #include "src/accessors.h" |
10 #include "src/allocation-site-scopes.h" | 10 #include "src/allocation-site-scopes.h" |
(...skipping 11762 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
11773 MemsetPointer(proto_transitions->data_start(), | 11773 MemsetPointer(proto_transitions->data_start(), |
11774 GetHeap()->the_hole_value(), | 11774 GetHeap()->the_hole_value(), |
11775 proto_transitions->length()); | 11775 proto_transitions->length()); |
11776 } | 11776 } |
11777 | 11777 |
11778 | 11778 |
11779 // static | 11779 // static |
11780 void Map::AddDependentCompilationInfo(Handle<Map> map, | 11780 void Map::AddDependentCompilationInfo(Handle<Map> map, |
11781 DependentCode::DependencyGroup group, | 11781 DependentCode::DependencyGroup group, |
11782 CompilationInfo* info) { | 11782 CompilationInfo* info) { |
11783 Handle<DependentCode> codes = | 11783 Handle<DependentCode> codes = DependentCode::InsertCompilationInfo( |
11784 DependentCode::Insert(handle(map->dependent_code(), info->isolate()), | 11784 handle(map->dependent_code(), info->isolate()), group, |
11785 group, info->object_wrapper()); | 11785 info->object_wrapper()); |
11786 if (*codes != map->dependent_code()) map->set_dependent_code(*codes); | 11786 if (*codes != map->dependent_code()) map->set_dependent_code(*codes); |
11787 info->dependencies(group)->Add(map, info->zone()); | 11787 info->dependencies(group)->Add(map, info->zone()); |
11788 } | 11788 } |
11789 | 11789 |
11790 | 11790 |
11791 // static | 11791 // static |
11792 void Map::AddDependentCode(Handle<Map> map, | 11792 void Map::AddDependentCode(Handle<Map> map, |
11793 DependentCode::DependencyGroup group, | 11793 DependentCode::DependencyGroup group, |
11794 Handle<Code> code) { | 11794 Handle<Code> code) { |
11795 Handle<DependentCode> codes = DependentCode::Insert( | 11795 Handle<WeakCell> cell = Code::WeakCellFor(code); |
11796 Handle<DependentCode>(map->dependent_code()), group, code); | 11796 Handle<DependentCode> codes = DependentCode::InsertWeakCode( |
11797 Handle<DependentCode>(map->dependent_code()), group, cell); | |
11797 if (*codes != map->dependent_code()) map->set_dependent_code(*codes); | 11798 if (*codes != map->dependent_code()) map->set_dependent_code(*codes); |
11798 } | 11799 } |
11799 | 11800 |
11800 | 11801 |
11801 DependentCode::GroupStartIndexes::GroupStartIndexes(DependentCode* entries) { | 11802 DependentCode::GroupStartIndexes::GroupStartIndexes(DependentCode* entries) { |
11802 Recompute(entries); | 11803 Recompute(entries); |
11803 } | 11804 } |
11804 | 11805 |
11805 | 11806 |
11806 void DependentCode::GroupStartIndexes::Recompute(DependentCode* entries) { | 11807 void DependentCode::GroupStartIndexes::Recompute(DependentCode* entries) { |
(...skipping 11 matching lines...) Expand all Loading... | |
11818 if (group == DependentCode::kPropertyCellChangedGroup) { | 11819 if (group == DependentCode::kPropertyCellChangedGroup) { |
11819 return Handle<PropertyCell>::cast(object)->dependent_code(); | 11820 return Handle<PropertyCell>::cast(object)->dependent_code(); |
11820 } else if (group == DependentCode::kAllocationSiteTenuringChangedGroup || | 11821 } else if (group == DependentCode::kAllocationSiteTenuringChangedGroup || |
11821 group == DependentCode::kAllocationSiteTransitionChangedGroup) { | 11822 group == DependentCode::kAllocationSiteTransitionChangedGroup) { |
11822 return Handle<AllocationSite>::cast(object)->dependent_code(); | 11823 return Handle<AllocationSite>::cast(object)->dependent_code(); |
11823 } | 11824 } |
11824 return Handle<Map>::cast(object)->dependent_code(); | 11825 return Handle<Map>::cast(object)->dependent_code(); |
11825 } | 11826 } |
11826 | 11827 |
11827 | 11828 |
11829 Handle<DependentCode> DependentCode::InsertCompilationInfo( | |
11830 Handle<DependentCode> entries, DependencyGroup group, | |
11831 Handle<Foreign> info) { | |
11832 return Insert(entries, group, info); | |
11833 } | |
11834 | |
11835 | |
11836 Handle<DependentCode> DependentCode::InsertWeakCode( | |
11837 Handle<DependentCode> entries, DependencyGroup group, | |
11838 Handle<WeakCell> code_cell) { | |
11839 return Insert(entries, group, code_cell); | |
11840 } | |
11841 | |
11842 | |
11828 Handle<DependentCode> DependentCode::Insert(Handle<DependentCode> entries, | 11843 Handle<DependentCode> DependentCode::Insert(Handle<DependentCode> entries, |
11829 DependencyGroup group, | 11844 DependencyGroup group, |
11830 Handle<Object> object) { | 11845 Handle<Object> object) { |
11831 GroupStartIndexes starts(*entries); | 11846 GroupStartIndexes starts(*entries); |
11832 int start = starts.at(group); | 11847 int start = starts.at(group); |
11833 int end = starts.at(group + 1); | 11848 int end = starts.at(group + 1); |
11834 int number_of_entries = starts.number_of_entries(); | 11849 int number_of_entries = starts.number_of_entries(); |
11835 // Check for existing entry to avoid duplicates. | 11850 // Check for existing entry to avoid duplicates. |
11836 for (int i = start; i < end; i++) { | 11851 for (int i = start; i < end; i++) { |
11837 if (entries->object_at(i) == *object) return entries; | 11852 if (entries->object_at(i) == *object) return entries; |
11838 } | 11853 } |
11839 if (entries->length() < kCodesStartIndex + number_of_entries + 1) { | 11854 if (entries->length() < kCodesStartIndex + number_of_entries + 1) { |
11840 int capacity = kCodesStartIndex + number_of_entries + 1; | 11855 entries = EnsureSpace(entries); |
11841 if (capacity > 5) capacity = capacity * 5 / 4; | 11856 // The number of codes can change after Compact and GC. |
11842 Handle<DependentCode> new_entries = Handle<DependentCode>::cast( | |
11843 FixedArray::CopySize(entries, capacity, TENURED)); | |
11844 // The number of codes can change after GC. | |
11845 starts.Recompute(*entries); | 11857 starts.Recompute(*entries); |
11846 start = starts.at(group); | 11858 start = starts.at(group); |
11847 end = starts.at(group + 1); | 11859 end = starts.at(group + 1); |
11848 number_of_entries = starts.number_of_entries(); | |
11849 for (int i = 0; i < number_of_entries; i++) { | |
11850 entries->clear_at(i); | |
11851 } | |
11852 // If the old fixed array was empty, we need to reset counters of the | |
11853 // new array. | |
11854 if (number_of_entries == 0) { | |
11855 for (int g = 0; g < kGroupCount; g++) { | |
11856 new_entries->set_number_of_entries(static_cast<DependencyGroup>(g), 0); | |
11857 } | |
11858 } | |
11859 entries = new_entries; | |
11860 } | 11860 } |
11861 | |
11861 entries->ExtendGroup(group); | 11862 entries->ExtendGroup(group); |
11862 entries->set_object_at(end, *object); | 11863 entries->set_object_at(end, *object); |
11863 entries->set_number_of_entries(group, end + 1 - start); | 11864 entries->set_number_of_entries(group, end + 1 - start); |
11864 return entries; | 11865 return entries; |
11865 } | 11866 } |
11866 | 11867 |
11867 | 11868 |
11868 void DependentCode::UpdateToFinishedCode(DependencyGroup group, | 11869 Handle<DependentCode> DependentCode::EnsureSpace( |
11869 CompilationInfo* info, | 11870 Handle<DependentCode> entries) { |
11870 Code* code) { | 11871 if (entries->length() == 0) { |
11872 entries = Handle<DependentCode>::cast( | |
11873 FixedArray::CopySize(entries, kCodesStartIndex + 1, TENURED)); | |
11874 for (int g = 0; g < kGroupCount; g++) { | |
11875 entries->set_number_of_entries(static_cast<DependencyGroup>(g), 0); | |
11876 } | |
11877 return entries; | |
11878 } | |
11879 if (entries->Compact()) return entries; | |
11880 GroupStartIndexes starts(*entries); | |
11881 int capacity = | |
11882 kCodesStartIndex + DependentCode::Grow(starts.number_of_entries()); | |
11883 return Handle<DependentCode>::cast( | |
11884 FixedArray::CopySize(entries, capacity, TENURED)); | |
11885 } | |
11886 | |
11887 | |
11888 bool DependentCode::Compact() { | |
11889 GroupStartIndexes starts(this); | |
11890 int n = 0; | |
11891 for (int g = 0; g < kGroupCount; g++) { | |
11892 int start = starts.at(g); | |
11893 int end = starts.at(g + 1); | |
11894 int count = 0; | |
11895 for (int i = start; i < end; i++) { | |
11896 Object* obj = object_at(i); | |
11897 if (!obj->IsWeakCell() || !WeakCell::cast(obj)->cleared()) { | |
11898 if (i != n + count) { | |
11899 copy(i, n + count); | |
Yang
2015/01/27 14:43:24
Can we assert here that i < n+count so that we nev
| |
11900 } | |
11901 count++; | |
11902 } | |
11903 } | |
11904 if (count != end - start) { | |
11905 set_number_of_entries(static_cast<DependencyGroup>(g), count); | |
11906 } | |
11907 n += count; | |
11908 } | |
11909 return n < starts.number_of_entries(); | |
11910 } | |
11911 | |
11912 | |
11913 void DependentCode::UpdateToFinishedCode(DependencyGroup group, Foreign* info, | |
11914 WeakCell* code_cell) { | |
11871 DisallowHeapAllocation no_gc; | 11915 DisallowHeapAllocation no_gc; |
11872 AllowDeferredHandleDereference get_object_wrapper; | |
11873 Foreign* info_wrapper = *info->object_wrapper(); | |
11874 GroupStartIndexes starts(this); | 11916 GroupStartIndexes starts(this); |
11875 int start = starts.at(group); | 11917 int start = starts.at(group); |
11876 int end = starts.at(group + 1); | 11918 int end = starts.at(group + 1); |
11877 for (int i = start; i < end; i++) { | 11919 for (int i = start; i < end; i++) { |
11878 if (object_at(i) == info_wrapper) { | 11920 if (object_at(i) == info) { |
11879 set_object_at(i, code); | 11921 set_object_at(i, code_cell); |
11880 break; | 11922 break; |
11881 } | 11923 } |
11882 } | 11924 } |
11883 | 11925 |
11884 #ifdef DEBUG | 11926 #ifdef DEBUG |
11885 for (int i = start; i < end; i++) { | 11927 for (int i = start; i < end; i++) { |
11886 DCHECK(is_code_at(i) || compilation_info_at(i) != info); | 11928 DCHECK(object_at(i) != info); |
11887 } | 11929 } |
11888 #endif | 11930 #endif |
11889 } | 11931 } |
11890 | 11932 |
11891 | 11933 |
11892 void DependentCode::RemoveCompilationInfo(DependentCode::DependencyGroup group, | 11934 void DependentCode::RemoveCompilationInfo(DependentCode::DependencyGroup group, |
11893 CompilationInfo* info) { | 11935 Foreign* info) { |
11894 DisallowHeapAllocation no_allocation; | 11936 DisallowHeapAllocation no_allocation; |
11895 AllowDeferredHandleDereference get_object_wrapper; | |
11896 Foreign* info_wrapper = *info->object_wrapper(); | |
11897 GroupStartIndexes starts(this); | 11937 GroupStartIndexes starts(this); |
11898 int start = starts.at(group); | 11938 int start = starts.at(group); |
11899 int end = starts.at(group + 1); | 11939 int end = starts.at(group + 1); |
11900 // Find compilation info wrapper. | 11940 // Find compilation info wrapper. |
11901 int info_pos = -1; | 11941 int info_pos = -1; |
11902 for (int i = start; i < end; i++) { | 11942 for (int i = start; i < end; i++) { |
11903 if (object_at(i) == info_wrapper) { | 11943 if (object_at(i) == info) { |
11904 info_pos = i; | 11944 info_pos = i; |
11905 break; | 11945 break; |
11906 } | 11946 } |
11907 } | 11947 } |
11908 if (info_pos == -1) return; // Not found. | 11948 if (info_pos == -1) return; // Not found. |
11909 int gap = info_pos; | 11949 int gap = info_pos; |
11910 // Use the last of each group to fill the gap in the previous group. | 11950 // Use the last of each group to fill the gap in the previous group. |
11911 for (int i = group; i < kGroupCount; i++) { | 11951 for (int i = group; i < kGroupCount; i++) { |
11912 int last_of_group = starts.at(i + 1) - 1; | 11952 int last_of_group = starts.at(i + 1) - 1; |
11913 DCHECK(last_of_group >= gap); | 11953 DCHECK(last_of_group >= gap); |
11914 if (last_of_group == gap) continue; | 11954 if (last_of_group == gap) continue; |
11915 copy(last_of_group, gap); | 11955 copy(last_of_group, gap); |
11916 gap = last_of_group; | 11956 gap = last_of_group; |
11917 } | 11957 } |
11918 DCHECK(gap == starts.number_of_entries() - 1); | 11958 DCHECK(gap == starts.number_of_entries() - 1); |
11919 clear_at(gap); // Clear last gap. | 11959 clear_at(gap); // Clear last gap. |
11920 set_number_of_entries(group, end - start - 1); | 11960 set_number_of_entries(group, end - start - 1); |
11921 | 11961 |
11922 #ifdef DEBUG | 11962 #ifdef DEBUG |
11923 for (int i = start; i < end - 1; i++) { | 11963 for (int i = start; i < end - 1; i++) { |
11924 DCHECK(is_code_at(i) || compilation_info_at(i) != info); | 11964 DCHECK(object_at(i) != info); |
11925 } | 11965 } |
11926 #endif | 11966 #endif |
11927 } | 11967 } |
11928 | 11968 |
11929 | 11969 |
11930 bool DependentCode::Contains(DependencyGroup group, Code* code) { | 11970 bool DependentCode::Contains(DependencyGroup group, WeakCell* code_cell) { |
11931 GroupStartIndexes starts(this); | 11971 GroupStartIndexes starts(this); |
11932 int start = starts.at(group); | 11972 int start = starts.at(group); |
11933 int end = starts.at(group + 1); | 11973 int end = starts.at(group + 1); |
11934 for (int i = start; i < end; i++) { | 11974 for (int i = start; i < end; i++) { |
11935 if (object_at(i) == code) return true; | 11975 if (object_at(i) == code_cell) return true; |
11936 } | 11976 } |
11937 return false; | 11977 return false; |
11938 } | 11978 } |
11939 | 11979 |
11940 | 11980 |
11941 bool DependentCode::MarkCodeForDeoptimization( | 11981 bool DependentCode::MarkCodeForDeoptimization( |
11942 Isolate* isolate, | 11982 Isolate* isolate, |
11943 DependentCode::DependencyGroup group) { | 11983 DependentCode::DependencyGroup group) { |
11944 DisallowHeapAllocation no_allocation_scope; | 11984 DisallowHeapAllocation no_allocation_scope; |
11945 DependentCode::GroupStartIndexes starts(this); | 11985 DependentCode::GroupStartIndexes starts(this); |
11946 int start = starts.at(group); | 11986 int start = starts.at(group); |
11947 int end = starts.at(group + 1); | 11987 int end = starts.at(group + 1); |
11948 int code_entries = starts.number_of_entries(); | 11988 int code_entries = starts.number_of_entries(); |
11949 if (start == end) return false; | 11989 if (start == end) return false; |
11950 | 11990 |
11951 // Mark all the code that needs to be deoptimized. | 11991 // Mark all the code that needs to be deoptimized. |
11952 bool marked = false; | 11992 bool marked = false; |
11993 bool invalidate_embedded_objects = group == kWeakCodeGroup; | |
11953 for (int i = start; i < end; i++) { | 11994 for (int i = start; i < end; i++) { |
11954 if (is_code_at(i)) { | 11995 Object* obj = object_at(i); |
11955 Code* code = code_at(i); | 11996 if (obj->IsWeakCell()) { |
11997 WeakCell* cell = WeakCell::cast(obj); | |
11998 if (cell->cleared()) continue; | |
11999 Code* code = Code::cast(cell->value()); | |
11956 if (!code->marked_for_deoptimization()) { | 12000 if (!code->marked_for_deoptimization()) { |
11957 SetMarkedForDeoptimization(code, group); | 12001 SetMarkedForDeoptimization(code, group); |
12002 if (invalidate_embedded_objects) { | |
12003 code->InvalidateEmbeddedObjects(); | |
12004 } | |
11958 marked = true; | 12005 marked = true; |
11959 } | 12006 } |
11960 } else { | 12007 } else { |
11961 CompilationInfo* info = compilation_info_at(i); | 12008 DCHECK(obj->IsForeign()); |
12009 CompilationInfo* info = reinterpret_cast<CompilationInfo*>( | |
12010 Foreign::cast(obj)->foreign_address()); | |
11962 info->AbortDueToDependencyChange(); | 12011 info->AbortDueToDependencyChange(); |
11963 } | 12012 } |
11964 } | 12013 } |
11965 // Compact the array by moving all subsequent groups to fill in the new holes. | 12014 // Compact the array by moving all subsequent groups to fill in the new holes. |
11966 for (int src = end, dst = start; src < code_entries; src++, dst++) { | 12015 for (int src = end, dst = start; src < code_entries; src++, dst++) { |
11967 copy(src, dst); | 12016 copy(src, dst); |
11968 } | 12017 } |
11969 // Now the holes are at the end of the array, zap them for heap-verifier. | 12018 // Now the holes are at the end of the array, zap them for heap-verifier. |
11970 int removed = end - start; | 12019 int removed = end - start; |
11971 for (int i = code_entries - removed; i < code_entries; i++) { | 12020 for (int i = code_entries - removed; i < code_entries; i++) { |
11972 clear_at(i); | 12021 clear_at(i); |
11973 } | 12022 } |
11974 set_number_of_entries(group, 0); | 12023 set_number_of_entries(group, 0); |
11975 return marked; | 12024 return marked; |
11976 } | 12025 } |
11977 | 12026 |
11978 | 12027 |
11979 void DependentCode::DeoptimizeDependentCodeGroup( | 12028 void DependentCode::DeoptimizeDependentCodeGroup( |
11980 Isolate* isolate, | 12029 Isolate* isolate, |
11981 DependentCode::DependencyGroup group) { | 12030 DependentCode::DependencyGroup group) { |
11982 DCHECK(AllowCodeDependencyChange::IsAllowed()); | 12031 DCHECK(AllowCodeDependencyChange::IsAllowed()); |
11983 DisallowHeapAllocation no_allocation_scope; | 12032 DisallowHeapAllocation no_allocation_scope; |
11984 bool marked = MarkCodeForDeoptimization(isolate, group); | 12033 bool marked = MarkCodeForDeoptimization(isolate, group); |
11985 | |
11986 if (marked) Deoptimizer::DeoptimizeMarkedCode(isolate); | 12034 if (marked) Deoptimizer::DeoptimizeMarkedCode(isolate); |
11987 } | 12035 } |
11988 | 12036 |
11989 | 12037 |
11990 void DependentCode::SetMarkedForDeoptimization(Code* code, | 12038 void DependentCode::SetMarkedForDeoptimization(Code* code, |
11991 DependencyGroup group) { | 12039 DependencyGroup group) { |
11992 code->set_marked_for_deoptimization(true); | 12040 code->set_marked_for_deoptimization(true); |
11993 if (FLAG_trace_deopt && | 12041 if (FLAG_trace_deopt && |
11994 (code->deoptimization_data() != code->GetHeap()->empty_fixed_array())) { | 12042 (code->deoptimization_data() != code->GetHeap()->empty_fixed_array())) { |
11995 DeoptimizationInputData* deopt_data = | 12043 DeoptimizationInputData* deopt_data = |
(...skipping 1069 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
13065 } | 13113 } |
13066 } | 13114 } |
13067 | 13115 |
13068 | 13116 |
13069 // static | 13117 // static |
13070 void AllocationSite::AddDependentCompilationInfo( | 13118 void AllocationSite::AddDependentCompilationInfo( |
13071 Handle<AllocationSite> site, DependentCode::DependencyGroup group, | 13119 Handle<AllocationSite> site, DependentCode::DependencyGroup group, |
13072 CompilationInfo* info) { | 13120 CompilationInfo* info) { |
13073 Handle<DependentCode> dep(site->dependent_code()); | 13121 Handle<DependentCode> dep(site->dependent_code()); |
13074 Handle<DependentCode> codes = | 13122 Handle<DependentCode> codes = |
13075 DependentCode::Insert(dep, group, info->object_wrapper()); | 13123 DependentCode::InsertCompilationInfo(dep, group, info->object_wrapper()); |
13076 if (*codes != site->dependent_code()) site->set_dependent_code(*codes); | 13124 if (*codes != site->dependent_code()) site->set_dependent_code(*codes); |
13077 info->dependencies(group)->Add(Handle<HeapObject>(*site), info->zone()); | 13125 info->dependencies(group)->Add(Handle<HeapObject>(*site), info->zone()); |
13078 } | 13126 } |
13079 | 13127 |
13080 | 13128 |
13081 const char* AllocationSite::PretenureDecisionName(PretenureDecision decision) { | 13129 const char* AllocationSite::PretenureDecisionName(PretenureDecision decision) { |
13082 switch (decision) { | 13130 switch (decision) { |
13083 case kUndecided: return "undecided"; | 13131 case kUndecided: return "undecided"; |
13084 case kDontTenure: return "don't tenure"; | 13132 case kDontTenure: return "don't tenure"; |
13085 case kMaybeTenure: return "maybe tenure"; | 13133 case kMaybeTenure: return "maybe tenure"; |
(...skipping 3765 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
16851 Handle<HeapType> new_type = UpdatedType(cell, value); | 16899 Handle<HeapType> new_type = UpdatedType(cell, value); |
16852 cell->set_type(*new_type); | 16900 cell->set_type(*new_type); |
16853 } | 16901 } |
16854 return value; | 16902 return value; |
16855 } | 16903 } |
16856 | 16904 |
16857 | 16905 |
16858 // static | 16906 // static |
16859 void PropertyCell::AddDependentCompilationInfo(Handle<PropertyCell> cell, | 16907 void PropertyCell::AddDependentCompilationInfo(Handle<PropertyCell> cell, |
16860 CompilationInfo* info) { | 16908 CompilationInfo* info) { |
16861 Handle<DependentCode> codes = | 16909 Handle<DependentCode> codes = DependentCode::InsertCompilationInfo( |
16862 DependentCode::Insert(handle(cell->dependent_code(), info->isolate()), | 16910 handle(cell->dependent_code(), info->isolate()), |
16863 DependentCode::kPropertyCellChangedGroup, | 16911 DependentCode::kPropertyCellChangedGroup, info->object_wrapper()); |
16864 info->object_wrapper()); | |
16865 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); | 16912 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); |
16866 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( | 16913 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( |
16867 cell, info->zone()); | 16914 cell, info->zone()); |
16868 } | 16915 } |
16869 | 16916 |
16870 } } // namespace v8::internal | 16917 } } // namespace v8::internal |
OLD | NEW |