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;
}