Title: [97362] trunk
Revision
97362
Author
mnaga...@chromium.org
Date
2011-10-13 04:08:49 -0700 (Thu, 13 Oct 2011)

Log Message

Web Inspector: [Chromium] Add an ability to look up and explore an object from a heap profile.
https://bugs.webkit.org/show_bug.cgi?id=61179

This is exteremely helpful when dealing with DOM wrappers, as
their properties are mostly implemented with getters and thus not
stored in heap snapshots.

Reviewed by Pavel Feldman.

* English.lproj/localizedStrings.js:
* bindings/js/ScriptProfiler.cpp:
(WebCore::ScriptProfiler::objectByHeapObjectId):
* bindings/js/ScriptProfiler.h:
* bindings/v8/ScriptProfiler.cpp:
(WebCore::ScriptProfiler::objectByHeapObjectId):
* bindings/v8/ScriptProfiler.h:
* inspector/Inspector.json:
* inspector/InspectorController.cpp:
(WebCore::InspectorController::InspectorController):
* inspector/InspectorProfilerAgent.cpp:
(WebCore::InspectorProfilerAgent::create):
(WebCore::InspectorProfilerAgent::InspectorProfilerAgent):
(WebCore::InspectorProfilerAgent::getObjectByHeapObjectId):
* inspector/InspectorProfilerAgent.h:
* inspector/front-end/DetailedHeapshotGridNodes.js:
(WebInspector.HeapSnapshotGridNode.prototype.hasHoverMessage.false.queryObjectContent):
(WebInspector.HeapSnapshotGenericObjectNode):
(WebInspector.HeapSnapshotGenericObjectNode.prototype.get data):
(WebInspector.HeapSnapshotGenericObjectNode.prototype.queryObjectContent.else.formatResult):
(WebInspector.HeapSnapshotGenericObjectNode.prototype.queryObjectContent):
(WebInspector.HeapSnapshotGenericObjectNode.prototype.shortenWindowURL):
* inspector/front-end/DetailedHeapshotView.js:
(WebInspector.DetailedHeapshotView.prototype._showObjectPopover):
* inspector/front-end/HeapSnapshot.js:
(WebInspector.HeapSnapshotNode.prototype.get canBeQueried):
(WebInspector.HeapSnapshotNode.prototype.get flags):
(WebInspector.HeapSnapshotNode.prototype.get isDOMWindow):
(WebInspector.HeapSnapshot.prototype._init):
(WebInspector.HeapSnapshot.prototype.dispose):
(WebInspector.HeapSnapshot.prototype._flagsOfNode):
(WebInspector.HeapSnapshot.prototype._calculateFlags):
(WebInspector.HeapSnapshot.prototype.updateStaticData):
(WebInspector.HeapSnapshotNodesProvider.prototype._serialize):
* inspector/front-end/HeapSnapshotProxy.js:
(WebInspector.HeapSnapshotProxy.prototype.get nodeFlags):
* inspector/front-end/RemoteObject.js:
(WebInspector.RemoteObject.fromError):
* inspector/front-end/heapProfiler.css:
(.detailed-heapshot-view tr:not(.selected) td.object-column span.highlight):

* inspector/profiler/heap-snapshot-expected.txt:
* inspector/profiler/heap-snapshot-test.js:
(initialize_HeapSnapshotTest.InspectorTest.createHeapSnapshotMockWithDOM):
(initialize_HeapSnapshotTest):
* inspector/profiler/heap-snapshot.html:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (97361 => 97362)


--- trunk/LayoutTests/ChangeLog	2011-10-13 10:59:31 UTC (rev 97361)
+++ trunk/LayoutTests/ChangeLog	2011-10-13 11:08:49 UTC (rev 97362)
@@ -1,3 +1,20 @@
+2011-10-13  Mikhail Naganov  <mnaga...@chromium.org>
+
+        Web Inspector: [Chromium] Add an ability to look up and explore an object from a heap profile.
+        https://bugs.webkit.org/show_bug.cgi?id=61179
+
+        This is exteremely helpful when dealing with DOM wrappers, as
+        their properties are mostly implemented with getters and thus not
+        stored in heap snapshots.
+
+        Reviewed by Pavel Feldman.
+
+        * inspector/profiler/heap-snapshot-expected.txt:
+        * inspector/profiler/heap-snapshot-test.js:
+        (initialize_HeapSnapshotTest.InspectorTest.createHeapSnapshotMockWithDOM):
+        (initialize_HeapSnapshotTest):
+        * inspector/profiler/heap-snapshot.html:
+
 2011-10-13  Kent Tamura  <tk...@chromium.org>
 
         [Chromium] Fix test expectations.

Modified: trunk/LayoutTests/inspector/profiler/heap-snapshot-expected.txt (97361 => 97362)


