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 11906 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11917 // static | 11917 // static |
11918 void Map::AddDependentCode(Handle<Map> map, | 11918 void Map::AddDependentCode(Handle<Map> map, |
11919 DependentCode::DependencyGroup group, | 11919 DependentCode::DependencyGroup group, |
11920 Handle<Code> code) { | 11920 Handle<Code> code) { |
11921 Handle<DependentCode> codes = DependentCode::Insert( | 11921 Handle<DependentCode> codes = DependentCode::Insert( |
11922 Handle<DependentCode>(map->dependent_code()), group, code); | 11922 Handle<DependentCode>(map->dependent_code()), group, code); |
11923 if (*codes != map->dependent_code()) map->set_dependent_code(*codes); | 11923 if (*codes != map->dependent_code()) map->set_dependent_code(*codes); |
11924 } | 11924 } |
11925 | 11925 |
11926 | 11926 |
11927 // static | |
11928 void Map::AddDependentIC(Handle<Map> map, | |
11929 Handle<Code> stub) { | |
11930 DCHECK(stub->next_code_link()->IsUndefined()); | |
11931 int n = map->dependent_code()->number_of_entries(DependentCode::kWeakICGroup); | |
11932 if (n == 0) { | |
11933 // Slow path: insert the head of the list with possible heap allocation. | |
11934 Map::AddDependentCode(map, DependentCode::kWeakICGroup, stub); | |
11935 } else { | |
11936 // Fast path: link the stub to the existing head of the list without any | |
11937 // heap allocation. | |
11938 DCHECK(n == 1); | |
11939 map->dependent_code()->AddToDependentICList(stub); | |
11940 } | |
11941 } | |
11942 | |
11943 | |
11944 DependentCode::GroupStartIndexes::GroupStartIndexes(DependentCode* entries) { | 11927 DependentCode::GroupStartIndexes::GroupStartIndexes(DependentCode* entries) { |
11945 Recompute(entries); | 11928 Recompute(entries); |
11946 } | 11929 } |
11947 | 11930 |
11948 | 11931 |
11949 void DependentCode::GroupStartIndexes::Recompute(DependentCode* entries) { | 11932 void DependentCode::GroupStartIndexes::Recompute(DependentCode* entries) { |
11950 start_indexes_[0] = 0; | 11933 start_indexes_[0] = 0; |
11951 for (int g = 1; g <= kGroupCount; g++) { | 11934 for (int g = 1; g <= kGroupCount; g++) { |
11952 int count = entries->number_of_entries(static_cast<DependencyGroup>(g - 1)); | 11935 int count = entries->number_of_entries(static_cast<DependencyGroup>(g - 1)); |
11953 start_indexes_[g] = start_indexes_[g - 1] + count; | 11936 start_indexes_[g] = start_indexes_[g - 1] + count; |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12063 set_number_of_entries(group, end - start - 1); | 12046 set_number_of_entries(group, end - start - 1); |
12064 | 12047 |
12065 #ifdef DEBUG | 12048 #ifdef DEBUG |
12066 for (int i = start; i < end - 1; i++) { | 12049 for (int i = start; i < end - 1; i++) { |
12067 DCHECK(is_code_at(i) || compilation_info_at(i) != info); | 12050 DCHECK(is_code_at(i) || compilation_info_at(i) != info); |
12068 } | 12051 } |
12069 #endif | 12052 #endif |
12070 } | 12053 } |
12071 | 12054 |
12072 | 12055 |
12073 static bool CodeListContains(Object* head, Code* code) { | |
12074 while (!head->IsUndefined()) { | |
12075 if (head == code) return true; | |
12076 head = Code::cast(head)->next_code_link(); | |
12077 } | |
12078 return false; | |
12079 } | |
12080 | |
12081 | |
12082 bool DependentCode::Contains(DependencyGroup group, Code* code) { | 12056 bool DependentCode::Contains(DependencyGroup group, Code* code) { |
12083 GroupStartIndexes starts(this); | 12057 GroupStartIndexes starts(this); |
12084 int start = starts.at(group); | 12058 int start = starts.at(group); |
12085 int end = starts.at(group + 1); | 12059 int end = starts.at(group + 1); |
12086 if (group == kWeakICGroup) { | |
12087 return CodeListContains(object_at(start), code); | |
12088 } | |
12089 for (int i = start; i < end; i++) { | 12060 for (int i = start; i < end; i++) { |
12090 if (object_at(i) == code) return true; | 12061 if (object_at(i) == code) return true; |
12091 } | 12062 } |
12092 return false; | 12063 return false; |
12093 } | 12064 } |
12094 | 12065 |
12095 | 12066 |
12096 bool DependentCode::MarkCodeForDeoptimization( | 12067 bool DependentCode::MarkCodeForDeoptimization( |
12097 Isolate* isolate, | 12068 Isolate* isolate, |
12098 DependentCode::DependencyGroup group) { | 12069 DependentCode::DependencyGroup group) { |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12135 Isolate* isolate, | 12106 Isolate* isolate, |
12136 DependentCode::DependencyGroup group) { | 12107 DependentCode::DependencyGroup group) { |
12137 DCHECK(AllowCodeDependencyChange::IsAllowed()); | 12108 DCHECK(AllowCodeDependencyChange::IsAllowed()); |
12138 DisallowHeapAllocation no_allocation_scope; | 12109 DisallowHeapAllocation no_allocation_scope; |
12139 bool marked = MarkCodeForDeoptimization(isolate, group); | 12110 bool marked = MarkCodeForDeoptimization(isolate, group); |
12140 | 12111 |
12141 if (marked) Deoptimizer::DeoptimizeMarkedCode(isolate); | 12112 if (marked) Deoptimizer::DeoptimizeMarkedCode(isolate); |
12142 } | 12113 } |
12143 | 12114 |
12144 | 12115 |
12145 void DependentCode::AddToDependentICList(Handle<Code> stub) { | |
12146 DisallowHeapAllocation no_heap_allocation; | |
12147 GroupStartIndexes starts(this); | |
12148 int i = starts.at(kWeakICGroup); | |
12149 Object* head = object_at(i); | |
12150 // Try to insert the stub after the head of the list to minimize number of | |
12151 // writes to the DependentCode array, since a write to the array can make it | |
12152 // strong if it was alread marked by incremental marker. | |
12153 if (head->IsCode()) { | |
12154 stub->set_next_code_link(Code::cast(head)->next_code_link()); | |
12155 Code::cast(head)->set_next_code_link(*stub); | |
12156 } else { | |
12157 stub->set_next_code_link(head); | |
12158 set_object_at(i, *stub); | |
12159 } | |
12160 } | |
12161 | |
12162 | |
12163 void DependentCode::SetMarkedForDeoptimization(Code* code, | 12116 void DependentCode::SetMarkedForDeoptimization(Code* code, |
12164 DependencyGroup group) { | 12117 DependencyGroup group) { |
12165 code->set_marked_for_deoptimization(true); | 12118 code->set_marked_for_deoptimization(true); |
12166 if (FLAG_trace_deopt && | 12119 if (FLAG_trace_deopt && |
12167 (code->deoptimization_data() != code->GetHeap()->empty_fixed_array())) { | 12120 (code->deoptimization_data() != code->GetHeap()->empty_fixed_array())) { |
12168 DeoptimizationInputData* deopt_data = | 12121 DeoptimizationInputData* deopt_data = |
12169 DeoptimizationInputData::cast(code->deoptimization_data()); | 12122 DeoptimizationInputData::cast(code->deoptimization_data()); |
12170 CodeTracer::Scope scope(code->GetHeap()->isolate()->GetCodeTracer()); | 12123 CodeTracer::Scope scope(code->GetHeap()->isolate()->GetCodeTracer()); |
12171 PrintF(scope.file(), "[marking dependent code 0x%08" V8PRIxPTR | 12124 PrintF(scope.file(), "[marking dependent code 0x%08" V8PRIxPTR |
12172 " (opt #%d) for deoptimization, reason: %s]\n", | 12125 " (opt #%d) for deoptimization, reason: %s]\n", |
12173 reinterpret_cast<intptr_t>(code), | 12126 reinterpret_cast<intptr_t>(code), |
12174 deopt_data->OptimizationId()->value(), DependencyGroupName(group)); | 12127 deopt_data->OptimizationId()->value(), DependencyGroupName(group)); |
12175 } | 12128 } |
12176 } | 12129 } |
12177 | 12130 |
12178 | 12131 |
12179 const char* DependentCode::DependencyGroupName(DependencyGroup group) { | 12132 const char* DependentCode::DependencyGroupName(DependencyGroup group) { |
12180 switch (group) { | 12133 switch (group) { |
12181 case kWeakICGroup: | |
12182 return "weak-ic"; | |
12183 case kWeakCodeGroup: | 12134 case kWeakCodeGroup: |
12184 return "weak-code"; | 12135 return "weak-code"; |
12185 case kTransitionGroup: | 12136 case kTransitionGroup: |
12186 return "transition"; | 12137 return "transition"; |
12187 case kPrototypeCheckGroup: | 12138 case kPrototypeCheckGroup: |
12188 return "prototype-check"; | 12139 return "prototype-check"; |
12189 case kElementsCantBeAddedGroup: | 12140 case kElementsCantBeAddedGroup: |
12190 return "elements-cant-be-added"; | 12141 return "elements-cant-be-added"; |
12191 case kPropertyCellChangedGroup: | 12142 case kPropertyCellChangedGroup: |
12192 return "property-cell-changed"; | 12143 return "property-cell-changed"; |
(...skipping 4913 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
17106 Handle<DependentCode> codes = | 17057 Handle<DependentCode> codes = |
17107 DependentCode::Insert(handle(cell->dependent_code(), info->isolate()), | 17058 DependentCode::Insert(handle(cell->dependent_code(), info->isolate()), |
17108 DependentCode::kPropertyCellChangedGroup, | 17059 DependentCode::kPropertyCellChangedGroup, |
17109 info->object_wrapper()); | 17060 info->object_wrapper()); |
17110 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); | 17061 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); |
17111 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( | 17062 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( |
17112 cell, info->zone()); | 17063 cell, info->zone()); |
17113 } | 17064 } |
17114 | 17065 |
17115 } } // namespace v8::internal | 17066 } } // namespace v8::internal |
OLD | NEW |