LCOV - code coverage report
Current view: top level - toolkit/components/telemetry - HangReports.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 61 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 9 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #include "HangReports.h"
       8             : 
       9             : namespace mozilla {
      10             : namespace Telemetry {
      11             : 
      12             : using namespace HangMonitor;
      13             : 
      14             : // This utility function generates a string key that is used to index the annotations
      15             : // in a hash map from |HangReports::AddHang|.
      16             : nsresult
      17           0 : ComputeAnnotationsKey(const HangAnnotationsPtr& aAnnotations, nsAString& aKeyOut)
      18             : {
      19           0 :   UniquePtr<HangAnnotations::Enumerator> annotationsEnum = aAnnotations->GetEnumerator();
      20           0 :   if (!annotationsEnum) {
      21           0 :     return NS_ERROR_FAILURE;
      22             :   }
      23             : 
      24             :   // Append all the attributes to the key, to uniquely identify this annotation.
      25           0 :   nsAutoString  key;
      26           0 :   nsAutoString  value;
      27           0 :   while (annotationsEnum->Next(key, value)) {
      28           0 :     aKeyOut.Append(key);
      29           0 :     aKeyOut.Append(value);
      30             :   }
      31             : 
      32           0 :   return NS_OK;
      33             : }
      34             : 
      35             : #if defined(MOZ_GECKO_PROFILER)
      36             : /** The maximum number of stacks that we're keeping for hang reports. */
      37             : const size_t kMaxHangStacksKept = 50;
      38             : 
      39             : void
      40           0 : HangReports::AddHang(const Telemetry::ProcessedStack& aStack,
      41             :                      uint32_t aDuration,
      42             :                      int32_t aSystemUptime,
      43             :                      int32_t aFirefoxUptime,
      44             :                      HangAnnotationsPtr aAnnotations) {
      45             :   // Append the new stack to the stack's circular queue.
      46           0 :   size_t hangIndex = mStacks.AddStack(aStack);
      47             :   // Append the hang info at the same index, in mHangInfo.
      48           0 :   HangInfo info = { aDuration, aSystemUptime, aFirefoxUptime };
      49           0 :   if (mHangInfo.size() < kMaxHangStacksKept) {
      50           0 :     mHangInfo.push_back(info);
      51             :   } else {
      52           0 :     mHangInfo[hangIndex] = info;
      53             :     // Remove any reference to the stack overwritten in the circular queue
      54             :     // from the annotations.
      55           0 :     PruneStackReferences(hangIndex);
      56             :   }
      57             : 
      58           0 :   if (!aAnnotations) {
      59           0 :     return;
      60             :   }
      61             : 
      62           0 :   nsAutoString annotationsKey;
      63             :   // Generate a key to index aAnnotations in the hash map.
      64           0 :   nsresult rv = ComputeAnnotationsKey(aAnnotations, annotationsKey);
      65           0 :   if (NS_FAILED(rv)) {
      66           0 :     return;
      67             :   }
      68             : 
      69           0 :   AnnotationInfo* annotationsEntry = mAnnotationInfo.Get(annotationsKey);
      70           0 :   if (annotationsEntry) {
      71             :     // If the key is already in the hash map, append the index of the chrome hang
      72             :     // to its indices.
      73           0 :     annotationsEntry->mHangIndices.AppendElement(hangIndex);
      74           0 :     return;
      75             :   }
      76             : 
      77             :   // If the key was not found, add the annotations to the hash map.
      78           0 :   mAnnotationInfo.Put(annotationsKey, new AnnotationInfo(hangIndex, Move(aAnnotations)));
      79             : }
      80             : 
      81             : /**
      82             :  * This function removes links to discarded chrome hangs stacks and prunes unused
      83             :  * annotations.
      84             :  */
      85             : void
      86           0 : HangReports::PruneStackReferences(const size_t aRemovedStackIndex) {
      87             :   // We need to adjust the indices that link annotations to chrome hangs. Since we
      88             :   // removed a stack, we must remove all references to it and prune annotations
      89             :   // linked to no stacks.
      90           0 :   for (auto iter = mAnnotationInfo.Iter(); !iter.Done(); iter.Next()) {
      91           0 :     nsTArray<uint32_t>& stackIndices = iter.Data()->mHangIndices;
      92           0 :     size_t toRemove = stackIndices.NoIndex;
      93           0 :     for (size_t k = 0; k < stackIndices.Length(); k++) {
      94             :       // Is this index referencing the removed stack?
      95           0 :       if (stackIndices[k] == aRemovedStackIndex) {
      96           0 :         toRemove = k;
      97           0 :         break;
      98             :       }
      99             :     }
     100             : 
     101             :     // Remove the index referencing the old stack from the annotation.
     102           0 :     if (toRemove != stackIndices.NoIndex) {
     103           0 :       stackIndices.RemoveElementAt(toRemove);
     104             :     }
     105             : 
     106             :     // If this annotation no longer references any stack, drop it.
     107           0 :     if (!stackIndices.Length()) {
     108           0 :       iter.Remove();
     109             :     }
     110             :   }
     111           0 : }
     112             : #endif
     113             : 
     114             : size_t
     115           0 : HangReports::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const {
     116           0 :   size_t n = 0;
     117           0 :   n += mStacks.SizeOfExcludingThis();
     118             :   // This is a crude approximation. See comment on
     119             :   // CombinedStacks::SizeOfExcludingThis.
     120           0 :   n += mHangInfo.capacity() * sizeof(HangInfo);
     121           0 :   n += mAnnotationInfo.ShallowSizeOfExcludingThis(aMallocSizeOf);
     122           0 :   n += mAnnotationInfo.Count() * sizeof(AnnotationInfo);
     123           0 :   for (auto iter = mAnnotationInfo.ConstIter(); !iter.Done(); iter.Next()) {
     124           0 :     n += iter.Key().SizeOfExcludingThisIfUnshared(aMallocSizeOf);
     125           0 :     n += iter.Data()->mAnnotations->SizeOfIncludingThis(aMallocSizeOf);
     126             :   }
     127           0 :   return n;
     128             : }
     129             : 
     130             : const CombinedStacks&
     131           0 : HangReports::GetStacks() const {
     132           0 :   return mStacks;
     133             : }
     134             : 
     135             : uint32_t
     136           0 : HangReports::GetDuration(unsigned aIndex) const {
     137           0 :   return mHangInfo[aIndex].mDuration;
     138             : }
     139             : 
     140             : int32_t
     141           0 : HangReports::GetSystemUptime(unsigned aIndex) const {
     142           0 :   return mHangInfo[aIndex].mSystemUptime;
     143             : }
     144             : 
     145             : int32_t
     146           0 : HangReports::GetFirefoxUptime(unsigned aIndex) const {
     147           0 :   return mHangInfo[aIndex].mFirefoxUptime;
     148             : }
     149             : 
     150             : const nsClassHashtable<nsStringHashKey, HangReports::AnnotationInfo>&
     151           0 : HangReports::GetAnnotationInfo() const {
     152           0 :   return mAnnotationInfo;
     153             : }
     154             : 
     155             : } // namespace Telemetry
     156             : } // namespace mozilla

Generated by: LCOV version 1.13