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

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

Issue 2695823003: [debugger] add lcov support to d8. (Closed)
Patch Set: actual fix 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
« no previous file with comments | « src/debug/debug-coverage.h ('k') | src/objects.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/isolate.h" 9 #include "src/isolate.h"
10 #include "src/objects-inl.h" 10 #include "src/objects-inl.h"
(...skipping 25 matching lines...) Expand all
36 } 36 }
37 37
38 private: 38 private:
39 static uint32_t Hash(SharedFunctionInfo* key) { 39 static uint32_t Hash(SharedFunctionInfo* key) {
40 return static_cast<uint32_t>(reinterpret_cast<intptr_t>(key)); 40 return static_cast<uint32_t>(reinterpret_cast<intptr_t>(key));
41 } 41 }
42 42
43 DisallowHeapAllocation no_gc; 43 DisallowHeapAllocation no_gc;
44 }; 44 };
45 45
46 namespace {
47 int StartPosition(SharedFunctionInfo* info) {
48 int start = info->function_token_position();
49 if (start == kNoSourcePosition) start = info->start_position();
50 return start;
51 }
52
53 bool CompareSharedFunctionInfo(SharedFunctionInfo* a, SharedFunctionInfo* b) {
54 int a_start = StartPosition(a);
55 int b_start = StartPosition(b);
56 if (a_start == b_start) return a->end_position() > b->end_position();
57 return a_start < b_start;
58 }
59 } // anonymous namespace
60
46 std::vector<Coverage::ScriptData> Coverage::Collect(Isolate* isolate) { 61 std::vector<Coverage::ScriptData> Coverage::Collect(Isolate* isolate) {
47 SharedToCounterMap counter_map; 62 SharedToCounterMap counter_map;
48 63
64 // Feed invocation count into the counter map.
49 if (isolate->IsCodeCoverageEnabled()) { 65 if (isolate->IsCodeCoverageEnabled()) {
50 // Feedback vectors are already listed to prevent losing them to GC. 66 // Feedback vectors are already listed to prevent losing them to GC.
51 Handle<ArrayList> list = 67 Handle<ArrayList> list =
52 Handle<ArrayList>::cast(isolate->factory()->code_coverage_list()); 68 Handle<ArrayList>::cast(isolate->factory()->code_coverage_list());
53 for (int i = 0; i < list->Length(); i++) { 69 for (int i = 0; i < list->Length(); i++) {
54 FeedbackVector* vector = FeedbackVector::cast(list->Get(i)); 70 FeedbackVector* vector = FeedbackVector::cast(list->Get(i));
55 SharedFunctionInfo* shared = vector->shared_function_info(); 71 SharedFunctionInfo* shared = vector->shared_function_info();
56 DCHECK(shared->IsSubjectToDebugging()); 72 DCHECK(shared->IsSubjectToDebugging());
57 uint32_t count = static_cast<uint32_t>(vector->invocation_count()); 73 uint32_t count = static_cast<uint32_t>(vector->invocation_count());
58 counter_map.Add(shared, count); 74 counter_map.Add(shared, count);
59 } 75 }
60 } else { 76 } else {
61 // Iterate the heap to find all feedback vectors and accumulate the 77 // Iterate the heap to find all feedback vectors and accumulate the
62 // invocation counts into the map for each shared function info. 78 // invocation counts into the map for each shared function info.
63 HeapIterator heap_iterator(isolate->heap()); 79 HeapIterator heap_iterator(isolate->heap());
64 // Initializing the heap iterator might have triggered a GC, which
65 // invalidates entries in the counter_map.
66 DCHECK_EQ(0, counter_map.occupancy());
67 while (HeapObject* current_obj = heap_iterator.next()) { 80 while (HeapObject* current_obj = heap_iterator.next()) {
68 if (!current_obj->IsFeedbackVector()) continue; 81 if (!current_obj->IsFeedbackVector()) continue;
69 FeedbackVector* vector = FeedbackVector::cast(current_obj); 82 FeedbackVector* vector = FeedbackVector::cast(current_obj);
70 SharedFunctionInfo* shared = vector->shared_function_info(); 83 SharedFunctionInfo* shared = vector->shared_function_info();
71 if (!shared->IsSubjectToDebugging()) continue; 84 if (!shared->IsSubjectToDebugging()) continue;
72 uint32_t count = static_cast<uint32_t>(vector->invocation_count()); 85 uint32_t count = static_cast<uint32_t>(vector->invocation_count());
73 counter_map.Add(shared, count); 86 counter_map.Add(shared, count);
74 } 87 }
75 } 88 }
76 89
77 // Make sure entries in the counter map is not invalidated by GC.
78 DisallowHeapAllocation no_gc;
79
80 std::vector<Range*> stack;
81
82 // Iterate shared function infos of every script and build a mapping 90 // Iterate shared function infos of every script and build a mapping
83 // between source ranges and invocation counts. 91 // between source ranges and invocation counts.
84 std::vector<Coverage::ScriptData> result; 92 std::vector<Coverage::ScriptData> result;
85 Script::Iterator scripts(isolate); 93 Script::Iterator scripts(isolate);
86 while (Script* script = scripts.Next()) { 94 while (Script* script = scripts.Next()) {
87 // Dismiss non-user scripts. 95 // Dismiss non-user scripts.
88 if (script->type() != Script::TYPE_NORMAL) continue; 96 if (script->type() != Script::TYPE_NORMAL) continue;
89 DCHECK(stack.empty()); 97
98 // Create and add new script data.
90 int source_length = String::cast(script->source())->length(); 99 int source_length = String::cast(script->source())->length();
91 result.emplace_back(Handle<Script>(script, isolate), source_length); 100 result.emplace_back(Handle<Script>(script, isolate), source_length);
101
102 std::vector<SharedFunctionInfo*> sorted;
103
104 {
105 // Collect a list of shared function infos sorted by start position.
106 // Shared function infos are usually already sorted. Except for classes.
107 // If the start position is the same, sort from outer to inner function.
108 HandleScope scope(isolate);
109 SharedFunctionInfo::ScriptIterator infos(Handle<Script>(script, isolate));
110 while (SharedFunctionInfo* info = infos.Next()) sorted.push_back(info);
111 std::sort(sorted.begin(), sorted.end(), CompareSharedFunctionInfo);
112 }
113
114 std::vector<Range*> stack;
92 stack.push_back(&result.back().toplevel); 115 stack.push_back(&result.back().toplevel);
93 // Iterate through the list of shared function infos, reconstruct the 116
94 // nesting, and compute the ranges covering different invocation counts. 117 // Use sorted list to reconstruct function nesting.
95 HandleScope scope(isolate); 118 for (SharedFunctionInfo* info : sorted) {
96 SharedFunctionInfo::ScriptIterator infos(Handle<Script>(script, isolate)); 119 int start = StartPosition(info);
97 while (SharedFunctionInfo* info = infos.Next()) {
98 int start = info->function_token_position();
99 if (start == kNoSourcePosition) start = info->start_position();
100 int end = info->end_position(); 120 int end = info->end_position();
101 uint32_t count = counter_map.Get(info); 121 uint32_t count = counter_map.Get(info);
102 if (info->is_toplevel()) { 122 if (info->is_toplevel()) {
103 // Top-level function is available. 123 // Top-level function is available.
104 DCHECK_EQ(1, stack.size()); 124 DCHECK_EQ(1, stack.size());
105 result.back().toplevel.start = start; 125 result.back().toplevel.start = start;
106 result.back().toplevel.end = end; 126 result.back().toplevel.end = end;
107 result.back().toplevel.count = count; 127 result.back().toplevel.count = count;
108 } else { 128 } else {
109 // The shared function infos are sorted by start. 129 // The shared function infos are sorted by start.
110 DCHECK_LE(stack.back()->start, start); 130 DCHECK_LE(stack.back()->start, start);
111 // Drop the stack to the outer function. 131 // Drop the stack to the outer function.
112 while (start > stack.back()->end) stack.pop_back(); 132 while (start >= stack.back()->end) stack.pop_back();
113 Range* outer = stack.back(); 133 Range* outer = stack.back();
114 // New nested function. 134 // New nested function.
115 DCHECK_LE(end, outer->end); 135 DCHECK_LE(end, outer->end);
116 outer->inner.emplace_back(start, end, count); 136 outer->inner.emplace_back(start, end, count);
117 Range& nested = outer->inner.back(); 137 Range& nested = outer->inner.back();
118 String* name = info->DebugName(); 138 String* name = info->DebugName();
119 nested.name.resize(name->length()); 139 nested.name.resize(name->length());
120 String::WriteToFlat(name, nested.name.data(), 0, name->length()); 140 String::WriteToFlat(name, nested.name.data(), 0, name->length());
121 stack.push_back(&nested); 141 stack.push_back(&nested);
122 } 142 }
123 } 143 }
124 stack.clear();
125 } 144 }
126 return result; 145 return result;
127 } 146 }
128 147
129 void Coverage::EnablePrecise(Isolate* isolate) { 148 void Coverage::EnablePrecise(Isolate* isolate) {
130 HandleScope scope(isolate); 149 HandleScope scope(isolate);
131 // Remove all optimized function. Optimized and inlined functions do not 150 // Remove all optimized function. Optimized and inlined functions do not
132 // increment invocation count. 151 // increment invocation count.
133 Deoptimizer::DeoptimizeAll(isolate); 152 Deoptimizer::DeoptimizeAll(isolate);
134 // Collect existing feedback vectors. 153 // Collect existing feedback vectors.
(...skipping 15 matching lines...) Expand all
150 for (const auto& vector : vectors) list = ArrayList::Add(list, vector); 169 for (const auto& vector : vectors) list = ArrayList::Add(list, vector);
151 isolate->SetCodeCoverageList(*list); 170 isolate->SetCodeCoverageList(*list);
152 } 171 }
153 172
154 void Coverage::DisablePrecise(Isolate* isolate) { 173 void Coverage::DisablePrecise(Isolate* isolate) {
155 isolate->SetCodeCoverageList(isolate->heap()->undefined_value()); 174 isolate->SetCodeCoverageList(isolate->heap()->undefined_value());
156 } 175 }
157 176
158 } // namespace internal 177 } // namespace internal
159 } // namespace v8 178 } // namespace v8
OLDNEW
« no previous file with comments | « src/debug/debug-coverage.h ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698