Chromium Code Reviews| Index: src/debug/debug-coverage.cc |
| diff --git a/src/debug/debug-coverage.cc b/src/debug/debug-coverage.cc |
| index 5446cdfab66291d649c096721d777b9966efce62..c5684ad8ff4af2159352fdb493ddf30bfe799c4e 100644 |
| --- a/src/debug/debug-coverage.cc |
| +++ b/src/debug/debug-coverage.cc |
| @@ -5,6 +5,8 @@ |
| #include "src/debug/debug-coverage.h" |
| #include "src/base/hashmap.h" |
| +#include "src/deoptimizer.h" |
| +#include "src/isolate.h" |
| #include "src/objects-inl.h" |
| #include "src/objects.h" |
| @@ -61,17 +63,33 @@ class ScriptDataBuilder { |
| std::vector<Coverage::ScriptData> Coverage::Collect(Isolate* isolate) { |
| SharedToCounterMap counter_map; |
| - // Iterate the heap to find all feedback vectors and accumulate the |
| - // invocation counts into the map for each shared function info. |
| - HeapIterator heap_iterator(isolate->heap()); |
| - HeapObject* current_obj; |
| - while ((current_obj = heap_iterator.next())) { |
| - if (!current_obj->IsFeedbackVector()) continue; |
| - FeedbackVector* vector = FeedbackVector::cast(current_obj); |
| - SharedFunctionInfo* shared = vector->shared_function_info(); |
| - if (!shared->IsSubjectToDebugging()) continue; |
| - uint32_t count = static_cast<uint32_t>(vector->invocation_count()); |
| - counter_map.Add(shared, count); |
| + |
| + if (isolate->IsCodeCoverageEnabled()) { |
| + // Feedback vectors are already listed to prevent losing them to GC. |
| + Handle<ArrayList> list = |
| + Handle<ArrayList>::cast(isolate->factory()->code_coverage_list()); |
| + for (int i = 0; i < list->Length(); i++) { |
| + FeedbackVector* vector = FeedbackVector::cast(list->Get(i)); |
| + SharedFunctionInfo* shared = vector->shared_function_info(); |
| + DCHECK(shared->IsSubjectToDebugging()); |
| + uint32_t count = static_cast<uint32_t>(vector->invocation_count()); |
| + counter_map.Add(shared, count); |
| + } |
| + } else { |
| + // Iterate the heap to find all feedback vectors and accumulate the |
| + // invocation counts into the map for each shared function info. |
| + HeapIterator heap_iterator(isolate->heap()); |
| + // Initializing the heap iterator might have triggered a GC, which |
| + // invalidates entries in the counter_map. |
| + DCHECK_EQ(0, counter_map.occupancy()); |
| + while (HeapObject* current_obj = heap_iterator.next()) { |
| + if (!current_obj->IsFeedbackVector()) continue; |
| + FeedbackVector* vector = FeedbackVector::cast(current_obj); |
| + SharedFunctionInfo* shared = vector->shared_function_info(); |
| + if (!shared->IsSubjectToDebugging()) continue; |
| + uint32_t count = static_cast<uint32_t>(vector->invocation_count()); |
| + counter_map.Add(shared, count); |
| + } |
| } |
| // Make sure entries in the counter map is not invalidated by GC. |
| @@ -133,5 +151,34 @@ std::vector<Coverage::ScriptData> Coverage::Collect(Isolate* isolate) { |
| return result; |
| } |
| +void Coverage::EnablePrecise(Isolate* isolate) { |
| + HandleScope scope(isolate); |
| + // Remove all optimized function. Optimized and inlined functions do not |
| + // increment invocation count. |
| + Deoptimizer::DeoptimizeAll(isolate); |
| + // Collect existing feedback vectors. |
| + std::vector<Handle<FeedbackVector>> vectors; |
| + { |
| + HeapIterator heap_iterator(isolate->heap()); |
| + while (HeapObject* current_obj = heap_iterator.next()) { |
| + if (!current_obj->IsFeedbackVector()) continue; |
| + FeedbackVector* vector = FeedbackVector::cast(current_obj); |
| + SharedFunctionInfo* shared = vector->shared_function_info(); |
| + if (!shared->IsSubjectToDebugging()) continue; |
| + vector->clear_invocation_count(); |
| + vectors.push_back(Handle<FeedbackVector>(vector, isolate)); |
|
jgruber
2017/02/09 16:08:47
Nit: emplace_back
Yang
2017/02/09 17:42:15
Done.
|
| + } |
| + } |
| + // Add collected feedback vectors to the root list lest we lose them to GC. |
| + Handle<ArrayList> list = |
| + Handle<ArrayList>::cast(isolate->factory()->empty_fixed_array()); |
|
jgruber
2017/02/09 16:08:48
We could preallocate a fixed array of the right si
Yang
2017/02/09 17:42:15
Done.
|
| + for (const auto& vector : vectors) list = ArrayList::Add(list, vector); |
| + isolate->SetCodeCoverageList(*list); |
| +} |
| + |
| +void Coverage::DisablePrecise(Isolate* isolate) { |
| + isolate->SetCodeCoverageList(isolate->heap()->undefined_value()); |
| +} |
| + |
| } // namespace internal |
| } // namespace v8 |