Diff
Modified: trunk/LayoutTests/ChangeLog (173198 => 173199)
--- trunk/LayoutTests/ChangeLog 2014-09-03 03:17:47 UTC (rev 173198)
+++ trunk/LayoutTests/ChangeLog 2014-09-03 04:58:55 UTC (rev 173199)
@@ -1,3 +1,16 @@
+2014-09-02 Brian J. Burg <[email protected]>
+
+ LegacyProfiler: remove redundant ProfileNode members and other cleanup
+ https://bugs.webkit.org/show_bug.cgi?id=136380
+
+ Reviewed by Timothy Hatcher.
+
+ Renamed Profile.head to Profile.rootNode.
+
+ * fast/profiler/resources/profiler-test-JS-resources.js:
+ (printHeavyProfilesDataWithoutTime):
+ (printProfilesDataWithoutTime):
+
2014-09-02 Simon Fraser <[email protected]>
Avoid backing store allocation with some combinations of replaced elements, masking and visibility:hidden
Modified: trunk/LayoutTests/fast/profiler/resources/profiler-test-JS-resources.js (173198 => 173199)
--- trunk/LayoutTests/fast/profiler/resources/profiler-test-JS-resources.js 2014-09-03 03:17:47 UTC (rev 173198)
+++ trunk/LayoutTests/fast/profiler/resources/profiler-test-JS-resources.js 2014-09-03 04:58:55 UTC (rev 173199)
@@ -52,7 +52,7 @@
var profiles = internals.consoleProfiles;
for (var i = 0; i < profiles.length; ++i) {
preElement.appendChild(document.createTextNode("Profile title: " + profiles[i].title + "\n"));
- printProfileNodeWithoutTime(preElement, profiles[i].heavyProfile.head, 0);
+ printProfileNodeWithoutTime(preElement, profiles[i].heavyProfile.rootNode, 0);
preElement.appendChild(document.createTextNode("\n"));
}
@@ -67,7 +67,7 @@
var profiles = internals.consoleProfiles;
for (var i = 0; i < profiles.length; ++i) {
preElement.appendChild(document.createTextNode("Profile title: " + profiles[i].title + "\n"));
- printProfileNodeWithoutTime(preElement, profiles[i].head, 0);
+ printProfileNodeWithoutTime(preElement, profiles[i].rootNode, 0);
preElement.appendChild(document.createTextNode("\n"));
}
Modified: trunk/Source/_javascript_Core/ChangeLog (173198 => 173199)
--- trunk/Source/_javascript_Core/ChangeLog 2014-09-03 03:17:47 UTC (rev 173198)
+++ trunk/Source/_javascript_Core/ChangeLog 2014-09-03 04:58:55 UTC (rev 173199)
@@ -1,5 +1,81 @@
2014-09-02 Brian J. Burg <[email protected]>
+ LegacyProfiler: remove redundant ProfileNode members and other cleanup
+ https://bugs.webkit.org/show_bug.cgi?id=136380
+
+ Reviewed by Timothy Hatcher.
+
+ ProfileNode's selfTime and totalTime members are redundant and only used
+ for dumping profile data from debug-only code. Remove the members and compute
+ the same data on-demand when necessary using a postorder traversal functor.
+
+ Remove ProfileNode.head since it is only used to calculate percentages for
+ dumped profile data. This can be explicitly passed around when needed.
+
+ Rename Profile.head to Profile.rootNode, and other various renamings.
+
+ Rearrange some header includes so that touching LegacyProfiler-related headers
+ will no longer cause a full rebuild.
+
+ * inspector/JSConsoleClient.cpp: Add header include.
+ * inspector/agents/InspectorProfilerAgent.cpp:
+ (Inspector::InspectorProfilerAgent::buildProfileInspectorObject):
+ * inspector/protocol/Profiler.json: Remove unused Profile.idleTime member.
+ * jit/JIT.h: Remove header include.
+ * jit/JITCode.h: Remove header include.
+ * jit/JITOperations.cpp: Sort and add header include.
+ * llint/LLIntSlowPaths.cpp: Sort and add header include.
+ * profiler/Profile.cpp: Rename the debug dumping functions. Move the node
+ postorder traversal code to ProfileNode so we can traverse any subtree.
+ (JSC::Profile::Profile):
+ (JSC::Profile::debugPrint):
+ (JSC::Profile::debugPrintSampleStyle):
+ (JSC::Profile::forEach): Deleted.
+ (JSC::Profile::debugPrintData): Deleted.
+ (JSC::Profile::debugPrintDataSampleStyle): Deleted.
+ * profiler/Profile.h:
+ * profiler/ProfileGenerator.cpp:
+ (JSC::ProfileGenerator::ProfileGenerator):
+ (JSC::AddParentForConsoleStartFunctor::AddParentForConsoleStartFunctor):
+ (JSC::AddParentForConsoleStartFunctor::operator()):
+ (JSC::ProfileGenerator::addParentForConsoleStart):
+ (JSC::ProfileGenerator::didExecute):
+ (JSC::StopProfilingFunctor::operator()):
+ (JSC::ProfileGenerator::stopProfiling):
+ (JSC::ProfileGenerator::removeProfileStart):
+ (JSC::ProfileGenerator::removeProfileEnd):
+ * profiler/ProfileGenerator.h:
+ * profiler/ProfileNode.cpp:
+ (JSC::ProfileNode::ProfileNode):
+ (JSC::ProfileNode::willExecute):
+ (JSC::ProfileNode::removeChild):
+ (JSC::ProfileNode::stopProfiling):
+ (JSC::ProfileNode::endAndRecordCall):
+ (JSC::ProfileNode::debugPrint):
+ (JSC::ProfileNode::debugPrintSampleStyle):
+ (JSC::ProfileNode::debugPrintRecursively):
+ (JSC::ProfileNode::debugPrintSampleStyleRecursively):
+ (JSC::ProfileNode::debugPrintData): Deleted.
+ (JSC::ProfileNode::debugPrintDataSampleStyle): Deleted.
+ * profiler/ProfileNode.h: Calculate per-node self and total times using a postorder traversal.
+ The forEachNodePostorder functor traverses the subtree rooted at |this|.
+ (JSC::ProfileNode::create):
+ (JSC::ProfileNode::calls):
+ (JSC::ProfileNode::forEachNodePostorder):
+ (JSC::CalculateProfileSubtreeDataFunctor::returnValue):
+ (JSC::CalculateProfileSubtreeDataFunctor::operator()):
+ (JSC::ProfileNode::head): Deleted.
+ (JSC::ProfileNode::setHead): Deleted.
+ (JSC::ProfileNode::totalTime): Deleted.
+ (JSC::ProfileNode::setTotalTime): Deleted.
+ (JSC::ProfileNode::selfTime): Deleted.
+ (JSC::ProfileNode::setSelfTime): Deleted.
+ (JSC::ProfileNode::totalPercent): Deleted.
+ (JSC::ProfileNode::selfPercent): Deleted.
+ * runtime/ConsoleClient.h: Remove header include.
+
+2014-09-02 Brian J. Burg <[email protected]>
+
Web Inspector: remove ProfilerAgent and legacy profiler files in the frontend
https://bugs.webkit.org/show_bug.cgi?id=136462
Modified: trunk/Source/_javascript_Core/jit/JIT.h (173198 => 173199)
--- trunk/Source/_javascript_Core/jit/JIT.h 2014-09-03 03:17:47 UTC (rev 173198)
+++ trunk/Source/_javascript_Core/jit/JIT.h 2014-09-03 04:58:55 UTC (rev 173199)
@@ -44,7 +44,6 @@
#include "JITDisassembler.h"
#include "JITInlineCacheGenerator.h"
#include "JSInterfaceJIT.h"
-#include "LegacyProfiler.h"
#include "Opcode.h"
#include "ResultType.h"
#include "SamplingTool.h"
Modified: trunk/Source/_javascript_Core/jit/JITCode.h (173198 => 173199)
--- trunk/Source/_javascript_Core/jit/JITCode.h 2014-09-03 03:17:47 UTC (rev 173198)
+++ trunk/Source/_javascript_Core/jit/JITCode.h 2014-09-03 04:58:55 UTC (rev 173199)
@@ -31,7 +31,6 @@
#include "Disassembler.h"
#include "JITStubs.h"
#include "JSCJSValue.h"
-#include "LegacyProfiler.h"
#include "MacroAssemblerCodeRef.h"
#include "RegisterPreservationMode.h"
Modified: trunk/Source/_javascript_Core/jit/JITOperations.cpp (173198 => 173199)
--- trunk/Source/_javascript_Core/jit/JITOperations.cpp 2014-09-03 03:17:47 UTC (rev 173198)
+++ trunk/Source/_javascript_Core/jit/JITOperations.cpp 2014-09-03 04:58:55 UTC (rev 173199)
@@ -43,13 +43,14 @@
#include "HostCallReturnValue.h"
#include "JIT.h"
#include "JITToDFGDeferredCompilationCallback.h"
+#include "JSCInlines.h"
#include "JSGlobalObjectFunctions.h"
#include "JSNameScope.h"
#include "JSPropertyNameEnumerator.h"
#include "JSStackInlines.h"
#include "JSWithScope.h"
+#include "LegacyProfiler.h"
#include "ObjectConstructor.h"
-#include "JSCInlines.h"
#include "Repatch.h"
#include "RepatchBuffer.h"
#include "TestRunnerUtils.h"
Modified: trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp (173198 => 173199)
--- trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp 2014-09-03 03:17:47 UTC (rev 173198)
+++ trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp 2014-09-03 04:58:55 UTC (rev 173199)
@@ -25,6 +25,7 @@
#include "config.h"
#include "LLIntSlowPaths.h"
+
#include "Arguments.h"
#include "ArrayConstructor.h"
#include "CallFrame.h"
@@ -38,6 +39,7 @@
#include "JIT.h"
#include "JITExceptions.h"
#include "JSActivation.h"
+#include "JSCInlines.h"
#include "JSCJSValue.h"
#include "JSGlobalObjectFunctions.h"
#include "JSNameScope.h"
@@ -46,9 +48,9 @@
#include "JSWithScope.h"
#include "LLIntCommon.h"
#include "LLIntExceptions.h"
+#include "LegacyProfiler.h"
#include "LowLevelInterpreter.h"
#include "ObjectConstructor.h"
-#include "JSCInlines.h"
#include "ProtoCallFrame.h"
#include "StructureRareDataInlines.h"
#include <wtf/StringPrintStream.h>
Modified: trunk/Source/_javascript_Core/profiler/Profile.cpp (173198 => 173199)
--- trunk/Source/_javascript_Core/profiler/Profile.cpp 2014-09-03 03:17:47 UTC (rev 173198)
+++ trunk/Source/_javascript_Core/profiler/Profile.cpp 2014-09-03 04:58:55 UTC (rev 173199)
@@ -39,38 +39,25 @@
Profile::Profile(const String& title, unsigned uid)
: m_title(title)
, m_uid(uid)
- , m_idleTime(0)
{
// FIXME: When multi-threading is supported this will be a vector and calls
// into the profiler will need to know which thread it is executing on.
- m_head = ProfileNode::create(0, CallIdentifier(ASCIILiteral("Thread_1"), String(), 0, 0), 0, 0);
+ m_rootNode = ProfileNode::create(nullptr, CallIdentifier(ASCIILiteral("Thread_1"), String(), 0, 0), nullptr);
}
Profile::~Profile()
{
}
-void Profile::forEach(void (ProfileNode::*function)())
-{
- ProfileNode* currentNode = m_head->firstChild();
- for (ProfileNode* nextNode = currentNode; nextNode; nextNode = nextNode->firstChild())
- currentNode = nextNode;
-
- if (!currentNode)
- currentNode = m_head.get();
-
- ProfileNode* endNode = m_head->traverseNextNodePostOrder();
- while (currentNode && currentNode != endNode) {
- (currentNode->*function)();
- currentNode = currentNode->traverseNextNodePostOrder();
- }
-}
-
#ifndef NDEBUG
-void Profile::debugPrintData() const
+void Profile::debugPrint()
{
+ CalculateProfileSubtreeDataFunctor functor;
+ m_rootNode->forEachNodePostorder(functor);
+ ProfileNode::ProfileSubtreeData data = ""
+
dataLogF("Call graph:\n");
- m_head->debugPrintData(0);
+ m_rootNode->debugPrintRecursively(0, data);
}
typedef WTF::KeyValuePair<FunctionCallHashCount::ValueType, unsigned> NameCountPair;
@@ -80,13 +67,17 @@
return a.value > b.value;
}
-void Profile::debugPrintDataSampleStyle() const
+void Profile::debugPrintSampleStyle()
{
typedef Vector<NameCountPair> NameCountPairVector;
+ CalculateProfileSubtreeDataFunctor functor;
+ m_rootNode->forEachNodePostorder(functor);
+ ProfileNode::ProfileSubtreeData data = ""
+
FunctionCallHashCount countedFunctions;
dataLogF("Call graph:\n");
- m_head->debugPrintDataSampleStyle(0, countedFunctions);
+ m_rootNode->debugPrintSampleStyleRecursively(0, countedFunctions, data);
dataLogF("\nTotal number in stack:\n");
NameCountPairVector sortedFunctions(countedFunctions.size());
Modified: trunk/Source/_javascript_Core/profiler/Profile.h (173198 => 173199)
--- trunk/Source/_javascript_Core/profiler/Profile.h 2014-09-03 03:17:47 UTC (rev 173198)
+++ trunk/Source/_javascript_Core/profiler/Profile.h 2014-09-03 04:58:55 UTC (rev 173199)
@@ -41,19 +41,12 @@
const String& title() const { return m_title; }
unsigned uid() const { return m_uid; }
- ProfileNode* head() const { return m_head.get(); }
- void setHead(PassRefPtr<ProfileNode> head) { m_head = head; }
+ ProfileNode* rootNode() const { return m_rootNode.get(); }
+ void setRootNode(PassRefPtr<ProfileNode> rootNode) { m_rootNode = rootNode; }
- double totalTime() const { return m_head->totalTime(); }
-
- double idleTime() const { return m_idleTime; }
- void setIdleTime(double idleTime) { m_idleTime = idleTime; }
-
- void forEach(void (ProfileNode::*)());
-
#ifndef NDEBUG
- void debugPrintData() const;
- void debugPrintDataSampleStyle() const;
+ void debugPrint();
+ void debugPrintSampleStyle();
#endif
protected:
@@ -64,9 +57,8 @@
void removeProfileEnd();
String m_title;
- RefPtr<ProfileNode> m_head;
+ RefPtr<ProfileNode> m_rootNode;
unsigned m_uid;
- double m_idleTime;
};
} // namespace JSC
Modified: trunk/Source/_javascript_Core/profiler/ProfileGenerator.cpp (173198 => 173199)
--- trunk/Source/_javascript_Core/profiler/ProfileGenerator.cpp 2014-09-03 03:17:47 UTC (rev 173198)
+++ trunk/Source/_javascript_Core/profiler/ProfileGenerator.cpp 2014-09-03 04:58:55 UTC (rev 173199)
@@ -50,18 +50,18 @@
, m_foundConsoleStartParent(false)
{
m_profile = Profile::create(title, uid);
- m_currentNode = m_head = m_profile->head();
+ m_currentNode = m_rootNode = m_profile->rootNode();
if (exec)
addParentForConsoleStart(exec);
}
class AddParentForConsoleStartFunctor {
public:
- AddParentForConsoleStartFunctor(ExecState* exec, RefPtr<ProfileNode>& head, RefPtr<ProfileNode>& currentNode)
+ AddParentForConsoleStartFunctor(ExecState* exec, RefPtr<ProfileNode>& rootNode, RefPtr<ProfileNode>& currentNode)
: m_exec(exec)
, m_hasSkippedFirstFrame(false)
, m_foundParent(false)
- , m_head(head)
+ , m_rootNode(rootNode)
, m_currentNode(currentNode)
{
}
@@ -78,8 +78,8 @@
unsigned line = 0;
unsigned column = 0;
visitor->computeLineAndColumn(line, column);
- m_currentNode = ProfileNode::create(m_exec, LegacyProfiler::createCallIdentifier(m_exec, visitor->callee(), visitor->sourceURL(), line, column), m_head.get(), m_head.get());
- m_head->insertNode(m_currentNode.get());
+ m_currentNode = ProfileNode::create(m_exec, LegacyProfiler::createCallIdentifier(m_exec, visitor->callee(), visitor->sourceURL(), line, column), m_rootNode.get());
+ m_rootNode->insertNode(m_currentNode.get());
m_foundParent = true;
return StackVisitor::Done;
@@ -88,14 +88,14 @@
private:
ExecState* m_exec;
bool m_hasSkippedFirstFrame;
- bool m_foundParent;
- RefPtr<ProfileNode>& m_head;
+ bool m_foundParent;
+ RefPtr<ProfileNode>& m_rootNode;
RefPtr<ProfileNode>& m_currentNode;
};
void ProfileGenerator::addParentForConsoleStart(ExecState* exec)
{
- AddParentForConsoleStartFunctor functor(exec, m_head, m_currentNode);
+ AddParentForConsoleStartFunctor functor(exec, m_rootNode, m_currentNode);
exec->iterate(functor);
m_foundConsoleStartParent = functor.foundParent();
@@ -134,7 +134,7 @@
ASSERT(m_currentNode);
if (m_currentNode->callIdentifier() != callIdentifier) {
- RefPtr<ProfileNode> returningNode = ProfileNode::create(callerCallFrame, callIdentifier, m_head.get(), m_currentNode.get());
+ RefPtr<ProfileNode> returningNode = ProfileNode::create(callerCallFrame, callIdentifier, m_currentNode.get());
returningNode->lastCall().setStartTime(m_currentNode->lastCall().startTime());
returningNode->didExecute();
m_currentNode->insertNode(returningNode.release());
@@ -155,9 +155,16 @@
}
}
+struct StopProfilingFunctor {
+ void operator()(ProfileNode* node) { node->stopProfiling(); }
+};
+
void ProfileGenerator::stopProfiling()
{
- m_profile->forEach(&ProfileNode::stopProfiling);
+ // FIXME: we shouldn't need a full traversal here, since only the spine from
+ // m_currentNode to m_rootNode should have any nodes currently accruing time.
+ StopProfilingFunctor functor;
+ m_profile->rootNode()->forEachNodePostorder(functor);
if (m_foundConsoleStartParent) {
removeProfileStart();
@@ -169,25 +176,18 @@
// Set the current node to the parent, because we are in a call that
// will not get didExecute call.
m_currentNode = m_currentNode->parent();
-
- if (double headSelfTime = m_head->selfTime()) {
- m_head->setSelfTime(0.0);
- m_profile->setIdleTime(headSelfTime);
- }
}
// The console.profile that started this ProfileGenerator will be the first child.
void ProfileGenerator::removeProfileStart()
{
ProfileNode* currentNode = 0;
- for (ProfileNode* next = m_head.get(); next; next = next->firstChild())
+ for (ProfileNode* next = m_rootNode.get(); next; next = next->firstChild())
currentNode = next;
if (currentNode->callIdentifier().functionName() != "profile")
return;
- // Attribute the time of the node aobut to be removed to the self time of its parent
- currentNode->parent()->setSelfTime(currentNode->parent()->selfTime() + currentNode->totalTime());
currentNode->parent()->removeChild(currentNode);
}
@@ -195,15 +195,12 @@
void ProfileGenerator::removeProfileEnd()
{
ProfileNode* currentNode = 0;
- for (ProfileNode* next = m_head.get(); next; next = next->lastChild())
+ for (ProfileNode* next = m_rootNode.get(); next; next = next->lastChild())
currentNode = next;
if (currentNode->callIdentifier().functionName() != "profileEnd")
return;
- // Attribute the time of the node aobut to be removed to the self time of its parent
- currentNode->parent()->setSelfTime(currentNode->parent()->selfTime() + currentNode->totalTime());
-
ASSERT(currentNode->callIdentifier() == (currentNode->parent()->children()[currentNode->parent()->children().size() - 1])->callIdentifier());
currentNode->parent()->removeChild(currentNode);
}
Modified: trunk/Source/_javascript_Core/profiler/ProfileGenerator.h (173198 => 173199)
--- trunk/Source/_javascript_Core/profiler/ProfileGenerator.h 2014-09-03 03:17:47 UTC (rev 173198)
+++ trunk/Source/_javascript_Core/profiler/ProfileGenerator.h 2014-09-03 04:58:55 UTC (rev 173199)
@@ -22,7 +22,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-
+
#ifndef ProfileGenerator_h
#define ProfileGenerator_h
@@ -37,7 +37,7 @@
class JSGlobalObject;
class Profile;
class ProfileNode;
- struct CallIdentifier;
+ struct CallIdentifier;
class ProfileGenerator : public RefCounted<ProfileGenerator> {
public:
@@ -70,7 +70,7 @@
RefPtr<Profile> m_profile;
JSGlobalObject* m_origin;
unsigned m_profileGroup;
- RefPtr<ProfileNode> m_head;
+ RefPtr<ProfileNode> m_rootNode;
RefPtr<ProfileNode> m_currentNode;
bool m_foundConsoleStartParent;
};
Modified: trunk/Source/_javascript_Core/profiler/ProfileNode.cpp (173198 => 173199)
--- trunk/Source/_javascript_Core/profiler/ProfileNode.cpp 2014-09-03 03:17:47 UTC (rev 173198)
+++ trunk/Source/_javascript_Core/profiler/ProfileNode.cpp 2014-09-03 04:58:55 UTC (rev 173199)
@@ -38,26 +38,20 @@
namespace JSC {
-ProfileNode::ProfileNode(ExecState* callerCallFrame, const CallIdentifier& callIdentifier, ProfileNode* headNode, ProfileNode* parentNode)
+ProfileNode::ProfileNode(ExecState* callerCallFrame, const CallIdentifier& callIdentifier, ProfileNode* parentNode)
: m_callerCallFrame(callerCallFrame)
, m_callIdentifier(callIdentifier)
- , m_head(headNode)
, m_parent(parentNode)
, m_nextSibling(nullptr)
- , m_totalTime(0)
- , m_selfTime(0)
{
startTimer();
}
-ProfileNode::ProfileNode(ExecState* callerCallFrame, ProfileNode* headNode, ProfileNode* nodeToCopy)
+ProfileNode::ProfileNode(ExecState* callerCallFrame, ProfileNode* nodeToCopy)
: m_callerCallFrame(callerCallFrame)
, m_callIdentifier(nodeToCopy->callIdentifier())
- , m_head(headNode)
, m_parent(nodeToCopy->parent())
- , m_nextSibling(0)
- , m_totalTime(nodeToCopy->totalTime())
- , m_selfTime(nodeToCopy->selfTime())
+ , m_nextSibling(nullptr)
, m_calls(nodeToCopy->calls())
{
}
@@ -71,7 +65,7 @@
}
}
- RefPtr<ProfileNode> newChild = ProfileNode::create(callerCallFrame, callIdentifier, m_head ? m_head : this, this); // If this ProfileNode has no head it is the head.
+ RefPtr<ProfileNode> newChild = ProfileNode::create(callerCallFrame, callIdentifier, this);
if (m_children.size())
m_children.last()->setNextSibling(newChild.get());
m_children.append(newChild.release());
@@ -104,7 +98,7 @@
break;
}
}
-
+
resetChildrensSiblings();
}
@@ -125,13 +119,6 @@
if (isnan(m_calls.last().totalTime()))
endAndRecordCall();
-
- // Because we iterate in post order all of our children have been stopped before us.
- for (unsigned i = 0; i < m_children.size(); ++i)
- m_selfTime += m_children[i]->totalTime();
-
- ASSERT(m_selfTime <= m_totalTime);
- m_selfTime = m_totalTime - m_selfTime;
}
ProfileNode* ProfileNode::traverseNextNodePostOrder() const
@@ -150,8 +137,6 @@
ASSERT(isnan(last.totalTime()));
last.setTotalTime(currentTime() - last.startTime());
-
- m_totalTime += last.totalTime();
}
void ProfileNode::startTimer()
@@ -167,32 +152,63 @@
}
#ifndef NDEBUG
-void ProfileNode::debugPrintData(int indentLevel) const
+void ProfileNode::debugPrint()
{
+ CalculateProfileSubtreeDataFunctor functor;
+ forEachNodePostorder(functor);
+ ProfileNode::ProfileSubtreeData data = ""
+
+ debugPrintRecursively(0, data);
+}
+
+void ProfileNode::debugPrintSampleStyle()
+{
+ FunctionCallHashCount countedFunctions;
+
+ CalculateProfileSubtreeDataFunctor functor;
+ forEachNodePostorder(functor);
+ ProfileNode::ProfileSubtreeData data = ""
+
+ debugPrintSampleStyleRecursively(0, countedFunctions, data);
+}
+
+void ProfileNode::debugPrintRecursively(int indentLevel, const ProfileSubtreeData& data)
+{
// Print function names
for (int i = 0; i < indentLevel; ++i)
dataLogF(" ");
+ auto it = data.selfAndTotalTimes.find(this);
+ ASSERT(it != data.selfAndTotalTimes.end());
+
+ double nodeSelfTime = it->value.first;
+ double nodeTotalTime = it->value.second;
+ double rootTotalTime = data.rootTotalTime;
+
dataLogF("Function Name %s %zu SelfTime %.3fms/%.3f%% TotalTime %.3fms/%.3f%% Next Sibling %s\n",
functionName().utf8().data(),
- numberOfCalls(), m_selfTime, selfPercent(), m_totalTime, totalPercent(),
+ numberOfCalls(), nodeSelfTime, nodeSelfTime / rootTotalTime * 100.0, nodeTotalTime, nodeTotalTime / rootTotalTime * 100.0,
m_nextSibling ? m_nextSibling->functionName().utf8().data() : "");
++indentLevel;
// Print children's names and information
for (StackIterator currentChild = m_children.begin(); currentChild != m_children.end(); ++currentChild)
- (*currentChild)->debugPrintData(indentLevel);
+ (*currentChild)->debugPrintRecursively(indentLevel, data);
}
// print the profiled data in a format that matches the tool sample's output.
-double ProfileNode::debugPrintDataSampleStyle(int indentLevel, FunctionCallHashCount& countedFunctions) const
+double ProfileNode::debugPrintSampleStyleRecursively(int indentLevel, FunctionCallHashCount& countedFunctions, const ProfileSubtreeData& data)
{
dataLogF(" ");
+ auto it = data.selfAndTotalTimes.find(this);
+ ASSERT(it != data.selfAndTotalTimes.end());
+ double nodeTotalTime = it->value.second;
+
// Print function names
const char* name = functionName().utf8().data();
- double sampleCount = m_totalTime * 1000;
+ double sampleCount = nodeTotalTime * 1000;
if (indentLevel) {
for (int i = 0; i < indentLevel; ++i)
dataLogF(" ");
@@ -208,7 +224,7 @@
// Print children's names and information
double sumOfChildrensCount = 0.0;
for (StackIterator currentChild = m_children.begin(); currentChild != m_children.end(); ++currentChild)
- sumOfChildrensCount += (*currentChild)->debugPrintDataSampleStyle(indentLevel, countedFunctions);
+ sumOfChildrensCount += (*currentChild)->debugPrintSampleStyleRecursively(indentLevel, countedFunctions, data);
sumOfChildrensCount *= 1000; //
// Print remainder of samples to match sample's output
@@ -220,7 +236,7 @@
dataLogF("%.0f %s\n", sampleCount - sumOfChildrensCount, functionName().utf8().data());
}
- return m_totalTime;
+ return nodeTotalTime;
}
#endif
Modified: trunk/Source/_javascript_Core/profiler/ProfileNode.h (173198 => 173199)
--- trunk/Source/_javascript_Core/profiler/ProfileNode.h 2014-09-03 03:17:47 UTC (rev 173198)
+++ trunk/Source/_javascript_Core/profiler/ProfileNode.h 2014-09-03 04:58:55 UTC (rev 173199)
@@ -44,14 +44,14 @@
class ProfileNode : public RefCounted<ProfileNode> {
public:
- static PassRefPtr<ProfileNode> create(ExecState* callerCallFrame, const CallIdentifier& callIdentifier, ProfileNode* headNode, ProfileNode* parentNode)
+ static PassRefPtr<ProfileNode> create(ExecState* callerCallFrame, const CallIdentifier& callIdentifier, ProfileNode* parentNode)
{
- return adoptRef(new ProfileNode(callerCallFrame, callIdentifier, headNode, parentNode));
+ return adoptRef(new ProfileNode(callerCallFrame, callIdentifier, parentNode));
}
- static PassRefPtr<ProfileNode> create(ExecState* callerCallFrame, ProfileNode* headNode, ProfileNode* node)
+ static PassRefPtr<ProfileNode> create(ExecState* callerCallFrame, ProfileNode* node)
{
- return adoptRef(new ProfileNode(callerCallFrame, headNode, node));
+ return adoptRef(new ProfileNode(callerCallFrame, node));
}
struct Call {
@@ -90,26 +90,13 @@
unsigned columnNumber() const { return m_callIdentifier.columnNumber(); }
// Relationships
- ProfileNode* head() const { return m_head; }
- void setHead(ProfileNode* head) { m_head = head; }
-
ProfileNode* parent() const { return m_parent; }
void setParent(ProfileNode* parent) { m_parent = parent; }
ProfileNode* nextSibling() const { return m_nextSibling; }
void setNextSibling(ProfileNode* nextSibling) { m_nextSibling = nextSibling; }
- // Time members
- double totalTime() const { return m_totalTime; }
- void setTotalTime(double time) { m_totalTime = time; }
-
- double selfTime() const { return m_selfTime; }
- void setSelfTime(double time) { m_selfTime = time; }
-
- double totalPercent() const { return (m_totalTime / (m_head ? m_head->totalTime() : totalTime())) * 100.0; }
- double selfPercent() const { return (m_selfTime / (m_head ? m_head->totalTime() : totalTime())) * 100.0; }
-
- Vector<Call> calls() const { return m_calls; }
+ const Vector<Call>& calls() const { return m_calls; }
Call& lastCall() { ASSERT(!m_calls.isEmpty()); return m_calls.last(); }
size_t numberOfCalls() const { return m_calls.size(); }
@@ -121,37 +108,85 @@
void addChild(PassRefPtr<ProfileNode> prpChild);
void insertNode(PassRefPtr<ProfileNode> prpNode);
- ProfileNode* traverseNextNodePostOrder() const;
+ template <typename Functor> void forEachNodePostorder(Functor&);
#ifndef NDEBUG
+ struct ProfileSubtreeData {
+ HashMap<ProfileNode*, std::pair<double, double>> selfAndTotalTimes;
+ double rootTotalTime;
+ };
+
const char* c_str() const { return m_callIdentifier; }
- void debugPrintData(int indentLevel) const;
- double debugPrintDataSampleStyle(int indentLevel, FunctionCallHashCount&) const;
+ // Use these functions to dump the subtree rooted at this node.
+ void debugPrint();
+ void debugPrintSampleStyle();
+
+ // These are used to recursively print entire subtrees using precomputed self and total times.
+ void debugPrintRecursively(int indentLevel, const ProfileSubtreeData&);
+ double debugPrintSampleStyleRecursively(int indentLevel, FunctionCallHashCount&, const ProfileSubtreeData&);
#endif
private:
typedef Vector<RefPtr<ProfileNode>>::const_iterator StackIterator;
- ProfileNode(ExecState* callerCallFrame, const CallIdentifier&, ProfileNode* headNode, ProfileNode* parentNode);
- ProfileNode(ExecState* callerCallFrame, ProfileNode* headNode, ProfileNode* nodeToCopy);
+ ProfileNode(ExecState* callerCallFrame, const CallIdentifier&, ProfileNode* parentNode);
+ ProfileNode(ExecState* callerCallFrame, ProfileNode* nodeToCopy);
void startTimer();
void resetChildrensSiblings();
void endAndRecordCall();
+ ProfileNode* traverseNextNodePostOrder() const;
ExecState* m_callerCallFrame;
CallIdentifier m_callIdentifier;
- ProfileNode* m_head;
ProfileNode* m_parent;
ProfileNode* m_nextSibling;
- double m_totalTime;
- double m_selfTime;
-
- Vector<Call, 1> m_calls;
+ Vector<Call> m_calls;
Vector<RefPtr<ProfileNode>> m_children;
};
+ template <typename Functor> inline void ProfileNode::forEachNodePostorder(Functor& functor)
+ {
+ ProfileNode* currentNode = this;
+ // Go down to the first node of the traversal, and slowly walk back up.
+ for (ProfileNode* nextNode = currentNode; nextNode; nextNode = nextNode->firstChild())
+ currentNode = nextNode;
+
+ ProfileNode* endNode = this;
+ while (currentNode && currentNode != endNode) {
+ functor(currentNode);
+ currentNode = currentNode->traverseNextNodePostOrder();
+ }
+
+ functor(endNode);
+ }
+
+#ifndef NDEBUG
+ struct CalculateProfileSubtreeDataFunctor {
+ void operator()(ProfileNode* node)
+ {
+ double selfTime = 0.0;
+ for (const ProfileNode::Call& call : node->calls())
+ selfTime += call.totalTime();
+
+ double totalTime = selfTime;
+ for (RefPtr<ProfileNode> child : node->children()) {
+ auto it = m_data.selfAndTotalTimes.find(child.get());
+ if (it != m_data.selfAndTotalTimes.end())
+ totalTime += it->value.second;
+ }
+
+ ASSERT(node);
+ m_data.selfAndTotalTimes.set(node, std::make_pair(selfTime, totalTime));
+ }
+
+ ProfileNode::ProfileSubtreeData returnValue() { return WTF::move(m_data); }
+
+ ProfileNode::ProfileSubtreeData m_data;
+ };
+#endif
+
} // namespace JSC
#endif // ProfileNode_h
Modified: trunk/Source/_javascript_Core/runtime/ConsoleClient.h (173198 => 173199)
--- trunk/Source/_javascript_Core/runtime/ConsoleClient.h 2014-09-03 03:17:47 UTC (rev 173198)
+++ trunk/Source/_javascript_Core/runtime/ConsoleClient.h 2014-09-03 04:58:55 UTC (rev 173199)
@@ -27,7 +27,6 @@
#define ConsoleClient_h
#include "ConsoleTypes.h"
-#include "Profile.h"
#include <wtf/Forward.h>
namespace Inspector {
Modified: trunk/Source/WebCore/ChangeLog (173198 => 173199)
--- trunk/Source/WebCore/ChangeLog 2014-09-03 03:17:47 UTC (rev 173198)
+++ trunk/Source/WebCore/ChangeLog 2014-09-03 04:58:55 UTC (rev 173199)
@@ -1,5 +1,20 @@
2014-09-02 Brian J. Burg <[email protected]>
+ LegacyProfiler: remove redundant ProfileNode members and other cleanup
+ https://bugs.webkit.org/show_bug.cgi?id=136380
+
+ Reviewed by Timothy Hatcher.
+
+ Remove Profile.idleTime, rename head to rootNode, and remove ProfileNode members.
+
+ Covered by existing tests.
+
+ * inspector/ScriptProfile.idl:
+ * inspector/ScriptProfileNode.idl:
+ * inspector/TimelineRecordFactory.cpp:
+
+2014-09-02 Brian J. Burg <[email protected]>
+
Web Inspector: remove ProfilerAgent and legacy profiler files in the frontend
https://bugs.webkit.org/show_bug.cgi?id=136462
Modified: trunk/Source/WebCore/inspector/ScriptProfile.idl (173198 => 173199)
--- trunk/Source/WebCore/inspector/ScriptProfile.idl 2014-09-03 03:17:47 UTC (rev 173198)
+++ trunk/Source/WebCore/inspector/ScriptProfile.idl 2014-09-03 04:58:55 UTC (rev 173199)
@@ -30,7 +30,6 @@
] interface ScriptProfile {
readonly attribute DOMString title;
readonly attribute unsigned long uid;
- readonly attribute ScriptProfileNode head;
- readonly attribute unrestricted double idleTime;
+ readonly attribute ScriptProfileNode rootNode;
};
Modified: trunk/Source/WebCore/inspector/ScriptProfileNode.idl (173198 => 173199)
--- trunk/Source/WebCore/inspector/ScriptProfileNode.idl 2014-09-03 03:17:47 UTC (rev 173198)
+++ trunk/Source/WebCore/inspector/ScriptProfileNode.idl 2014-09-03 04:58:55 UTC (rev 173199)
@@ -36,9 +36,6 @@
readonly attribute unsigned long lineNumber;
readonly attribute unsigned long columnNumber;
- readonly attribute unrestricted double totalTime;
- readonly attribute unrestricted double selfTime;
-
readonly attribute unsigned long numberOfCalls;
sequence<ScriptProfileNode> children();
Modified: trunk/Source/WebCore/inspector/TimelineRecordFactory.cpp (173198 => 173199)
--- trunk/Source/WebCore/inspector/TimelineRecordFactory.cpp 2014-09-03 03:17:47 UTC (rev 173198)
+++ trunk/Source/WebCore/inspector/TimelineRecordFactory.cpp 2014-09-03 04:58:55 UTC (rev 173199)
@@ -310,15 +310,12 @@
static PassRefPtr<Protocol::Timeline::CPUProfile> buildProfileInspectorObject(const JSC::Profile* profile)
{
RefPtr<Protocol::Array<Protocol::Timeline::CPUProfileNode>> rootNodes = Protocol::Array<Protocol::Timeline::CPUProfileNode>::create();
- for (RefPtr<JSC::ProfileNode> profileNode : profile->head()->children())
+ for (RefPtr<JSC::ProfileNode> profileNode : profile->rootNode()->children())
rootNodes->addItem(buildInspectorObject(profileNode.get()));
RefPtr<Protocol::Timeline::CPUProfile> result = Protocol::Timeline::CPUProfile::create()
.setRootNodes(rootNodes);
- if (profile->idleTime())
- result->setIdleTime(profile->idleTime());
-
return result.release();
}
Modified: trunk/Source/WebInspectorUI/ChangeLog (173198 => 173199)
--- trunk/Source/WebInspectorUI/ChangeLog 2014-09-03 03:17:47 UTC (rev 173198)
+++ trunk/Source/WebInspectorUI/ChangeLog 2014-09-03 04:58:55 UTC (rev 173199)
@@ -1,5 +1,19 @@
2014-09-02 Brian J. Burg <[email protected]>
+ LegacyProfiler: remove redundant ProfileNode members and other cleanup
+ https://bugs.webkit.org/show_bug.cgi?id=136380
+
+ Reviewed by Timothy Hatcher.
+
+ Remove unused Profile.idleTime member.
+
+ * UserInterface/Models/Profile.js:
+ (WebInspector.Profile.prototype.get idleTime): Deleted.
+ * UserInterface/Models/ScriptTimelineRecord.js:
+ (WebInspector.ScriptTimelineRecord.prototype._initializeProfileFromPayload):
+
+2014-09-02 Brian J. Burg <[email protected]>
+
Web Inspector: remove ProfilerAgent and legacy profiler files in the frontend
https://bugs.webkit.org/show_bug.cgi?id=136462
Modified: trunk/Source/WebInspectorUI/UserInterface/Models/Profile.js (173198 => 173199)
--- trunk/Source/WebInspectorUI/UserInterface/Models/Profile.js 2014-09-03 03:17:47 UTC (rev 173198)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/Profile.js 2014-09-03 04:58:55 UTC (rev 173199)
@@ -23,7 +23,7 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
-WebInspector.Profile = "" idleTime)
+WebInspector.Profile = ""
{
WebInspector.Object.call(this);
@@ -33,7 +33,6 @@
console.assert(topDownRootNodes.reduce(function(previousValue, node) { return previousValue && node instanceof WebInspector.ProfileNode; }, true));
this._topDownRootNodes = topDownRootNodes;
- this._idleTime = idleTime || 0;
};
WebInspector.Profile.prototype = {
@@ -42,11 +41,6 @@
// Public
- get idleTime()
- {
- return this._idleTime;
- },
-
get topDownRootNodes()
{
return this._topDownRootNodes;
Modified: trunk/Source/WebInspectorUI/UserInterface/Models/ScriptTimelineRecord.js (173198 => 173199)
--- trunk/Source/WebInspectorUI/UserInterface/Models/ScriptTimelineRecord.js 2014-09-03 03:17:47 UTC (rev 173198)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/ScriptTimelineRecord.js 2014-09-03 04:58:55 UTC (rev 173199)
@@ -346,7 +346,7 @@
}
}
- this._profile = new WebInspector.Profile(rootNodes, payload.idleTime);
+ this._profile = new WebInspector.Profile(rootNodes);
}
};