OLD | NEW |
---|---|
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 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
112 | 112 |
113 // Iterate shared function infos of every script and build a mapping | 113 // Iterate shared function infos of every script and build a mapping |
114 // between source ranges and invocation counts. | 114 // between source ranges and invocation counts. |
115 Coverage* result = new Coverage(); | 115 Coverage* result = new Coverage(); |
116 Script::Iterator scripts(isolate); | 116 Script::Iterator scripts(isolate); |
117 while (Script* script = scripts.Next()) { | 117 while (Script* script = scripts.Next()) { |
118 if (!script->IsUserJavaScript()) continue; | 118 if (!script->IsUserJavaScript()) continue; |
119 | 119 |
120 // Create and add new script data. | 120 // Create and add new script data. |
121 Handle<Script> script_handle(script, isolate); | 121 Handle<Script> script_handle(script, isolate); |
122 result->emplace_back(isolate, script_handle); | 122 result->emplace_back(script_handle); |
123 std::vector<CoverageFunction>* functions = &result->back().functions; | 123 std::vector<CoverageFunction>* functions = &result->back().functions; |
124 | 124 |
125 std::vector<SharedFunctionInfo*> sorted; | 125 std::vector<SharedFunctionInfo*> sorted; |
126 | 126 |
127 { | 127 { |
128 // Sort functions by start position, from outer to inner functions. | 128 // Sort functions by start position, from outer to inner functions. |
129 SharedFunctionInfo::ScriptIterator infos(script_handle); | 129 SharedFunctionInfo::ScriptIterator infos(script_handle); |
130 while (SharedFunctionInfo* info = infos.Next()) { | 130 while (SharedFunctionInfo* info = infos.Next()) { |
131 sorted.push_back(info); | 131 sorted.push_back(info); |
132 } | 132 } |
133 std::sort(sorted.begin(), sorted.end(), CompareSharedFunctionInfo); | 133 std::sort(sorted.begin(), sorted.end(), CompareSharedFunctionInfo); |
134 } | 134 } |
135 | 135 |
136 // Stack to track nested functions, referring function by index. | |
137 std::vector<size_t> nesting; | |
caseq
2017/03/23 00:09:56
nit: perhaps std::vector<const CoverageFunction*>
Yang
2017/03/23 07:43:16
I considered that. However, std::vector reallocate
| |
138 | |
136 // Use sorted list to reconstruct function nesting. | 139 // Use sorted list to reconstruct function nesting. |
137 for (SharedFunctionInfo* info : sorted) { | 140 for (SharedFunctionInfo* info : sorted) { |
138 int start = StartPosition(info); | 141 int start = StartPosition(info); |
139 int end = info->end_position(); | 142 int end = info->end_position(); |
140 uint32_t count = counter_map.Get(info); | 143 uint32_t count = counter_map.Get(info); |
141 if (isolate->is_precise_binary_code_coverage() && count > 0) { | 144 if (isolate->is_precise_binary_code_coverage() && count > 0) { |
142 count = info->has_reported_binary_coverage() ? 0 : 1; | 145 count = info->has_reported_binary_coverage() ? 0 : 1; |
143 info->set_has_reported_binary_coverage(true); | 146 info->set_has_reported_binary_coverage(true); |
144 } | 147 } |
145 Handle<String> name(info->DebugName(), isolate); | 148 // Find the correct outer function based on start position. |
146 functions->emplace_back(start, end, count, name); | 149 while (!nesting.empty() && functions->at(nesting.back()).end <= start) { |
150 nesting.pop_back(); | |
151 } | |
152 if (count > 0 || | |
153 (!nesting.empty() && functions->at(nesting.back()).count > 0)) { | |
154 // Only include a function range if it has a non-0 count, or | |
155 // if it is directly nested inside a function with non-0 count. | |
156 Handle<String> name(info->DebugName(), isolate); | |
157 nesting.push_back(functions->size()); | |
158 functions->emplace_back(start, end, count, name); | |
159 } | |
147 } | 160 } |
161 | |
162 // Remove entries for scripts that have no coverage. | |
163 if (functions->empty()) result->pop_back(); | |
148 } | 164 } |
149 return result; | 165 return result; |
150 } | 166 } |
151 | 167 |
152 void Coverage::SelectMode(Isolate* isolate, debug::Coverage::Mode mode) { | 168 void Coverage::SelectMode(Isolate* isolate, debug::Coverage::Mode mode) { |
153 switch (mode) { | 169 switch (mode) { |
154 case debug::Coverage::kBestEffort: | 170 case debug::Coverage::kBestEffort: |
155 isolate->SetCodeCoverageList(isolate->heap()->undefined_value()); | 171 isolate->SetCodeCoverageList(isolate->heap()->undefined_value()); |
156 break; | 172 break; |
157 case debug::Coverage::kPreciseBinary: | 173 case debug::Coverage::kPreciseBinary: |
(...skipping 25 matching lines...) Expand all Loading... | |
183 for (const auto& vector : vectors) list = ArrayList::Add(list, vector); | 199 for (const auto& vector : vectors) list = ArrayList::Add(list, vector); |
184 isolate->SetCodeCoverageList(*list); | 200 isolate->SetCodeCoverageList(*list); |
185 break; | 201 break; |
186 } | 202 } |
187 } | 203 } |
188 isolate->set_code_coverage_mode(mode); | 204 isolate->set_code_coverage_mode(mode); |
189 } | 205 } |
190 | 206 |
191 } // namespace internal | 207 } // namespace internal |
192 } // namespace v8 | 208 } // namespace v8 |
OLD | NEW |