--- trunk/LayoutTests/inspector/profiler/heap-snapshot-expected.txt	2011-10-13 10:59:31 UTC (rev 97361)
+++ trunk/LayoutTests/inspector/profiler/heap-snapshot-expected.txt	2011-10-13 11:08:49 UTC (rev 97362)
@@ -17,6 +17,8 @@
 
 Running: heapSnapshotAggregatesTest
 
+Running: heapSnapshotFlagsTest
+
 Running: heapSnapshotNodesProviderTest
 
 Running: heapSnapshotEdgesProviderTest

Modified: trunk/LayoutTests/inspector/profiler/heap-snapshot-test.js (97361 => 97362)


--- trunk/LayoutTests/inspector/profiler/heap-snapshot-test.js	2011-10-13 10:59:31 UTC (rev 97361)
+++ trunk/LayoutTests/inspector/profiler/heap-snapshot-test.js	2011-10-13 11:08:49 UTC (rev 97362)
@@ -66,4 +66,41 @@
     };
 };
 
+InspectorTest.createHeapSnapshotMockWithDOM = function()
+{
+    return {
+        snapshot: {},
+        nodes: [
+            { fields: ["type", "name", "id", "children_count", "children"],
+              types: [["hidden", "object"], "", "", "", { fields: ["type", "name_or_index", "to_node"], types: [["element", "hidden", "internal"], "", ""] }] },
+            // A tree with DOMWindow objects.
+            //
+            //    |----->DOMWindow--->A
+            //    |                \
+            //    |----->DOMWindow--->B--->C
+            //    |        |     \
+            //  (root)   hidden   --->D--internal / "native"-->N
+            //    |         \         |
+            //    |----->E   H     internal
+            //    |                   v
+            //    |----->F--->G------>M
+            //
+            /* (root) */    0,  0,  1, 4, 0,  1, 17, 0, 2, 27, 0, 3, 40, 0, 4, 44,
+            /* DOMWindow */ 1, 11,  2, 2, 0,  1, 51, 0, 2, 55,
+            /* DOMWindow */ 1, 11,  3, 3, 0,  1, 55, 0, 2, 62, 1, 3, 72,
+            /* E */         1,  5,  4, 0,
+            /* F */         1,  6,  5, 1, 0,  1, 76,
+            /* A */         1,  1,  6, 0,
+            /* B */         1,  2,  7, 1, 0,  1, 80,
+            /* D */         1,  4,  8, 2, 2, 12, 84, 2, 1, 88,
+            /* H */         1,  8,  9, 0,
+            /* G */         1,  7, 10, 0,
+            /* C */         1,  3, 11, 0,
+            /* N */         1, 10, 12, 0,
+            /* M */         1,  9, 13, 0
+            ],
+        strings: ["", "A", "B", "C", "D", "E", "F", "G", "H", "M", "N", "DOMWindow", "native"]
+    };
 };
+
+};

Modified: trunk/LayoutTests/inspector/profiler/heap-snapshot.html (97361 => 97362)


--- trunk/LayoutTests/inspector/profiler/heap-snapshot.html	2011-10-13 10:59:31 UTC (rev 97361)
+++ trunk/LayoutTests/inspector/profiler/heap-snapshot.html	2011-10-13 11:08:49 UTC (rev 97362)
@@ -148,6 +148,30 @@
             next();
         },
 
