Home | History | Annotate | Download | only in renderer
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "content/shell/renderer/leak_detector.h"
      6 
      7 #include "base/json/json_writer.h"
      8 #include "base/logging.h"
      9 #include "base/values.h"
     10 #include "content/shell/renderer/webkit_test_runner.h"
     11 #include "third_party/WebKit/public/web/WebLeakDetector.h"
     12 
     13 using blink::WebLeakDetector;
     14 
     15 namespace content {
     16 
     17 // The initial states of the DOM objects at about:blank. The four nodes are a
     18 // Document, a HTML, a HEAD and a BODY.
     19 //
     20 // TODO(hajimehoshi): Now these are hard-corded. If we add target to count like
     21 // RefCoutned objects whose initial state is diffcult to estimate, we stop using
     22 // hard-coded values. Instead, we need to load about:blank ahead of the layout
     23 // tests actually and initialize LeakDetector by the got values.
     24 const int kInitialNumberOfLiveAudioNodes = 0;
     25 const int kInitialNumberOfLiveDocuments = 1;
     26 const int kInitialNumberOfLiveNodes = 4;
     27 const int kInitialNumberOfLiveRenderObjects = 3;
     28 const int kInitialNumberOfLiveResources = 0;
     29 
     30 LeakDetector::LeakDetector(WebKitTestRunner* test_runner)
     31     : test_runner_(test_runner),
     32       web_leak_detector_(blink::WebLeakDetector::create(this)) {
     33   previous_result_.numberOfLiveAudioNodes = kInitialNumberOfLiveAudioNodes;
     34   previous_result_.numberOfLiveDocuments = kInitialNumberOfLiveDocuments;
     35   previous_result_.numberOfLiveNodes = kInitialNumberOfLiveNodes;
     36   previous_result_.numberOfLiveRenderObjects =
     37       kInitialNumberOfLiveRenderObjects;
     38   previous_result_.numberOfLiveResources = kInitialNumberOfLiveResources;
     39 }
     40 
     41 LeakDetector::~LeakDetector() {
     42 }
     43 
     44 void LeakDetector::TryLeakDetection(blink::WebLocalFrame* frame) {
     45   web_leak_detector_->collectGarbageAndGetDOMCounts(frame);
     46 }
     47 
     48 void LeakDetector::onLeakDetectionComplete(
     49     const WebLeakDetectorClient::Result& result) {
     50   LeakDetectionResult report;
     51   report.leaked = false;
     52   base::DictionaryValue detail;
     53 
     54   if (previous_result_.numberOfLiveAudioNodes < result.numberOfLiveAudioNodes) {
     55     base::ListValue* list = new base::ListValue();
     56     list->AppendInteger(previous_result_.numberOfLiveAudioNodes);
     57     list->AppendInteger(result.numberOfLiveAudioNodes);
     58     detail.Set("numberOfLiveAudioNodes", list);
     59   }
     60   if (previous_result_.numberOfLiveDocuments < result.numberOfLiveDocuments) {
     61     base::ListValue* list = new base::ListValue();
     62     list->AppendInteger(previous_result_.numberOfLiveDocuments);
     63     list->AppendInteger(result.numberOfLiveDocuments);
     64     detail.Set("numberOfLiveDocuments", list);
     65   }
     66   if (previous_result_.numberOfLiveNodes < result.numberOfLiveNodes) {
     67     base::ListValue* list = new base::ListValue();
     68     list->AppendInteger(previous_result_.numberOfLiveNodes);
     69     list->AppendInteger(result.numberOfLiveNodes);
     70     detail.Set("numberOfLiveNodes", list);
     71   }
     72   if (previous_result_.numberOfLiveRenderObjects <
     73       result.numberOfLiveRenderObjects) {
     74     base::ListValue* list = new base::ListValue();
     75     list->AppendInteger(previous_result_.numberOfLiveRenderObjects);
     76     list->AppendInteger(result.numberOfLiveRenderObjects);
     77     detail.Set("numberOfLiveRenderObjects", list);
     78   }
     79   if (previous_result_.numberOfLiveResources < result.numberOfLiveResources) {
     80     base::ListValue* list = new base::ListValue();
     81     list->AppendInteger(previous_result_.numberOfLiveResources);
     82     list->AppendInteger(result.numberOfLiveResources);
     83     detail.Set("numberOfLiveResources", list);
     84   }
     85 
     86   if (!detail.empty()) {
     87     std::string detail_str;
     88     base::JSONWriter::Write(&detail, &detail_str);
     89     report.detail = detail_str;
     90     report.leaked = true;
     91   }
     92 
     93   previous_result_ = result;
     94   test_runner_->ReportLeakDetectionResult(report);
     95 }
     96 
     97 }  // namespace content
     98