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 11866 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11877 MemsetPointer(proto_transitions->data_start(), | 11877 MemsetPointer(proto_transitions->data_start(), |
11878 GetHeap()->the_hole_value(), | 11878 GetHeap()->the_hole_value(), |
11879 proto_transitions->length()); | 11879 proto_transitions->length()); |
11880 } | 11880 } |
11881 | 11881 |
11882 | 11882 |
11883 // static | 11883 // static |
11884 void Map::AddDependentCompilationInfo(Handle<Map> map, | 11884 void Map::AddDependentCompilationInfo(Handle<Map> map, |
11885 DependentCode::DependencyGroup group, | 11885 DependentCode::DependencyGroup group, |
11886 CompilationInfo* info) { | 11886 CompilationInfo* info) { |
11887 Handle<DependentCode> codes = | 11887 Handle<DependentCode> codes = DependentCode::InsertCompilationInfo( |
11888 DependentCode::Insert(handle(map->dependent_code(), info->isolate()), | 11888 handle(map->dependent_code(), info->isolate()), group, |
11889 group, info->object_wrapper()); | 11889 info->object_wrapper()); |
11890 if (*codes != map->dependent_code()) map->set_dependent_code(*codes); | 11890 if (*codes != map->dependent_code()) map->set_dependent_code(*codes); |
11891 info->dependencies(group)->Add(map, info->zone()); | 11891 info->dependencies(group)->Add(map, info->zone()); |
11892 } | 11892 } |
11893 | 11893 |
11894 | 11894 |
11895 // static | 11895 // static |
11896 void Map::AddDependentCode(Handle<Map> map, | 11896 void Map::AddDependentCode(Handle<Map> map, |
11897 DependentCode::DependencyGroup group, | 11897 DependentCode::DependencyGroup group, |
11898 Handle<Code> code) { | 11898 Handle<Code> code) { |
11899 Handle<DependentCode> codes = DependentCode::Insert( | 11899 Handle<WeakCell> cell = Code::WeakCellFor(code); |
11900 Handle<DependentCode>(map->dependent_code()), group, code); | 11900 Handle<DependentCode> codes = DependentCode::InsertWeakCode( |
| 11901 Handle<DependentCode>(map->dependent_code()), group, cell); |
11901 if (*codes != map->dependent_code()) map->set_dependent_code(*codes); | 11902 if (*codes != map->dependent_code()) map->set_dependent_code(*codes); |
11902 } | 11903 } |
11903 | 11904 |
11904 | 11905 |
11905 DependentCode::GroupStartIndexes::GroupStartIndexes(DependentCode* entries) { | 11906 DependentCode::GroupStartIndexes::GroupStartIndexes(DependentCode* entries) { |
11906 Recompute(entries); | 11907 Recompute(entries); |
11907 } | 11908 } |
11908 | 11909 |
11909 | 11910 |
11910 void DependentCode::GroupStartIndexes::Recompute(DependentCode* entries) { | 11911 void DependentCode::GroupStartIndexes::Recompute(DependentCode* entries) { |
(...skipping 11 matching lines...) Expand all Loading... |
11922 if (group == DependentCode::kPropertyCellChangedGroup) { | 11923 if (group == DependentCode::kPropertyCellChangedGroup) { |
11923 return Handle<PropertyCell>::cast(object)->dependent_code(); | 11924 return Handle<PropertyCell>::cast(object)->dependent_code(); |
11924 } else if (group == DependentCode::kAllocationSiteTenuringChangedGroup || | 11925 } else if (group == DependentCode::kAllocationSiteTenuringChangedGroup || |
11925 group == DependentCode::kAllocationSiteTransitionChangedGroup) { | 11926 group == DependentCode::kAllocationSiteTransitionChangedGroup) { |
11926 return Handle<AllocationSite>::cast(object)->dependent_code(); | 11927 return Handle<AllocationSite>::cast(object)->dependent_code(); |
11927 } | 11928 } |
11928 return Handle<Map>::cast(object)->dependent_code(); | 11929 return Handle<Map>::cast(object)->dependent_code(); |
11929 } | 11930 } |
11930 | 11931 |
11931 | 11932 |
| 11933 Handle<DependentCode> DependentCode::InsertCompilationInfo( |
| 11934 Handle<DependentCode> entries, DependencyGroup group, |
| 11935 Handle<Foreign> info) { |
| 11936 return Insert(entries, group, info); |
| 11937 } |
| 11938 |
| 11939 |
| 11940 Handle<DependentCode> DependentCode::InsertWeakCode( |
| 11941 Handle<DependentCode> entries, DependencyGroup group, |
| 11942 Handle<WeakCell> code_cell) { |
| 11943 return Insert(entries, group, code_cell); |
| 11944 } |
| 11945 |
| 11946 |
11932 Handle<DependentCode> DependentCode::Insert(Handle<DependentCode> entries, | 11947 Handle<DependentCode> DependentCode::Insert(Handle<DependentCode> entries, |
11933 DependencyGroup group, | 11948 DependencyGroup group, |
11934 Handle<Object> object) { | 11949 Handle<Object> object) { |
11935 GroupStartIndexes starts(*entries); | 11950 GroupStartIndexes starts(*entries); |
11936 int start = starts.at(group); | 11951 int start = starts.at(group); |
11937 int end = starts.at(group + 1); | 11952 int end = starts.at(group + 1); |
11938 int number_of_entries = starts.number_of_entries(); | 11953 int number_of_entries = starts.number_of_entries(); |
11939 // Check for existing entry to avoid duplicates. | 11954 // Check for existing entry to avoid duplicates. |
11940 for (int i = start; i < end; i++) { | 11955 for (int i = start; i < end; i++) { |
11941 if (entries->object_at(i) == *object) return entries; | 11956 if (entries->object_at(i) == *object) return entries; |
11942 } | 11957 } |
11943 if (entries->length() < kCodesStartIndex + number_of_entries + 1) { | 11958 if (entries->length() < kCodesStartIndex + number_of_entries + 1) { |
11944 int capacity = kCodesStartIndex + number_of_entries + 1; | 11959 entries = EnsureSpace(entries); |
11945 if (capacity > 5) capacity = capacity * 5 / 4; | 11960 // The number of codes can change after Compact and GC. |
11946 Handle<DependentCode> new_entries = Handle<DependentCode>::cast( | |
11947 FixedArray::CopySize(entries, capacity, TENURED)); | |
11948 // The number of codes can change after GC. | |
11949 starts.Recompute(*entries); | 11961 starts.Recompute(*entries); |
11950 start = starts.at(group); | 11962 start = starts.at(group); |
11951 end = starts.at(group + 1); | 11963 end = starts.at(group + 1); |
11952 number_of_entries = starts.number_of_entries(); | |
11953 for (int i = 0; i < number_of_entries; i++) { | |
11954 entries->clear_at(i); | |
11955 } | |
11956 // If the old fixed array was empty, we need to reset counters of the | |
11957 // new array. | |
11958 if (number_of_entries == 0) { | |
11959 for (int g = 0; g < kGroupCount; g++) { | |
11960 new_entries->set_number_of_entries(static_cast<DependencyGroup>(g), 0); | |
11961 } | |
11962 } | |
11963 entries = new_entries; | |
11964 } | 11964 } |
| 11965 |
11965 entries->ExtendGroup(group); | 11966 entries->ExtendGroup(group); |
11966 entries->set_object_at(end, *object); | 11967 entries->set_object_at(end, *object); |
11967 entries->set_number_of_entries(group, end + 1 - start); | 11968 entries->set_number_of_entries(group, end + 1 - start); |
11968 return entries; | 11969 return entries; |
11969 } | 11970 } |
11970 | 11971 |
11971 | 11972 |
11972 void DependentCode::UpdateToFinishedCode(DependencyGroup group, | 11973 Handle<DependentCode> DependentCode::EnsureSpace( |
11973 CompilationInfo* info, | 11974 Handle<DependentCode> entries) { |
11974 Code* code) { | 11975 if (entries->length() == 0) { |
| 11976 entries = Handle<DependentCode>::cast( |
| 11977 FixedArray::CopySize(entries, kCodesStartIndex + 1, TENURED)); |
| 11978 for (int g = 0; g < kGroupCount; g++) { |
| 11979 entries->set_number_of_entries(static_cast<DependencyGroup>(g), 0); |
| 11980 } |
| 11981 return entries; |
| 11982 } |
| 11983 if (entries->Compact()) return entries; |
| 11984 GroupStartIndexes starts(*entries); |
| 11985 int capacity = |
| 11986 kCodesStartIndex + DependentCode::Grow(starts.number_of_entries()); |
| 11987 return Handle<DependentCode>::cast( |
| 11988 FixedArray::CopySize(entries, capacity, TENURED)); |
| 11989 } |
| 11990 |
| 11991 |
| 11992 bool DependentCode::Compact() { |
| 11993 GroupStartIndexes starts(this); |
| 11994 int n = 0; |
| 11995 for (int g = 0; g < kGroupCount; g++) { |
| 11996 int start = starts.at(g); |
| 11997 int end = starts.at(g + 1); |
| 11998 int count = 0; |
| 11999 DCHECK(start >= n); |
| 12000 for (int i = start; i < end; i++) { |
| 12001 Object* obj = object_at(i); |
| 12002 if (!obj->IsWeakCell() || !WeakCell::cast(obj)->cleared()) { |
| 12003 if (i != n + count) { |
| 12004 copy(i, n + count); |
| 12005 } |
| 12006 count++; |
| 12007 } |
| 12008 } |
| 12009 if (count != end - start) { |
| 12010 set_number_of_entries(static_cast<DependencyGroup>(g), count); |
| 12011 } |
| 12012 n += count; |
| 12013 } |
| 12014 return n < starts.number_of_entries(); |
| 12015 } |
| 12016 |
| 12017 |
| 12018 void DependentCode::UpdateToFinishedCode(DependencyGroup group, Foreign* info, |
| 12019 WeakCell* code_cell) { |
11975 DisallowHeapAllocation no_gc; | 12020 DisallowHeapAllocation no_gc; |
11976 AllowDeferredHandleDereference get_object_wrapper; | |
11977 Foreign* info_wrapper = *info->object_wrapper(); | |
11978 GroupStartIndexes starts(this); | 12021 GroupStartIndexes starts(this); |
11979 int start = starts.at(group); | 12022 int start = starts.at(group); |
11980 int end = starts.at(group + 1); | 12023 int end = starts.at(group + 1); |
11981 for (int i = start; i < end; i++) { | 12024 for (int i = start; i < end; i++) { |
11982 if (object_at(i) == info_wrapper) { | 12025 if (object_at(i) == info) { |
11983 set_object_at(i, code); | 12026 set_object_at(i, code_cell); |
11984 break; | 12027 break; |
11985 } | 12028 } |
11986 } | 12029 } |
11987 | 12030 |
11988 #ifdef DEBUG | 12031 #ifdef DEBUG |
11989 for (int i = start; i < end; i++) { | 12032 for (int i = start; i < end; i++) { |
11990 DCHECK(is_code_at(i) || compilation_info_at(i) != info); | 12033 DCHECK(object_at(i) != info); |
11991 } | 12034 } |
11992 #endif | 12035 #endif |
11993 } | 12036 } |
11994 | 12037 |
11995 | 12038 |
11996 void DependentCode::RemoveCompilationInfo(DependentCode::DependencyGroup group, | 12039 void DependentCode::RemoveCompilationInfo(DependentCode::DependencyGroup group, |
11997 CompilationInfo* info) { | 12040 Foreign* info) { |
11998 DisallowHeapAllocation no_allocation; | 12041 DisallowHeapAllocation no_allocation; |
11999 AllowDeferredHandleDereference get_object_wrapper; | |
12000 Foreign* info_wrapper = *info->object_wrapper(); | |
12001 GroupStartIndexes starts(this); | 12042 GroupStartIndexes starts(this); |
12002 int start = starts.at(group); | 12043 int start = starts.at(group); |
12003 int end = starts.at(group + 1); | 12044 int end = starts.at(group + 1); |
12004 // Find compilation info wrapper. | 12045 // Find compilation info wrapper. |
12005 int info_pos = -1; | 12046 int info_pos = -1; |
12006 for (int i = start; i < end; i++) { | 12047 for (int i = start; i < end; i++) { |
12007 if (object_at(i) == info_wrapper) { | 12048 if (object_at(i) == info) { |
12008 info_pos = i; | 12049 info_pos = i; |
12009 break; | 12050 break; |
12010 } | 12051 } |
12011 } | 12052 } |
12012 if (info_pos == -1) return; // Not found. | 12053 if (info_pos == -1) return; // Not found. |
12013 int gap = info_pos; | 12054 int gap = info_pos; |
12014 // Use the last of each group to fill the gap in the previous group. | 12055 // Use the last of each group to fill the gap in the previous group. |
12015 for (int i = group; i < kGroupCount; i++) { | 12056 for (int i = group; i < kGroupCount; i++) { |
12016 int last_of_group = starts.at(i + 1) - 1; | 12057 int last_of_group = starts.at(i + 1) - 1; |
12017 DCHECK(last_of_group >= gap); | 12058 DCHECK(last_of_group >= gap); |
12018 if (last_of_group == gap) continue; | 12059 if (last_of_group == gap) continue; |
12019 copy(last_of_group, gap); | 12060 copy(last_of_group, gap); |
12020 gap = last_of_group; | 12061 gap = last_of_group; |
12021 } | 12062 } |
12022 DCHECK(gap == starts.number_of_entries() - 1); | 12063 DCHECK(gap == starts.number_of_entries() - 1); |
12023 clear_at(gap); // Clear last gap. | 12064 clear_at(gap); // Clear last gap. |
12024 set_number_of_entries(group, end - start - 1); | 12065 set_number_of_entries(group, end - start - 1); |
12025 | 12066 |
12026 #ifdef DEBUG | 12067 #ifdef DEBUG |
12027 for (int i = start; i < end - 1; i++) { | 12068 for (int i = start; i < end - 1; i++) { |
12028 DCHECK(is_code_at(i) || compilation_info_at(i) != info); | 12069 DCHECK(object_at(i) != info); |
12029 } | 12070 } |
12030 #endif | 12071 #endif |
12031 } | 12072 } |
12032 | 12073 |
12033 | 12074 |
12034 bool DependentCode::Contains(DependencyGroup group, Code* code) { | 12075 bool DependentCode::Contains(DependencyGroup group, WeakCell* code_cell) { |
12035 GroupStartIndexes starts(this); | 12076 GroupStartIndexes starts(this); |
12036 int start = starts.at(group); | 12077 int start = starts.at(group); |
12037 int end = starts.at(group + 1); | 12078 int end = starts.at(group + 1); |
12038 for (int i = start; i < end; i++) { | 12079 for (int i = start; i < end; i++) { |
12039 if (object_at(i) == code) return true; | 12080 if (object_at(i) == code_cell) return true; |
12040 } | 12081 } |
12041 return false; | 12082 return false; |
12042 } | 12083 } |
12043 | 12084 |
12044 | 12085 |
12045 bool DependentCode::MarkCodeForDeoptimization( | 12086 bool DependentCode::MarkCodeForDeoptimization( |
12046 Isolate* isolate, | 12087 Isolate* isolate, |
12047 DependentCode::DependencyGroup group) { | 12088 DependentCode::DependencyGroup group) { |
12048 DisallowHeapAllocation no_allocation_scope; | 12089 DisallowHeapAllocation no_allocation_scope; |
12049 DependentCode::GroupStartIndexes starts(this); | 12090 DependentCode::GroupStartIndexes starts(this); |
12050 int start = starts.at(group); | 12091 int start = starts.at(group); |
12051 int end = starts.at(group + 1); | 12092 int end = starts.at(group + 1); |
12052 int code_entries = starts.number_of_entries(); | 12093 int code_entries = starts.number_of_entries(); |
12053 if (start == end) return false; | 12094 if (start == end) return false; |
12054 | 12095 |
12055 // Mark all the code that needs to be deoptimized. | 12096 // Mark all the code that needs to be deoptimized. |
12056 bool marked = false; | 12097 bool marked = false; |
| 12098 bool invalidate_embedded_objects = group == kWeakCodeGroup; |
12057 for (int i = start; i < end; i++) { | 12099 for (int i = start; i < end; i++) { |
12058 if (is_code_at(i)) { | 12100 Object* obj = object_at(i); |
12059 Code* code = code_at(i); | 12101 if (obj->IsWeakCell()) { |
| 12102 WeakCell* cell = WeakCell::cast(obj); |
| 12103 if (cell->cleared()) continue; |
| 12104 Code* code = Code::cast(cell->value()); |
12060 if (!code->marked_for_deoptimization()) { | 12105 if (!code->marked_for_deoptimization()) { |
12061 SetMarkedForDeoptimization(code, group); | 12106 SetMarkedForDeoptimization(code, group); |
| 12107 if (invalidate_embedded_objects) { |
| 12108 code->InvalidateEmbeddedObjects(); |
| 12109 } |
12062 marked = true; | 12110 marked = true; |
12063 } | 12111 } |
12064 } else { | 12112 } else { |
12065 CompilationInfo* info = compilation_info_at(i); | 12113 DCHECK(obj->IsForeign()); |
| 12114 CompilationInfo* info = reinterpret_cast<CompilationInfo*>( |
| 12115 Foreign::cast(obj)->foreign_address()); |
12066 info->AbortDueToDependencyChange(); | 12116 info->AbortDueToDependencyChange(); |
12067 } | 12117 } |
12068 } | 12118 } |
12069 // Compact the array by moving all subsequent groups to fill in the new holes. | 12119 // Compact the array by moving all subsequent groups to fill in the new holes. |
12070 for (int src = end, dst = start; src < code_entries; src++, dst++) { | 12120 for (int src = end, dst = start; src < code_entries; src++, dst++) { |
12071 copy(src, dst); | 12121 copy(src, dst); |
12072 } | 12122 } |
12073 // Now the holes are at the end of the array, zap them for heap-verifier. | 12123 // Now the holes are at the end of the array, zap them for heap-verifier. |
12074 int removed = end - start; | 12124 int removed = end - start; |
12075 for (int i = code_entries - removed; i < code_entries; i++) { | 12125 for (int i = code_entries - removed; i < code_entries; i++) { |
12076 clear_at(i); | 12126 clear_at(i); |
12077 } | 12127 } |
12078 set_number_of_entries(group, 0); | 12128 set_number_of_entries(group, 0); |
12079 return marked; | 12129 return marked; |
12080 } | 12130 } |
12081 | 12131 |
12082 | 12132 |
12083 void DependentCode::DeoptimizeDependentCodeGroup( | 12133 void DependentCode::DeoptimizeDependentCodeGroup( |
12084 Isolate* isolate, | 12134 Isolate* isolate, |
12085 DependentCode::DependencyGroup group) { | 12135 DependentCode::DependencyGroup group) { |
12086 DCHECK(AllowCodeDependencyChange::IsAllowed()); | 12136 DCHECK(AllowCodeDependencyChange::IsAllowed()); |
12087 DisallowHeapAllocation no_allocation_scope; | 12137 DisallowHeapAllocation no_allocation_scope; |
12088 bool marked = MarkCodeForDeoptimization(isolate, group); | 12138 bool marked = MarkCodeForDeoptimization(isolate, group); |
12089 | |
12090 if (marked) Deoptimizer::DeoptimizeMarkedCode(isolate); | 12139 if (marked) Deoptimizer::DeoptimizeMarkedCode(isolate); |
12091 } | 12140 } |
12092 | 12141 |
12093 | 12142 |
12094 void DependentCode::SetMarkedForDeoptimization(Code* code, | 12143 void DependentCode::SetMarkedForDeoptimization(Code* code, |
12095 DependencyGroup group) { | 12144 DependencyGroup group) { |
12096 code->set_marked_for_deoptimization(true); | 12145 code->set_marked_for_deoptimization(true); |
12097 if (FLAG_trace_deopt && | 12146 if (FLAG_trace_deopt && |
12098 (code->deoptimization_data() != code->GetHeap()->empty_fixed_array())) { | 12147 (code->deoptimization_data() != code->GetHeap()->empty_fixed_array())) { |
12099 DeoptimizationInputData* deopt_data = | 12148 DeoptimizationInputData* deopt_data = |
(...skipping 1060 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13160 } | 13209 } |
13161 } | 13210 } |
13162 | 13211 |
13163 | 13212 |
13164 // static | 13213 // static |
13165 void AllocationSite::AddDependentCompilationInfo( | 13214 void AllocationSite::AddDependentCompilationInfo( |
13166 Handle<AllocationSite> site, DependentCode::DependencyGroup group, | 13215 Handle<AllocationSite> site, DependentCode::DependencyGroup group, |
13167 CompilationInfo* info) { | 13216 CompilationInfo* info) { |
13168 Handle<DependentCode> dep(site->dependent_code()); | 13217 Handle<DependentCode> dep(site->dependent_code()); |
13169 Handle<DependentCode> codes = | 13218 Handle<DependentCode> codes = |
13170 DependentCode::Insert(dep, group, info->object_wrapper()); | 13219 DependentCode::InsertCompilationInfo(dep, group, info->object_wrapper()); |
13171 if (*codes != site->dependent_code()) site->set_dependent_code(*codes); | 13220 if (*codes != site->dependent_code()) site->set_dependent_code(*codes); |
13172 info->dependencies(group)->Add(Handle<HeapObject>(*site), info->zone()); | 13221 info->dependencies(group)->Add(Handle<HeapObject>(*site), info->zone()); |
13173 } | 13222 } |
13174 | 13223 |
13175 | 13224 |
13176 const char* AllocationSite::PretenureDecisionName(PretenureDecision decision) { | 13225 const char* AllocationSite::PretenureDecisionName(PretenureDecision decision) { |
13177 switch (decision) { | 13226 switch (decision) { |
13178 case kUndecided: return "undecided"; | 13227 case kUndecided: return "undecided"; |
13179 case kDontTenure: return "don't tenure"; | 13228 case kDontTenure: return "don't tenure"; |
13180 case kMaybeTenure: return "maybe tenure"; | 13229 case kMaybeTenure: return "maybe tenure"; |
(...skipping 2792 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15973 } | 16022 } |
15974 | 16023 |
15975 | 16024 |
15976 void ObjectHashTable::RemoveEntry(int entry) { | 16025 void ObjectHashTable::RemoveEntry(int entry) { |
15977 set_the_hole(EntryToIndex(entry)); | 16026 set_the_hole(EntryToIndex(entry)); |
15978 set_the_hole(EntryToIndex(entry) + 1); | 16027 set_the_hole(EntryToIndex(entry) + 1); |
15979 ElementRemoved(); | 16028 ElementRemoved(); |
15980 } | 16029 } |
15981 | 16030 |
15982 | 16031 |
15983 Object* WeakHashTable::Lookup(Handle<Object> key) { | 16032 Object* WeakHashTable::Lookup(Handle<HeapObject> key) { |
15984 DisallowHeapAllocation no_gc; | 16033 DisallowHeapAllocation no_gc; |
15985 DCHECK(IsKey(*key)); | 16034 DCHECK(IsKey(*key)); |
15986 int entry = FindEntry(key); | 16035 int entry = FindEntry(key); |
15987 if (entry == kNotFound) return GetHeap()->the_hole_value(); | 16036 if (entry == kNotFound) return GetHeap()->the_hole_value(); |
15988 return get(EntryToValueIndex(entry)); | 16037 return get(EntryToValueIndex(entry)); |
15989 } | 16038 } |
15990 | 16039 |
15991 | 16040 |
15992 Handle<WeakHashTable> WeakHashTable::Put(Handle<WeakHashTable> table, | 16041 Handle<WeakHashTable> WeakHashTable::Put(Handle<WeakHashTable> table, |
15993 Handle<Object> key, | 16042 Handle<HeapObject> key, |
15994 Handle<Object> value) { | 16043 Handle<HeapObject> value) { |
15995 DCHECK(table->IsKey(*key)); | 16044 DCHECK(table->IsKey(*key)); |
15996 int entry = table->FindEntry(key); | 16045 int entry = table->FindEntry(key); |
15997 // Key is already in table, just overwrite value. | 16046 // Key is already in table, just overwrite value. |
15998 if (entry != kNotFound) { | 16047 if (entry != kNotFound) { |
15999 // TODO(ulan): Skipping write barrier is a temporary solution to avoid | 16048 table->set(EntryToValueIndex(entry), *value); |
16000 // memory leaks. Remove this once we have special visitor for weak fixed | |
16001 // arrays. | |
16002 table->set(EntryToValueIndex(entry), *value, SKIP_WRITE_BARRIER); | |
16003 return table; | 16049 return table; |
16004 } | 16050 } |
16005 | 16051 |
| 16052 Handle<WeakCell> key_cell = key->GetIsolate()->factory()->NewWeakCell(key); |
| 16053 |
16006 // Check whether the hash table should be extended. | 16054 // Check whether the hash table should be extended. |
16007 table = EnsureCapacity(table, 1, key, TENURED); | 16055 table = EnsureCapacity(table, 1, key, TENURED); |
16008 | 16056 |
16009 table->AddEntry(table->FindInsertionEntry(table->Hash(key)), key, value); | 16057 table->AddEntry(table->FindInsertionEntry(table->Hash(key)), key_cell, value); |
16010 return table; | 16058 return table; |
16011 } | 16059 } |
16012 | 16060 |
16013 | 16061 |
16014 void WeakHashTable::AddEntry(int entry, | 16062 void WeakHashTable::AddEntry(int entry, Handle<WeakCell> key_cell, |
16015 Handle<Object> key, | 16063 Handle<HeapObject> value) { |
16016 Handle<Object> value) { | |
16017 DisallowHeapAllocation no_allocation; | 16064 DisallowHeapAllocation no_allocation; |
16018 // TODO(ulan): Skipping write barrier is a temporary solution to avoid | 16065 set(EntryToIndex(entry), *key_cell); |
16019 // memory leaks. Remove this once we have special visitor for weak fixed | 16066 set(EntryToValueIndex(entry), *value); |
16020 // arrays. | |
16021 set(EntryToIndex(entry), *key, SKIP_WRITE_BARRIER); | |
16022 set(EntryToValueIndex(entry), *value, SKIP_WRITE_BARRIER); | |
16023 ElementAdded(); | 16067 ElementAdded(); |
16024 } | 16068 } |
16025 | 16069 |
16026 | 16070 |
16027 template<class Derived, class Iterator, int entrysize> | 16071 template<class Derived, class Iterator, int entrysize> |
16028 Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Allocate( | 16072 Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Allocate( |
16029 Isolate* isolate, int capacity, PretenureFlag pretenure) { | 16073 Isolate* isolate, int capacity, PretenureFlag pretenure) { |
16030 // Capacity must be a power of two, since we depend on being able | 16074 // Capacity must be a power of two, since we depend on being able |
16031 // to divide and multiple by 2 (kLoadFactor) to derive capacity | 16075 // to divide and multiple by 2 (kLoadFactor) to derive capacity |
16032 // from number of buckets. If we decide to change kLoadFactor | 16076 // from number of buckets. If we decide to change kLoadFactor |
(...skipping 922 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16955 Handle<HeapType> new_type = UpdatedType(cell, value); | 16999 Handle<HeapType> new_type = UpdatedType(cell, value); |
16956 cell->set_type(*new_type); | 17000 cell->set_type(*new_type); |
16957 } | 17001 } |
16958 return value; | 17002 return value; |
16959 } | 17003 } |
16960 | 17004 |
16961 | 17005 |
16962 // static | 17006 // static |
16963 void PropertyCell::AddDependentCompilationInfo(Handle<PropertyCell> cell, | 17007 void PropertyCell::AddDependentCompilationInfo(Handle<PropertyCell> cell, |
16964 CompilationInfo* info) { | 17008 CompilationInfo* info) { |
16965 Handle<DependentCode> codes = | 17009 Handle<DependentCode> codes = DependentCode::InsertCompilationInfo( |
16966 DependentCode::Insert(handle(cell->dependent_code(), info->isolate()), | 17010 handle(cell->dependent_code(), info->isolate()), |
16967 DependentCode::kPropertyCellChangedGroup, | 17011 DependentCode::kPropertyCellChangedGroup, info->object_wrapper()); |
16968 info->object_wrapper()); | |
16969 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); | 17012 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); |
16970 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( | 17013 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( |
16971 cell, info->zone()); | 17014 cell, info->zone()); |
16972 } | 17015 } |
16973 | 17016 |
16974 } } // namespace v8::internal | 17017 } } // namespace v8::internal |
OLD | NEW |