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

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

Issue 2766573003: [debug] introduce precise binary code coverage. (Closed)
Patch Set: fix test Created 3 years, 9 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"
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 } // anonymous namespace 60 } // anonymous namespace
61 61
62 Coverage* Coverage::Collect(Isolate* isolate, bool reset_count) { 62 Coverage* Coverage::CollectPrecise(Isolate* isolate) {
63 DCHECK(!isolate->is_best_effort_code_coverage());
64 Coverage* result = Collect(isolate, isolate->code_coverage_mode());
65 if (isolate->is_precise_binary_code_coverage()) {
66 // We do not have to hold onto feedback vectors for invocations we already
67 // reported. So we can reset the list.
68 isolate->SetCodeCoverageList(*ArrayList::New(isolate, 0));
69 }
70 return result;
71 }
72
73 Coverage* Coverage::CollectBestEffort(Isolate* isolate) {
74 return Collect(isolate, v8::debug::Coverage::kBestEffort);
75 }
76
77 Coverage* Coverage::Collect(Isolate* isolate,
78 v8::debug::Coverage::Mode collectionMode) {
63 SharedToCounterMap counter_map; 79 SharedToCounterMap counter_map;
64 80
65 // Feed invocation count into the counter map.
66 switch (isolate->code_coverage_mode()) { 81 switch (isolate->code_coverage_mode()) {
67 case debug::Coverage::kPreciseCount: { 82 case v8::debug::Coverage::kPreciseBinary:
83 case v8::debug::Coverage::kPreciseCount: {
84 bool reset_count = collectionMode != v8::debug::Coverage::kBestEffort;
68 // Feedback vectors are already listed to prevent losing them to GC. 85 // Feedback vectors are already listed to prevent losing them to GC.
86 DCHECK(isolate->factory()->code_coverage_list()->IsArrayList());
69 Handle<ArrayList> list = 87 Handle<ArrayList> list =
70 Handle<ArrayList>::cast(isolate->factory()->code_coverage_list()); 88 Handle<ArrayList>::cast(isolate->factory()->code_coverage_list());
71 for (int i = 0; i < list->Length(); i++) { 89 for (int i = 0; i < list->Length(); i++) {
72 FeedbackVector* vector = FeedbackVector::cast(list->Get(i)); 90 FeedbackVector* vector = FeedbackVector::cast(list->Get(i));
73 SharedFunctionInfo* shared = vector->shared_function_info(); 91 SharedFunctionInfo* shared = vector->shared_function_info();
74 DCHECK(shared->IsSubjectToDebugging()); 92 DCHECK(shared->IsSubjectToDebugging());
75 uint32_t count = static_cast<uint32_t>(vector->invocation_count()); 93 uint32_t count = static_cast<uint32_t>(vector->invocation_count());
76 if (reset_count) vector->clear_invocation_count(); 94 if (reset_count) vector->clear_invocation_count();
77 counter_map.Add(shared, count); 95 counter_map.Add(shared, count);
78 } 96 }
79 break; 97 break;
80 } 98 }
81 case debug::Coverage::kBestEffort: { 99 case v8::debug::Coverage::kBestEffort: {
82 // Iterate the heap to find all feedback vectors and accumulate the 100 DCHECK(!isolate->factory()->code_coverage_list()->IsArrayList());
83 // invocation counts into the map for each shared function info. 101 DCHECK_EQ(v8::debug::Coverage::kBestEffort, collectionMode);
84 HeapIterator heap_iterator(isolate->heap()); 102 HeapIterator heap_iterator(isolate->heap());
85 while (HeapObject* current_obj = heap_iterator.next()) { 103 while (HeapObject* current_obj = heap_iterator.next()) {
86 if (!current_obj->IsFeedbackVector()) continue; 104 if (!current_obj->IsFeedbackVector()) continue;
87 FeedbackVector* vector = FeedbackVector::cast(current_obj); 105 FeedbackVector* vector = FeedbackVector::cast(current_obj);
88 SharedFunctionInfo* shared = vector->shared_function_info(); 106 SharedFunctionInfo* shared = vector->shared_function_info();
89 if (!shared->IsSubjectToDebugging()) continue; 107 if (!shared->IsSubjectToDebugging()) continue;
90 uint32_t count = static_cast<uint32_t>(vector->invocation_count()); 108 uint32_t count = static_cast<uint32_t>(vector->invocation_count());
91 if (reset_count) vector->clear_invocation_count();
92 counter_map.Add(shared, count); 109 counter_map.Add(shared, count);
93 } 110 }
94 break; 111 break;
95 } 112 }
96 } 113 }
97 114
98 // Iterate shared function infos of every script and build a mapping 115 // Iterate shared function infos of every script and build a mapping
99 // between source ranges and invocation counts. 116 // between source ranges and invocation counts.
100 Coverage* result = new Coverage(); 117 Coverage* result = new Coverage();
101 Script::Iterator scripts(isolate); 118 Script::Iterator scripts(isolate);
(...skipping 14 matching lines...) Expand all
116 sorted.push_back(info); 133 sorted.push_back(info);
117 } 134 }
118 std::sort(sorted.begin(), sorted.end(), CompareSharedFunctionInfo); 135 std::sort(sorted.begin(), sorted.end(), CompareSharedFunctionInfo);
119 } 136 }
120 137
121 // Use sorted list to reconstruct function nesting. 138 // Use sorted list to reconstruct function nesting.
122 for (SharedFunctionInfo* info : sorted) { 139 for (SharedFunctionInfo* info : sorted) {
123 int start = StartPosition(info); 140 int start = StartPosition(info);
124 int end = info->end_position(); 141 int end = info->end_position();
125 uint32_t count = counter_map.Get(info); 142 uint32_t count = counter_map.Get(info);
143 if (count != 0) {
144 switch (collectionMode) {
145 case v8::debug::Coverage::kPreciseCount:
146 break;
147 case v8::debug::Coverage::kPreciseBinary:
148 count = info->has_reported_binary_coverage() ? 0 : 1;
149 info->set_has_reported_binary_coverage(true);
150 break;
151 case v8::debug::Coverage::kBestEffort:
152 count = 1;
153 break;
154 }
155 }
126 Handle<String> name(info->DebugName(), isolate); 156 Handle<String> name(info->DebugName(), isolate);
127 functions->emplace_back(start, end, count, name); 157 functions->emplace_back(start, end, count, name);
128 } 158 }
129 } 159 }
130 return result; 160 return result;
131 } 161 }
132 162
133 void Coverage::SelectMode(Isolate* isolate, debug::Coverage::Mode mode) { 163 void Coverage::SelectMode(Isolate* isolate, debug::Coverage::Mode mode) {
134 switch (mode) { 164 switch (mode) {
135 case debug::Coverage::kBestEffort: 165 case debug::Coverage::kBestEffort:
136 isolate->SetCodeCoverageList(isolate->heap()->undefined_value()); 166 isolate->SetCodeCoverageList(isolate->heap()->undefined_value());
137 break; 167 break;
168 case debug::Coverage::kPreciseBinary:
138 case debug::Coverage::kPreciseCount: { 169 case debug::Coverage::kPreciseCount: {
139 HandleScope scope(isolate); 170 HandleScope scope(isolate);
140 // Remove all optimized function. Optimized and inlined functions do not 171 // Remove all optimized function. Optimized and inlined functions do not
141 // increment invocation count. 172 // increment invocation count.
142 Deoptimizer::DeoptimizeAll(isolate); 173 Deoptimizer::DeoptimizeAll(isolate);
143 // Collect existing feedback vectors. 174 // Collect existing feedback vectors.
144 std::vector<Handle<FeedbackVector>> vectors; 175 std::vector<Handle<FeedbackVector>> vectors;
145 { 176 {
146 HeapIterator heap_iterator(isolate->heap()); 177 HeapIterator heap_iterator(isolate->heap());
147 while (HeapObject* current_obj = heap_iterator.next()) { 178 while (HeapObject* current_obj = heap_iterator.next()) {
148 if (!current_obj->IsFeedbackVector()) continue; 179 if (current_obj->IsSharedFunctionInfo()) {
149 FeedbackVector* vector = FeedbackVector::cast(current_obj); 180 SharedFunctionInfo* shared = SharedFunctionInfo::cast(current_obj);
150 SharedFunctionInfo* shared = vector->shared_function_info(); 181 shared->set_has_reported_binary_coverage(false);
151 if (!shared->IsSubjectToDebugging()) continue; 182 } else if (current_obj->IsFeedbackVector()) {
152 vectors.emplace_back(vector, isolate); 183 FeedbackVector* vector = FeedbackVector::cast(current_obj);
184 SharedFunctionInfo* shared = vector->shared_function_info();
185 if (!shared->IsSubjectToDebugging()) continue;
186 vectors.emplace_back(vector, isolate);
187 }
153 } 188 }
154 } 189 }
155 // Add collected feedback vectors to the root list lest we lose them to 190 // Add collected feedback vectors to the root list lest we lose them to
156 // GC. 191 // GC.
157 Handle<ArrayList> list = 192 Handle<ArrayList> list =
158 ArrayList::New(isolate, static_cast<int>(vectors.size())); 193 ArrayList::New(isolate, static_cast<int>(vectors.size()));
159 for (const auto& vector : vectors) list = ArrayList::Add(list, vector); 194 for (const auto& vector : vectors) list = ArrayList::Add(list, vector);
160 isolate->SetCodeCoverageList(*list); 195 isolate->SetCodeCoverageList(*list);
161 break; 196 break;
162 } 197 }
163 } 198 }
164 isolate->set_code_coverage_mode(mode); 199 isolate->set_code_coverage_mode(mode);
165 } 200 }
166 201
167 } // namespace internal 202 } // namespace internal
168 } // namespace v8 203 } // 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