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

Side by Side Diff: src/debug/debug-coverage.cc

Issue 2882973002: [coverage] Block coverage with support for IfStatements (Closed)
Patch Set: Address comments Created 3 years, 6 months 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/debug/debug-coverage.h ('k') | src/debug/debug-interface.h » ('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 2017 the V8 project authors. All rights reserved. 1 // Copyright 2017 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/debug/debug-coverage.h" 5 #include "src/debug/debug-coverage.h"
6 6
7 #include "src/base/hashmap.h" 7 #include "src/base/hashmap.h"
8 #include "src/deoptimizer.h" 8 #include "src/deoptimizer.h"
9 #include "src/frames-inl.h" 9 #include "src/frames-inl.h"
10 #include "src/isolate.h" 10 #include "src/isolate.h"
11 #include "src/objects-inl.h"
12 #include "src/objects.h" 11 #include "src/objects.h"
12 #include "src/objects/debug-objects-inl.h"
13 13
14 namespace v8 { 14 namespace v8 {
15 namespace internal { 15 namespace internal {
16 16
17 class SharedToCounterMap 17 class SharedToCounterMap
18 : public base::TemplateHashMapImpl<SharedFunctionInfo*, uint32_t, 18 : public base::TemplateHashMapImpl<SharedFunctionInfo*, uint32_t,
19 base::KeyEqualityMatcher<void*>, 19 base::KeyEqualityMatcher<void*>,
20 base::DefaultAllocationPolicy> { 20 base::DefaultAllocationPolicy> {
21 public: 21 public:
22 typedef base::TemplateHashMapEntry<SharedFunctionInfo*, uint32_t> Entry; 22 typedef base::TemplateHashMapEntry<SharedFunctionInfo*, uint32_t> Entry;
(...skipping 27 matching lines...) Expand all
50 if (start == kNoSourcePosition) start = info->start_position(); 50 if (start == kNoSourcePosition) start = info->start_position();
51 return start; 51 return start;
52 } 52 }
53 53
54 bool CompareSharedFunctionInfo(SharedFunctionInfo* a, SharedFunctionInfo* b) { 54 bool CompareSharedFunctionInfo(SharedFunctionInfo* a, SharedFunctionInfo* b) {
55 int a_start = StartPosition(a); 55 int a_start = StartPosition(a);
56 int b_start = StartPosition(b); 56 int b_start = StartPosition(b);
57 if (a_start == b_start) return a->end_position() > b->end_position(); 57 if (a_start == b_start) return a->end_position() > b->end_position();
58 return a_start < b_start; 58 return a_start < b_start;
59 } 59 }
60
61 bool CompareCoverageBlock(const CoverageBlock& a, const CoverageBlock& b) {
62 DCHECK(a.start != kNoSourcePosition && a.end != kNoSourcePosition);
63 DCHECK(b.start != kNoSourcePosition && b.end != kNoSourcePosition);
64 if (a.start == b.start) return a.end > b.end;
65 return a.start < b.start;
66 }
67
68 std::vector<CoverageBlock> GetSortedBlockData(Isolate* isolate,
69 SharedFunctionInfo* shared) {
70 DCHECK(FLAG_block_coverage);
71 DCHECK(shared->HasCoverageInfo());
72
73 std::vector<CoverageBlock> result;
74
75 CoverageInfo* coverage_info =
76 CoverageInfo::cast(shared->GetDebugInfo()->coverage_info());
77
78 for (int i = 0; i < coverage_info->SlotCount(); i++) {
79 const int start_pos = coverage_info->StartSourcePosition(i);
80 const int until_pos = coverage_info->EndSourcePosition(i);
81 const int count = coverage_info->BlockCount(i);
82
83 DCHECK(start_pos != kNoSourcePosition);
84 DCHECK(until_pos != kNoSourcePosition);
85
86 result.emplace_back(start_pos, until_pos, count);
87 }
88
89 // Sort according to the block nesting structure.
90 std::sort(result.begin(), result.end(), CompareCoverageBlock);
91
92 return result;
93 }
60 } // anonymous namespace 94 } // anonymous namespace
61 95
62 Coverage* Coverage::CollectPrecise(Isolate* isolate) { 96 Coverage* Coverage::CollectPrecise(Isolate* isolate) {
63 DCHECK(!isolate->is_best_effort_code_coverage()); 97 DCHECK(!isolate->is_best_effort_code_coverage());
64 Coverage* result = Collect(isolate, isolate->code_coverage_mode()); 98 Coverage* result = Collect(isolate, isolate->code_coverage_mode());
65 if (isolate->is_precise_binary_code_coverage()) { 99 if (isolate->is_precise_binary_code_coverage()) {
66 // We do not have to hold onto feedback vectors for invocations we already 100 // We do not have to hold onto feedback vectors for invocations we already
67 // reported. So we can reset the list. 101 // reported. So we can reset the list.
68 isolate->SetCodeCoverageList(*ArrayList::New(isolate, 0)); 102 isolate->SetCodeCoverageList(*ArrayList::New(isolate, 0));
69 } 103 }
70 return result; 104 return result;
71 } 105 }
72 106
73 Coverage* Coverage::CollectBestEffort(Isolate* isolate) { 107 Coverage* Coverage::CollectBestEffort(Isolate* isolate) {
74 return Collect(isolate, v8::debug::Coverage::kBestEffort); 108 return Collect(isolate, v8::debug::Coverage::kBestEffort);
75 } 109 }
76 110
77 Coverage* Coverage::Collect(Isolate* isolate, 111 Coverage* Coverage::Collect(Isolate* isolate,
78 v8::debug::Coverage::Mode collectionMode) { 112 v8::debug::Coverage::Mode collectionMode) {
79 SharedToCounterMap counter_map; 113 SharedToCounterMap counter_map;
80 114
81 switch (isolate->code_coverage_mode()) { 115 switch (isolate->code_coverage_mode()) {
116 case v8::debug::Coverage::kBlockCount:
82 case v8::debug::Coverage::kPreciseBinary: 117 case v8::debug::Coverage::kPreciseBinary:
83 case v8::debug::Coverage::kPreciseCount: { 118 case v8::debug::Coverage::kPreciseCount: {
84 bool reset_count = collectionMode != v8::debug::Coverage::kBestEffort; 119 bool reset_count = collectionMode != v8::debug::Coverage::kBestEffort;
85 // Feedback vectors are already listed to prevent losing them to GC. 120 // Feedback vectors are already listed to prevent losing them to GC.
86 DCHECK(isolate->factory()->code_coverage_list()->IsArrayList()); 121 DCHECK(isolate->factory()->code_coverage_list()->IsArrayList());
87 Handle<ArrayList> list = 122 Handle<ArrayList> list =
88 Handle<ArrayList>::cast(isolate->factory()->code_coverage_list()); 123 Handle<ArrayList>::cast(isolate->factory()->code_coverage_list());
89 for (int i = 0; i < list->Length(); i++) { 124 for (int i = 0; i < list->Length(); i++) {
90 FeedbackVector* vector = FeedbackVector::cast(list->Get(i)); 125 FeedbackVector* vector = FeedbackVector::cast(list->Get(i));
91 SharedFunctionInfo* shared = vector->shared_function_info(); 126 SharedFunctionInfo* shared = vector->shared_function_info();
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
142 for (SharedFunctionInfo* info : sorted) { 177 for (SharedFunctionInfo* info : sorted) {
143 int start = StartPosition(info); 178 int start = StartPosition(info);
144 int end = info->end_position(); 179 int end = info->end_position();
145 uint32_t count = counter_map.Get(info); 180 uint32_t count = counter_map.Get(info);
146 // Find the correct outer function based on start position. 181 // Find the correct outer function based on start position.
147 while (!nesting.empty() && functions->at(nesting.back()).end <= start) { 182 while (!nesting.empty() && functions->at(nesting.back()).end <= start) {
148 nesting.pop_back(); 183 nesting.pop_back();
149 } 184 }
150 if (count != 0) { 185 if (count != 0) {
151 switch (collectionMode) { 186 switch (collectionMode) {
187 case v8::debug::Coverage::kBlockCount:
152 case v8::debug::Coverage::kPreciseCount: 188 case v8::debug::Coverage::kPreciseCount:
153 break; 189 break;
154 case v8::debug::Coverage::kPreciseBinary: 190 case v8::debug::Coverage::kPreciseBinary:
155 count = info->has_reported_binary_coverage() ? 0 : 1; 191 count = info->has_reported_binary_coverage() ? 0 : 1;
156 info->set_has_reported_binary_coverage(true); 192 info->set_has_reported_binary_coverage(true);
157 break; 193 break;
158 case v8::debug::Coverage::kBestEffort: 194 case v8::debug::Coverage::kBestEffort:
159 count = 1; 195 count = 1;
160 break; 196 break;
161 } 197 }
162 } 198 }
163 // Only include a function range if it has a non-0 count, or 199 // Only include a function range if it has a non-0 count, or
164 // if it is directly nested inside a function with non-0 count. 200 // if it is directly nested inside a function with non-0 count.
165 if (count != 0 || 201 if (count != 0 ||
166 (!nesting.empty() && functions->at(nesting.back()).count != 0)) { 202 (!nesting.empty() && functions->at(nesting.back()).count != 0)) {
167 Handle<String> name(info->DebugName(), isolate); 203 Handle<String> name(info->DebugName(), isolate);
168 nesting.push_back(functions->size()); 204 nesting.push_back(functions->size());
169 functions->emplace_back(start, end, count, name); 205 functions->emplace_back(start, end, count, name);
206
207 if (FLAG_block_coverage && info->HasCoverageInfo()) {
208 CoverageFunction* function = &functions->back();
209 function->blocks = GetSortedBlockData(isolate, info);
210 }
170 } 211 }
171 } 212 }
172 213
173 // Remove entries for scripts that have no coverage. 214 // Remove entries for scripts that have no coverage.
174 if (functions->empty()) result->pop_back(); 215 if (functions->empty()) result->pop_back();
175 } 216 }
176 return result; 217 return result;
177 } 218 }
178 219
179 void Coverage::SelectMode(Isolate* isolate, debug::Coverage::Mode mode) { 220 void Coverage::SelectMode(Isolate* isolate, debug::Coverage::Mode mode) {
180 switch (mode) { 221 switch (mode) {
181 case debug::Coverage::kBestEffort: 222 case debug::Coverage::kBestEffort:
223 if (FLAG_block_coverage) isolate->debug()->RemoveAllCoverageInfos();
182 isolate->SetCodeCoverageList(isolate->heap()->undefined_value()); 224 isolate->SetCodeCoverageList(isolate->heap()->undefined_value());
183 break; 225 break;
226 case debug::Coverage::kBlockCount:
184 case debug::Coverage::kPreciseBinary: 227 case debug::Coverage::kPreciseBinary:
185 case debug::Coverage::kPreciseCount: { 228 case debug::Coverage::kPreciseCount: {
186 HandleScope scope(isolate); 229 HandleScope scope(isolate);
187 // Remove all optimized function. Optimized and inlined functions do not 230 // Remove all optimized function. Optimized and inlined functions do not
188 // increment invocation count. 231 // increment invocation count.
189 Deoptimizer::DeoptimizeAll(isolate); 232 Deoptimizer::DeoptimizeAll(isolate);
190 // Collect existing feedback vectors. 233 // Collect existing feedback vectors.
191 std::vector<Handle<FeedbackVector>> vectors; 234 std::vector<Handle<FeedbackVector>> vectors;
192 { 235 {
193 HeapIterator heap_iterator(isolate->heap()); 236 HeapIterator heap_iterator(isolate->heap());
(...skipping 16 matching lines...) Expand all
210 for (const auto& vector : vectors) list = ArrayList::Add(list, vector); 253 for (const auto& vector : vectors) list = ArrayList::Add(list, vector);
211 isolate->SetCodeCoverageList(*list); 254 isolate->SetCodeCoverageList(*list);
212 break; 255 break;
213 } 256 }
214 } 257 }
215 isolate->set_code_coverage_mode(mode); 258 isolate->set_code_coverage_mode(mode);
216 } 259 }
217 260
218 } // namespace internal 261 } // namespace internal
219 } // namespace v8 262 } // namespace v8
OLDNEW
« no previous file with comments | « src/debug/debug-coverage.h ('k') | src/debug/debug-interface.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698