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

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

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

Powered by Google App Engine
This is Rietveld 408576698