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.
5 #include "content/shell/renderer/leak_detector.h"
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"
13 using blink::WebLeakDetector
;
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.
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;
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
;
41 LeakDetector::~LeakDetector() {
44 void LeakDetector::TryLeakDetection(blink::WebLocalFrame
* frame
) {
45 web_leak_detector_
->collectGarbageAndGetDOMCounts(frame
);
48 void LeakDetector::onLeakDetectionComplete(
49 const WebLeakDetectorClient::Result
& result
) {
50 LeakDetectionResult report
;
51 report
.leaked
= false;
52 base::DictionaryValue detail
;
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
);
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
);
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
);
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
);
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
);
86 if (!detail
.empty()) {
87 std::string detail_str
;
88 base::JSONWriter::Write(&detail
, &detail_str
);
89 report
.detail
= detail_str
;
93 previous_result_
= result
;
94 test_runner_
->ReportLeakDetectionResult(report
);
97 } // namespace content