+        function heapSnapshotFlagsTest(next)
+        {
+            var snapshot = new WebInspector.HeapSnapshot(InspectorTest.createHeapSnapshotMockWithDOM());
+            var expectedCanBeQueried = {
+                "": false,
+               "A": true,
+               "B": true,
+               "C": true,
+               "D": true,
+               "E": false,
+               "F": false,
+               "G": false,
+               "H": false,
+               "M": false,
+               "N": true,
+               "DOMWindow": true
+            };
+            for (var nodes = snapshot._allNodes; nodes.hasNext(); nodes.next()) {
+                var node = nodes.item;
+                InspectorTest.assertEquals(expectedCanBeQueried[node.name], node.canBeQueried, "canBeQueried of \"" + node.name + "\"");
+            }
+            next();
+        },
+
         function heapSnapshotNodesProviderTest(next)
         {
             var snapshot = new WebInspector.HeapSnapshot(InspectorTest.createHeapSnapshotMock());

Modified: trunk/Source/WebCore/ChangeLog (97361 => 97362)


--- trunk/Source/WebCore/ChangeLog	2011-10-13 10:59:31 UTC (rev 97361)
+++ trunk/Source/WebCore/ChangeLog	2011-10-13 11:08:49 UTC (rev 97362)
@@ -1,3 +1,55 @@
+2011-10-13  Mikhail Naganov  <mnaga...@chromium.org>
+
+        Web Inspector: [Chromium] Add an ability to look up and explore an object from a heap profile.
+        https://bugs.webkit.org/show_bug.cgi?id=61179
+
+        This is exteremely helpful when dealing with DOM wrappers, as
+        their properties are mostly implemented with getters and thus not
+        stored in heap snapshots.
+
+        Reviewed by Pavel Feldman.
+
+        * English.lproj/localizedStrings.js:
+        * bindings/js/ScriptProfiler.cpp:
+        (WebCore::ScriptProfiler::objectByHeapObjectId):
+        * bindings/js/ScriptProfiler.h:
+        * bindings/v8/ScriptProfiler.cpp:
+        (WebCore::ScriptProfiler::objectByHeapObjectId):
+        * bindings/v8/ScriptProfiler.h:
+        * inspector/Inspector.json:
+        * inspector/InspectorController.cpp:
+        (WebCore::InspectorController::InspectorController):
+        * inspector/InspectorProfilerAgent.cpp:
+        (WebCore::InspectorProfilerAgent::create):
+        (WebCore::InspectorProfilerAgent::InspectorProfilerAgent):
+        (WebCore::InspectorProfilerAgent::getObjectByHeapObjectId):
+        * inspector/InspectorProfilerAgent.h:
+        * inspector/front-end/DetailedHeapshotGridNodes.js:
+        (WebInspector.HeapSnapshotGridNode.prototype.hasHoverMessage.false.queryObjectContent):
+        (WebInspector.HeapSnapshotGenericObjectNode):
+        (WebInspector.HeapSnapshotGenericObjectNode.prototype.get data):
+        (WebInspector.HeapSnapshotGenericObjectNode.prototype.queryObjectContent.else.formatResult):
+        (WebInspector.HeapSnapshotGenericObjectNode.prototype.queryObjectContent):
+        (WebInspector.HeapSnapshotGenericObjectNode.prototype.shortenWindowURL):
+        * inspector/front-end/DetailedHeapshotView.js:
+        (WebInspector.DetailedHeapshotView.prototype._showObjectPopover):
+        * inspector/front-end/HeapSnapshot.js:
+        (WebInspector.HeapSnapshotNode.prototype.get canBeQueried):
+        (WebInspector.HeapSnapshotNode.prototype.get flags):
+        (WebInspector.HeapSnapshotNode.prototype.get isDOMWindow):
+        (WebInspector.HeapSnapshot.prototype._init):
+        (WebInspector.HeapSnapshot.prototype.dispose):
+        (WebInspector.HeapSnapshot.prototype._flagsOfNode):
+        (WebInspector.HeapSnapshot.prototype._calculateFlags):
+        (WebInspector.HeapSnapshot.prototype.updateStaticData):
+        (WebInspector.HeapSnapshotNodesProvider.prototype._serialize):
+        * inspector/front-end/HeapSnapshotProxy.js:
+        (WebInspector.HeapSnapshotProxy.prototype.get nodeFlags):
+        * inspector/front-end/RemoteObject.js:
+        (WebInspector.RemoteObject.fromError):
+        * inspector/front-end/heapProfiler.css:
+        (.detailed-heapshot-view tr:not(.selected) td.object-column span.highlight):
+
 2011-10-13  Adam Barth  <aba...@webkit.org>
 
         script-src * should allow all URLs

Modified: trunk/Source/WebCore/English.lproj/localizedStrings.js


(Binary files differ)

Modified: trunk/Source/WebCore/bindings/js/ScriptProfiler.cpp (97361 => 97362)


--- trunk/Source/WebCore/bindings/js/ScriptProfiler.cpp	2011-10-13 10:59:31 UTC (rev 97361)
+++ trunk/Source/WebCore/bindings/js/ScriptProfiler.cpp	2011-10-13 11:08:49 UTC (rev 97362)
@@ -31,6 +31,7 @@
 #include "ScriptProfiler.h"
 
 #include "GCController.h"
+#include "InspectorValues.h"
 #include "JSDOMBinding.h"
 #include <profiler/Profiler.h>
 
@@ -41,6 +42,11 @@
     gcController().garbageCollectNow();
 }
 
