• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2010, Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  *     * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *     * Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following disclaimer
12  * in the documentation and/or other materials provided with the
13  * distribution.
14  *     * Neither the name of Google Inc. nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #include "config.h"
32 #include "ScriptProfiler.h"
33 
34 #include "InspectorValues.h"
35 #include "RetainedDOMInfo.h"
36 #include "V8Binding.h"
37 #include "V8Node.h"
38 
39 #include <v8-profiler.h>
40 
41 namespace WebCore {
42 
43 #if ENABLE(INSPECTOR)
start(ScriptState * state,const String & title)44 void ScriptProfiler::start(ScriptState* state, const String& title)
45 {
46     v8::HandleScope hs;
47     v8::CpuProfiler::StartProfiling(v8String(title));
48 }
49 
stop(ScriptState * state,const String & title)50 PassRefPtr<ScriptProfile> ScriptProfiler::stop(ScriptState* state, const String& title)
51 {
52     v8::HandleScope hs;
53     const v8::CpuProfile* profile = state ?
54         v8::CpuProfiler::StopProfiling(v8String(title), state->context()->GetSecurityToken()) :
55         v8::CpuProfiler::StopProfiling(v8String(title));
56     return profile ? ScriptProfile::create(profile) : 0;
57 }
58 
collectGarbage()59 void ScriptProfiler::collectGarbage()
60 {
61     // NOTE : There is currently no direct way to collect memory from the v8 C++ API
62     // but notifying low-memory forces a mark-compact, which is exactly what we want
63     // in this case.
64     v8::V8::LowMemoryNotification();
65 }
66 
67 namespace {
68 
69 class ActivityControlAdapter : public v8::ActivityControl {
70 public:
ActivityControlAdapter(ScriptProfiler::HeapSnapshotProgress * progress)71     ActivityControlAdapter(ScriptProfiler::HeapSnapshotProgress* progress)
72             : m_progress(progress), m_firstReport(true) { }
ReportProgressValue(int done,int total)73     ControlOption ReportProgressValue(int done, int total)
74     {
75         ControlOption result = m_progress->isCanceled() ? kAbort : kContinue;
76         if (m_firstReport) {
77             m_firstReport = false;
78             m_progress->Start(total);
79         } else
80             m_progress->Worked(done);
81         if (done >= total)
82             m_progress->Done();
83         return result;
84     }
85 private:
86     ScriptProfiler::HeapSnapshotProgress* m_progress;
87     bool m_firstReport;
88 };
89 
90 } // namespace
91 
takeHeapSnapshot(const String & title,HeapSnapshotProgress * control)92 PassRefPtr<ScriptHeapSnapshot> ScriptProfiler::takeHeapSnapshot(const String& title, HeapSnapshotProgress* control)
93 {
94     v8::HandleScope hs;
95     const v8::HeapSnapshot* snapshot = 0;
96     if (control) {
97         ActivityControlAdapter adapter(control);
98         snapshot = v8::HeapProfiler::TakeSnapshot(v8String(title), v8::HeapSnapshot::kFull, &adapter);
99     } else
100         snapshot = v8::HeapProfiler::TakeSnapshot(v8String(title), v8::HeapSnapshot::kAggregated);
101     return snapshot ? ScriptHeapSnapshot::create(snapshot) : 0;
102 }
103 
retainedDOMInfo(uint16_t classId,v8::Handle<v8::Value> wrapper)104 static v8::RetainedObjectInfo* retainedDOMInfo(uint16_t classId, v8::Handle<v8::Value> wrapper)
105 {
106     ASSERT(classId == v8DOMSubtreeClassId);
107     if (!wrapper->IsObject())
108         return 0;
109     Node* node = V8Node::toNative(wrapper.As<v8::Object>());
110     return node ? new RetainedDOMInfo(node) : 0;
111 }
112 #endif // ENABLE(INSPECTOR)
113 
initialize()114 void ScriptProfiler::initialize()
115 {
116 #if ENABLE(INSPECTOR)
117     v8::HeapProfiler::DefineWrapperClass(v8DOMSubtreeClassId, &retainedDOMInfo);
118 #endif // ENABLE(INSPECTOR)
119 }
120 
121 
122 } // namespace WebCore
123