Chromium Code Reviews| Index: src/debug/debug-coverage.cc |
| diff --git a/src/debug/debug-coverage.cc b/src/debug/debug-coverage.cc |
| index 9ee871e7ca69c6ecd595d67f8556c78b8c853aec..3b7d05fde664d5dcfad43c831e4777800111eb8f 100644 |
| --- a/src/debug/debug-coverage.cc |
| +++ b/src/debug/debug-coverage.cc |
| @@ -59,39 +59,47 @@ bool CompareSharedFunctionInfo(SharedFunctionInfo* a, SharedFunctionInfo* b) { |
| } |
| } // anonymous namespace |
| +Coverage* Coverage::CollectPrecise(Isolate* isolate) { |
| + DCHECK(!isolate->is_best_effort_code_coverage()); |
| + Coverage* result = Collect(isolate, true); |
| + if (isolate->is_precise_binary_code_coverage()) { |
| + // We do not have to hold onto feedback vectors for invocations we already |
| + // reported. So we can reset the list. |
| + isolate->SetCodeCoverageList(*ArrayList::New(isolate, 0)); |
| + } |
| + return result; |
| +} |
| + |
| +Coverage* Coverage::CollectBestEffort(Isolate* isolate) { |
| + return Collect(isolate, false); |
| +} |
| + |
| Coverage* Coverage::Collect(Isolate* isolate, bool reset_count) { |
| SharedToCounterMap counter_map; |
| - // Feed invocation count into the counter map. |
| - switch (isolate->code_coverage_mode()) { |
| - case debug::Coverage::kPreciseCount: { |
| - // Feedback vectors are already listed to prevent losing them to GC. |
|
jgruber
2017/03/21 16:54:34
Nit: These comments were pretty useful. I also pre
|
| - 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()); |
| - if (reset_count) vector->clear_invocation_count(); |
| - counter_map.Add(shared, count); |
| - } |
| - break; |
| + if (isolate->factory()->code_coverage_list()->IsArrayList()) { |
| + DCHECK(!isolate->is_best_effort_code_coverage()); |
| + 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()); |
| + if (reset_count) vector->clear_invocation_count(); |
|
jgruber
2017/03/21 16:54:34
If counts are reset iff collecting precise coverag
Yang
2017/03/22 06:46:00
One use case I expect is that precise coverage has
|
| + counter_map.Add(shared, count); |
| } |
| - case debug::Coverage::kBestEffort: { |
| - // 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()); |
| - 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()); |
| - if (reset_count) vector->clear_invocation_count(); |
| - counter_map.Add(shared, count); |
| - } |
| - break; |
| + } else { |
| + DCHECK(isolate->is_best_effort_code_coverage()); |
| + 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; |
| + uint32_t count = static_cast<uint32_t>(vector->invocation_count()); |
| + if (reset_count) vector->clear_invocation_count(); |
| + counter_map.Add(shared, count); |
| } |
| } |
| @@ -123,6 +131,10 @@ Coverage* Coverage::Collect(Isolate* isolate, bool reset_count) { |
| int start = StartPosition(info); |
| int end = info->end_position(); |
| uint32_t count = counter_map.Get(info); |
| + if (isolate->is_precise_binary_code_coverage() && count > 0) { |
| + count = info->has_reported_binary_coverage() ? 0 : 1; |
| + info->set_has_reported_binary_coverage(true); |
| + } |
| Handle<String> name(info->DebugName(), isolate); |
| functions->emplace_back(start, end, count, name); |
| } |
| @@ -135,6 +147,7 @@ void Coverage::SelectMode(Isolate* isolate, debug::Coverage::Mode mode) { |
| case debug::Coverage::kBestEffort: |
| isolate->SetCodeCoverageList(isolate->heap()->undefined_value()); |
| break; |
| + case debug::Coverage::kPreciseBinary: |
| case debug::Coverage::kPreciseCount: { |
| HandleScope scope(isolate); |
| // Remove all optimized function. Optimized and inlined functions do not |
| @@ -145,11 +158,15 @@ void Coverage::SelectMode(Isolate* isolate, debug::Coverage::Mode mode) { |
| { |
| 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; |
| - vectors.emplace_back(vector, isolate); |
| + if (current_obj->IsSharedFunctionInfo()) { |
| + SharedFunctionInfo* shared = SharedFunctionInfo::cast(current_obj); |
| + shared->set_has_reported_binary_coverage(false); |
| + } else if (current_obj->IsFeedbackVector()) { |
| + FeedbackVector* vector = FeedbackVector::cast(current_obj); |
| + SharedFunctionInfo* shared = vector->shared_function_info(); |
| + if (!shared->IsSubjectToDebugging()) continue; |
| + vectors.emplace_back(vector, isolate); |
| + } |
| } |
| } |
| // Add collected feedback vectors to the root list lest we lose them to |