summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortc@google.com <tc@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-26 22:15:17 +0000
committertc@google.com <tc@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-26 22:15:17 +0000
commit756cefa0028e898e6a401ae3154db87d53f59914 (patch)
tree9c13d3039e82f2887e11462f3c71d96dc8cbd9bf
parentfe60195a19a160fa09f76aab21f355e63caa4faa (diff)
downloadchromium_src-756cefa0028e898e6a401ae3154db87d53f59914.zip
chromium_src-756cefa0028e898e6a401ae3154db87d53f59914.tar.gz
chromium_src-756cefa0028e898e6a401ae3154db87d53f59914.tar.bz2
Check in a new linux reference build and enable the page cycler tests.
We were crashing while trying to load fonts. Your patch for font fallback fixes the crash. Review URL: http://codereview.chromium.org/112061 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@16932 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/test/page_cycler/page_cycler_test.cc4
-rwxr-xr-xchrome/tools/test/reference_build/chrome_linux/chromebin33009105 -> 33803577 bytes
-rw-r--r--chrome/tools/test/reference_build/chrome_linux/chrome.pakbin571807 -> 626294 bytes
-rw-r--r--chrome/tools/test/reference_build/chrome_linux/locales/da.pakbin85018 -> 85828 bytes
-rw-r--r--chrome/tools/test/reference_build/chrome_linux/locales/en-US.pakbin79964 -> 80762 bytes
-rw-r--r--chrome/tools/test/reference_build/chrome_linux/locales/he.pakbin70128 -> 71040 bytes
-rw-r--r--chrome/tools/test/reference_build/chrome_linux/locales/zh-TW.pakbin48410 -> 49720 bytes
-rw-r--r--chrome/tools/test/reference_build/chrome_linux/resources/inspector/Console.js49
-rw-r--r--chrome/tools/test/reference_build/chrome_linux/resources/inspector/ElementsTreeOutline.js2
-rw-r--r--chrome/tools/test/reference_build/chrome_linux/resources/inspector/ProfileDataGridTree.js398
-rw-r--r--chrome/tools/test/reference_build/chrome_linux/resources/inspector/codemap.js230
-rw-r--r--chrome/tools/test/reference_build/chrome_linux/resources/inspector/consarray.js93
-rw-r--r--chrome/tools/test/reference_build/chrome_linux/resources/inspector/csvparser.js98
-rw-r--r--chrome/tools/test/reference_build/chrome_linux/resources/inspector/debugger_agent.js531
-rw-r--r--chrome/tools/test/reference_build/chrome_linux/resources/inspector/devtools.html8
-rw-r--r--chrome/tools/test/reference_build/chrome_linux/resources/inspector/devtools.js219
-rw-r--r--chrome/tools/test/reference_build/chrome_linux/resources/inspector/devtools_host_stub.js59
-rw-r--r--chrome/tools/test/reference_build/chrome_linux/resources/inspector/dom_agent.js10
-rw-r--r--chrome/tools/test/reference_build/chrome_linux/resources/inspector/inject.js1
-rw-r--r--chrome/tools/test/reference_build/chrome_linux/resources/inspector/inspector.js99
-rw-r--r--chrome/tools/test/reference_build/chrome_linux/resources/inspector/inspector_controller.js6
-rw-r--r--chrome/tools/test/reference_build/chrome_linux/resources/inspector/inspector_controller_impl.js16
-rw-r--r--chrome/tools/test/reference_build/chrome_linux/resources/inspector/net_agent.js34
-rw-r--r--chrome/tools/test/reference_build/chrome_linux/resources/inspector/profile.js605
-rw-r--r--chrome/tools/test/reference_build/chrome_linux/resources/inspector/profile_view.js251
-rw-r--r--chrome/tools/test/reference_build/chrome_linux/resources/inspector/profiler_processor.js201
-rw-r--r--chrome/tools/test/reference_build/chrome_linux/resources/inspector/splaytree.js322
-rw-r--r--chrome/tools/test/reference_build/chrome_linux/themes/default.pakbin340643 -> 332053 bytes
28 files changed, 2926 insertions, 310 deletions
diff --git a/chrome/test/page_cycler/page_cycler_test.cc b/chrome/test/page_cycler/page_cycler_test.cc
index 1978c3c..1158248 100644
--- a/chrome/test/page_cycler/page_cycler_test.cc
+++ b/chrome/test/page_cycler/page_cycler_test.cc
@@ -259,8 +259,6 @@ class PageCyclerReferenceTest : public PageCyclerTest {
}
};
-#if !defined(OS_LINUX)
-
// file-URL tests
TEST_F(PageCyclerTest, MozFile) {
RunTest("moz", false);
@@ -359,6 +357,4 @@ TEST_F(PageCyclerReferenceTest, BloatHttp) {
}
#endif
-#endif // !defined(OS_LINUX)
-
} // namespace
diff --git a/chrome/tools/test/reference_build/chrome_linux/chrome b/chrome/tools/test/reference_build/chrome_linux/chrome
index d9c91bf..deebaa3 100755
--- a/chrome/tools/test/reference_build/chrome_linux/chrome
+++ b/chrome/tools/test/reference_build/chrome_linux/chrome
Binary files differ
diff --git a/chrome/tools/test/reference_build/chrome_linux/chrome.pak b/chrome/tools/test/reference_build/chrome_linux/chrome.pak
index a1b28e3..9cc4b57 100644
--- a/chrome/tools/test/reference_build/chrome_linux/chrome.pak
+++ b/chrome/tools/test/reference_build/chrome_linux/chrome.pak
Binary files differ
diff --git a/chrome/tools/test/reference_build/chrome_linux/locales/da.pak b/chrome/tools/test/reference_build/chrome_linux/locales/da.pak
index 0a47477..454f647 100644
--- a/chrome/tools/test/reference_build/chrome_linux/locales/da.pak
+++ b/chrome/tools/test/reference_build/chrome_linux/locales/da.pak
Binary files differ
diff --git a/chrome/tools/test/reference_build/chrome_linux/locales/en-US.pak b/chrome/tools/test/reference_build/chrome_linux/locales/en-US.pak
index 22ba218..820f520 100644
--- a/chrome/tools/test/reference_build/chrome_linux/locales/en-US.pak
+++ b/chrome/tools/test/reference_build/chrome_linux/locales/en-US.pak
Binary files differ
diff --git a/chrome/tools/test/reference_build/chrome_linux/locales/he.pak b/chrome/tools/test/reference_build/chrome_linux/locales/he.pak
index a3ac813..dd94230 100644
--- a/chrome/tools/test/reference_build/chrome_linux/locales/he.pak
+++ b/chrome/tools/test/reference_build/chrome_linux/locales/he.pak
Binary files differ
diff --git a/chrome/tools/test/reference_build/chrome_linux/locales/zh-TW.pak b/chrome/tools/test/reference_build/chrome_linux/locales/zh-TW.pak
index 9d564c5..a2c8627 100644
--- a/chrome/tools/test/reference_build/chrome_linux/locales/zh-TW.pak
+++ b/chrome/tools/test/reference_build/chrome_linux/locales/zh-TW.pak
Binary files differ
diff --git a/chrome/tools/test/reference_build/chrome_linux/resources/inspector/Console.js b/chrome/tools/test/reference_build/chrome_linux/resources/inspector/Console.js
index ba879a0..65cc7d0 100644
--- a/chrome/tools/test/reference_build/chrome_linux/resources/inspector/Console.js
+++ b/chrome/tools/test/reference_build/chrome_linux/resources/inspector/Console.js
@@ -577,31 +577,36 @@ WebInspector.ConsoleMessage = function(source, level, line, url, groupLevel, rep
this.url = url;
this.groupLevel = groupLevel;
this.repeatCount = repeatCount;
-
- switch (this.level) {
- case WebInspector.ConsoleMessage.MessageLevel.Trace:
- var span = document.createElement("span");
- span.addStyleClass("console-formatted-trace");
- var stack = Array.prototype.slice.call(arguments, 6);
- var funcNames = stack.map(function(f) {
- return f || WebInspector.UIString("(anonymous function)");
- });
- span.appendChild(document.createTextNode(funcNames.join("\n")));
- this.formattedMessage = span;
- break;
- case WebInspector.ConsoleMessage.MessageLevel.Object:
- this.formattedMessage = this._format(["%O", arguments[6]]);
- break;
- default:
- this.formattedMessage = this._format(Array.prototype.slice.call(arguments, 6));
- break;
- }
-
- // This is used for inline message bubbles in SourceFrames, or other plain-text representations.
- this.message = this.formattedMessage.textContent;
+ if (arguments.length > 6)
+ this.setMessageBody(Array.prototype.slice.call(arguments, 6));
}
WebInspector.ConsoleMessage.prototype = {
+ setMessageBody: function(args)
+ {
+ switch (this.level) {
+ case WebInspector.ConsoleMessage.MessageLevel.Trace:
+ var span = document.createElement("span");
+ span.addStyleClass("console-formatted-trace");
+ var stack = Array.prototype.slice.call(args);
+ var funcNames = stack.map(function(f) {
+ return f || WebInspector.UIString("(anonymous function)");
+ });
+ span.appendChild(document.createTextNode(funcNames.join("\n")));
+ this.formattedMessage = span;
+ break;
+ case WebInspector.ConsoleMessage.MessageLevel.Object:
+ this.formattedMessage = this._format(["%O", args[0]]);
+ break;
+ default:
+ this.formattedMessage = this._format(args);
+ break;
+ }
+
+ // This is used for inline message bubbles in SourceFrames, or other plain-text representations.
+ this.message = this.formattedMessage.textContent;
+ },
+
isErrorOrWarning: function()
{
return (this.level === WebInspector.ConsoleMessage.MessageLevel.Warning || this.level === WebInspector.ConsoleMessage.MessageLevel.Error);
diff --git a/chrome/tools/test/reference_build/chrome_linux/resources/inspector/ElementsTreeOutline.js b/chrome/tools/test/reference_build/chrome_linux/resources/inspector/ElementsTreeOutline.js
index 16e31b8..822bf35 100644
--- a/chrome/tools/test/reference_build/chrome_linux/resources/inspector/ElementsTreeOutline.js
+++ b/chrome/tools/test/reference_build/chrome_linux/resources/inspector/ElementsTreeOutline.js
@@ -571,7 +571,7 @@ WebInspector.ElementsTreeElement.prototype = {
parseContainerElement.innerHTML = "<span " + newText + "></span>";
var parseElement = parseContainerElement.firstChild;
if (!parseElement || !parseElement.hasAttributes()) {
- editingCancelled(element, context);
+ this._editingCancelled(element, context);
return;
}
diff --git a/chrome/tools/test/reference_build/chrome_linux/resources/inspector/ProfileDataGridTree.js b/chrome/tools/test/reference_build/chrome_linux/resources/inspector/ProfileDataGridTree.js
new file mode 100644
index 0000000..84d9923
--- /dev/null
+++ b/chrome/tools/test/reference_build/chrome_linux/resources/inspector/ProfileDataGridTree.js
@@ -0,0 +1,398 @@
+/*
+ * Copyright (C) 2009 280 North Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WebInspector.ProfileDataGridNode = function(profileView, profileNode, owningTree, hasChildren)
+{
+ this.profileView = profileView;
+ this.profileNode = profileNode;
+
+ WebInspector.DataGridNode.call(this, null, hasChildren);
+
+ this.addEventListener("populate", this._populate, this);
+
+ this.tree = owningTree;
+
+ this.childrenByCallUID = {};
+ this.lastComparator = null;
+
+ this.callUID = profileNode.callUID;
+ this.selfTime = profileNode.selfTime;
+ this.totalTime = profileNode.totalTime;
+ this.functionName = profileNode.functionName;
+ this.numberOfCalls = profileNode.numberOfCalls;
+ this.url = profileNode.url;
+}
+
+WebInspector.ProfileDataGridNode.prototype = {
+ get data()
+ {
+ function formatMilliseconds(time)
+ {
+ return Number.secondsToString(time / 1000, WebInspector.UIString.bind(WebInspector), true);
+ }
+
+ var data = {};
+
+ data["function"] = this.functionName;
+ data["calls"] = this.numberOfCalls;
+
+ if (this.profileView.showSelfTimeAsPercent)
+ data["self"] = WebInspector.UIString("%.2f%%", this.selfPercent);
+ else
+ data["self"] = formatMilliseconds(this.selfTime);
+
+ if (this.profileView.showTotalTimeAsPercent)
+ data["total"] = WebInspector.UIString("%.2f%%", this.totalPercent);
+ else
+ data["total"] = formatMilliseconds(this.totalTime);
+
+ if (this.profileView.showAverageTimeAsPercent)
+ data["average"] = WebInspector.UIString("%.2f%%", this.averagePercent);
+ else
+ data["average"] = formatMilliseconds(this.averageTime);
+
+ return data;
+ },
+
+ createCell: function(columnIdentifier)
+ {
+ var cell = WebInspector.DataGridNode.prototype.createCell.call(this, columnIdentifier);
+
+ if (columnIdentifier === "self" && this._searchMatchedSelfColumn)
+ cell.addStyleClass("highlight");
+ else if (columnIdentifier === "total" && this._searchMatchedTotalColumn)
+ cell.addStyleClass("highlight");
+ else if (columnIdentifier === "average" && this._searchMatchedAverageColumn)
+ cell.addStyleClass("highlight");
+ else if (columnIdentifier === "calls" && this._searchMatchedCallsColumn)
+ cell.addStyleClass("highlight");
+
+ if (columnIdentifier !== "function")
+ return cell;
+
+ if (this.profileNode._searchMatchedFunctionColumn)
+ cell.addStyleClass("highlight");
+
+ if (this.profileNode.url) {
+ var fileName = WebInspector.displayNameForURL(this.profileNode.url);
+
+ var urlElement = document.createElement("a");
+ urlElement.className = "profile-node-file webkit-html-resource-link";
+ urlElement.href = this.profileNode.url;
+ urlElement.lineNumber = this.profileNode.lineNumber;
+
+ if (this.profileNode.lineNumber > 0)
+ urlElement.textContent = fileName + ":" + this.profileNode.lineNumber;
+ else
+ urlElement.textContent = fileName;
+
+ cell.insertBefore(urlElement, cell.firstChild);
+ }
+
+ return cell;
+ },
+
+ select: function(supressSelectedEvent)
+ {
+ WebInspector.DataGridNode.prototype.select.call(this, supressSelectedEvent);
+ this.profileView._dataGridNodeSelected(this);
+ },
+
+ deselect: function(supressDeselectedEvent)
+ {
+ WebInspector.DataGridNode.prototype.deselect.call(this, supressDeselectedEvent);
+ this.profileView._dataGridNodeDeselected(this);
+ },
+
+ expand: function()
+ {
+ if (!this.parent) {
+ var currentComparator = this.parent.lastComparator;
+
+ if (!currentComparator || (currentComparator === this.lastComparator))
+ return;
+
+ this.sort(currentComparator);
+ }
+
+ WebInspector.DataGridNode.prototype.expand.call(this);
+ },
+
+ sort: function(/*Function*/ comparator, /*Boolean*/ force)
+ {
+ var gridNodeGroups = [[this]];
+
+ for (var gridNodeGroupIndex = 0; gridNodeGroupIndex < gridNodeGroups.length; ++gridNodeGroupIndex) {
+ var gridNodes = gridNodeGroups[gridNodeGroupIndex];
+ var count = gridNodes.length;
+
+ for (var index = 0; index < count; ++index) {
+ var gridNode = gridNodes[index];
+
+ // If the grid node is collapsed, then don't sort children (save operation for later).
+ // If the grid node has the same sorting as previously, then there is no point in sorting it again.
+ if (!force && !gridNode.expanded || gridNode.lastComparator === comparator)
+ continue;
+
+ gridNode.lastComparator = comparator;
+
+ var children = gridNode.children;
+ var childCount = children.length;
+
+ if (childCount) {
+ children.sort(comparator);
+
+ for (var childIndex = 0; childIndex < childCount; ++childIndex)
+ children[childIndex]._recalculateSiblings(childIndex);
+
+ gridNodeGroups.push(children);
+ }
+ }
+ }
+ },
+
+ insertChild: function(/*ProfileDataGridNode*/ profileDataGridNode, index)
+ {
+ WebInspector.DataGridNode.prototype.insertChild.call(this, profileDataGridNode, index);
+
+ this.childrenByCallUID[profileDataGridNode.callUID] = profileDataGridNode;
+ },
+
+ removeChild: function(/*ProfileDataGridNode*/ profileDataGridNode)
+ {
+ WebInspector.DataGridNode.prototype.removeChild.call(this, profileDataGridNode);
+
+ delete this.childrenByCallUID[profileDataGridNode.callUID];
+ },
+
+ removeChildren: function(/*ProfileDataGridNode*/ profileDataGridNode)
+ {
+ WebInspector.DataGridNode.prototype.removeChildren.call(this);
+
+ this.childrenByCallUID = {};
+ },
+
+ findChild: function(/*Node*/ node)
+ {
+ if (!node)
+ return null;
+ return this.childrenByCallUID[node.callUID];
+ },
+
+ get averageTime()
+ {
+ return this.selfTime / Math.max(1, this.numberOfCalls);
+ },
+
+ get averagePercent()
+ {
+ return this.averageTime / this.tree.totalTime * 100.0;
+ },
+
+ get selfPercent()
+ {
+ return this.selfTime / this.tree.totalTime * 100.0;
+ },
+
+ get totalPercent()
+ {
+ return this.totalTime / this.tree.totalTime * 100.0;
+ },
+
+ // When focusing and collapsing we modify lots of nodes in the tree.
+ // This allows us to restore them all to their original state when we revert.
+ _save: function()
+ {
+ if (this._savedChildren)
+ return;
+
+ this._savedSelfTime = this.selfTime;
+ this._savedTotalTime = this.totalTime;
+ this._savedNumberOfCalls = this.numberOfCalls;
+
+ this._savedChildren = this.children.slice();
+ },
+
+ // When focusing and collapsing we modify lots of nodes in the tree.
+ // This allows us to restore them all to their original state when we revert.
+ _restore: function()
+ {
+ if (!this._savedChildren)
+ return;
+
+ this.selfTime = this._savedSelfTime;
+ this.totalTime = this._savedTotalTime;
+ this.numberOfCalls = this._savedNumberOfCalls;
+
+ this.removeChildren();
+
+ var children = this._savedChildren;
+ var count = children.length;
+
+ for (var index = 0; index < count; ++index) {
+ children[index]._restore();
+ this.appendChild(children[index]);
+ }
+ },
+
+ _merge: function(child, shouldAbsorb)
+ {
+ this.selfTime += child.selfTime;
+
+ if (!shouldAbsorb) {
+ this.totalTime += child.totalTime;
+ this.numberOfCalls += child.numberOfCalls;
+ }
+
+ var children = this.children.slice();
+
+ this.removeChildren();
+
+ var count = children.length;
+
+ for (var index = 0; index < count; ++index) {
+ if (!shouldAbsorb || children[index] !== child)
+ this.appendChild(children[index]);
+ }
+
+ children = child.children.slice();
+ count = children.length;
+
+ for (var index = 0; index < count; ++index) {
+ var orphanedChild = children[index],
+ existingChild = this.childrenByCallUID[orphanedChild.callUID];
+
+ if (existingChild)
+ existingChild._merge(orphanedChild, false);
+ else
+ this.appendChild(orphanedChild);
+ }
+ }
+}
+
+WebInspector.ProfileDataGridNode.prototype.__proto__ = WebInspector.DataGridNode.prototype;
+
+WebInspector.ProfileDataGridTree = function(profileView, profileNode)
+{
+ this.tree = this;
+ this.children = [];
+
+ this.profileView = profileView;
+
+ this.totalTime = profileNode.totalTime;
+ this.lastComparator = null;
+
+ this.childrenByCallUID = {};
+}
+
+WebInspector.ProfileDataGridTree.prototype = {
+ get expanded()
+ {
+ return true;
+ },
+
+ appendChild: function(child)
+ {
+ this.insertChild(child, this.children.length);
+ },
+
+ insertChild: function(child, index)
+ {
+ this.children.splice(index, 0, child);
+ this.childrenByCallUID[child.callUID] = child;
+ },
+
+ removeChildren: function()
+ {
+ this.children = [];
+ this.childrenByCallUID = {};
+ },
+
+ findChild: WebInspector.ProfileDataGridNode.prototype.findChild,
+ sort: WebInspector.ProfileDataGridNode.prototype.sort,
+
+ _save: function()
+ {
+ if (this._savedChildren)
+ return;
+
+ this._savedTotalTime = this.totalTime;
+ this._savedChildren = this.children.slice();
+ },
+
+ restore: function()
+ {
+ if (!this._savedChildren)
+ return;
+
+ this.children = this._savedChildren;
+ this.totalTime = this._savedTotalTime;
+
+ var children = this.children;
+ var count = children.length;
+
+ for (var index = 0; index < count; ++index)
+ children[index]._restore();
+
+ this._savedChildren = null;
+ }
+}
+
+WebInspector.ProfileDataGridTree.propertyComparators = [{}, {}];
+
+WebInspector.ProfileDataGridTree.propertyComparator = function(/*String*/ property, /*Boolean*/ isAscending)
+{
+ var comparator = this.propertyComparators[(isAscending ? 1 : 0)][property];
+
+ if (!comparator) {
+ if (isAscending) {
+ comparator = function(lhs, rhs)
+ {
+ if (lhs[property] < rhs[property])
+ return -1;
+
+ if (lhs[property] > rhs[property])
+ return 1;
+
+ return 0;
+ }
+ } else {
+ comparator = function(lhs, rhs)
+ {
+ if (lhs[property] > rhs[property])
+ return -1;
+
+ if (lhs[property] < rhs[property])
+ return 1;
+
+ return 0;
+ }
+ }
+
+ this.propertyComparators[(isAscending ? 1 : 0)][property] = comparator;
+ }
+
+ return comparator;
+}
diff --git a/chrome/tools/test/reference_build/chrome_linux/resources/inspector/codemap.js b/chrome/tools/test/reference_build/chrome_linux/resources/inspector/codemap.js
new file mode 100644
index 0000000..3766db0
--- /dev/null
+++ b/chrome/tools/test/reference_build/chrome_linux/resources/inspector/codemap.js
@@ -0,0 +1,230 @@
+// Copyright 2009 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+// Initlialize namespaces
+var devtools = devtools || {};
+devtools.profiler = devtools.profiler || {};
+
+
+/**
+ * Constructs a mapper that maps addresses into code entries.
+ *
+ * @constructor
+ */
+devtools.profiler.CodeMap = function() {
+ /**
+ * Dynamic code entries. Used for JIT compiled code.
+ */
+ this.dynamics_ = new goog.structs.SplayTree();
+
+ /**
+ * Name generator for entries having duplicate names.
+ */
+ this.dynamicsNameGen_ = new devtools.profiler.CodeMap.NameGenerator();
+
+ /**
+ * Static code entries. Used for libraries code.
+ */
+ this.statics_ = new goog.structs.SplayTree();
+
+ /**
+ * Map of memory pages occupied with static code.
+ */
+ this.pages_ = [];
+};
+
+
+/**
+ * The number of alignment bits in a page address.
+ */
+devtools.profiler.CodeMap.PAGE_ALIGNMENT = 12;
+
+
+/**
+ * Page size in bytes.
+ */
+devtools.profiler.CodeMap.PAGE_SIZE =
+ 1 << devtools.profiler.CodeMap.PAGE_ALIGNMENT;
+
+
+/**
+ * Adds a dynamic (i.e. moveable and discardable) code entry.
+ *
+ * @param {number} start The starting address.
+ * @param {devtools.profiler.CodeMap.CodeEntry} codeEntry Code entry object.
+ */
+devtools.profiler.CodeMap.prototype.addCode = function(start, codeEntry) {
+ this.dynamics_.insert(start, codeEntry);
+};
+
+
+/**
+ * Moves a dynamic code entry. Throws an exception if there is no dynamic
+ * code entry with the specified starting address.
+ *
+ * @param {number} from The starting address of the entry being moved.
+ * @param {number} to The destination address.
+ */
+devtools.profiler.CodeMap.prototype.moveCode = function(from, to) {
+ var removedNode = this.dynamics_.remove(from);
+ this.dynamics_.insert(to, removedNode.value);
+};
+
+
+/**
+ * Discards a dynamic code entry. Throws an exception if there is no dynamic
+ * code entry with the specified starting address.
+ *
+ * @param {number} start The starting address of the entry being deleted.
+ */
+devtools.profiler.CodeMap.prototype.deleteCode = function(start) {
+ var removedNode = this.dynamics_.remove(start);
+};
+
+
+/**
+ * Adds a static code entry.
+ *
+ * @param {number} start The starting address.
+ * @param {devtools.profiler.CodeMap.CodeEntry} codeEntry Code entry object.
+ */
+devtools.profiler.CodeMap.prototype.addStaticCode = function(
+ start, codeEntry) {
+ this.markPages_(start, start + codeEntry.size);
+ this.statics_.insert(start, codeEntry);
+};
+
+
+/**
+ * @private
+ */
+devtools.profiler.CodeMap.prototype.markPages_ = function(start, end) {
+ for (var addr = start; addr <= end;
+ addr += devtools.profiler.CodeMap.PAGE_SIZE) {
+ this.pages_[addr >> devtools.profiler.CodeMap.PAGE_ALIGNMENT] = 1;
+ }
+};
+
+
+/**
+ * @private
+ */
+devtools.profiler.CodeMap.prototype.isAddressBelongsTo_ = function(addr, node) {
+ return addr >= node.key && addr < (node.key + node.value.size);
+};
+
+
+/**
+ * @private
+ */
+devtools.profiler.CodeMap.prototype.findInTree_ = function(tree, addr) {
+ var node = tree.findGreatestLessThan(addr);
+ return node && this.isAddressBelongsTo_(addr, node) ? node.value : null;
+};
+
+
+/**
+ * Finds a code entry that contains the specified address. Both static and
+ * dynamic code entries are considered.
+ *
+ * @param {number} addr Address.
+ */
+devtools.profiler.CodeMap.prototype.findEntry = function(addr) {
+ var pageAddr = addr >> devtools.profiler.CodeMap.PAGE_ALIGNMENT;
+ if (pageAddr in this.pages_) {
+ return this.findInTree_(this.statics_, addr);
+ }
+ var min = this.dynamics_.findMin();
+ var max = this.dynamics_.findMax();
+ if (max != null && addr < (max.key + max.value.size) && addr >= min.key) {
+ var dynaEntry = this.findInTree_(this.dynamics_, addr);
+ if (dynaEntry == null) return null;
+ // Dedupe entry name.
+ if (!dynaEntry.nameUpdated_) {
+ dynaEntry.name = this.dynamicsNameGen_.getName(dynaEntry.name);
+ dynaEntry.nameUpdated_ = true;
+ }
+ return dynaEntry;
+ }
+ return null;
+};
+
+
+/**
+ * Returns an array of all dynamic code entries, including deleted ones.
+ */
+devtools.profiler.CodeMap.prototype.getAllDynamicEntries = function() {
+ return this.dynamics_.exportValues();
+};
+
+
+/**
+ * Returns an array of all static code entries.
+ */
+devtools.profiler.CodeMap.prototype.getAllStaticEntries = function() {
+ return this.statics_.exportValues();
+};
+
+
+/**
+ * Creates a code entry object.
+ *
+ * @param {number} size Code entry size in bytes.
+ * @param {string} opt_name Code entry name.
+ * @constructor
+ */
+devtools.profiler.CodeMap.CodeEntry = function(size, opt_name) {
+ this.size = size;
+ this.name = opt_name || '';
+ this.nameUpdated_ = false;
+};
+
+
+devtools.profiler.CodeMap.CodeEntry.prototype.getName = function() {
+ return this.name;
+};
+
+
+devtools.profiler.CodeMap.CodeEntry.prototype.toString = function() {
+ return this.name + ': ' + this.size.toString(16);
+};
+
+
+devtools.profiler.CodeMap.NameGenerator = function() {
+ this.knownNames_ = [];
+};
+
+
+devtools.profiler.CodeMap.NameGenerator.prototype.getName = function(name) {
+ if (!(name in this.knownNames_)) {
+ this.knownNames_[name] = 0;
+ return name;
+ }
+ var count = ++this.knownNames_[name];
+ return name + ' {' + count + '}';
+};
diff --git a/chrome/tools/test/reference_build/chrome_linux/resources/inspector/consarray.js b/chrome/tools/test/reference_build/chrome_linux/resources/inspector/consarray.js
new file mode 100644
index 0000000..c67abb7
--- /dev/null
+++ b/chrome/tools/test/reference_build/chrome_linux/resources/inspector/consarray.js
@@ -0,0 +1,93 @@
+// Copyright 2009 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+/**
+ * Constructs a ConsArray object. It is used mainly for tree traversal.
+ * In this use case we have lots of arrays that we need to iterate
+ * sequentally. The internal Array implementation is horribly slow
+ * when concatenating on large (10K items) arrays due to memory copying.
+ * That's why we avoid copying memory and insead build a linked list
+ * of arrays to iterate through.
+ *
+ * @constructor
+ */
+function ConsArray() {
+ this.tail_ = new ConsArray.Cell(null, null);
+ this.currCell_ = this.tail_;
+ this.currCellPos_ = 0;
+};
+
+
+/**
+ * Concatenates another array for iterating. Empty arrays are ignored.
+ * This operation can be safely performed during ongoing ConsArray
+ * iteration.
+ *
+ * @param {Array} arr Array to concatenate.
+ */
+ConsArray.prototype.concat = function(arr) {
+ if (arr.length > 0) {
+ this.tail_.data = arr;
+ this.tail_ = this.tail_.next = new ConsArray.Cell(null, null);
+ }
+};
+
+
+/**
+ * Whether the end of iteration is reached.
+ */
+ConsArray.prototype.atEnd = function() {
+ return this.currCell_ === null ||
+ this.currCell_.data === null ||
+ this.currCellPos_ >= this.currCell_.data.length;
+};
+
+
+/**
+ * Returns the current item, moves to the next one.
+ */
+ConsArray.prototype.next = function() {
+ var result = this.currCell_.data[this.currCellPos_++];
+ if (this.currCellPos_ >= this.currCell_.data.length) {
+ this.currCell_ = this.currCell_.next;
+ this.currCellPos_ = 0;
+ }
+ return result;
+};
+
+
+/**
+ * A cell object used for constructing a list in ConsArray.
+ *
+ * @constructor
+ */
+ConsArray.Cell = function(data, next) {
+ this.data = data;
+ this.next = next;
+};
+
diff --git a/chrome/tools/test/reference_build/chrome_linux/resources/inspector/csvparser.js b/chrome/tools/test/reference_build/chrome_linux/resources/inspector/csvparser.js
new file mode 100644
index 0000000..9e58dea
--- /dev/null
+++ b/chrome/tools/test/reference_build/chrome_linux/resources/inspector/csvparser.js
@@ -0,0 +1,98 @@
+// Copyright 2009 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+// Initlialize namespaces.
+var devtools = devtools || {};
+devtools.profiler = devtools.profiler || {};
+
+
+/**
+ * Creates a CSV lines parser.
+ */
+devtools.profiler.CsvParser = function() {
+};
+
+
+/**
+ * A regex for matching a trailing quote.
+ * @private
+ */
+devtools.profiler.CsvParser.TRAILING_QUOTE_RE_ = /\"$/;
+
+
+/**
+ * A regex for matching a double quote.
+ * @private
+ */
+devtools.profiler.CsvParser.DOUBLE_QUOTE_RE_ = /\"\"/g;
+
+
+/**
+ * Parses a line of CSV-encoded values. Returns an array of fields.
+ *
+ * @param {string} line Input line.
+ */
+devtools.profiler.CsvParser.prototype.parseLine = function(line) {
+ var insideQuotes = false;
+ var fields = [];
+ var prevPos = 0;
+ for (var i = 0, n = line.length; i < n; ++i) {
+ switch (line.charAt(i)) {
+ case ',':
+ if (!insideQuotes) {
+ fields.push(line.substring(prevPos, i));
+ prevPos = i + 1;
+ }
+ break;
+ case '"':
+ if (!insideQuotes) {
+ insideQuotes = true;
+ // Skip the leading quote.
+ prevPos++;
+ } else {
+ if (i + 1 < n && line.charAt(i + 1) != '"') {
+ insideQuotes = false;
+ } else {
+ i++;
+ }
+ }
+ break;
+ }
+ }
+ if (n > 0) {
+ fields.push(line.substring(prevPos));
+ }
+
+ for (i = 0; i < fields.length; ++i) {
+ // Eliminate trailing quotes.
+ fields[i] = fields[i].replace(devtools.profiler.CsvParser.TRAILING_QUOTE_RE_, '');
+ // Convert quoted quotes into single ones.
+ fields[i] = fields[i].replace(devtools.profiler.CsvParser.DOUBLE_QUOTE_RE_, '"');
+ }
+ return fields;
+};
diff --git a/chrome/tools/test/reference_build/chrome_linux/resources/inspector/debugger_agent.js b/chrome/tools/test/reference_build/chrome_linux/resources/inspector/debugger_agent.js
index 4454b83..890f704 100644
--- a/chrome/tools/test/reference_build/chrome_linux/resources/inspector/debugger_agent.js
+++ b/chrome/tools/test/reference_build/chrome_linux/resources/inspector/debugger_agent.js
@@ -15,13 +15,25 @@ goog.provide('devtools.DebuggerAgent');
devtools.DebuggerAgent = function() {
RemoteDebuggerAgent.DebuggerOutput =
goog.bind(this.handleDebuggerOutput_, this);
-
+ RemoteDebuggerAgent.DidGetContextId =
+ goog.bind(this.didGetContextId_, this);
+ RemoteDebuggerAgent.DidIsProfilingStarted =
+ goog.bind(this.didIsProfilingStarted_, this);
+ RemoteDebuggerAgent.DidGetLogLines =
+ goog.bind(this.didGetLogLines_, this);
+
+ /**
+ * Id of the inspected page global context. It is used for filtering scripts.
+ * @type {number}
+ */
+ this.contextId_ = null;
+
/**
* Mapping from script id to script info.
* @type {Object}
*/
this.parsedScripts_ = null;
-
+
/**
* Mapping from the request id to the devtools.BreakpointInfo for the
* breakpoints whose v8 ids are not set yet. These breakpoints are waiting for
@@ -30,36 +42,74 @@ devtools.DebuggerAgent = function() {
* @type {Object}
*/
this.requestNumberToBreakpointInfo_ = null;
-
+
/**
* Information on current stack top frame.
* See JavaScriptCallFrame.idl.
* @type {?devtools.CallFrame}
*/
this.currentCallFrame_ = null;
-
+
/**
* Whether to stop in the debugger on the exceptions.
* @type {boolean}
*/
this.pauseOnExceptions_ = true;
-
+
/**
* Mapping: request sequence number->callback.
* @type {Object}
*/
- this.requestSeqToCallback_ = null;
+ this.requestSeqToCallback_ = null;
+
+ /**
+ * Whether the scripts list has been requested.
+ * @type {boolean}
+ */
+ this.scriptsCacheInitialized_ = false;
+
+ /**
+ * Whether user has stopped profiling and we are retrieving the rest of
+ * profiler's log.
+ * @type {boolean}
+ */
+ this.isProcessingProfile_ = false;
+
+ /**
+ * The position in log file to read from.
+ * @type {number}
+ */
+ this.lastProfileLogPosition_ = 0;
+
+ /**
+ * Profiler processor instance.
+ * @type {devtools.profiler.Processor}
+ */
+ this.profilerProcessor_ = new devtools.profiler.Processor();
};
/**
* Resets debugger agent to its initial state.
*/
- devtools.DebuggerAgent.prototype.reset = function() {
- this.parsedScripts_ = {};
- this.requestNumberToBreakpointInfo_ = {};
- this.currentCallFrame_ = null;
- this.requestSeqToCallback_ = {};
+devtools.DebuggerAgent.prototype.reset = function() {
+ this.scriptsCacheInitialized_ = false;
+ this.contextId_ = null;
+ this.parsedScripts_ = {};
+ this.requestNumberToBreakpointInfo_ = {};
+ this.currentCallFrame_ = null;
+ this.requestSeqToCallback_ = {};
+};
+
+
+/**
+ * Requests scripts list if it has not been requested yet.
+ */
+devtools.DebuggerAgent.prototype.initializeScriptsCache = function() {
+ if (!this.scriptsCacheInitialized_) {
+ this.scriptsCacheInitialized_ = true;
+ this.requestScripts();
+ }
};
@@ -68,12 +118,51 @@ devtools.DebuggerAgent = function() {
* processed in handleScriptsResponse_.
*/
devtools.DebuggerAgent.prototype.requestScripts = function() {
+ if (this.contextId_ === null) {
+ // Update context id first to filter the scripts.
+ RemoteDebuggerAgent.GetContextId();
+ return;
+ }
+ var cmd = new devtools.DebugCommand('scripts', {
+ 'includeSource': false
+ });
+ devtools.DebuggerAgent.sendCommand_(cmd);
+ // Force v8 execution so that it gets to processing the requested command.
+ devtools.tools.evaluateJavaScript('javascript:void(0)');
+};
+
+
+/**
+ * Asynchronously requests the debugger for the script source.
+ * @param {number} scriptId Id of the script whose source should be resolved.
+ * @param {function(source:?string):void} callback Function that will be called
+ * when the source resolution is completed. 'source' parameter will be null
+ * if the resolution fails.
+ */
+devtools.DebuggerAgent.prototype.resolveScriptSource = function(
+ scriptId, callback) {
+ var script = this.parsedScripts_[scriptId];
+ if (!script) {
+ callback(null);
+ return;
+ }
+
var cmd = new devtools.DebugCommand('scripts', {
+ 'ids': [scriptId],
'includeSource': true
});
devtools.DebuggerAgent.sendCommand_(cmd);
// Force v8 execution so that it gets to processing the requested command.
devtools.tools.evaluateJavaScript('javascript:void(0)');
+
+ this.requestSeqToCallback_[cmd.getSequenceNumber()] = function(msg) {
+ if (msg.isSuccess()) {
+ var scriptJson = msg.getBody()[0];
+ callback(scriptJson.source);
+ } else {
+ callback(null);
+ }
+ };
};
@@ -94,14 +183,14 @@ devtools.DebuggerAgent.prototype.addBreakpoint = function(sourceId, line) {
if (!script) {
return;
}
-
+
line = devtools.DebuggerAgent.webkitToV8LineNumber_(line);
-
+
var breakpointInfo = script.getBreakpointInfo(line);
if (breakpointInfo) {
return;
}
-
+
breakpointInfo = new devtools.BreakpointInfo(sourceId, line);
script.addBreakpointInfo(breakpointInfo);
@@ -110,9 +199,9 @@ devtools.DebuggerAgent.prototype.addBreakpoint = function(sourceId, line) {
'target': sourceId,
'line': line
});
-
+
this.requestNumberToBreakpointInfo_[cmd.getSequenceNumber()] = breakpointInfo;
-
+
devtools.DebuggerAgent.sendCommand_(cmd);
};
@@ -126,7 +215,7 @@ devtools.DebuggerAgent.prototype.removeBreakpoint = function(sourceId, line) {
if (!script) {
return;
}
-
+
line = devtools.DebuggerAgent.webkitToV8LineNumber_(line);
var breakpointInfo = script.getBreakpointInfo(line);
@@ -182,7 +271,7 @@ devtools.DebuggerAgent.prototype.resumeExecution = function() {
* @return {boolean} True iff the debugger will pause execution on the
* exceptions.
*/
-devtools.DebuggerAgent.prototype.pauseOnExceptions = function() {
+devtools.DebuggerAgent.prototype.pauseOnExceptions = function() {
return this.pauseOnExceptions_;
};
@@ -192,7 +281,7 @@ devtools.DebuggerAgent.prototype.pauseOnExceptions = function() {
* @param {boolean} value True iff execution should be stopped in the debugger
* on the exceptions.
*/
-devtools.DebuggerAgent.prototype.setPauseOnExceptions = function(value) {
+devtools.DebuggerAgent.prototype.setPauseOnExceptions = function(value) {
this.pauseOnExceptions_ = value;
};
@@ -229,28 +318,51 @@ devtools.DebuggerAgent.prototype.requestEvaluate = function(
* children are resolved.
*/
devtools.DebuggerAgent.prototype.resolveChildren = function(object, callback) {
- var handles = [];
- var names = [];
- for (var name in object) {
- var value = object[name];
- if (goog.isObject(value) && 'ref' in value) {
- handles.push(value.ref);
- names.push(name);
+ if ('ref' in object) {
+ this.requestLookup_([object.ref], function(msg) {
+ var result = {};
+ if (msg.isSuccess()) {
+ var handleToObject = msg.getBody();
+ var resolved = handleToObject[object.ref];
+ devtools.DebuggerAgent.formatObjectProperties_(resolved, result);
+ } else {
+ result.error = 'Failed to resolve children: ' + msg.getMessage();
+ }
+ object.resolvedValue = result;
+ callback(object);
+ });
+
+ return;
+ } else {
+ if (!object.resolvedValue) {
+ var message = 'Corrupted object: ' + JSON.stringify(object);
+ object.resolvedValue = {};
+ object.resolvedValue.error = message;
}
- }
- if (handles.length == 0) {
callback(object);
+ }
+};
+
+
+/**
+ * Starts (resumes) profiling.
+ */
+devtools.DebuggerAgent.prototype.startProfiling = function() {
+ if (this.isProcessingProfile_) {
return;
}
- this.requestLookup_(handles, function(msg) {
- var handleToObject = msg.getBody();
- for (var i = 0; i < names.length; i++) {
- var name = names[i];
- var jsonObj = handleToObject[object[name].ref]
- object[name] = devtools.DebuggerAgent.formatValue_(jsonObj, msg);
- }
- callback(object);
- });
+ RemoteDebuggerAgent.StartProfiling();
+ // Query if profiling has been really started.
+ RemoteDebuggerAgent.IsProfilingStarted();
+};
+
+
+/**
+ * Stops (pauses) profiling.
+ */
+devtools.DebuggerAgent.prototype.stopProfiling = function() {
+ this.isProcessingProfile_ = true;
+ RemoteDebuggerAgent.StopProfiling();
};
@@ -271,7 +383,9 @@ devtools.DebuggerAgent.prototype.requestClearBreakpoint_ = function(
* Sends 'backtrace' request to v8.
*/
devtools.DebuggerAgent.prototype.requestBacktrace_ = function() {
- var cmd = new devtools.DebugCommand('backtrace');
+ var cmd = new devtools.DebugCommand('backtrace', {
+ 'compactFormat':true
+ });
devtools.DebuggerAgent.sendCommand_(cmd);
};
@@ -304,6 +418,7 @@ devtools.DebuggerAgent.prototype.stepCommand_ = function(action) {
*/
devtools.DebuggerAgent.prototype.requestLookup_ = function(handles, callback) {
var cmd = new devtools.DebugCommand('lookup', {
+ 'compactFormat':true,
'handles': handles
});
devtools.DebuggerAgent.sendCommand_(cmd);
@@ -312,6 +427,17 @@ devtools.DebuggerAgent.prototype.requestLookup_ = function(handles, callback) {
/**
+ * Handles GetContextId response.
+ * @param {number} contextId Id of the inspected page global context.
+ */
+devtools.DebuggerAgent.prototype.didGetContextId_ = function(contextId) {
+ this.contextId_ = contextId;
+ // Update scripts.
+ this.requestScripts();
+};
+
+
+/**
* Handles output sent by v8 debugger. The output is either asynchronous event
* or response to a previously sent request. See protocol definitioun for more
* details on the output format.
@@ -325,8 +451,8 @@ devtools.DebuggerAgent.prototype.handleDebuggerOutput_ = function(output) {
debugPrint('Failed to handle debugger reponse:\n' + e);
throw e;
}
-
-
+
+
if (msg.getType() == 'event') {
if (msg.getEvent() == 'break') {
this.handleBreakEvent_(msg);
@@ -383,15 +509,15 @@ devtools.DebuggerAgent.prototype.handleExceptionEvent_ = function(msg) {
if (body.script) {
sourceId = body.script.id;
}
-
+
var line = devtools.DebuggerAgent.v8ToWwebkitLineNumber_(body.sourceLine);
-
+
this.currentCallFrame_ = new devtools.CallFrame();
this.currentCallFrame_.sourceID = sourceId;
this.currentCallFrame_.line = line;
this.currentCallFrame_.script = body.script;
this.requestBacktrace_();
- } else {
+ } else {
this.resumeExecution();
}
};
@@ -401,10 +527,19 @@ devtools.DebuggerAgent.prototype.handleExceptionEvent_ = function(msg) {
* @param {devtools.DebuggerMessage} msg
*/
devtools.DebuggerAgent.prototype.handleScriptsResponse_ = function(msg) {
+ if (this.invokeCallbackForResponse_(msg)) {
+ return;
+ }
+
var scripts = msg.getBody();
for (var i = 0; i < scripts.length; i++) {
var script = scripts[i];
-
+
+ // Skip scripts from other tabs.
+ if (!this.isScriptFromInspectedContext_(script, msg)) {
+ continue;
+ }
+
// We may already have received the info in an afterCompile event.
if (script.id in this.parsedScripts_) {
continue;
@@ -415,11 +550,33 @@ devtools.DebuggerAgent.prototype.handleScriptsResponse_ = function(msg) {
/**
+ * @param {Object} script Json object representing script.
+ * @param {devtools.DebuggerMessage} msg Debugger response.
+ */
+devtools.DebuggerAgent.prototype.isScriptFromInspectedContext_ = function(
+ script, msg) {
+ if (!script.context) {
+ // Always ignore scripts from the utility context.
+ return false;
+ }
+ var context = msg.lookup(script.context.ref);
+ var scriptContextId = context.data;
+ if (!goog.isDef(scriptContextId)) {
+ return false; // Always ignore scripts from the utility context.
+ }
+ if (this.contextId_ === null) {
+ return true;
+ }
+ return (scriptContextId == this.contextId_);
+};
+
+
+/**
* @param {devtools.DebuggerMessage} msg
*/
devtools.DebuggerAgent.prototype.handleSetBreakpointResponse_ = function(msg) {
var requestSeq = msg.getRequestSeq();
- var breakpointInfo = this.requestNumberToBreakpointInfo_[requestSeq];
+ var breakpointInfo = this.requestNumberToBreakpointInfo_[requestSeq];
if (!breakpointInfo) {
// TODO(yurys): handle this case
return;
@@ -431,7 +588,7 @@ devtools.DebuggerAgent.prototype.handleSetBreakpointResponse_ = function(msg) {
}
var idInV8 = msg.getBody().breakpoint;
breakpointInfo.setV8Id(idInV8);
-
+
if (breakpointInfo.isRemoved()) {
this.requestClearBreakpoint_(idInV8);
}
@@ -443,11 +600,50 @@ devtools.DebuggerAgent.prototype.handleSetBreakpointResponse_ = function(msg) {
*/
devtools.DebuggerAgent.prototype.handleAfterCompileEvent_ = function(msg) {
var script = msg.getBody().script;
+ // Ignore scripts from other tabs.
+ if (!this.isScriptFromInspectedContext_(script, msg)) {
+ return;
+ }
this.addScriptInfo_(script);
};
/**
+ * Handles current profiler status.
+ */
+devtools.DebuggerAgent.prototype.didIsProfilingStarted_ = function(
+ is_started) {
+ if (is_started) {
+ // Start to query log data.
+ RemoteDebuggerAgent.GetLogLines(this.lastProfileLogPosition_);
+ }
+ WebInspector.setRecordingProfile(is_started);
+};
+
+
+/**
+ * Handles a portion of a profiler log retrieved by GetLogLines call.
+ * @param {string} log A portion of profiler log.
+ * @param {number} newPosition The position in log file to read from
+ * next time.
+ */
+devtools.DebuggerAgent.prototype.didGetLogLines_ = function(
+ log, newPosition) {
+ if (log.length > 0) {
+ this.profilerProcessor_.processLogChunk(log);
+ this.lastProfileLogPosition_ = newPosition;
+ } else if (this.isProcessingProfile_) {
+ this.isProcessingProfile_ = false;
+ WebInspector.setRecordingProfile(false);
+ WebInspector.addProfile(this.profilerProcessor_.createProfileForView());
+ return;
+ }
+ setTimeout(function() { RemoteDebuggerAgent.GetLogLines(newPosition); },
+ this.isProcessingProfile_ ? 100 : 1000);
+};
+
+
+/**
* Adds the script info to the local cache. This method assumes that the script
* is not in the cache yet.
* @param {Object} script Script json object from the debugger message.
@@ -477,9 +673,9 @@ devtools.DebuggerAgent.prototype.handleBacktraceResponse_ = function(msg) {
if (!this.currentCallFrame_) {
return;
}
-
+
var script = this.currentCallFrame_.script;
-
+
var callerFrame = null;
var f = null;
var frames = msg.getBody().frames;
@@ -490,9 +686,9 @@ devtools.DebuggerAgent.prototype.handleBacktraceResponse_ = function(msg) {
f.caller = callerFrame;
callerFrame = f;
}
-
+
this.currentCallFrame_ = f;
-
+
WebInspector.pausedScript();
DevToolsHost.activateWindow();
};
@@ -501,15 +697,18 @@ devtools.DebuggerAgent.prototype.handleBacktraceResponse_ = function(msg) {
/**
* Handles response to a command by invoking its callback (if any).
* @param {devtools.DebuggerMessage} msg
+ * @return {boolean} Whether a callback for the given message was found and
+ * excuted.
*/
devtools.DebuggerAgent.prototype.invokeCallbackForResponse_ = function(msg) {
var callback = this.requestSeqToCallback_[msg.getRequestSeq()];
if (!callback) {
// It may happend if reset was called.
- return;
+ return false;
}
delete this.requestSeqToCallback_[msg.getRequestSeq()];
callback(msg);
+ return true;
};
@@ -526,26 +725,24 @@ devtools.DebuggerAgent.prototype.evaluateInCallFrame_ = function(expression) {
*/
devtools.DebuggerAgent.formatCallFrame_ = function(stackFrame, script, msg) {
var sourceId = script.id;
- var func = msg.lookup(stackFrame.func.ref);
- var funcScript = msg.lookup(func.script.ref);
- if (funcScript && 'id' in funcScript) {
- sourceId = funcScript.id;
- }
- var funcName = devtools.DebuggerAgent.formatFunctionCall_(stackFrame, msg);
-
+ var func = stackFrame.func;
+ var sourceId = func.scriptId;
+ var funcName = func.name || func.inferredName || '(anonymous function)';
+
var scope = {};
-
+
// Add arguments.
- devtools.DebuggerAgent.valuesArrayToMap_(stackFrame.arguments, scope, msg);
-
+ devtools.DebuggerAgent.argumentsArrayToMap_(stackFrame.arguments, scope);
+
// Add local variables.
- devtools.DebuggerAgent.valuesArrayToMap_(stackFrame.locals, scope, msg);
+ devtools.DebuggerAgent.propertiesToMap_(stackFrame.locals, scope);
- var thisObject = msg.lookup(stackFrame.receiver.ref);
+ var thisObject = devtools.DebuggerAgent.formatObjectReference_(
+ stackFrame.receiver);
// Add variable with name 'this' to the scope.
- scope['this'] = devtools.DebuggerAgent.formatObject_(thisObject, msg);
-
+ scope['this'] = thisObject;
+
var line = devtools.DebuggerAgent.v8ToWwebkitLineNumber_(stackFrame.line);
var result = new devtools.CallFrame();
result.sourceID = sourceId;
@@ -560,187 +757,86 @@ devtools.DebuggerAgent.formatCallFrame_ = function(stackFrame, script, msg) {
/**
- * Returns user-friendly representation of the function call from the stack
- * frame.
- * @param {Object} stackFrame Frame json object from 'backtrace' response.
- * @return {!string} Function name with argument values.
- */
-devtools.DebuggerAgent.formatFunctionCall_ = function(stackFrame, msg) {
- var func = msg.lookup(stackFrame.func.ref);
- return func.name || func.inferredName || '(anonymous function)';
-};
-
-
-/**
- * Converts an object from the debugger response to the format understandable
- * by ScriptsPanel.
- * @param {Object} object An object from the debugger protocol response.
- * @param {devtools.DebuggerMessage} msg Parsed debugger response.
- * @return {!Object} Object describing 'object' in the format expected by
- * ScriptsPanel and its panes.
- */
-devtools.DebuggerAgent.formatObject_ = function(object, msg) {
- var result = {};
- devtools.DebuggerAgent.formatObjectProperties_(object, msg, result);
- return { 'value': result };
-};
-
-
-/**
- * Converts a function from the debugger response to the format understandable
- * by ScriptsPanel.
- * @param {Object} func Function object from the debugger protocol response.
- * @param {devtools.DebuggerMessage} msg Parsed debugger response.
- * @return {!Object} Object describing 'func' in the format expected by
- * ScriptsPanel and its panes.
- */
-devtools.DebuggerAgent.formatFunction_ = function(func, msg) {
- var result = {};
- devtools.DebuggerAgent.formatObjectProperties_(func, msg, result);
- result.name = func.name;
-
- var holder = function() {};
- holder.value = result;
- return holder;
-};
-
-
-/**
* Collects properties for an object from the debugger response.
* @param {Object} object An object from the debugger protocol response.
- * @param {devtools.DebuggerMessage} msg Parsed debugger response.
* @param {Object} result A map to put the properties in.
*/
-devtools.DebuggerAgent.formatObjectProperties_ = function(object,
- msg, result) {
- devtools.DebuggerAgent.propertiesToMap_(object.properties, result, msg);
+devtools.DebuggerAgent.formatObjectProperties_ = function(object, result) {
+ devtools.DebuggerAgent.propertiesToMap_(object.properties, result);
result.protoObject = devtools.DebuggerAgent.formatObjectReference_(
- object.protoObject, msg);
+ object.protoObject);
result.prototypeObject = devtools.DebuggerAgent.formatObjectReference_(
- object.prototypeObject, msg);
+ object.prototypeObject);
result.constructorFunction = devtools.DebuggerAgent.formatObjectReference_(
- object.constructorFunction, msg);
+ object.constructorFunction);
};
/**
* For each property in 'properties' puts its name and user-friendly value into
* 'map'.
- * @param {Array.<Object>} properties Receiver properties array from 'backtrace'
- * response.
+ * @param {Array.<Object>} properties Receiver properties or locals array from
+ * 'backtrace' response.
* @param {Object} map Result holder.
- * @param {devtools.DebuggerMessage} msg Parsed 'backtrace' response.
*/
-devtools.DebuggerAgent.propertiesToMap_ = function(properties, map, msg) {
+devtools.DebuggerAgent.propertiesToMap_ = function(properties, map) {
for (var j = 0; j < properties.length; j++) {
var nextValue = properties[j];
- map[nextValue.name] = devtools.DebuggerAgent.formatObjectReference_(
- nextValue, msg);
+ // Skip unnamed properties. They may appear e.g. when number of actual
+ // parameters is greater the that of formal. In that case the superfluous
+ // parameters will be present in the arguments list as elements without
+ // names.
+ if (nextValue.name) {
+ map[nextValue.name] =
+ devtools.DebuggerAgent.formatObjectReference_(nextValue.value);
+ }
}
};
/**
- * For each property in 'array' puts its name and user-friendly value into
- * 'map'. Each object referenced from the array is expected to be included in
- * the message.
- * @param {Array.<Object>} array Arguments or locals array from 'backtrace'
- * response.
+ * Puts arguments from the protocol arguments array to the map assigning names
+ * to the anonymous arguments.
+ * @param {Array.<Object>} array Arguments array from 'backtrace' response.
* @param {Object} map Result holder.
- * @param {devtools.DebuggerMessage} msg Parsed 'backtrace' response.
*/
-devtools.DebuggerAgent.valuesArrayToMap_ = function(array, map, msg) {
+devtools.DebuggerAgent.argumentsArrayToMap_ = function(array, map) {
for (var j = 0; j < array.length; j++) {
var nextValue = array[j];
-
- var object = msg.lookup(nextValue.value.ref);
- var val = object ?
- devtools.DebuggerAgent.formatValue_(object, msg) :
- '<unresolved ref: ' + nextValue.value.ref + '>';
- map[nextValue.name] = val;
- }
-};
-
-
-/**
- * TODO(yurys): we should merge all this formatting code with the one for
- * elements tree.
- * @param {Object} object An object reference from the debugger response.
- * @param {devtools.DebuggerMessage} msg Parsed debugger response.
- * @return {*} The reference representation expected by ScriptsPanel.
- */
-devtools.DebuggerAgent.formatObjectReference_ = function(objectRef, msg) {
- if (!('ref' in objectRef)) {
- return objectRef;
+ // Skip unnamed properties. They may appear e.g. when number of actual
+ // parameters is greater the that of formal. In that case the superfluous
+ // parameters will be present in the arguments list as elements without
+ // names.
+ var name = nextValue.name ? nextValue.name : '<arg #' + j + '>';
+ map[name] = devtools.DebuggerAgent.formatObjectReference_(nextValue.value);
}
- var object = msg.lookup(objectRef.ref);
- if (!object) {
- return objectRef;
- }
- switch (object.type) {
- case 'number':
- case 'string':
- case 'boolean':
- return object.value;
- case 'undefined':
- return undefined;
- case 'null':
- return null;
- case 'function': {
- var result = function() {};
- result.ref = objectRef.ref;
- return result;
- }
- case 'object':
- return objectRef;
- default:
- return objectRef;
- };
};
/**
- * @param {Object} object An object from the debugger response.
- * @param {devtools.DebuggerMessage} msg Parsed debugger response.
+ * @param {Object} v An object reference from the debugger response.
* @return {*} The value representation expected by ScriptsPanel.
*/
-devtools.DebuggerAgent.formatValue_ = function(object, msg) {
- if (!object) {
- return object;
- }
- switch (object.type) {
- case 'number':
- case 'string':
- case 'boolean':
- return object.value;
- case 'undefined':
- return undefined;
- case 'null':
- return null;
- case 'function':
- return devtools.DebuggerAgent.formatFunction_(object, msg);
- case 'object':
- return devtools.DebuggerAgent.formatObject_(object, msg);
- default:
- return '<invalid value>';
- };
-};
-
-
-devtools.DebuggerAgent.formatObjectReference_old = function(objectRef, msg) {
- if (!objectRef.ref) {
- return 'illegal ref';
- }
-
- var object = msg.lookup(objectRef.ref);
- if (!object) {
- return '{ref: ' + objectRef.ref + '}';
- }
-
- if ('value' in object) {
- return object.value;
+devtools.DebuggerAgent.formatObjectReference_ = function(v) {
+ if (v.type == 'object') {
+ return v;
+ } else if (v.type == 'function') {
+ var f = function() {};
+ f.ref = v.ref;
+ return f;
+ } else if (goog.isDef(v.value)) {
+ return v.value;
+ } else if (v.type == 'undefined') {
+ return 'undefined';
+ } else if (v.type == 'null') {
+ return 'null';
+ } else if (v.name) {
+ return v.name;
+ } else if (v.className) {
+ return v.className;
+ } else {
+ return '<unresolved ref: ' + v.ref + ', type: ' + v.type + '>';
}
- return '[' + object.type + ']';
};
@@ -773,7 +869,7 @@ devtools.DebuggerAgent.v8ToWwebkitLineNumber_ = function(line) {
devtools.ScriptInfo = function(scriptId, lineOffset) {
this.scriptId_ = scriptId;
this.lineOffset_ = lineOffset;
-
+
this.lineToBreakpointInfo_ = {};
};
@@ -823,7 +919,7 @@ devtools.ScriptInfo.prototype.removeBreakpointInfo = function(breakpoint) {
*/
devtools.BreakpointInfo = function(sourceId, line) {
this.sourceId_ = sourceId;
- this.line_ = line;
+ this.line_ = line;
this.v8id_ = -1;
this.removed_ = false;
};
@@ -922,7 +1018,7 @@ devtools.CallFrame.prototype.evaluate = function(expression) {
*/
devtools.CallFrame.handleEvaluateResponse_ = function(response) {
var body = response.getBody();
- var value = devtools.DebuggerAgent.formatValue_(body);
+ var value = devtools.DebuggerAgent.formatObjectReference_(body);
WebInspector.addMessageToConsole(new WebInspector.ConsoleCommandResult(
value, false /* exception */, null /* commandMessage */));
};
@@ -936,7 +1032,7 @@ devtools.CallFrame.handleEvaluateResponse_ = function(response) {
*/
devtools.DebugCommand = function(command, opt_arguments) {
this.command_ = command;
- this.type_ = 'request';
+ this.type_ = 'request';
this.seq_ = ++devtools.DebugCommand.nextSeq_;
if (opt_arguments) {
this.arguments_ = opt_arguments;
@@ -971,11 +1067,10 @@ devtools.DebugCommand.prototype.toJSONProtocol = function() {
if (this.arguments_) {
json.arguments = this.arguments_;
}
- return goog.json.serialize(json);
+ return JSON.stringify(json);
};
-
/**
* JSON messages sent from v8 debugger. See protocol definition for more
* details: http://code.google.com/p/v8/wiki/DebuggerProtocol
diff --git a/chrome/tools/test/reference_build/chrome_linux/resources/inspector/devtools.html b/chrome/tools/test/reference_build/chrome_linux/resources/inspector/devtools.html
index 3176bea..5fd2c60 100644
--- a/chrome/tools/test/reference_build/chrome_linux/resources/inspector/devtools.html
+++ b/chrome/tools/test/reference_build/chrome_linux/resources/inspector/devtools.html
@@ -54,6 +54,13 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<script type="text/javascript" src="inspector_controller.js"></script>
<script type="text/javascript" src="inspector_controller_impl.js"></script>
<script type="text/javascript" src="inspector.js"></script>
+ <script type="text/javascript" src="codemap.js"></script>
+ <script type="text/javascript" src="consarray.js"></script>
+ <script type="text/javascript" src="csvparser.js"></script>
+ <script type="text/javascript" src="profile.js"></script>
+ <script type="text/javascript" src="profile_view.js"></script>
+ <script type="text/javascript" src="profiler_processor.js"></script>
+ <script type="text/javascript" src="splaytree.js"></script>
<script type="text/javascript" src="Object.js"></script>
<script type="text/javascript" src="TextPrompt.js"></script>
<script type="text/javascript" src="Placard.js"></script>
@@ -95,6 +102,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<script type="text/javascript" src="DatabaseQueryView.js"></script>
<script type="text/javascript" src="ScriptView.js"></script>
<script type="text/javascript" src="ProfileView.js"></script>
+ <script type="text/javascript" src="ProfileDataGridTree.js"></script>
<script type="text/javascript" src="devtools.js"></script>
<script type="text/javascript" src="devtools_host_stub.js"></script>
</head>
diff --git a/chrome/tools/test/reference_build/chrome_linux/resources/inspector/devtools.js b/chrome/tools/test/reference_build/chrome_linux/resources/inspector/devtools.js
index 107a8ea..3b2a6e1 100644
--- a/chrome/tools/test/reference_build/chrome_linux/resources/inspector/devtools.js
+++ b/chrome/tools/test/reference_build/chrome_linux/resources/inspector/devtools.js
@@ -13,6 +13,29 @@ goog.require('devtools.DebuggerAgent');
goog.require('devtools.DomAgent');
goog.require('devtools.NetAgent');
+
+/**
+ * Dispatches raw message from the host.
+ * @param {Object} msg Message to dispatch.
+ */
+devtools.dispatch = function(msg) {
+ var delegate = msg[0];
+ var methodName = msg[1];
+ var remoteName = 'Remote' + delegate.substring(0, delegate.length - 8);
+ var agent = window[remoteName];
+ if (!agent) {
+ debugPrint('No remote agent "' + remoteName + '" found.');
+ return;
+ }
+ var method = agent[methodName];
+ if (!method) {
+ debugPrint('No method "' + remoteName + '.' + methodName + '" found.');
+ return;
+ }
+ method.apply(this, msg.slice(2));
+};
+
+
devtools.ToolsAgent = function() {
RemoteToolsAgent.DidEvaluateJavaScript = devtools.Callback.processCallback;
RemoteToolsAgent.DidExecuteUtilityFunction =
@@ -38,7 +61,6 @@ devtools.ToolsAgent.prototype.reset = function() {
this.debuggerAgent_.reset();
this.domAgent_.getDocumentElementAsync();
- this.debuggerAgent_.requestScripts();
};
@@ -266,6 +288,17 @@ WebInspector.Console.prototype._evalInInspectedWindow = function(expr) {
/**
+ * Disable autocompletion in the console.
+ * TODO(yurys): change WebKit implementation to allow asynchronous completion.
+ * @override
+ */
+WebInspector.Console.prototype.completions = function(
+ wordRange, bestMatchOnly) {
+ return null;
+};
+
+
+/**
* @override
*/
WebInspector.ElementsPanel.prototype.updateStyles = function(forceUpdate) {
@@ -309,7 +342,7 @@ WebInspector.ElementsPanel.prototype.invokeWithStyleSet_ =
if (node && node.nodeType == Node.ELEMENT_NODE) {
var callback = function(stylesStr) {
- var styles = goog.json.parse(stylesStr);
+ var styles = JSON.parse(stylesStr);
if (!styles.computedStyle) {
return;
}
@@ -375,7 +408,7 @@ WebInspector.PropertiesSidebarPane.prototype.update = function(object) {
devtools.tools.getDomAgent().getNodePrototypesAsync(object.id_,
function(json) {
// Get array of prototype user-friendly names.
- var prototypes = goog.json.parse(json);
+ var prototypes = JSON.parse(json);
for (var i = 0; i < prototypes.length; ++i) {
var prototype = {};
prototype.id_ = object.id_;
@@ -469,7 +502,7 @@ WebInspector.SourceView.prototype.setupSourceFrameIfNeeded = function() {
var netAgent = devtools.tools.getNetAgent();
netAgent.getResourceContentAsync(identifier, function(source) {
- var resource = netAgent.getResource(identifier);
+ var resource = WebInspector.resources[identifier];
if (InspectorController.addSourceToFrame(resource.mimeType, source,
element)) {
delete self._frameNeedsSetup;
@@ -487,6 +520,48 @@ WebInspector.SourceView.prototype.setupSourceFrameIfNeeded = function() {
/**
+ * This override is necessary for adding script source asynchronously.
+ * @override
+ */
+WebInspector.ScriptView.prototype.setupSourceFrameIfNeeded = function() {
+ if (!this._frameNeedsSetup) {
+ return;
+ }
+
+ this.attach();
+
+ if (this.script.source) {
+ this.didResolveScriptSource_();
+ } else {
+ var self = this;
+ devtools.tools.getDebuggerAgent().resolveScriptSource(
+ this.script.sourceID,
+ function(source) {
+ self.script.source = source || '<source is not available>';
+ self.didResolveScriptSource_();
+ });
+ }
+};
+
+
+/**
+ * Performs source frame setup when script source is aready resolved.
+ */
+WebInspector.ScriptView.prototype.didResolveScriptSource_ = function() {
+ if (!InspectorController.addSourceToFrame(
+ "text/javascript", this.script.source, this.sourceFrame.element)) {
+ return;
+ }
+
+ delete this._frameNeedsSetup;
+
+ this.sourceFrame.addEventListener(
+ "syntax highlighting complete", this._syntaxHighlightingComplete, this);
+ this.sourceFrame.syntaxHighlightJavascript();
+};
+
+
+/**
* Dummy object used during properties inspection.
* @see WebInspector.didGetNodePropertiesAsync_
*/
@@ -505,7 +580,7 @@ WebInspector.dummyFunction_ = function() {};
*/
WebInspector.didGetNodePropertiesAsync_ = function(treeOutline, constructor,
nodeId, path, json) {
- var props = goog.json.parse(json);
+ var props = JSON.parse(json);
var properties = [];
var obj = {};
obj.devtools$$nodeId_ = nodeId;
@@ -596,7 +671,7 @@ WebInspector.ScopeChainSidebarPane.TreeElement.inherits(
*/
WebInspector.ScopeChainSidebarPane.TreeElement.prototype.onpopulate =
function() {
- var obj = this.parentObject[this.propertyName].value;
+ var obj = this.parentObject[this.propertyName];
devtools.tools.getDebuggerAgent().resolveChildren(obj,
goog.bind(this.didResolveChildren_, this));
};
@@ -608,15 +683,15 @@ WebInspector.ScopeChainSidebarPane.TreeElement.prototype.onpopulate =
WebInspector.ScopeChainSidebarPane.TreeElement.prototype.didResolveChildren_ =
function(object) {
this.removeChildren();
-
var constructor = this.treeOutline.section.treeElementConstructor;
+ object = object.resolvedValue;
for (var name in object) {
this.appendChild(new constructor(object, name));
}
};
-/**
+/**
* @override
*/
WebInspector.StylePropertyTreeElement.prototype.toggleEnabled =
@@ -705,3 +780,131 @@ WebInspector.Console.prototype._evalInInspectedWindow = function(expression) {
// the command log message.
return 'evaluating...';
};
+
+
+(function() {
+ var oldShow = WebInspector.ScriptsPanel.prototype.show;
+ WebInspector.ScriptsPanel.prototype.show = function() {
+ devtools.tools.getDebuggerAgent().initializeScriptsCache();
+ oldShow.call(this);
+ };
+})();
+
+
+/**
+ * We don't use WebKit's BottomUpProfileDataGridTree, instead using
+ * our own (because BottomUpProfileDataGridTree's functionality is
+ * implemented in profile_view.js for V8's Tick Processor).
+ *
+ * @param {WebInspector.ProfileView} profileView Profile view.
+ * @param {devtools.profiler.ProfileView} profile Profile.
+ */
+WebInspector.BottomUpProfileDataGridTree = function(profileView, profile) {
+ return WebInspector.buildProfileDataGridTree_(
+ profileView, profile.heavyProfile);
+};
+
+
+/**
+ * We don't use WebKit's TopDownProfileDataGridTree, instead using
+ * our own (because TopDownProfileDataGridTree's functionality is
+ * implemented in profile_view.js for V8's Tick Processor).
+ *
+ * @param {WebInspector.ProfileView} profileView Profile view.
+ * @param {devtools.profiler.ProfileView} profile Profile.
+ */
+WebInspector.TopDownProfileDataGridTree = function(profileView, profile) {
+ return WebInspector.buildProfileDataGridTree_(
+ profileView, profile.treeProfile);
+};
+
+
+/**
+ * A helper function, checks whether a profile node has visible children.
+ *
+ * @param {devtools.profiler.ProfileView.Node} profileNode Profile node.
+ * @return {boolean} Whether a profile node has visible children.
+ */
+WebInspector.nodeHasChildren_ = function(profileNode) {
+ var children = profileNode.children;
+ for (var i = 0, n = children.length; i < n; ++i) {
+ if (children[i].visible) {
+ return true;
+ }
+ }
+ return false;
+};
+
+
+/**
+ * Common code for populating a profiler grid node or a tree with
+ * given profile nodes.
+ *
+ * @param {WebInspector.ProfileDataGridNode|
+ * WebInspector.ProfileDataGridTree} viewNode Grid node or a tree.
+ * @param {WebInspector.ProfileView} profileView Profile view.
+ * @param {Array<devtools.profiler.ProfileView.Node>} children Profile nodes.
+ * @param {WebInspector.ProfileDataGridTree} owningTree Grid tree.
+ */
+WebInspector.populateNode_ = function(
+ viewNode, profileView, children, owningTree) {
+ for (var i = 0, n = children.length; i < n; ++i) {
+ var child = children[i];
+ if (child.visible) {
+ viewNode.appendChild(
+ new WebInspector.ProfileDataGridNode(
+ profileView, child, owningTree,
+ WebInspector.nodeHasChildren_(child)));
+ }
+ }
+};
+
+
+/**
+ * A helper function for building a profile grid tree.
+ *
+ * @param {WebInspector.ProfileView} profileview Profile view.
+ * @param {devtools.profiler.ProfileView} profile Profile.
+ * @return {WebInspector.ProfileDataGridTree} Profile grid tree.
+ */
+WebInspector.buildProfileDataGridTree_ = function(profileView, profile) {
+ var children = profile.head.children;
+ var dataGridTree = new WebInspector.ProfileDataGridTree(
+ profileView, profile.head);
+ WebInspector.populateNode_(dataGridTree, profileView, children, dataGridTree);
+ return dataGridTree;
+};
+
+
+/**
+ * @override
+ */
+WebInspector.ProfileDataGridNode.prototype._populate = function(event) {
+ var children = this.profileNode.children;
+ WebInspector.populateNode_(this, this.profileView, children, this.tree);
+ this.removeEventListener("populate", this._populate, this);
+};
+
+
+// As columns in data grid can't be changed after initialization,
+// we need to intercept the constructor and modify columns upon creation.
+(function InterceptDataGridForProfiler() {
+ var originalDataGrid = WebInspector.DataGrid;
+ WebInspector.DataGrid = function(columns) {
+ if (('average' in columns) && ('calls' in columns)) {
+ delete columns['average'];
+ delete columns['calls'];
+ }
+ return new originalDataGrid(columns);
+ };
+})();
+
+
+/**
+ * @override
+ * TODO(pfeldman): Add l10n.
+ */
+WebInspector.UIString = function(string)
+{
+ return String.vsprintf(string, Array.prototype.slice.call(arguments, 1));
+}
diff --git a/chrome/tools/test/reference_build/chrome_linux/resources/inspector/devtools_host_stub.js b/chrome/tools/test/reference_build/chrome_linux/resources/inspector/devtools_host_stub.js
index d91ed1b..801d42e 100644
--- a/chrome/tools/test/reference_build/chrome_linux/resources/inspector/devtools_host_stub.js
+++ b/chrome/tools/test/reference_build/chrome_linux/resources/inspector/devtools_host_stub.js
@@ -13,18 +13,37 @@
RemoteDebuggerAgentStub = function() {
};
-RemoteDebuggerAgentStub.prototype.DebugAttach = function() {
+RemoteDebuggerAgentStub.prototype.DebugBreak = function() {
};
-RemoteDebuggerAgentStub.prototype.DebugDetach = function() {
+RemoteDebuggerAgentStub.prototype.GetContextId = function() {
+ RemoteDebuggerAgent.DidGetContextId(3);
};
-RemoteDebuggerAgentStub.prototype.DebugCommand = function() {
+RemoteDebuggerAgentStub.prototype.StopProfiling = function() {
};
-RemoteDebuggerAgentStub.prototype.DebugBreak = function() {
+RemoteDebuggerAgentStub.prototype.StartProfiling = function() {
};
+RemoteDebuggerAgentStub.prototype.IsProfilingStarted = function() {
+ setTimeout(function() {
+ RemoteDebuggerAgent.DidIsProfilingStarted(true);
+ }, 100);
+};
+
+RemoteDebuggerAgentStub.prototype.GetLogLines = function(pos) {
+ if (pos < RemoteDebuggerAgentStub.ProfilerLogBuffer.length) {
+ setTimeout(function() {
+ RemoteDebuggerAgent.DidGetLogLines(
+ RemoteDebuggerAgentStub.ProfilerLogBuffer,
+ pos + RemoteDebuggerAgentStub.ProfilerLogBuffer.length);
+ },
+ 100);
+ } else {
+ setTimeout(function() { RemoteDebuggerAgent.DidGetLogLines('', pos); }, 100);
+ }
+};
/**
* @constructor
@@ -38,7 +57,7 @@ RemoteDomAgentStub.sendDocumentElement_ = function() {
1, // id
1, // type = Node.ELEMENT_NODE,
'HTML', // nodeName
- '', // nodeValue
+ '', // nodeValue
['foo','bar'], // attributes
2, // childNodeCount
]);
@@ -53,7 +72,7 @@ RemoteDomAgentStub.sendChildNodes_ = function(id) {
2, // id
1, // type = Node.ELEMENT_NODE,
'DIV', // nodeName
- '', // nodeValue
+ '', // nodeValue
['foo','bar'], // attributes
1, // childNodeCount
],
@@ -61,17 +80,17 @@ RemoteDomAgentStub.sendChildNodes_ = function(id) {
3, // id
3, // type = Node.TEXT_NODE,
'', // nodeName
- 'Text', // nodeValue
+ 'Text', // nodeValue
]
]);
} else if (id == 2) {
- RemoteDomAgent.SetChildNodes(id,
+ RemoteDomAgent.SetChildNodes(id,
[
[
4, // id
1, // type = Node.ELEMENT_NODE,
'span', // nodeName
- '', // nodeValue
+ '', // nodeValue
['foo','bar'], // attributes
0, // childNodeCount
]
@@ -154,7 +173,7 @@ RemoteToolsAgentStub.prototype.EvaluateJavaScript = function(callId, script) {
};
-RemoteToolsAgentStub.prototype.ExecuteUtilityFunction = function(callId,
+RemoteToolsAgentStub.prototype.ExecuteUtilityFunction = function(callId,
functionName, nodeId, args) {
setTimeout(function() {
var result = [];
@@ -193,7 +212,7 @@ RemoteToolsAgentStub.prototype.ExecuteUtilityFunction = function(callId,
alert('Unexpected utility function:' + functionName);
}
RemoteToolsAgent.DidExecuteUtilityFunction(callId,
- goog.json.serialize(result), '');
+ JSON.stringify(result), '');
}, 0);
};
@@ -201,7 +220,7 @@ RemoteToolsAgentStub.prototype.ExecuteUtilityFunction = function(callId,
RemoteToolsAgentStub.prototype.GetNodePrototypes = function(callId, nodeId) {
setTimeout(function() {
RemoteToolsAgent.DidGetNodePrototypes(callId,
- goog.json.serialize());
+ JSON.stringify());
}, 0);
};
@@ -210,6 +229,20 @@ RemoteToolsAgentStub.prototype.ClearConsoleMessages = function() {
};
+RemoteDebuggerAgentStub.ProfilerLogBuffer =
+ 'code-creation,LazyCompile,0x1000,256,"test1 http://aaa.js:1"\n' +
+ 'code-creation,LazyCompile,0x2000,256,"test2 http://bbb.js:2"\n' +
+ 'code-creation,LazyCompile,0x3000,256,"test3 http://ccc.js:3"\n' +
+ 'tick,0x1010,0x0,3\n' +
+ 'tick,0x2020,0x0,3,0x1010\n' +
+ 'tick,0x2020,0x0,3,0x1010\n' +
+ 'tick,0x3010,0x0,3,0x2020, 0x1010\n' +
+ 'tick,0x2020,0x0,3,0x1010\n' +
+ 'tick,0x2030,0x0,3,0x2020, 0x1010\n' +
+ 'tick,0x2020,0x0,3,0x1010\n' +
+ 'tick,0x1010,0x0,3\n';
+
+
/**
* @constructor
*/
@@ -217,7 +250,7 @@ RemoteDebuggerCommandExecutorStub = function() {
};
-RemoteDebuggerCommandExecutorStub.prototype.DebuggerCommand = function() {
+RemoteDebuggerCommandExecutorStub.prototype.DebuggerCommand = function(cmd) {
};
diff --git a/chrome/tools/test/reference_build/chrome_linux/resources/inspector/dom_agent.js b/chrome/tools/test/reference_build/chrome_linux/resources/inspector/dom_agent.js
index 09ea809..2cf8904 100644
--- a/chrome/tools/test/reference_build/chrome_linux/resources/inspector/dom_agent.js
+++ b/chrome/tools/test/reference_build/chrome_linux/resources/inspector/dom_agent.js
@@ -832,7 +832,7 @@ devtools.DomAgent.prototype.getNodePropertiesAsync = function(nodeId,
var callbackId = this.utilityFunctionCallbackWrapper_(callback);
RemoteToolsAgent.ExecuteUtilityFunction(callbackId,
'getProperties', nodeId,
- goog.json.serialize([path, protoDepth]));
+ JSON.stringify([path, protoDepth]));
};
@@ -861,7 +861,7 @@ devtools.DomAgent.prototype.getNodeStylesAsync = function(node,
RemoteToolsAgent.ExecuteUtilityFunction(callbackId,
'getStyles',
node.id_,
- goog.json.serialize([authorOnly]));
+ JSON.stringify([authorOnly]));
};
@@ -878,7 +878,7 @@ devtools.DomAgent.prototype.toggleNodeStyleAsync = function(
RemoteToolsAgent.ExecuteUtilityFunction(callbackId,
'toggleNodeStyle',
style.nodeId_,
- goog.json.serialize([style.id_, enabled, name]));
+ JSON.stringify([style.id_, enabled, name]));
};
@@ -896,7 +896,7 @@ devtools.DomAgent.prototype.applyStyleTextAsync = function(
callbackId,
'applyStyleText',
style.nodeId_,
- goog.json.serialize([style.id_, name, styleText]));
+ JSON.stringify([style.id_, name, styleText]));
};
@@ -914,7 +914,7 @@ devtools.DomAgent.prototype.setStylePropertyAsync = function(
callbackId,
'setStyleProperty',
node.id_,
- goog.json.serialize([name, value]));
+ JSON.stringify([name, value]));
};
diff --git a/chrome/tools/test/reference_build/chrome_linux/resources/inspector/inject.js b/chrome/tools/test/reference_build/chrome_linux/resources/inspector/inject.js
index 83c94d5..5c1050a 100644
--- a/chrome/tools/test/reference_build/chrome_linux/resources/inspector/inject.js
+++ b/chrome/tools/test/reference_build/chrome_linux/resources/inspector/inject.js
@@ -6,7 +6,6 @@
* @fileoverview Javascript that is being injected into the inspectable page
* while debugging.
*/
-goog.require('goog.json');
goog.provide('devtools.Injected');
diff --git a/chrome/tools/test/reference_build/chrome_linux/resources/inspector/inspector.js b/chrome/tools/test/reference_build/chrome_linux/resources/inspector/inspector.js
index 633dee5..4188849 100644
--- a/chrome/tools/test/reference_build/chrome_linux/resources/inspector/inspector.js
+++ b/chrome/tools/test/reference_build/chrome_linux/resources/inspector/inspector.js
@@ -41,7 +41,7 @@ var Preferences = {
}
var WebInspector = {
- resources: [],
+ resources: {},
resourceURLMap: {},
missingLocalizedStrings: {},
@@ -771,9 +771,18 @@ WebInspector.showDatabasesPanel = function()
this.currentPanel = this.panels.databases;
}
-WebInspector.addResource = function(resource)
+WebInspector.addResource = function(identifier, payload)
{
- this.resources.push(resource);
+ var resource = new WebInspector.Resource(
+ payload.requestHeaders,
+ payload.requestURL,
+ payload.host,
+ payload.path,
+ payload.lastPathComponent,
+ identifier,
+ payload.isMainResource,
+ payload.cached);
+ this.resources[identifier] = resource;
this.resourceURLMap[resource.url] = resource;
if (resource.mainResource) {
@@ -785,24 +794,83 @@ WebInspector.addResource = function(resource)
this.panels.resources.addResource(resource);
}
-WebInspector.removeResource = function(resource)
+WebInspector.updateResource = function(identifier, payload)
{
+ var resource = this.resources[identifier];
+ if (!resource)
+ return;
+
+ if (payload.didRequestChange) {
+ resource.url = payload.url;
+ resource.domain = payload.domain;
+ resource.path = payload.path;
+ resource.lastPathComponent = payload.lastPathComponent;
+ resource.requestHeaders = payload.requestHeaders;
+ resource.mainResource = payload.mainResource;
+ }
+
+ if (payload.didResponseChange) {
+ resource.mimeType = payload.mimeType;
+ resource.suggestedFilename = payload.suggestedFilename;
+ resource.expectedContentLength = payload.expectedContentLength;
+ resource.statusCode = payload.statusCode;
+ resource.suggestedFilename = payload.suggestedFilename;
+ resource.responseHeaders = payload.responseHeaders;
+ }
+
+ if (payload.didTypeChange) {
+ resource.type = payload.type;
+ }
+
+ if (payload.didLengthChange) {
+ resource.contentLength = payload.contentLength;
+ }
+
+ if (payload.didCompletionChange) {
+ resource.failed = payload.failed;
+ resource.finished = payload.finished;
+ }
+
+ if (payload.didTimingChange) {
+ if (payload.startTime)
+ resource.startTime = payload.startTime;
+ if (payload.responseReceivedTime)
+ resource.responseReceivedTime = payload.responseReceivedTime;
+ if (payload.endTime)
+ resource.endTime = payload.endTime;
+ }
+}
+
+WebInspector.removeResource = function(identifier)
+{
+ var resource = this.resources[identifier];
+ if (!resource)
+ return;
+
resource.category.removeResource(resource);
delete this.resourceURLMap[resource.url];
-
- this.resources.remove(resource, true);
+ delete this.resources[identifier];
if (this.panels.resources)
this.panels.resources.removeResource(resource);
}
-WebInspector.addDatabase = function(database)
+WebInspector.addDatabase = function(payload)
{
+ var database = new WebInspector.Database(
+ payload.database,
+ payload.domain,
+ payload.name,
+ payload.version);
this.panels.databases.addDatabase(database);
}
-WebInspector.addDOMStorage = function(domStorage)
+WebInspector.addDOMStorage = function(payload)
{
+ var domStorage = new WebInspector.DOMStorage(
+ payload.domStorage,
+ payload.host,
+ payload.isLocalStorage);
this.panels.databases.addDOMStorage(domStorage);
}
@@ -866,7 +934,7 @@ WebInspector.reset = function()
for (var category in this.resourceCategories)
this.resourceCategories[category].removeAllResources();
- this.resources = [];
+ this.resources = {};
this.resourceURLMap = {};
this.hoveredDOMNode = null;
@@ -886,9 +954,17 @@ WebInspector.resourceURLChanged = function(resource, oldURL)
this.resourceURLMap[resource.url] = resource;
}
-WebInspector.addMessageToConsole = function(msg)
+WebInspector.addMessageToConsole = function(payload)
{
- this.console.addMessage(msg);
+ var consoleMessage = new WebInspector.ConsoleMessage(
+ payload.source,
+ payload.level,
+ payload.line,
+ payload.url,
+ payload.groupLevel,
+ payload.repeatCount);
+ consoleMessage.setMessageBody(Array.prototype.slice.call(arguments, 1));
+ this.console.addMessage(consoleMessage);
}
WebInspector.addProfile = function(profile)
@@ -1263,6 +1339,7 @@ WebInspector.MIMETypes = {
"image/png": {2: true},
"image/gif": {2: true},
"image/bmp": {2: true},
+ "image/vnd.microsoft.icon": {2: true},
"image/x-icon": {2: true},
"image/x-xbitmap": {2: true},
"font/ttf": {3: true},
diff --git a/chrome/tools/test/reference_build/chrome_linux/resources/inspector/inspector_controller.js b/chrome/tools/test/reference_build/chrome_linux/resources/inspector/inspector_controller.js
index 09238e2..dd4193c 100644
--- a/chrome/tools/test/reference_build/chrome_linux/resources/inspector/inspector_controller.js
+++ b/chrome/tools/test/reference_build/chrome_linux/resources/inspector/inspector_controller.js
@@ -302,9 +302,9 @@ devtools.InspectorController.prototype.pauseOnExceptions = function() {
* @param {boolean} value True iff execution should be stopped in the debugger
* on the exceptions.
*/
-devtools.InspectorController.prototype.setPauseOnExceptions = function(value) {
-};
-
+devtools.InspectorController.prototype.setPauseOnExceptions = function(value) {
+};
+
/**
* Tells backend to resume execution.
diff --git a/chrome/tools/test/reference_build/chrome_linux/resources/inspector/inspector_controller_impl.js b/chrome/tools/test/reference_build/chrome_linux/resources/inspector/inspector_controller_impl.js
index 45abbe2..2f6f65e7 100644
--- a/chrome/tools/test/reference_build/chrome_linux/resources/inspector/inspector_controller_impl.js
+++ b/chrome/tools/test/reference_build/chrome_linux/resources/inspector/inspector_controller_impl.js
@@ -145,4 +145,20 @@ devtools.InspectorControllerImpl.prototype.setPauseOnExceptions = function(
};
+/**
+ * @override
+ */
+devtools.InspectorControllerImpl.prototype.startProfiling = function() {
+ devtools.tools.getDebuggerAgent().startProfiling();
+};
+
+
+/**
+ * @override
+ */
+devtools.InspectorControllerImpl.prototype.stopProfiling = function() {
+ devtools.tools.getDebuggerAgent().stopProfiling();
+};
+
+
var InspectorController = new devtools.InspectorControllerImpl();
diff --git a/chrome/tools/test/reference_build/chrome_linux/resources/inspector/net_agent.js b/chrome/tools/test/reference_build/chrome_linux/resources/inspector/net_agent.js
index 64ef4a6..957e119 100644
--- a/chrome/tools/test/reference_build/chrome_linux/resources/inspector/net_agent.js
+++ b/chrome/tools/test/reference_build/chrome_linux/resources/inspector/net_agent.js
@@ -10,7 +10,6 @@
goog.provide('devtools.NetAgent');
devtools.NetAgent = function() {
- this.resources_ = {};
this.id_for_url_ = {};
RemoteNetAgent.GetResourceContentResult =
@@ -28,22 +27,11 @@ devtools.NetAgent = function() {
* Resets dom agent to its initial state.
*/
devtools.NetAgent.prototype.reset = function() {
- this.resources_ = {};
this.id_for_url_ = {};
};
/**
- * Returns resource object for given identifier.
- * @param {number} identifier Identifier to get resource for.
- * @return {WebInspector.Resouce} Resulting resource.
- */
-devtools.NetAgent.prototype.getResource = function(identifier) {
- return this.resources_[identifier];
-};
-
-
-/**
* Asynchronously queries for the resource content.
* @param {number} identifier Resource identifier.
* @param {function(string):undefined} opt_callback Callback to call when
@@ -51,7 +39,7 @@ devtools.NetAgent.prototype.getResource = function(identifier) {
*/
devtools.NetAgent.prototype.getResourceContentAsync = function(identifier,
opt_callback) {
- var resource = this.resources_[identifier];
+ var resource = WebInspector.resources[identifier];
if (!resource) {
return;
}
@@ -71,20 +59,15 @@ devtools.NetAgent.prototype.getResourceContentAsync = function(identifier,
*/
devtools.NetAgent.prototype.willSendRequest = function(identifier, request) {
// Resource object is already created.
- var resource = this.resources_[identifier];
+ var resource = WebInspector.resources[identifier];
if (resource) {
return;
}
- var mainResource = false;
- var cached = false;
- var resource = new WebInspector.Resource(request.requestHeaders,
- request.url, request.domain, request.path, request.lastPathComponent,
- identifier, mainResource, cached);
+ WebInspector.addResource(identifier, request);
+ var resource = WebInspector.resources[identifier];
resource.startTime = request.startTime;
- WebInspector.addResource(resource);
- this.resources_[identifier] = resource;
- this.id_for_url_[request.url] = identifier;
+ this.id_for_url_[resource.url] = identifier;
};
@@ -93,7 +76,7 @@ devtools.NetAgent.prototype.willSendRequest = function(identifier, request) {
* {@inheritDoc}.
*/
devtools.NetAgent.prototype.didReceiveResponse = function(identifier, response) {
- var resource = this.resources_[identifier];
+ var resource = WebInspector.resources[identifier];
if (!resource) {
return;
}
@@ -130,11 +113,14 @@ devtools.NetAgent.prototype.didFinishLoading = function(identifier, value) {
this.willSendRequest(identifier, value);
this.didReceiveResponse(identifier, value);
- var resource = this.resources_[identifier];
+ var resource = WebInspector.resources[identifier];
if (!resource) {
return;
}
resource.endTime = value.endTime;
resource.finished = true;
resource.failed = !!value.errorCode;
+ if (resource.mainResource) {
+ document.title = 'Developer Tools - ' + resource.url;
+ }
};
diff --git a/chrome/tools/test/reference_build/chrome_linux/resources/inspector/profile.js b/chrome/tools/test/reference_build/chrome_linux/resources/inspector/profile.js
new file mode 100644
index 0000000..614c635
--- /dev/null
+++ b/chrome/tools/test/reference_build/chrome_linux/resources/inspector/profile.js
@@ -0,0 +1,605 @@
+// Copyright 2009 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+// Initlialize namespaces
+var devtools = devtools || {};
+devtools.profiler = devtools.profiler || {};
+
+
+/**
+ * Creates a profile object for processing profiling-related events
+ * and calculating function execution times.
+ *
+ * @constructor
+ */
+devtools.profiler.Profile = function() {
+ this.codeMap_ = new devtools.profiler.CodeMap();
+ this.topDownTree_ = new devtools.profiler.CallTree();
+ this.bottomUpTree_ = new devtools.profiler.CallTree();
+};
+
+
+/**
+ * Returns whether a function with the specified name must be skipped.
+ * Should be overriden by subclasses.
+ *
+ * @param {string} name Function name.
+ */
+devtools.profiler.Profile.prototype.skipThisFunction = function(name) {
+ return false;
+};
+
+
+/**
+ * Enum for profiler operations that involve looking up existing
+ * code entries.
+ *
+ * @enum {number}
+ */
+devtools.profiler.Profile.Operation = {
+ MOVE: 0,
+ DELETE: 1,
+ TICK: 2
+};
+
+
+/**
+ * Called whenever the specified operation has failed finding a function
+ * containing the specified address. Should be overriden by subclasses.
+ * See the devtools.profiler.Profile.Operation enum for the list of
+ * possible operations.
+ *
+ * @param {number} operation Operation.
+ * @param {number} addr Address of the unknown code.
+ * @param {number} opt_stackPos If an unknown address is encountered
+ * during stack strace processing, specifies a position of the frame
+ * containing the address.
+ */
+devtools.profiler.Profile.prototype.handleUnknownCode = function(
+ operation, addr, opt_stackPos) {
+};
+
+
+/**
+ * Registers static (library) code entry.
+ *
+ * @param {string} name Code entry name.
+ * @param {number} startAddr Starting address.
+ * @param {number} endAddr Ending address.
+ */
+devtools.profiler.Profile.prototype.addStaticCode = function(
+ name, startAddr, endAddr) {
+ var entry = new devtools.profiler.CodeMap.CodeEntry(
+ endAddr - startAddr, name);
+ this.codeMap_.addStaticCode(startAddr, entry);
+ return entry;
+};
+
+
+/**
+ * Registers dynamic (JIT-compiled) code entry.
+ *
+ * @param {string} type Code entry type.
+ * @param {string} name Code entry name.
+ * @param {number} start Starting address.
+ * @param {number} size Code entry size.
+ */
+devtools.profiler.Profile.prototype.addCode = function(
+ type, name, start, size) {
+ var entry = new devtools.profiler.Profile.DynamicCodeEntry(size, type, name);
+ this.codeMap_.addCode(start, entry);
+ return entry;
+};
+
+
+/**
+ * Reports about moving of a dynamic code entry.
+ *
+ * @param {number} from Current code entry address.
+ * @param {number} to New code entry address.
+ */
+devtools.profiler.Profile.prototype.moveCode = function(from, to) {
+ try {
+ this.codeMap_.moveCode(from, to);
+ } catch (e) {
+ this.handleUnknownCode(devtools.profiler.Profile.Operation.MOVE, from);
+ }
+};
+
+
+/**
+ * Reports about deletion of a dynamic code entry.
+ *
+ * @param {number} start Starting address.
+ */
+devtools.profiler.Profile.prototype.deleteCode = function(start) {
+ try {
+ this.codeMap_.deleteCode(start);
+ } catch (e) {
+ this.handleUnknownCode(devtools.profiler.Profile.Operation.DELETE, start);
+ }
+};
+
+
+/**
+ * Records a tick event. Stack must contain a sequence of
+ * addresses starting with the program counter value.
+ *
+ * @param {Array<number>} stack Stack sample.
+ */
+devtools.profiler.Profile.prototype.recordTick = function(stack) {
+ var processedStack = this.resolveAndFilterFuncs_(stack);
+ this.bottomUpTree_.addPath(processedStack);
+ processedStack.reverse();
+ this.topDownTree_.addPath(processedStack);
+};
+
+
+/**
+ * Translates addresses into function names and filters unneeded
+ * functions.
+ *
+ * @param {Array<number>} stack Stack sample.
+ */
+devtools.profiler.Profile.prototype.resolveAndFilterFuncs_ = function(stack) {
+ var result = [];
+ for (var i = 0; i < stack.length; ++i) {
+ var entry = this.codeMap_.findEntry(stack[i]);
+ if (entry) {
+ var name = entry.getName();
+ if (!this.skipThisFunction(name)) {
+ result.push(name);
+ }
+ } else {
+ this.handleUnknownCode(
+ devtools.profiler.Profile.Operation.TICK, stack[i], i);
+ }
+ }
+ return result;
+};
+
+
+/**
+ * Performs a BF traversal of the top down call graph.
+ *
+ * @param {function(devtools.profiler.CallTree.Node)} f Visitor function.
+ */
+devtools.profiler.Profile.prototype.traverseTopDownTree = function(f) {
+ this.topDownTree_.traverse(f);
+};
+
+
+/**
+ * Performs a BF traversal of the bottom up call graph.
+ *
+ * @param {function(devtools.profiler.CallTree.Node)} f Visitor function.
+ */
+devtools.profiler.Profile.prototype.traverseBottomUpTree = function(f) {
+ this.bottomUpTree_.traverse(f);
+};
+
+
+/**
+ * Calculates a top down profile for a node with the specified label.
+ * If no name specified, returns the whole top down calls tree.
+ *
+ * @param {string} opt_label Node label.
+ */
+devtools.profiler.Profile.prototype.getTopDownProfile = function(opt_label) {
+ return this.getTreeProfile_(this.topDownTree_, opt_label);
+};
+
+
+/**
+ * Calculates a bottom up profile for a node with the specified label.
+ * If no name specified, returns the whole bottom up calls tree.
+ *
+ * @param {string} opt_label Node label.
+ */
+devtools.profiler.Profile.prototype.getBottomUpProfile = function(opt_label) {
+ return this.getTreeProfile_(this.bottomUpTree_, opt_label);
+};
+
+
+/**
+ * Helper function for calculating a tree profile.
+ *
+ * @param {devtools.profiler.Profile.CallTree} tree Call tree.
+ * @param {string} opt_label Node label.
+ */
+devtools.profiler.Profile.prototype.getTreeProfile_ = function(tree, opt_label) {
+ if (!opt_label) {
+ tree.computeTotalWeights();
+ return tree;
+ } else {
+ var subTree = tree.cloneSubtree(opt_label);
+ subTree.computeTotalWeights();
+ return subTree;
+ }
+};
+
+
+/**
+ * Calculates a flat profile of callees starting from a node with
+ * the specified label. If no name specified, starts from the root.
+ *
+ * @param {string} opt_label Starting node label.
+ */
+devtools.profiler.Profile.prototype.getFlatProfile = function(opt_label) {
+ var counters = new devtools.profiler.CallTree();
+ var rootLabel = opt_label || devtools.profiler.CallTree.ROOT_NODE_LABEL;
+ var precs = {};
+ precs[rootLabel] = 0;
+ var root = counters.findOrAddChild(rootLabel);
+
+ this.topDownTree_.computeTotalWeights();
+ this.topDownTree_.traverseInDepth(
+ function onEnter(node) {
+ if (!(node.label in precs)) {
+ precs[node.label] = 0;
+ }
+ var nodeLabelIsRootLabel = node.label == rootLabel;
+ if (nodeLabelIsRootLabel || precs[rootLabel] > 0) {
+ if (precs[rootLabel] == 0) {
+ root.selfWeight += node.selfWeight;
+ root.totalWeight += node.totalWeight;
+ } else {
+ var rec = root.findOrAddChild(node.label);
+ rec.selfWeight += node.selfWeight;
+ if (nodeLabelIsRootLabel || precs[node.label] == 0) {
+ rec.totalWeight += node.totalWeight;
+ }
+ }
+ precs[node.label]++;
+ }
+ },
+ function onExit(node) {
+ if (node.label == rootLabel || precs[rootLabel] > 0) {
+ precs[node.label]--;
+ }
+ },
+ null);
+
+ if (!opt_label) {
+ // If we have created a flat profile for the whole program, we don't
+ // need an explicit root in it. Thus, replace the counters tree
+ // root with the node corresponding to the whole program.
+ counters.root_ = root;
+ } else {
+ // Propagate weights so percents can be calculated correctly.
+ counters.getRoot().selfWeight = root.selfWeight;
+ counters.getRoot().totalWeight = root.totalWeight;
+ }
+ return counters;
+};
+
+
+/**
+ * Creates a dynamic code entry.
+ *
+ * @param {number} size Code size.
+ * @param {string} type Code type.
+ * @param {string} name Function name.
+ * @constructor
+ */
+devtools.profiler.Profile.DynamicCodeEntry = function(size, type, name) {
+ devtools.profiler.CodeMap.CodeEntry.call(this, size, name);
+ this.type = type;
+};
+
+
+/**
+ * Returns node name.
+ */
+devtools.profiler.Profile.DynamicCodeEntry.prototype.getName = function() {
+ var name = this.name;
+ if (name.length == 0) {
+ name = '<anonymous>';
+ } else if (name.charAt(0) == ' ') {
+ // An anonymous function with location: " aaa.js:10".
+ name = '<anonymous>' + name;
+ }
+ return this.type + ': ' + name;
+};
+
+
+/**
+ * Constructs a call graph.
+ *
+ * @constructor
+ */
+devtools.profiler.CallTree = function() {
+ this.root_ = new devtools.profiler.CallTree.Node(
+ devtools.profiler.CallTree.ROOT_NODE_LABEL);
+};
+
+
+/**
+ * The label of the root node.
+ */
+devtools.profiler.CallTree.ROOT_NODE_LABEL = '';
+
+
+/**
+ * @private
+ */
+devtools.profiler.CallTree.prototype.totalsComputed_ = false;
+
+
+/**
+ * Returns the tree root.
+ */
+devtools.profiler.CallTree.prototype.getRoot = function() {
+ return this.root_;
+};
+
+
+/**
+ * Adds the specified call path, constructing nodes as necessary.
+ *
+ * @param {Array<string>} path Call path.
+ */
+devtools.profiler.CallTree.prototype.addPath = function(path) {
+ if (path.length == 0) {
+ return;
+ }
+ var curr = this.root_;
+ for (var i = 0; i < path.length; ++i) {
+ curr = curr.findOrAddChild(path[i]);
+ }
+ curr.selfWeight++;
+ this.totalsComputed_ = false;
+};
+
+
+/**
+ * Finds an immediate child of the specified parent with the specified
+ * label, creates a child node if necessary. If a parent node isn't
+ * specified, uses tree root.
+ *
+ * @param {string} label Child node label.
+ */
+devtools.profiler.CallTree.prototype.findOrAddChild = function(label) {
+ return this.root_.findOrAddChild(label);
+};
+
+
+/**
+ * Creates a subtree by cloning and merging all subtrees rooted at nodes
+ * with a given label. E.g. cloning the following call tree on label 'A'
+ * will give the following result:
+ *
+ * <A>--<B> <B>
+ * / /
+ * <root> == clone on 'A' ==> <root>--<A>
+ * \ \
+ * <C>--<A>--<D> <D>
+ *
+ * And <A>'s selfWeight will be the sum of selfWeights of <A>'s from the
+ * source call tree.
+ *
+ * @param {string} label The label of the new root node.
+ */
+devtools.profiler.CallTree.prototype.cloneSubtree = function(label) {
+ var subTree = new devtools.profiler.CallTree();
+ this.traverse(function(node, parent) {
+ if (!parent && node.label != label) {
+ return null;
+ }
+ var child = (parent ? parent : subTree).findOrAddChild(node.label);
+ child.selfWeight += node.selfWeight;
+ return child;
+ });
+ return subTree;
+};
+
+
+/**
+ * Computes total weights in the call graph.
+ */
+devtools.profiler.CallTree.prototype.computeTotalWeights = function() {
+ if (this.totalsComputed_) {
+ return;
+ }
+ this.root_.computeTotalWeight();
+ this.totalsComputed_ = true;
+};
+
+
+/**
+ * Traverses the call graph in preorder. This function can be used for
+ * building optionally modified tree clones. This is the boilerplate code
+ * for this scenario:
+ *
+ * callTree.traverse(function(node, parentClone) {
+ * var nodeClone = cloneNode(node);
+ * if (parentClone)
+ * parentClone.addChild(nodeClone);
+ * return nodeClone;
+ * });
+ *
+ * @param {function(devtools.profiler.CallTree.Node, *)} f Visitor function.
+ * The second parameter is the result of calling 'f' on the parent node.
+ */
+devtools.profiler.CallTree.prototype.traverse = function(f) {
+ var pairsToProcess = new ConsArray();
+ pairsToProcess.concat([{node: this.root_, param: null}]);
+ while (!pairsToProcess.atEnd()) {
+ var pair = pairsToProcess.next();
+ var node = pair.node;
+ var newParam = f(node, pair.param);
+ var morePairsToProcess = [];
+ node.forEachChild(function (child) {
+ morePairsToProcess.push({node: child, param: newParam}); });
+ pairsToProcess.concat(morePairsToProcess);
+ }
+};
+
+
+/**
+ * Performs an indepth call graph traversal.
+ *
+ * @param {function(devtools.profiler.CallTree.Node)} enter A function called
+ * prior to visiting node's children.
+ * @param {function(devtools.profiler.CallTree.Node)} exit A function called
+ * after visiting node's children.
+ */
+devtools.profiler.CallTree.prototype.traverseInDepth = function(enter, exit) {
+ function traverse(node) {
+ enter(node);
+ node.forEachChild(traverse);
+ exit(node);
+ }
+ traverse(this.root_);
+};
+
+
+/**
+ * Constructs a call graph node.
+ *
+ * @param {string} label Node label.
+ * @param {devtools.profiler.CallTree.Node} opt_parent Node parent.
+ */
+devtools.profiler.CallTree.Node = function(label, opt_parent) {
+ this.label = label;
+ this.parent = opt_parent;
+ this.children = {};
+};
+
+
+/**
+ * Node self weight (how many times this node was the last node in
+ * a call path).
+ * @type {number}
+ */
+devtools.profiler.CallTree.Node.prototype.selfWeight = 0;
+
+
+/**
+ * Node total weight (includes weights of all children).
+ * @type {number}
+ */
+devtools.profiler.CallTree.Node.prototype.totalWeight = 0;
+
+
+/**
+ * Adds a child node.
+ *
+ * @param {string} label Child node label.
+ */
+devtools.profiler.CallTree.Node.prototype.addChild = function(label) {
+ var child = new devtools.profiler.CallTree.Node(label, this);
+ this.children[label] = child;
+ return child;
+};
+
+
+/**
+ * Computes node's total weight.
+ */
+devtools.profiler.CallTree.Node.prototype.computeTotalWeight =
+ function() {
+ var totalWeight = this.selfWeight;
+ this.forEachChild(function(child) {
+ totalWeight += child.computeTotalWeight(); });
+ return this.totalWeight = totalWeight;
+};
+
+
+/**
+ * Returns all node's children as an array.
+ */
+devtools.profiler.CallTree.Node.prototype.exportChildren = function() {
+ var result = [];
+ this.forEachChild(function (node) { result.push(node); });
+ return result;
+};
+
+
+/**
+ * Finds an immediate child with the specified label.
+ *
+ * @param {string} label Child node label.
+ */
+devtools.profiler.CallTree.Node.prototype.findChild = function(label) {
+ return this.children[label] || null;
+};
+
+
+/**
+ * Finds an immediate child with the specified label, creates a child
+ * node if necessary.
+ *
+ * @param {string} label Child node label.
+ */
+devtools.profiler.CallTree.Node.prototype.findOrAddChild = function(label) {
+ return this.findChild(label) || this.addChild(label);
+};
+
+
+/**
+ * Calls the specified function for every child.
+ *
+ * @param {function(devtools.profiler.CallTree.Node)} f Visitor function.
+ */
+devtools.profiler.CallTree.Node.prototype.forEachChild = function(f) {
+ for (var c in this.children) {
+ f(this.children[c]);
+ }
+};
+
+
+/**
+ * Walks up from the current node up to the call tree root.
+ *
+ * @param {function(devtools.profiler.CallTree.Node)} f Visitor function.
+ */
+devtools.profiler.CallTree.Node.prototype.walkUpToRoot = function(f) {
+ for (var curr = this; curr != null; curr = curr.parent) {
+ f(curr);
+ }
+};
+
+
+/**
+ * Tries to find a node with the specified path.
+ *
+ * @param {Array<string>} labels The path.
+ * @param {function(devtools.profiler.CallTree.Node)} opt_f Visitor function.
+ */
+devtools.profiler.CallTree.Node.prototype.descendToChild = function(
+ labels, opt_f) {
+ for (var pos = 0, curr = this; pos < labels.length && curr != null; pos++) {
+ var child = curr.findChild(labels[pos]);
+ if (opt_f) {
+ opt_f(child, pos);
+ }
+ curr = child;
+ }
+ return curr;
+};
diff --git a/chrome/tools/test/reference_build/chrome_linux/resources/inspector/profile_view.js b/chrome/tools/test/reference_build/chrome_linux/resources/inspector/profile_view.js
new file mode 100644
index 0000000..9d196a3
--- /dev/null
+++ b/chrome/tools/test/reference_build/chrome_linux/resources/inspector/profile_view.js
@@ -0,0 +1,251 @@
+// Copyright 2009 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+// Initlialize namespaces
+var devtools = devtools || {};
+devtools.profiler = devtools.profiler || {};
+
+
+/**
+ * Creates a Profile View builder object.
+ *
+ * @param {number} samplingRate Number of ms between profiler ticks.
+ * @constructor
+ */
+devtools.profiler.ViewBuilder = function(samplingRate) {
+ this.samplingRate = samplingRate;
+};
+
+
+/**
+ * Builds a profile view for the specified call tree.
+ *
+ * @param {devtools.profiler.CallTree} callTree A call tree.
+ * @param {boolean} opt_bottomUpViewWeights Whether remapping
+ * of self weights for a bottom up view is needed.
+ */
+devtools.profiler.ViewBuilder.prototype.buildView = function(
+ callTree, opt_bottomUpViewWeights) {
+ var head;
+ var samplingRate = this.samplingRate;
+ callTree.traverse(function(node, viewParent) {
+ var totalWeight = node.totalWeight * samplingRate;
+ var selfWeight = node.selfWeight * samplingRate;
+ if (opt_bottomUpViewWeights === true) {
+ if (viewParent === head) {
+ selfWeight = totalWeight;
+ } else {
+ selfWeight = 0;
+ }
+ }
+ var viewNode = new devtools.profiler.ProfileView.Node(
+ node.label, totalWeight, selfWeight, head);
+ if (viewParent) {
+ viewParent.addChild(viewNode);
+ } else {
+ head = viewNode;
+ }
+ return viewNode;
+ });
+ var view = new devtools.profiler.ProfileView(head);
+ return view;
+};
+
+
+/**
+ * Creates a Profile View object. It allows to perform sorting
+ * and filtering actions on the profile. Profile View mimicks
+ * the Profile object from WebKit's JSC profiler.
+ *
+ * @param {devtools.profiler.ProfileView.Node} head Head (root) node.
+ * @constructor
+ */
+devtools.profiler.ProfileView = function(head) {
+ this.head = head;
+ this.title = '';
+ this.uid = '';
+ this.heavyProfile = null;
+ this.treeProfile = null;
+ this.flatProfile = null;
+};
+
+
+/**
+ * Sorts the profile view using the specified sort function.
+ *
+ * @param {function(devtools.profiler.ProfileView.Node,
+ * devtools.profiler.ProfileView.Node):number} sortFunc A sorting
+ * functions. Must comply with Array.sort sorting function requirements.
+ */
+devtools.profiler.ProfileView.prototype.sort = function(sortFunc) {
+ this.traverse(function (node) {
+ node.sortChildren(sortFunc);
+ });
+};
+
+
+/**
+ * Traverses profile view nodes in preorder.
+ *
+ * @param {function(devtools.profiler.ProfileView.Node)} f Visitor function.
+ */
+devtools.profiler.ProfileView.prototype.traverse = function(f) {
+ var nodesToTraverse = new ConsArray();
+ nodesToTraverse.concat([this.head]);
+ while (!nodesToTraverse.atEnd()) {
+ var node = nodesToTraverse.next();
+ f(node);
+ nodesToTraverse.concat(node.children);
+ }
+};
+
+
+/**
+ * Constructs a Profile View node object. Each node object corresponds to
+ * a function call.
+ *
+ * @param {string} internalFuncName A fully qualified function name.
+ * @param {number} totalTime Amount of time that application spent in the
+ * corresponding function and its descendants (not that depending on
+ * profile they can be either callees or callers.)
+ * @param {number} selfTime Amount of time that application spent in the
+ * corresponding function only.
+ * @param {devtools.profiler.ProfileView.Node} head Profile view head.
+ * @constructor
+ */
+devtools.profiler.ProfileView.Node = function(
+ internalFuncName, totalTime, selfTime, head) {
+ this.callIdentifier = 0;
+ this.internalFuncName = internalFuncName;
+ this.initFuncInfo();
+ this.totalTime = totalTime;
+ this.selfTime = selfTime;
+ this.head = head;
+ this.parent = null;
+ this.children = [];
+ this.visible = true;
+};
+
+
+/**
+ * RegEx for stripping V8's prefixes of compiled functions.
+ */
+devtools.profiler.ProfileView.Node.FUNC_NAME_STRIP_RE =
+ /^(?:LazyCompile|Function): (.*)$/;
+
+
+/**
+ * RegEx for extracting script source URL and line number.
+ */
+devtools.profiler.ProfileView.Node.FUNC_NAME_PARSE_RE = /^([^ ]+) (.*):(\d+)$/;
+
+
+/**
+ * RegEx for removing protocol name from URL.
+ */
+devtools.profiler.ProfileView.Node.URL_PARSE_RE = /^(?:http:\/)?.*\/([^/]+)$/;
+
+
+/**
+ * Inits 'functionName', 'url', and 'lineNumber' fields using 'internalFuncName'
+ * field.
+ */
+devtools.profiler.ProfileView.Node.prototype.initFuncInfo = function() {
+ var nodeAlias = devtools.profiler.ProfileView.Node;
+ this.functionName = this.internalFuncName;
+
+ var strippedName = nodeAlias.FUNC_NAME_STRIP_RE.exec(this.functionName);
+ if (strippedName) {
+ this.functionName = strippedName[1];
+ }
+
+ var parsedName = nodeAlias.FUNC_NAME_PARSE_RE.exec(this.functionName);
+ if (parsedName) {
+ this.url = parsedName[2];
+ var parsedUrl = nodeAlias.URL_PARSE_RE.exec(this.url);
+ if (parsedUrl) {
+ this.url = parsedUrl[1];
+ }
+ this.functionName = parsedName[1];
+ this.lineNumber = parsedName[3];
+ } else {
+ this.url = '';
+ this.lineNumber = 0;
+ }
+};
+
+
+/**
+ * Returns a share of the function's total time in application's total time.
+ */
+devtools.profiler.ProfileView.Node.prototype.__defineGetter__(
+ 'totalPercent',
+ function() { return this.totalTime /
+ (this.head ? this.head.totalTime : this.totalTime) * 100.0; });
+
+
+/**
+ * Returns a share of the function's self time in application's total time.
+ */
+devtools.profiler.ProfileView.Node.prototype.__defineGetter__(
+ 'selfPercent',
+ function() { return this.selfTime /
+ (this.head ? this.head.totalTime : this.totalTime) * 100.0; });
+
+
+/**
+ * Returns a share of the function's total time in its parent's total time.
+ */
+devtools.profiler.ProfileView.Node.prototype.__defineGetter__(
+ 'parentTotalPercent',
+ function() { return this.totalTime /
+ (this.parent ? this.parent.totalTime : this.totalTime) * 100.0; });
+
+
+/**
+ * Adds a child to the node.
+ *
+ * @param {devtools.profiler.ProfileView.Node} node Child node.
+ */
+devtools.profiler.ProfileView.Node.prototype.addChild = function(node) {
+ node.parent = this;
+ this.children.push(node);
+};
+
+
+/**
+ * Sorts all the node's children recursively.
+ *
+ * @param {function(devtools.profiler.ProfileView.Node,
+ * devtools.profiler.ProfileView.Node):number} sortFunc A sorting
+ * functions. Must comply with Array.sort sorting function requirements.
+ */
+devtools.profiler.ProfileView.Node.prototype.sortChildren = function(
+ sortFunc) {
+ this.children.sort(sortFunc);
+};
diff --git a/chrome/tools/test/reference_build/chrome_linux/resources/inspector/profiler_processor.js b/chrome/tools/test/reference_build/chrome_linux/resources/inspector/profiler_processor.js
new file mode 100644
index 0000000..e290350
--- /dev/null
+++ b/chrome/tools/test/reference_build/chrome_linux/resources/inspector/profiler_processor.js
@@ -0,0 +1,201 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @fileoverview Profiler processor is used to process log file produced
+ * by V8 and produce an internal profile representation which is used
+ * for building profile views in 'Profiles' tab.
+ */
+goog.provide('devtools.profiler.Processor');
+
+
+/**
+ * Ancestor of a profile object that leaves out only JS-related functions.
+ * @constructor
+ */
+devtools.profiler.JsProfile = function() {
+ devtools.profiler.Profile.call(this);
+};
+goog.inherits(devtools.profiler.JsProfile, devtools.profiler.Profile);
+
+
+/**
+ * @type {RegExp}
+ */
+devtools.profiler.JsProfile.JS_FUNC_RE = /^(LazyCompile|Function|Script):/;
+
+
+/**
+ * @override
+ */
+devtools.profiler.JsProfile.prototype.skipThisFunction = function(name) {
+ return !devtools.profiler.JsProfile.JS_FUNC_RE.test(name);
+};
+
+
+/**
+ * Profiler processor. Consumes profiler log and builds profile views.
+ * @constructor
+ */
+devtools.profiler.Processor = function() {
+ /**
+ * Current profile.
+ * @type {devtools.profiler.JsProfile}
+ */
+ this.profile_ = new devtools.profiler.JsProfile();
+
+ /**
+ * Builder of profile views.
+ * @type {devtools.profiler.ViewBuilder}
+ */
+ this.viewBuilder_ = new devtools.profiler.ViewBuilder(1);
+
+ /**
+ * Next profile id.
+ * @type {number}
+ */
+ this.profileId_ = 1;
+};
+
+
+/**
+ * A dispatch table for V8 profiler event log records.
+ * @private
+ */
+devtools.profiler.Processor.RecordsDispatch_ = {
+ 'code-creation': { parsers: [null, parseInt, parseInt, null],
+ processor: 'processCodeCreation_' },
+ 'code-move': { parsers: [parseInt, parseInt],
+ processor: 'processCodeMove_' },
+ 'code-delete': { parsers: [parseInt], processor: 'processCodeDelete_' },
+ 'tick': { parsers: [parseInt, parseInt, parseInt, 'var-args'],
+ processor: 'processTick_' },
+ // Not used in DevTools Profiler.
+ 'profiler': null,
+ 'shared-library': null,
+ // Obsolete row types.
+ 'code-allocate': null,
+ 'begin-code-region': null,
+ 'end-code-region': null
+};
+
+
+/**
+ * Processes a portion of V8 profiler event log.
+ *
+ * @param {string} chunk A portion of log.
+ */
+devtools.profiler.Processor.prototype.processLogChunk = function(chunk) {
+ this.processLog_(chunk.split('\n'));
+};
+
+
+/**
+ * Processes a log lines.
+ *
+ * @param {Array<string>} lines Log lines.
+ * @private
+ */
+devtools.profiler.Processor.prototype.processLog_ = function(lines) {
+ var csvParser = new devtools.profiler.CsvParser();
+ try {
+ for (var i = 0, n = lines.length; i < n; ++i) {
+ var line = lines[i];
+ if (!line) {
+ continue;
+ }
+ var fields = csvParser.parseLine(line);
+ this.dispatchLogRow_(fields);
+ }
+ } catch (e) {
+ debugPrint('line ' + (i + 1) + ': ' + (e.message || e));
+ throw e;
+ }
+};
+
+
+/**
+ * Does a dispatch of a log record.
+ *
+ * @param {Array<string>} fields Log record.
+ * @private
+ */
+devtools.profiler.Processor.prototype.dispatchLogRow_ = function(fields) {
+ // Obtain the dispatch.
+ var command = fields[0];
+ if (!(command in devtools.profiler.Processor.RecordsDispatch_)) {
+ throw new Error('unknown command: ' + command);
+ }
+ var dispatch = devtools.profiler.Processor.RecordsDispatch_[command];
+
+ if (dispatch === null) {
+ return;
+ }
+
+ // Parse fields.
+ var parsedFields = [];
+ for (var i = 0; i < dispatch.parsers.length; ++i) {
+ var parser = dispatch.parsers[i];
+ if (parser === null) {
+ parsedFields.push(fields[1 + i]);
+ } else if (typeof parser == 'function') {
+ parsedFields.push(parser(fields[1 + i]));
+ } else {
+ // var-args
+ parsedFields.push(fields.slice(1 + i));
+ break;
+ }
+ }
+
+ // Run the processor.
+ this[dispatch.processor].apply(this, parsedFields);
+};
+
+
+devtools.profiler.Processor.prototype.processCodeCreation_ = function(
+ type, start, size, name) {
+ this.profile_.addCode(type, name, start, size);
+};
+
+
+devtools.profiler.Processor.prototype.processCodeMove_ = function(from, to) {
+ this.profile_.moveCode(from, to);
+};
+
+
+devtools.profiler.Processor.prototype.processCodeDelete_ = function(start) {
+ this.profile_.deleteCode(start);
+};
+
+
+devtools.profiler.Processor.prototype.processTick_ = function(
+ pc, sp, vmState, stack) {
+ var fullStack = [pc];
+ for (var i = 0, n = stack.length; i < n; ++i) {
+ var frame = stack[i];
+ // Leave only numbers starting with 0x. Filter possible 'overflow' string.
+ if (frame.charAt(0) == '0') {
+ fullStack.push(parseInt(frame, 16));
+ }
+ }
+ this.profile_.recordTick(fullStack);
+};
+
+
+/**
+ * Creates a profile for further displaying in ProfileView.
+ */
+devtools.profiler.Processor.prototype.createProfileForView = function() {
+ var profile = new devtools.profiler.ProfileView();
+ profile.uid = this.profileId_++;
+ profile.title = UserInitiatedProfileName + '.' + profile.uid;
+ // A trick to cope with ProfileView.bottomUpProfileDataGridTree and
+ // ProfileView.topDownProfileDataGridTree behavior.
+ profile.head = profile;
+ profile.heavyProfile = this.viewBuilder_.buildView(
+ this.profile_.getBottomUpProfile(), true);
+ profile.treeProfile = this.viewBuilder_.buildView(
+ this.profile_.getTopDownProfile());
+ return profile;
+};
diff --git a/chrome/tools/test/reference_build/chrome_linux/resources/inspector/splaytree.js b/chrome/tools/test/reference_build/chrome_linux/resources/inspector/splaytree.js
new file mode 100644
index 0000000..7b3af8b
--- /dev/null
+++ b/chrome/tools/test/reference_build/chrome_linux/resources/inspector/splaytree.js
@@ -0,0 +1,322 @@
+// Copyright 2009 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+// A namespace stub. It will become more clear how to declare it properly
+// during integration of this script into Dev Tools.
+var goog = goog || {};
+goog.structs = goog.structs || {};
+
+
+/**
+ * Constructs a Splay tree. A splay tree is a self-balancing binary
+ * search tree with the additional property that recently accessed
+ * elements are quick to access again. It performs basic operations
+ * such as insertion, look-up and removal in O(log(n)) amortized time.
+ *
+ * @constructor
+ */
+goog.structs.SplayTree = function() {
+};
+
+
+/**
+ * Pointer to the root node of the tree.
+ *
+ * @type {goog.structs.SplayTree.Node}
+ * @private
+ */
+goog.structs.SplayTree.prototype.root_ = null;
+
+
+/**
+ * @return {boolean} Whether the tree is empty.
+ */
+goog.structs.SplayTree.prototype.isEmpty = function() {
+ return !this.root_;
+};
+
+
+
+/**
+ * Inserts a node into the tree with the specified key and value if
+ * the tree does not already contain a node with the specified key. If
+ * the value is inserted, it becomes the root of the tree.
+ *
+ * @param {number} key Key to insert into the tree.
+ * @param {*} value Value to insert into the tree.
+ */
+goog.structs.SplayTree.prototype.insert = function(key, value) {
+ if (this.isEmpty()) {
+ this.root_ = new goog.structs.SplayTree.Node(key, value);
+ return;
+ }
+ // Splay on the key to move the last node on the search path for
+ // the key to the root of the tree.
+ this.splay_(key);
+ if (this.root_.key == key) {
+ return;
+ }
+ var node = new goog.structs.SplayTree.Node(key, value);
+ if (key > this.root_.key) {
+ node.left = this.root_;
+ node.right = this.root_.right;
+ this.root_.right = null;
+ } else {
+ node.right = this.root_;
+ node.left = this.root_.left;
+ this.root_.left = null;
+ }
+ this.root_ = node;
+};
+
+
+/**
+ * Removes a node with the specified key from the tree if the tree
+ * contains a node with this key. The removed node is returned. If the
+ * key is not found, an exception is thrown.
+ *
+ * @param {number} key Key to find and remove from the tree.
+ * @return {goog.structs.SplayTree.Node} The removed node.
+ */
+goog.structs.SplayTree.prototype.remove = function(key) {
+ if (this.isEmpty()) {
+ throw Error('Key not found: ' + key);
+ }
+ this.splay_(key);
+ if (this.root_.key != key) {
+ throw Error('Key not found: ' + key);
+ }
+ var removed = this.root_;
+ if (!this.root_.left) {
+ this.root_ = this.root_.right;
+ } else {
+ var right = this.root_.right;
+ this.root_ = this.root_.left;
+ // Splay to make sure that the new root has an empty right child.
+ this.splay_(key);
+ // Insert the original right child as the right child of the new
+ // root.
+ this.root_.right = right;
+ }
+ return removed;
+};
+
+
+/**
+ * Returns the node having the specified key or null if the tree doesn't contain
+ * a node with the specified key.
+ *
+ * @param {number} key Key to find in the tree.
+ * @return {goog.structs.SplayTree.Node} Node having the specified key.
+ */
+goog.structs.SplayTree.prototype.find = function(key) {
+ if (this.isEmpty()) {
+ return null;
+ }
+ this.splay_(key);
+ return this.root_.key == key ? this.root_ : null;
+};
+
+
+/**
+ * @return {goog.structs.SplayTree.Node} Node having the minimum key value.
+ */
+goog.structs.SplayTree.prototype.findMin = function() {
+ if (this.isEmpty()) {
+ return null;
+ }
+ var current = this.root_;
+ while (current.left) {
+ current = current.left;
+ }
+ return current;
+};
+
+
+/**
+ * @return {goog.structs.SplayTree.Node} Node having the maximum key value.
+ */
+goog.structs.SplayTree.prototype.findMax = function(opt_startNode) {
+ if (this.isEmpty()) {
+ return null;
+ }
+ var current = opt_startNode || this.root_;
+ while (current.right) {
+ current = current.right;
+ }
+ return current;
+};
+
+
+/**
+ * @return {goog.structs.SplayTree.Node} Node having the maximum key value that
+ * is less or equal to the specified key value.
+ */
+goog.structs.SplayTree.prototype.findGreatestLessThan = function(key) {
+ if (this.isEmpty()) {
+ return null;
+ }
+ // Splay on the key to move the node with the given key or the last
+ // node on the search path to the top of the tree.
+ this.splay_(key);
+ // Now the result is either the root node or the greatest node in
+ // the left subtree.
+ if (this.root_.key <= key) {
+ return this.root_;
+ } else if (this.root_.left) {
+ return this.findMax(this.root_.left);
+ } else {
+ return null;
+ }
+};
+
+
+/**
+ * @return {Array<*>} An array containing all the values of tree's nodes.
+ */
+goog.structs.SplayTree.prototype.exportValues = function() {
+ var result = [];
+ this.traverse_(function(node) { result.push(node.value); });
+ return result;
+};
+
+
+/**
+ * Perform the splay operation for the given key. Moves the node with
+ * the given key to the top of the tree. If no node has the given
+ * key, the last node on the search path is moved to the top of the
+ * tree. This is the simplified top-down splaying algorithm from:
+ * "Self-adjusting Binary Search Trees" by Sleator and Tarjan
+ *
+ * @param {number} key Key to splay the tree on.
+ * @private
+ */
+goog.structs.SplayTree.prototype.splay_ = function(key) {
+ if (this.isEmpty()) {
+ return;
+ }
+ // Create a dummy node. The use of the dummy node is a bit
+ // counter-intuitive: The right child of the dummy node will hold
+ // the L tree of the algorithm. The left child of the dummy node
+ // will hold the R tree of the algorithm. Using a dummy node, left
+ // and right will always be nodes and we avoid special cases.
+ var dummy, left, right;
+ dummy = left = right = new goog.structs.SplayTree.Node(null, null);
+ var current = this.root_;
+ while (true) {
+ if (key < current.key) {
+ if (!current.left) {
+ break;
+ }
+ if (key < current.left.key) {
+ // Rotate right.
+ var tmp = current.left;
+ current.left = tmp.right;
+ tmp.right = current;
+ current = tmp;
+ if (!current.left) {
+ break;
+ }
+ }
+ // Link right.
+ right.left = current;
+ right = current;
+ current = current.left;
+ } else if (key > current.key) {
+ if (!current.right) {
+ break;
+ }
+ if (key > current.right.key) {
+ // Rotate left.
+ var tmp = current.right;
+ current.right = tmp.left;
+ tmp.left = current;
+ current = tmp;
+ if (!current.right) {
+ break;
+ }
+ }
+ // Link left.
+ left.right = current;
+ left = current;
+ current = current.right;
+ } else {
+ break;
+ }
+ }
+ // Assemble.
+ left.right = current.left;
+ right.left = current.right;
+ current.left = dummy.right;
+ current.right = dummy.left;
+ this.root_ = current;
+};
+
+
+/**
+ * Performs a preorder traversal of the tree.
+ *
+ * @param {function(goog.structs.SplayTree.Node)} f Visitor function.
+ * @private
+ */
+goog.structs.SplayTree.prototype.traverse_ = function(f) {
+ var nodesToVisit = [this.root_];
+ while (nodesToVisit.length > 0) {
+ var node = nodesToVisit.shift();
+ if (node == null) {
+ continue;
+ }
+ f(node);
+ nodesToVisit.push(node.left);
+ nodesToVisit.push(node.right);
+ }
+};
+
+
+/**
+ * Constructs a Splay tree node.
+ *
+ * @param {number} key Key.
+ * @param {*} value Value.
+ */
+goog.structs.SplayTree.Node = function(key, value) {
+ this.key = key;
+ this.value = value;
+};
+
+
+/**
+ * @type {goog.structs.SplayTree.Node}
+ */
+goog.structs.SplayTree.Node.prototype.left = null;
+
+
+/**
+ * @type {goog.structs.SplayTree.Node}
+ */
+goog.structs.SplayTree.Node.prototype.right = null;
diff --git a/chrome/tools/test/reference_build/chrome_linux/themes/default.pak b/chrome/tools/test/reference_build/chrome_linux/themes/default.pak
index 73914be..3857cb18 100644
--- a/chrome/tools/test/reference_build/chrome_linux/themes/default.pak
+++ b/chrome/tools/test/reference_build/chrome_linux/themes/default.pak
Binary files differ