| Index: src/debug/debug-coverage.cc
|
| diff --git a/src/debug/debug-coverage.cc b/src/debug/debug-coverage.cc
|
| index 126139073d1485f6fdf02a9a80b52f74a57dfa63..dd54d2a616a2e9109e8dde93a28df2eace846d41 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"
|
|
|
| @@ -65,17 +67,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.
|
| @@ -140,5 +158,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.emplace_back(vector, isolate);
|
| + }
|
| + }
|
| + // Add collected feedback vectors to the root list lest we lose them to GC.
|
| + Handle<ArrayList> list =
|
| + ArrayList::New(isolate, static_cast<int>(vectors.size()));
|
| + 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
|
|
|