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

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

Issue 2696163002: [debugger] implement inspector-facing API for code coverage. (Closed)
Patch Set: Created 3 years, 10 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/isolate.h" 9 #include "src/isolate.h"
10 #include "src/objects-inl.h" 10 #include "src/objects-inl.h"
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 } 51 }
52 52
53 bool CompareSharedFunctionInfo(SharedFunctionInfo* a, SharedFunctionInfo* b) { 53 bool CompareSharedFunctionInfo(SharedFunctionInfo* a, SharedFunctionInfo* b) {
54 int a_start = StartPosition(a); 54 int a_start = StartPosition(a);
55 int b_start = StartPosition(b); 55 int b_start = StartPosition(b);
56 if (a_start == b_start) return a->end_position() > b->end_position(); 56 if (a_start == b_start) return a->end_position() > b->end_position();
57 return a_start < b_start; 57 return a_start < b_start;
58 } 58 }
59 } // anonymous namespace 59 } // anonymous namespace
60 60
61 std::vector<Coverage::ScriptData> Coverage::Collect(Isolate* isolate) { 61 CoverageScript::CoverageScript(Isolate* isolate, Handle<Script> s,
62 int source_length)
63 : script(s),
64 toplevel(0, source_length, 1, isolate->factory()->empty_string()) {}
65
66 Coverage* Coverage::Collect(Isolate* isolate) {
62 SharedToCounterMap counter_map; 67 SharedToCounterMap counter_map;
63 68
64 // Feed invocation count into the counter map. 69 // Feed invocation count into the counter map.
65 if (isolate->IsCodeCoverageEnabled()) { 70 if (isolate->IsCodeCoverageEnabled()) {
66 // Feedback vectors are already listed to prevent losing them to GC. 71 // Feedback vectors are already listed to prevent losing them to GC.
67 Handle<ArrayList> list = 72 Handle<ArrayList> list =
68 Handle<ArrayList>::cast(isolate->factory()->code_coverage_list()); 73 Handle<ArrayList>::cast(isolate->factory()->code_coverage_list());
69 for (int i = 0; i < list->Length(); i++) { 74 for (int i = 0; i < list->Length(); i++) {
70 FeedbackVector* vector = FeedbackVector::cast(list->Get(i)); 75 FeedbackVector* vector = FeedbackVector::cast(list->Get(i));
71 SharedFunctionInfo* shared = vector->shared_function_info(); 76 SharedFunctionInfo* shared = vector->shared_function_info();
(...skipping 10 matching lines...) Expand all
82 FeedbackVector* vector = FeedbackVector::cast(current_obj); 87 FeedbackVector* vector = FeedbackVector::cast(current_obj);
83 SharedFunctionInfo* shared = vector->shared_function_info(); 88 SharedFunctionInfo* shared = vector->shared_function_info();
84 if (!shared->IsSubjectToDebugging()) continue; 89 if (!shared->IsSubjectToDebugging()) continue;
85 uint32_t count = static_cast<uint32_t>(vector->invocation_count()); 90 uint32_t count = static_cast<uint32_t>(vector->invocation_count());
86 counter_map.Add(shared, count); 91 counter_map.Add(shared, count);
87 } 92 }
88 } 93 }
89 94
90 // Iterate shared function infos of every script and build a mapping 95 // Iterate shared function infos of every script and build a mapping
91 // between source ranges and invocation counts. 96 // between source ranges and invocation counts.
92 std::vector<Coverage::ScriptData> result; 97 Coverage* result = new Coverage();
93 Script::Iterator scripts(isolate); 98 Script::Iterator scripts(isolate);
94 while (Script* script = scripts.Next()) { 99 while (Script* script = scripts.Next()) {
95 // Dismiss non-user scripts. 100 // Dismiss non-user scripts.
96 if (script->type() != Script::TYPE_NORMAL) continue; 101 if (script->type() != Script::TYPE_NORMAL) continue;
97 102
98 // Create and add new script data. 103 // Create and add new script data.
99 int source_length = String::cast(script->source())->length(); 104 int source_end = String::cast(script->source())->length();
100 result.emplace_back(Handle<Script>(script, isolate), source_length); 105 Handle<Script> script_handle(script, isolate);
106 result->emplace_back(isolate, script_handle, source_end);
101 107
102 std::vector<SharedFunctionInfo*> sorted; 108 std::vector<SharedFunctionInfo*> sorted;
103 109
104 { 110 {
105 // Collect a list of shared function infos sorted by start position. 111 // Collect a list of shared function infos sorted by start position.
106 // Shared function infos are usually already sorted. Except for classes. 112 // Shared function infos are usually already sorted. Except for classes.
107 // If the start position is the same, sort from outer to inner function. 113 // If the start position is the same, sort from outer to inner function.
108 HandleScope scope(isolate); 114 SharedFunctionInfo::ScriptIterator infos(script_handle);
109 SharedFunctionInfo::ScriptIterator infos(Handle<Script>(script, isolate));
110 while (SharedFunctionInfo* info = infos.Next()) sorted.push_back(info); 115 while (SharedFunctionInfo* info = infos.Next()) sorted.push_back(info);
111 std::sort(sorted.begin(), sorted.end(), CompareSharedFunctionInfo); 116 std::sort(sorted.begin(), sorted.end(), CompareSharedFunctionInfo);
112 } 117 }
113 118
114 std::vector<Range*> stack; 119 std::vector<CoverageRange*> stack;
115 stack.push_back(&result.back().toplevel); 120 stack.push_back(&result->back().toplevel);
116 121
117 // Use sorted list to reconstruct function nesting. 122 // Use sorted list to reconstruct function nesting.
118 for (SharedFunctionInfo* info : sorted) { 123 for (SharedFunctionInfo* info : sorted) {
119 int start = StartPosition(info); 124 int start = StartPosition(info);
120 int end = info->end_position(); 125 int end = info->end_position();
121 uint32_t count = counter_map.Get(info); 126 uint32_t count = counter_map.Get(info);
122 if (info->is_toplevel()) { 127 if (info->is_toplevel()) {
123 // Top-level function is available. 128 // Top-level function is available.
124 DCHECK_EQ(1, stack.size()); 129 DCHECK_EQ(1, stack.size());
125 result.back().toplevel.start = start; 130 result->back().toplevel.start = start;
126 result.back().toplevel.end = end; 131 result->back().toplevel.end = end;
127 result.back().toplevel.count = count; 132 result->back().toplevel.count = count;
128 } else { 133 } else {
129 // The shared function infos are sorted by start. 134 // The shared function infos are sorted by start.
130 DCHECK_LE(stack.back()->start, start); 135 DCHECK_LE(stack.back()->start, start);
131 // Drop the stack to the outer function. 136 // Drop the stack to the outer function.
132 while (start >= stack.back()->end) stack.pop_back(); 137 while (start >= stack.back()->end) stack.pop_back();
133 Range* outer = stack.back(); 138 CoverageRange* outer = stack.back();
134 // New nested function. 139 // New nested function.
135 DCHECK_LE(end, outer->end); 140 DCHECK_LE(end, outer->end);
136 outer->inner.emplace_back(start, end, count); 141 Handle<String> name(info->DebugName(), isolate);
kozy 2017/02/15 16:33:41 Why GC couldn't happen for example here? Is it saf
Yang 2017/02/15 16:42:41 Yes. No GC can happen. We assert that in the Share
137 Range& nested = outer->inner.back(); 142 outer->inner.emplace_back(start, end, count, name);
138 String* name = info->DebugName(); 143 stack.push_back(&outer->inner.back());
139 nested.name.resize(name->length());
140 String::WriteToFlat(name, nested.name.data(), 0, name->length());
141 stack.push_back(&nested);
142 } 144 }
143 } 145 }
144 } 146 }
145 return result; 147 return result;
146 } 148 }
147 149
148 void Coverage::EnablePrecise(Isolate* isolate) { 150 void Coverage::TogglePrecise(Isolate* isolate, bool enable) {
149 HandleScope scope(isolate); 151 if (enable) {
150 // Remove all optimized function. Optimized and inlined functions do not 152 HandleScope scope(isolate);
151 // increment invocation count. 153 // Remove all optimized function. Optimized and inlined functions do not
152 Deoptimizer::DeoptimizeAll(isolate); 154 // increment invocation count.
153 // Collect existing feedback vectors. 155 Deoptimizer::DeoptimizeAll(isolate);
154 std::vector<Handle<FeedbackVector>> vectors; 156 // Collect existing feedback vectors.
155 { 157 std::vector<Handle<FeedbackVector>> vectors;
156 HeapIterator heap_iterator(isolate->heap()); 158 {
157 while (HeapObject* current_obj = heap_iterator.next()) { 159 HeapIterator heap_iterator(isolate->heap());
158 if (!current_obj->IsFeedbackVector()) continue; 160 while (HeapObject* current_obj = heap_iterator.next()) {
159 FeedbackVector* vector = FeedbackVector::cast(current_obj); 161 if (!current_obj->IsFeedbackVector()) continue;
160 SharedFunctionInfo* shared = vector->shared_function_info(); 162 FeedbackVector* vector = FeedbackVector::cast(current_obj);
161 if (!shared->IsSubjectToDebugging()) continue; 163 SharedFunctionInfo* shared = vector->shared_function_info();
162 vector->clear_invocation_count(); 164 if (!shared->IsSubjectToDebugging()) continue;
163 vectors.emplace_back(vector, isolate); 165 vector->clear_invocation_count();
166 vectors.emplace_back(vector, isolate);
167 }
164 } 168 }
169 // Add collected feedback vectors to the root list lest we lose them to GC.
170 Handle<ArrayList> list =
171 ArrayList::New(isolate, static_cast<int>(vectors.size()));
172 for (const auto& vector : vectors) list = ArrayList::Add(list, vector);
173 isolate->SetCodeCoverageList(*list);
174 } else {
175 isolate->SetCodeCoverageList(isolate->heap()->undefined_value());
165 } 176 }
166 // Add collected feedback vectors to the root list lest we lose them to GC.
167 Handle<ArrayList> list =
168 ArrayList::New(isolate, static_cast<int>(vectors.size()));
169 for (const auto& vector : vectors) list = ArrayList::Add(list, vector);
170 isolate->SetCodeCoverageList(*list);
171 }
172
173 void Coverage::DisablePrecise(Isolate* isolate) {
174 isolate->SetCodeCoverageList(isolate->heap()->undefined_value());
175 } 177 }
176 178
177 } // namespace internal 179 } // namespace internal
178 } // namespace v8 180 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698