+PassRefPtr<InspectorValue> ScriptProfiler::objectByHeapObjectId(unsigned, InjectedScriptManager*)
+{
+    return InspectorValue::null();
+}
+
 void ScriptProfiler::start(ScriptState* state, const String& title)
 {
     JSC::Profiler::profiler()->startProfiling(state, stringToUString(title));

Modified: trunk/Source/WebCore/bindings/js/ScriptProfiler.h (97361 => 97362)


--- trunk/Source/WebCore/bindings/js/ScriptProfiler.h	2011-10-13 10:59:31 UTC (rev 97361)
+++ trunk/Source/WebCore/bindings/js/ScriptProfiler.h	2011-10-13 11:08:49 UTC (rev 97362)
@@ -35,6 +35,9 @@
 
 namespace WebCore {
 
+class InjectedScriptManager;
+class InspectorValue;
+
 class ScriptProfiler {
     WTF_MAKE_NONCOPYABLE(ScriptProfiler);
 public:
@@ -48,6 +51,7 @@
     };
 
     static void collectGarbage();
+    static PassRefPtr<InspectorValue> objectByHeapObjectId(unsigned id, InjectedScriptManager*);
     static void start(ScriptState* state, const String& title);
     static PassRefPtr<ScriptProfile> stop(ScriptState* state, const String& title);
     static PassRefPtr<ScriptHeapSnapshot> takeHeapSnapshot(const String&, HeapSnapshotProgress*) { return 0; }

Modified: trunk/Source/WebCore/bindings/v8/ScriptProfiler.cpp (97361 => 97362)


--- trunk/Source/WebCore/bindings/v8/ScriptProfiler.cpp	2011-10-13 10:59:31 UTC (rev 97361)
+++ trunk/Source/WebCore/bindings/v8/ScriptProfiler.cpp	2011-10-13 11:08:49 UTC (rev 97362)
@@ -31,6 +31,7 @@
 #include "config.h"
 #include "ScriptProfiler.h"
 
+#include "InjectedScript.h"
 #include "InspectorValues.h"
 #include "RetainedDOMInfo.h"
 #include "V8Binding.h"
@@ -65,6 +66,34 @@
     while (!v8::V8::IdleNotification()) { }
 }
 
+PassRefPtr<InspectorValue> ScriptProfiler::objectByHeapObjectId(unsigned id, InjectedScriptManager* injectedScriptManager)
+{
+    // As ids are unique, it doesn't matter which HeapSnapshot owns HeapGraphNode.
+    // We need to find first HeapSnapshot containing a node with the specified id.
+    const v8::HeapGraphNode* node = 0;
+    for (int i = 0, l = v8::HeapProfiler::GetSnapshotsCount(); i < l; ++i) {
+        const v8::HeapSnapshot* snapshot = v8::HeapProfiler::GetSnapshot(i);
+        node = snapshot->GetNodeById(id);
+        if (node)
+            break;
+    }
+    if (!node)
+        return InspectorValue::null();
+
+    v8::HandleScope scope;
+    v8::Handle<v8::Value> value = node->GetHeapValue();
+    if (!value->IsObject())
+        return InspectorValue::null();
+
+    v8::Handle<v8::Object> object(value.As<v8::Object>());
+    v8::Local<v8::Context> creationContext = object->CreationContext();
+    v8::Context::Scope creationScope(creationContext);
+    ScriptState* scriptState = ScriptState::forContext(creationContext);
+    InjectedScript injectedScript = injectedScriptManager->injectedScriptFor(scriptState);
+    return !injectedScript.hasNoValue() ?
+            RefPtr<InspectorValue>(injectedScript.wrapObject(value, "")).release() : InspectorValue::null();
+}
+
 namespace {
 
 class ActivityControlAdapter : public v8::ActivityControl {

Modified: trunk/Source/WebCore/bindings/v8/ScriptProfiler.h (97361 => 97362)


--- trunk/Source/WebCore/bindings/v8/ScriptProfiler.h	2011-10-13 10:59:31 UTC (rev 97361)
+++ trunk/Source/WebCore/bindings/v8/ScriptProfiler.h	2011-10-13 11:08:49 UTC (rev 97362)
@@ -39,7 +39,8 @@
 
 namespace WebCore {
 
-class InspectorObject;
+class InjectedScriptManager;
+class InspectorValue;
 
 class ScriptProfiler {
     WTF_MAKE_NONCOPYABLE(ScriptProfiler);
@@ -54,6 +55,7 @@
     };
 
     static void collectGarbage();
+    static PassRefPtr<InspectorValue> objectByHeapObjectId(unsigned id, InjectedScriptManager*);
     static void start(ScriptState* state, const String& title);
     static PassRefPtr<ScriptProfile> stop(ScriptState* state, const String& title);
     static PassRefPtr<ScriptHeapSnapshot> takeHeapSnapshot(const String& title, HeapSnapshotProgress*);

Modified: trunk/Source/WebCore/inspector/Inspector.json (97361 => 97362)


--- trunk/Source/WebCore/inspector/Inspector.json	2011-10-13 10:59:31 UTC (rev 97361)
+++ trunk/Source/WebCore/inspector/Inspector.json	2011-10-13 11:08:49 UTC (rev 97362)
@@ -2009,6 +2009,15 @@
             },
             {
                 "name": "collectGarbage"
+            },
+            {
+                "name": "getObjectByHeapObjectId",
+                "parameters": [
+                    { "name": "objectId", "type": "integer" }
+                ],
+                "returns": [
+                    { "name": "result", "$ref": "Runtime.RemoteObject", "description": "Evaluation result." }
+                ]
             }
         ],
         "events": [

Modified: trunk/Source/WebCore/inspector/InspectorController.cpp (97361 => 97362)


--- trunk/Source/WebCore/inspector/InspectorController.cpp	2011-10-13 10:59:31 UTC (rev 97361)
+++ trunk/Source/WebCore/inspector/InspectorController.cpp	2011-10-13 11:08:49 UTC (rev 97362)
@@ -115,7 +115,7 @@
 #if ENABLE(_javascript__DEBUGGER)
     , m_debuggerAgent(PageDebuggerAgent::create(m_instrumentingAgents.get(), m_state.get(), page, m_injectedScriptManager.get()))
     , m_domDebuggerAgent(InspectorDOMDebuggerAgent::create(m_instrumentingAgents.get(), m_state.get(), m_domAgent.get(), m_debuggerAgent.get(), m_inspectorAgent.get()))
-    , m_profilerAgent(InspectorProfilerAgent::create(m_instrumentingAgents.get(), m_consoleAgent.get(), page, m_state.get()))
+    , m_profilerAgent(InspectorProfilerAgent::create(m_instrumentingAgents.get(), m_consoleAgent.get(), page, m_state.get(), m_injectedScriptManager.get()))
 #endif
 #if ENABLE(WORKERS)
     , m_workerAgent(InspectorWorkerAgent::create(m_instrumentingAgents.get(), m_state.get()))

Modified: trunk/Source/WebCore/inspector/InspectorProfilerAgent.cpp (97361 => 97362)


--- trunk/Source/WebCore/inspector/InspectorProfilerAgent.cpp	2011-10-13 10:59:31 UTC (rev 97361)
+++ trunk/Source/WebCore/inspector/InspectorProfilerAgent.cpp	2011-10-13 11:08:49 UTC (rev 97362)
@@ -62,16 +62,17 @@
 static const char* const CPUProfileType = "CPU";
 static const char* const HeapProfileType = "HEAP";
 
-PassOwnPtr<InspectorProfilerAgent> InspectorProfilerAgent::create(InstrumentingAgents* instrumentingAgents, InspectorConsoleAgent* consoleAgent, Page* inspectedPage, InspectorState* inspectorState)
+PassOwnPtr<InspectorProfilerAgent> InspectorProfilerAgent::create(InstrumentingAgents* instrumentingAgents, InspectorConsoleAgent* consoleAgent, Page* inspectedPage, InspectorState* inspectorState, InjectedScriptManager* injectedScriptManager)
 {
-    return adoptPtr(new InspectorProfilerAgent(instrumentingAgents, consoleAgent, inspectedPage, inspectorState));
+    return adoptPtr(new InspectorProfilerAgent(instrumentingAgents, consoleAgent, inspectedPage, inspectorState, injectedScriptManager));
 }
 
-InspectorProfilerAgent::InspectorProfilerAgent(InstrumentingAgents* instrumentingAgents, InspectorConsoleAgent* consoleAgent, Page* inspectedPage, InspectorState* inspectorState)
+InspectorProfilerAgent::InspectorProfilerAgent(InstrumentingAgents* instrumentingAgents, InspectorConsoleAgent* consoleAgent, Page* inspectedPage, InspectorState* inspectorState, InjectedScriptManager* injectedScriptManager)
     : m_instrumentingAgents(instrumentingAgents)
     , m_consoleAgent(consoleAgent)
     , m_inspectedPage(inspectedPage)
     , m_inspectorState(inspectorState)
+    , m_injectedScriptManager(injectedScriptManager)
     , m_frontend(0)
     , m_enabled(false)
     , m_recordingUserInitiatedProfile(false)
@@ -378,6 +379,15 @@
         m_frontend->setRecordingProfile(isProfiling);
 }
 
+void InspectorProfilerAgent::getObjectByHeapObjectId(ErrorString* error, int id, RefPtr<InspectorObject>* result)
+{
+    RefPtr<InspectorValue> heapObject = ScriptProfiler::objectByHeapObjectId(id, m_injectedScriptManager);
+    if (!heapObject->isNull())
+        heapObject->asObject(result);
+    else
+        *error = "Object is not available.";
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(_javascript__DEBUGGER) && ENABLE(INSPECTOR)

Modified: trunk/Source/WebCore/inspector/InspectorProfilerAgent.h (97361 => 97362)


--- trunk/Source/WebCore/inspector/InspectorProfilerAgent.h	2011-10-13 10:59:31 UTC (rev 97361)
+++ trunk/Source/WebCore/inspector/InspectorProfilerAgent.h	2011-10-13 11:08:49 UTC (rev 97362)
@@ -41,6 +41,7 @@
 
 namespace WebCore {
 
+class InjectedScriptManager;
 class InspectorArray;
 class InspectorConsoleAgent;
 class InspectorFrontend;
@@ -56,7 +57,7 @@
 class InspectorProfilerAgent {
     WTF_MAKE_NONCOPYABLE(InspectorProfilerAgent); WTF_MAKE_FAST_ALLOCATED;
 public:
-    static PassOwnPtr<InspectorProfilerAgent> create(InstrumentingAgents*, InspectorConsoleAgent*, Page*, InspectorState*);
+    static PassOwnPtr<InspectorProfilerAgent> create(InstrumentingAgents*, InspectorConsoleAgent*, Page*, InspectorState*, InjectedScriptManager*);
     virtual ~InspectorProfilerAgent();
 
     void addProfile(PassRefPtr<ScriptProfile> prpProfile, unsigned lineNumber, const String& sourceURL);
@@ -90,6 +91,8 @@
     void takeHeapSnapshot(ErrorString*);
     void toggleRecordButton(bool isProfiling);
 
+    void getObjectByHeapObjectId(ErrorString*, int id, RefPtr<InspectorObject>* result);
+
 private:
     typedef HashMap<unsigned int, RefPtr<ScriptProfile> > ProfilesMap;
     typedef HashMap<unsigned int, RefPtr<ScriptHeapSnapshot> > HeapSnapshotsMap;
@@ -97,7 +100,7 @@
     void resetFrontendProfiles();
     void restoreEnablement();
 
-    InspectorProfilerAgent(InstrumentingAgents*, InspectorConsoleAgent*, Page*, InspectorState*);
+    InspectorProfilerAgent(InstrumentingAgents*, InspectorConsoleAgent*, Page*, InspectorState*, InjectedScriptManager*);
     PassRefPtr<InspectorObject> createProfileHeader(const ScriptProfile& profile);
     PassRefPtr<InspectorObject> createSnapshotHeader(const ScriptHeapSnapshot& snapshot);
 
@@ -105,6 +108,7 @@
     InspectorConsoleAgent* m_consoleAgent;
     Page* m_inspectedPage;
     InspectorState* m_inspectorState;
+    InjectedScriptManager* m_injectedScriptManager;
     InspectorFrontend::Profiler* m_frontend;
     bool m_enabled;
     bool m_recordingUserInitiatedProfile;

Modified: trunk/Source/WebCore/inspector/front-end/DetailedHeapshotGridNodes.js (97361 => 97362)


--- trunk/Source/WebCore/inspector/front-end/DetailedHeapshotGridNodes.js	2011-10-13 10:59:31 UTC (rev 97361)
+++ trunk/Source/WebCore/inspector/front-end/DetailedHeapshotGridNodes.js	2011-10-13 11:08:49 UTC (rev 97362)
@@ -56,9 +56,8 @@
 
     hasHoverMessage: false,
 
-    hoverMessage: function(callback)
+    queryObjectContent: function(callback)
     {
-        callback("");
     },
 
     _populate: function(event)
@@ -185,11 +184,10 @@
     if (this._type === "string")
         this.hasHoverMessage = true;
     else if (this._type === "object" && this.isDOMWindow(this._name)) {
-        var url = ""
-        this._name = this.shortenWindowURL(this._name, false, url);
-        this._url = url[0];
+        this._name = this.shortenWindowURL(this._name, false);
         this.hasHoverMessage = true;
-    }
+    } else if (node.flags & tree.snapshot.nodeFlags.canBeQueried)
+        this.hasHoverMessage = true;
 };
 
 WebInspector.HeapSnapshotGenericObjectNode.prototype = {
@@ -259,6 +257,8 @@
                 value += " []";
             break;
         };
+        if (this.hasHoverMessage)
+            valueStyle += " highlight";
         data["object"] = { valueStyle: valueStyle, value: value + " @" + this.snapshotNodeId };
 
         var view = this.dataGrid.snapshotView;
@@ -268,12 +268,20 @@
         return this._enhanceData ? this._enhanceData(data) : data;
     },
 
-    hoverMessage: function(callback)
+    queryObjectContent: function(callback)
     {
         if (this._type === "string")
-            callback("\"" + this._name + "\"", "console-formatted-string");
-        else if (this._url)
-            callback(this._url, "console-formatted-object");
+            callback(WebInspector.RemoteObject.fromPrimitiveValue(this._name));
+        else {
+            function formatResult(error, object)
+            {
+                if (!error && object.type)
+                    callback(WebInspector.RemoteObject.fromPayload(object), !!error);
+                else
+                    callback(WebInspector.RemoteObject.fromError(WebInspector.UIString("Not available")));
+            }
+            ProfilerAgent.getObjectByHeapObjectId(this.snapshotNodeId, formatResult);
+        }
     },
 
     get _retainedSizePercent()
@@ -300,14 +308,12 @@
         return fullName.substr(0, 9) === "DOMWindow";
     },
 
-    shortenWindowURL: function(fullName, hasObjectId, fullURLPtr)
+    shortenWindowURL: function(fullName, hasObjectId)
     {
         var startPos = fullName.indexOf("/");
         var endPos = hasObjectId ? fullName.indexOf("@") : fullName.length;
         if (startPos !== -1 && endPos !== -1) {
             var fullURL = fullName.substring(startPos + 1, endPos).trimLeft();
-            if (fullURLPtr)
-                fullURLPtr[0] = fullURL;
             var url = ""
             if (url.length > 40)
                 url = ""

Modified: trunk/Source/WebCore/inspector/front-end/DetailedHeapshotView.js (97361 => 97362)


--- trunk/Source/WebCore/inspector/front-end/DetailedHeapshotView.js	2011-10-13 10:59:31 UTC (rev 97361)
+++ trunk/Source/WebCore/inspector/front-end/DetailedHeapshotView.js	2011-10-13 11:08:49 UTC (rev 97362)
@@ -621,7 +621,7 @@
     this.helpButton = new WebInspector.StatusBarButton("", "heapshot-help-status-bar-item status-bar-item");
     this.helpButton.addEventListener("click", this._helpClicked.bind(this), false);
 
-    var popoverHelper = new WebInspector.PopoverHelper(this.element, this._getHoverAnchor.bind(this), this._showStringContentPopover.bind(this));
+    var popoverHelper = new WebInspector.ObjectPopoverHelper(this.element, this._getHoverAnchor.bind(this), this._showObjectPopover.bind(this), null, true);
 
     this._loadProfile(this._profileUid, profileCallback.bind(this));
 
@@ -1066,19 +1066,9 @@
         this.refreshShowAsPercents();
     },
 
-    _showStringContentPopover: function(anchor, popover)
+    _showObjectPopover: function(element, showCallback)
     {
-        var stringContentElement = document.createElement("span");
-        stringContentElement.className = "monospace";
-        stringContentElement.style.whiteSpace = "pre";
-
-        function displayString(name, className)
-        {
-            stringContentElement.textContent = name;
-            stringContentElement.className += " " + className;
-            popover.show(stringContentElement, anchor);
-        }
-        anchor.node.hoverMessage(displayString);
+        element.node.queryObjectContent(showCallback);
     },
 
     _helpClicked: function(event)

Modified: trunk/Source/WebCore/inspector/front-end/HeapSnapshot.js (97361 => 97362)


--- trunk/Source/WebCore/inspector/front-end/HeapSnapshot.js	2011-10-13 10:59:31 UTC (rev 97361)
+++ trunk/Source/WebCore/inspector/front-end/HeapSnapshot.js	2011-10-13 11:08:49 UTC (rev 97362)
@@ -494,6 +494,12 @@
 }
 
 WebInspector.HeapSnapshotNode.prototype = {
+    get canBeQueried()
+    {
+        var flags = this._snapshot._flagsOfNode(this);
+        return !!(flags & this._snapshot._nodeFlags.canBeQueried);
+    },
+
     get className()
     {
         switch (this.type) {
@@ -529,6 +535,11 @@
         return this._nodes[this.nodeIndex + this._snapshot._edgesCountOffset];
     },
 
+    get flags()
+    {
+        return this._snapshot._flagsOfNode(this);
+    },
+
     get id()
     {
         return this._nodes[this.nodeIndex + this._snapshot._nodeIdOffset];
@@ -544,6 +555,11 @@
         return this._type() === this._snapshot._nodeHiddenType;
     },
 
+    get isDOMWindow()
+    {
+        return this.name.substr(0, 9) === "DOMWindow";
+    },
+
     get isRoot()
     {
         return this.nodeIndex === this._snapshot._rootNodeIndex;
@@ -682,6 +698,8 @@
         this._edgeInvisibleType = this._edgeTypes.length;
         this._edgeTypes.push("invisible");
 
+        this._nodeFlags = { canBeQueried: 1 };
+
         this._markInvisibleEdges();
     },
 
@@ -699,6 +717,7 @@
         delete this._baseNodeIds;
         delete this._dominatedNodes;
         delete this._dominatedIndex;
+        delete this._flags;
     },
 
     get _allNodes()
@@ -763,6 +782,13 @@
         return new WebInspector.HeapSnapshotArraySlice(this, "_dominatedNodes", dominatedIndexFrom, dominatedIndexTo);
     },
 
+    _flagsOfNode: function(node)
+    {
+        if (!this._flags)
+            this._calculateFlags();
+        return this._flags[node.nodeIndex];
+    },
+
     aggregates: function(sortedIndexes)
     {
         if (!this._aggregates)
@@ -959,6 +985,32 @@
         return a < b ? -1 : (a > b ? 1 : 0);
     },
 
+    _calculateFlags: function()
+    {
+        var flag = this._nodeFlags.canBeQueried;
+        this._flags = new Array(this.nodeCount);
+        // Allow runtime properties query for objects accessible from DOMWindow objects
+        // via regular properties, and for DOM wrappers. Trying to access random objects
+        // can cause a crash due to insonsistent state of internal properties of wrappers.
+        var list = [];
+        for (var iter = this.rootNode.edges; iter.hasNext(); iter.next()) {
+            if (iter.edge.node.isDOMWindow)
+                list.push(iter.edge.node);
+        }
+        while (list.length) {
+            var node = list.shift();
+            if (node.canBeQueried) continue;
+            this._flags[node.nodeIndex] = flag;
+            for (var iter = node.edges; iter.hasNext(); iter.next()) {
+                var edge = iter.edge;
+                if (!edge.isHidden && !edge.isInvisible &&
+                    edge.name && (!edge.isInternal || edge.name === "native") &&
+                    !edge.node.canBeQueried)
+                    list.push(edge.node);
+            }
+        }
+    },
+
     baseSnapshotHasNode: function(baseSnapshotId, className, nodeId)
     {
         return this._baseNodeIds[baseSnapshotId][className].binaryIndexOf(nodeId, this._numbersComparator) !== -1;
@@ -1014,7 +1066,7 @@
 
     updateStaticData: function()
     {
-        return {nodeCount: this.nodeCount, rootNodeIndex: this._rootNodeIndex, totalSize: this.totalSize, uid: this.uid};
+        return {nodeCount: this.nodeCount, rootNodeIndex: this._rootNodeIndex, totalSize: this.totalSize, uid: this.uid, nodeFlags: this._nodeFlags};
     }
 };
 
@@ -1235,7 +1287,7 @@
 WebInspector.HeapSnapshotNodesProvider.prototype = {
     _serialize: function(node)
     {
-        return {id: node.id, name: node.name, nodeIndex: node.nodeIndex, retainedSize: node.retainedSize, selfSize: node.selfSize, type: node.type};
+        return {id: node.id, name: node.name, nodeIndex: node.nodeIndex, retainedSize: node.retainedSize, selfSize: node.selfSize, type: node.type, flags: node.flags};
     },
 
     sort: function(comparator, leftBound, rightBound, count)

Modified: trunk/Source/WebCore/inspector/front-end/HeapSnapshotProxy.js (97361 => 97362)


--- trunk/Source/WebCore/inspector/front-end/HeapSnapshotProxy.js	2011-10-13 10:59:31 UTC (rev 97361)
+++ trunk/Source/WebCore/inspector/front-end/HeapSnapshotProxy.js	2011-10-13 11:08:49 UTC (rev 97362)
@@ -370,6 +370,11 @@
         this.callMethod(callback, "nodeFieldValuesByIndex", fieldName, indexes);
     },
 
+    get nodeFlags()
+    {
+        return this._staticData.nodeFlags;
+    },
+
     pushBaseIds: function(snapshotId, className, nodeIds)
     {
         this.callMethod(null, "pushBaseIds", snapshotId, className, nodeIds);

Modified: trunk/Source/WebCore/inspector/front-end/RemoteObject.js (97361 => 97362)


--- trunk/Source/WebCore/inspector/front-end/RemoteObject.js	2011-10-13 10:59:31 UTC (rev 97361)
+++ trunk/Source/WebCore/inspector/front-end/RemoteObject.js	2011-10-13 11:08:49 UTC (rev 97362)
@@ -54,6 +54,11 @@
     }
 }
 
+WebInspector.RemoteObject.fromError = function(errorDescription)
+{
+    return new WebInspector.RemoteObject(null, null, null, errorDescription);
+}
+
 WebInspector.RemoteObject.fromPrimitiveValue = function(value)
 {
     return new WebInspector.RemoteObject(null, typeof value, null, value);

Modified: trunk/Source/WebCore/inspector/front-end/heapProfiler.css (97361 => 97362)


--- trunk/Source/WebCore/inspector/front-end/heapProfiler.css	2011-10-13 10:59:31 UTC (rev 97361)
+++ trunk/Source/WebCore/inspector/front-end/heapProfiler.css	2011-10-13 11:08:49 UTC (rev 97362)
@@ -194,6 +194,10 @@
     margin-right: 8px;
 }
 
+.detailed-heapshot-view tr:not(.selected) td.object-column span.highlight {
+    background-color: rgb(255, 255, 200);
+}
+
 .heapshot-help-status-bar-item .glyph {
     -webkit-mask-position: -160px 0;
 }
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to