18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2008 Apple Inc. All rights reserved.
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Redistribution and use in source and binary forms, with or without
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modification, are permitted provided that the following conditions
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * are met:
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 1.  Redistributions of source code must retain the above copyright
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *     notice, this list of conditions and the following disclaimer.
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 2.  Redistributions in binary form must reproduce the above copyright
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *     notice, this list of conditions and the following disclaimer in the
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *     documentation and/or other materials provided with the distribution.
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *     its contributors may be used to endorse or promote products derived
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *     from this software without specific prior written permission.
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h"
308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "ProfileNode.h"
318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Profiler.h"
338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <stdio.h>
345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include <wtf/DateMath.h>
35dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include <wtf/text/StringHash.h>
368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
37d0825bca7fe65beaee391d30da42e937db621564Steve Block#if OS(WINDOWS)
388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <windows.h>
398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
41643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockusing namespace WTF;
42643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace JSC {
448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic double getCount()
468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
47d0825bca7fe65beaee391d30da42e937db621564Steve Block#if OS(WINDOWS)
48e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    static LARGE_INTEGER frequency;
498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!frequency.QuadPart)
508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        QueryPerformanceFrequency(&frequency);
518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    LARGE_INTEGER counter;
528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    QueryPerformanceCounter(&counter);
538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return static_cast<double>(counter.QuadPart) / frequency.QuadPart;
548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#else
55643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return currentTimeMS();
568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
594576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) WangProfileNode::ProfileNode(ExecState* callerCallFrame, const CallIdentifier& callIdentifier, ProfileNode* headNode, ProfileNode* parentNode)
604576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    : m_callerCallFrame(callerCallFrame)
614576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    , m_callIdentifier(callIdentifier)
628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_head(headNode)
638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_parent(parentNode)
648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_nextSibling(0)
658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_startTime(0.0)
668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_actualTotalTime(0.0)
678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_visibleTotalTime(0.0)
688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_actualSelfTime(0.0)
698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_visibleSelfTime(0.0)
708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_numberOfCalls(0)
718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_visible(true)
728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    startTimer();
748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
764576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) WangProfileNode::ProfileNode(ExecState* callerCallFrame, ProfileNode* headNode, ProfileNode* nodeToCopy)
774576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    : m_callerCallFrame(callerCallFrame)
784576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    , m_callIdentifier(nodeToCopy->callIdentifier())
798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_head(headNode)
808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_parent(nodeToCopy->parent())
818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_nextSibling(0)
828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_startTime(0.0)
838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_actualTotalTime(nodeToCopy->actualTotalTime())
848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_visibleTotalTime(nodeToCopy->totalTime())
858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_actualSelfTime(nodeToCopy->actualSelfTime())
868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_visibleSelfTime(nodeToCopy->selfTime())
878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_numberOfCalls(nodeToCopy->numberOfCalls())
888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_visible(nodeToCopy->visible())
898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
924576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) WangProfileNode* ProfileNode::willExecute(ExecState* callerCallFrame, const CallIdentifier& callIdentifier)
938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (StackIterator currentChild = m_children.begin(); currentChild != m_children.end(); ++currentChild) {
958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if ((*currentChild)->callIdentifier() == callIdentifier) {
968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            (*currentChild)->startTimer();
978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return (*currentChild).get();
988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1014576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    RefPtr<ProfileNode> newChild = ProfileNode::create(callerCallFrame, callIdentifier, m_head ? m_head : this, this); // If this ProfileNode has no head it is the head.
1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_children.size())
1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_children.last()->setNextSibling(newChild.get());
1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_children.append(newChild.release());
1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return m_children.last().get();
1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectProfileNode* ProfileNode::didExecute()
1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    endAndRecordCall();
1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return m_parent;
1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ProfileNode::addChild(PassRefPtr<ProfileNode> prpChild)
1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<ProfileNode> child = prpChild;
1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    child->setParent(this);
1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_children.size())
1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_children.last()->setNextSibling(child.get());
1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_children.append(child.release());
1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectProfileNode* ProfileNode::findChild(ProfileNode* node) const
1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!node)
1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (size_t i = 0; i < m_children.size(); ++i) {
1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (*node == m_children[i].get())
1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return m_children[i].get();
1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return 0;
1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ProfileNode::removeChild(ProfileNode* node)
1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!node)
1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (size_t i = 0; i < m_children.size(); ++i) {
1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (*node == m_children[i].get()) {
1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_children.remove(i);
1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    resetChildrensSiblings();
1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ProfileNode::insertNode(PassRefPtr<ProfileNode> prpNode)
1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<ProfileNode> node = prpNode;
1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (unsigned i = 0; i < m_children.size(); ++i)
1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        node->addChild(m_children[i].release());
1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_children.clear();
1598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_children.append(node.release());
1608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ProfileNode::stopProfiling()
1638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_startTime)
1658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        endAndRecordCall();
1668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_visibleTotalTime = m_actualTotalTime;
1688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(m_actualSelfTime == 0.0 && m_startTime == 0.0);
1708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Because we iterate in post order all of our children have been stopped before us.
1728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (unsigned i = 0; i < m_children.size(); ++i)
1738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_actualSelfTime += m_children[i]->totalTime();
1748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(m_actualSelfTime <= m_actualTotalTime);
1768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_actualSelfTime = m_actualTotalTime - m_actualSelfTime;
1778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_visibleSelfTime = m_actualSelfTime;
1788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectProfileNode* ProfileNode::traverseNextNodePostOrder() const
1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ProfileNode* next = m_nextSibling;
1838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!next)
1848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return m_parent;
1858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (ProfileNode* firstChild = next->firstChild())
1868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        next = firstChild;
1878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return next;
1888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectProfileNode* ProfileNode::traverseNextNodePreOrder(bool processChildren) const
1918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (processChildren && m_children.size())
1938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return m_children[0].get();
1948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_nextSibling)
1968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return m_nextSibling;
1978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ProfileNode* nextParent = m_parent;
1998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!nextParent)
2008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
2018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ProfileNode* next;
2038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (next = m_parent->nextSibling(); !next; next = nextParent->nextSibling()) {
2048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        nextParent = nextParent->parent();
2058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!nextParent)
2068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return 0;
2078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return next;
2108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ProfileNode::setTreeVisible(ProfileNode* node, bool visible)
2138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ProfileNode* nodeParent = node->parent();
2158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ProfileNode* nodeSibling = node->nextSibling();
2168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    node->setParent(0);
2178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    node->setNextSibling(0);
2188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (ProfileNode* currentNode = node; currentNode; currentNode = currentNode->traverseNextNodePreOrder())
2208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        currentNode->setVisible(visible);
2218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    node->setParent(nodeParent);
2238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    node->setNextSibling(nodeSibling);
2248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ProfileNode::calculateVisibleTotalTime()
2278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    double sumOfVisibleChildrensTime = 0.0;
2298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (unsigned i = 0; i < m_children.size(); ++i) {
2318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (m_children[i]->visible())
2328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            sumOfVisibleChildrensTime += m_children[i]->totalTime();
2338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_visibleTotalTime = m_visibleSelfTime + sumOfVisibleChildrensTime;
2368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool ProfileNode::focus(const CallIdentifier& callIdentifier)
2398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_visible)
2418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
2428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_callIdentifier != callIdentifier) {
2448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_visible = false;
2458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return true;
2468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (ProfileNode* currentParent = m_parent; currentParent; currentParent = currentParent->parent())
2498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        currentParent->setVisible(true);
2508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return false;
2528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ProfileNode::exclude(const CallIdentifier& callIdentifier)
2558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_visible && m_callIdentifier == callIdentifier) {
2578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        setTreeVisible(this, false);
2588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_parent->setVisibleSelfTime(m_parent->selfTime() + m_visibleTotalTime);
2608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ProfileNode::restore()
2648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_visibleTotalTime = m_actualTotalTime;
2668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_visibleSelfTime = m_actualSelfTime;
2678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_visible = true;
2688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ProfileNode::endAndRecordCall()
2718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_actualTotalTime += m_startTime ? getCount() - m_startTime : 0.0;
2738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_startTime = 0.0;
2748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ++m_numberOfCalls;
2768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ProfileNode::startTimer()
2798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_startTime)
2818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_startTime = getCount();
2828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ProfileNode::resetChildrensSiblings()
2858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    unsigned size = m_children.size();
2878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (unsigned i = 0; i < size; ++i)
2888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_children[i]->setNextSibling(i + 1 == size ? 0 : m_children[i + 1].get());
2898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifndef NDEBUG
2928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ProfileNode::debugPrintData(int indentLevel) const
2938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Print function names
2958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (int i = 0; i < indentLevel; ++i)
2968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        printf("  ");
2978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    printf("Function Name %s %d SelfTime %.3fms/%.3f%% TotalTime %.3fms/%.3f%% VSelf %.3fms VTotal %.3fms Visible %s Next Sibling %s\n",
299f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        functionName().utf8().data(),
3008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_numberOfCalls, m_actualSelfTime, selfPercent(), m_actualTotalTime, totalPercent(),
3018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_visibleSelfTime, m_visibleTotalTime,
3028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        (m_visible ? "True" : "False"),
303f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        m_nextSibling ? m_nextSibling->functionName().utf8().data() : "");
3048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ++indentLevel;
3068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Print children's names and information
3088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (StackIterator currentChild = m_children.begin(); currentChild != m_children.end(); ++currentChild)
3098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        (*currentChild)->debugPrintData(indentLevel);
3108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// print the profiled data in a format that matches the tool sample's output.
3138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectdouble ProfileNode::debugPrintDataSampleStyle(int indentLevel, FunctionCallHashCount& countedFunctions) const
3148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    printf("    ");
3168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Print function names
318f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    const char* name = functionName().utf8().data();
3198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    double sampleCount = m_actualTotalTime * 1000;
3208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (indentLevel) {
3218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        for (int i = 0; i < indentLevel; ++i)
3228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            printf("  ");
3238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
324f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick         countedFunctions.add(functionName().impl());
3258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        printf("%.0f %s\n", sampleCount ? sampleCount : 1, name);
3278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else
3288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        printf("%s\n", name);
3298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ++indentLevel;
3318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Print children's names and information
3338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    double sumOfChildrensCount = 0.0;
3348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (StackIterator currentChild = m_children.begin(); currentChild != m_children.end(); ++currentChild)
3358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        sumOfChildrensCount += (*currentChild)->debugPrintDataSampleStyle(indentLevel, countedFunctions);
3368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    sumOfChildrensCount *= 1000;    //
3388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Print remainder of samples to match sample's output
3398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (sumOfChildrensCount < sampleCount) {
3408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        printf("    ");
3418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        while (indentLevel--)
3428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            printf("  ");
3438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
344f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        printf("%.0f %s\n", sampleCount - sumOfChildrensCount, functionName().utf8().data());
3458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return m_actualTotalTime;
3488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
3508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace JSC
352