ProfileNode.cpp revision 643ca7872b450ea4efacab6188849e5aac2ba161
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>
358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if PLATFORM(WIN_OS)
378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <windows.h>
388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
40643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockusing namespace WTF;
41643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace JSC {
438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic double getCount()
458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if PLATFORM(WIN_OS)
478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    static LARGE_INTEGER frequency = {0};
488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!frequency.QuadPart)
498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        QueryPerformanceFrequency(&frequency);
508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    LARGE_INTEGER counter;
518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    QueryPerformanceCounter(&counter);
528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return static_cast<double>(counter.QuadPart) / frequency.QuadPart;
538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#else
54643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return currentTimeMS();
558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectProfileNode::ProfileNode(const CallIdentifier& callIdentifier, ProfileNode* headNode, ProfileNode* parentNode)
598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    : m_callIdentifier(callIdentifier)
608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_head(headNode)
618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_parent(parentNode)
628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_nextSibling(0)
638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_startTime(0.0)
648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_actualTotalTime(0.0)
658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_visibleTotalTime(0.0)
668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_actualSelfTime(0.0)
678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_visibleSelfTime(0.0)
688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_numberOfCalls(0)
698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_visible(true)
708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    startTimer();
728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectProfileNode::ProfileNode(ProfileNode* headNode, ProfileNode* nodeToCopy)
758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    : m_callIdentifier(nodeToCopy->callIdentifier())
768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_head(headNode)
778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_parent(nodeToCopy->parent())
788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_nextSibling(0)
798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_startTime(0.0)
808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_actualTotalTime(nodeToCopy->actualTotalTime())
818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_visibleTotalTime(nodeToCopy->totalTime())
828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_actualSelfTime(nodeToCopy->actualSelfTime())
838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_visibleSelfTime(nodeToCopy->selfTime())
848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_numberOfCalls(nodeToCopy->numberOfCalls())
858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_visible(nodeToCopy->visible())
868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectProfileNode* ProfileNode::willExecute(const CallIdentifier& callIdentifier)
908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (StackIterator currentChild = m_children.begin(); currentChild != m_children.end(); ++currentChild) {
928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if ((*currentChild)->callIdentifier() == callIdentifier) {
938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            (*currentChild)->startTimer();
948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return (*currentChild).get();
958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<ProfileNode> newChild = ProfileNode::create(callIdentifier, m_head ? m_head : this, this); // If this ProfileNode has no head it is the head.
998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_children.size())
1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_children.last()->setNextSibling(newChild.get());
1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_children.append(newChild.release());
1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return m_children.last().get();
1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectProfileNode* ProfileNode::didExecute()
1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    endAndRecordCall();
1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return m_parent;
1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ProfileNode::addChild(PassRefPtr<ProfileNode> prpChild)
1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<ProfileNode> child = prpChild;
1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    child->setParent(this);
1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_children.size())
1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_children.last()->setNextSibling(child.get());
1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_children.append(child.release());
1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectProfileNode* ProfileNode::findChild(ProfileNode* node) const
1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!node)
1238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (size_t i = 0; i < m_children.size(); ++i) {
1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (*node == m_children[i].get())
1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return m_children[i].get();
1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return 0;
1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ProfileNode::removeChild(ProfileNode* node)
1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!node)
1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (size_t i = 0; i < m_children.size(); ++i) {
1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (*node == m_children[i].get()) {
1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_children.remove(i);
1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    resetChildrensSiblings();
1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ProfileNode::insertNode(PassRefPtr<ProfileNode> prpNode)
1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<ProfileNode> node = prpNode;
1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (unsigned i = 0; i < m_children.size(); ++i)
1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        node->addChild(m_children[i].release());
1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_children.clear();
1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_children.append(node.release());
1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ProfileNode::stopProfiling()
1608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_startTime)
1628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        endAndRecordCall();
1638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_visibleTotalTime = m_actualTotalTime;
1658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(m_actualSelfTime == 0.0 && m_startTime == 0.0);
1678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Because we iterate in post order all of our children have been stopped before us.
1698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (unsigned i = 0; i < m_children.size(); ++i)
1708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_actualSelfTime += m_children[i]->totalTime();
1718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(m_actualSelfTime <= m_actualTotalTime);
1738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_actualSelfTime = m_actualTotalTime - m_actualSelfTime;
1748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_visibleSelfTime = m_actualSelfTime;
1758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectProfileNode* ProfileNode::traverseNextNodePostOrder() const
1788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ProfileNode* next = m_nextSibling;
1808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!next)
1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return m_parent;
1828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (ProfileNode* firstChild = next->firstChild())
1838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        next = firstChild;
1848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return next;
1858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectProfileNode* ProfileNode::traverseNextNodePreOrder(bool processChildren) const
1888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (processChildren && m_children.size())
1908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return m_children[0].get();
1918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_nextSibling)
1938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return m_nextSibling;
1948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ProfileNode* nextParent = m_parent;
1968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!nextParent)
1978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
1988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ProfileNode* next;
2008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (next = m_parent->nextSibling(); !next; next = nextParent->nextSibling()) {
2018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        nextParent = nextParent->parent();
2028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!nextParent)
2038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return 0;
2048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return next;
2078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ProfileNode::setTreeVisible(ProfileNode* node, bool visible)
2108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ProfileNode* nodeParent = node->parent();
2128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ProfileNode* nodeSibling = node->nextSibling();
2138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    node->setParent(0);
2148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    node->setNextSibling(0);
2158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (ProfileNode* currentNode = node; currentNode; currentNode = currentNode->traverseNextNodePreOrder())
2178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        currentNode->setVisible(visible);
2188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    node->setParent(nodeParent);
2208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    node->setNextSibling(nodeSibling);
2218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ProfileNode::calculateVisibleTotalTime()
2248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    double sumOfVisibleChildrensTime = 0.0;
2268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (unsigned i = 0; i < m_children.size(); ++i) {
2288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (m_children[i]->visible())
2298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            sumOfVisibleChildrensTime += m_children[i]->totalTime();
2308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_visibleTotalTime = m_visibleSelfTime + sumOfVisibleChildrensTime;
2338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool ProfileNode::focus(const CallIdentifier& callIdentifier)
2368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_visible)
2388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
2398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_callIdentifier != callIdentifier) {
2418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_visible = false;
2428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return true;
2438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (ProfileNode* currentParent = m_parent; currentParent; currentParent = currentParent->parent())
2468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        currentParent->setVisible(true);
2478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return false;
2498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ProfileNode::exclude(const CallIdentifier& callIdentifier)
2528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_visible && m_callIdentifier == callIdentifier) {
2548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        setTreeVisible(this, false);
2558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_parent->setVisibleSelfTime(m_parent->selfTime() + m_visibleTotalTime);
2578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ProfileNode::restore()
2618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_visibleTotalTime = m_actualTotalTime;
2638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_visibleSelfTime = m_actualSelfTime;
2648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_visible = true;
2658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ProfileNode::endAndRecordCall()
2688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_actualTotalTime += m_startTime ? getCount() - m_startTime : 0.0;
2708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_startTime = 0.0;
2718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ++m_numberOfCalls;
2738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ProfileNode::startTimer()
2768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_startTime)
2788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_startTime = getCount();
2798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ProfileNode::resetChildrensSiblings()
2828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    unsigned size = m_children.size();
2848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (unsigned i = 0; i < size; ++i)
2858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_children[i]->setNextSibling(i + 1 == size ? 0 : m_children[i + 1].get());
2868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifndef NDEBUG
2898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ProfileNode::debugPrintData(int indentLevel) const
2908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Print function names
2928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (int i = 0; i < indentLevel; ++i)
2938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        printf("  ");
2948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The 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",
2968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        functionName().UTF8String().c_str(),
2978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_numberOfCalls, m_actualSelfTime, selfPercent(), m_actualTotalTime, totalPercent(),
2988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_visibleSelfTime, m_visibleTotalTime,
2998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        (m_visible ? "True" : "False"),
3008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_nextSibling ? m_nextSibling->functionName().UTF8String().c_str() : "");
3018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ++indentLevel;
3038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Print children's names and information
3058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (StackIterator currentChild = m_children.begin(); currentChild != m_children.end(); ++currentChild)
3068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        (*currentChild)->debugPrintData(indentLevel);
3078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// print the profiled data in a format that matches the tool sample's output.
3108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectdouble ProfileNode::debugPrintDataSampleStyle(int indentLevel, FunctionCallHashCount& countedFunctions) const
3118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    printf("    ");
3138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Print function names
3158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const char* name = functionName().UTF8String().c_str();
3168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    double sampleCount = m_actualTotalTime * 1000;
3178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (indentLevel) {
3188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        for (int i = 0; i < indentLevel; ++i)
3198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            printf("  ");
3208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         countedFunctions.add(functionName().rep());
3228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        printf("%.0f %s\n", sampleCount ? sampleCount : 1, name);
3248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else
3258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        printf("%s\n", name);
3268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ++indentLevel;
3288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Print children's names and information
3308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    double sumOfChildrensCount = 0.0;
3318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (StackIterator currentChild = m_children.begin(); currentChild != m_children.end(); ++currentChild)
3328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        sumOfChildrensCount += (*currentChild)->debugPrintDataSampleStyle(indentLevel, countedFunctions);
3338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    sumOfChildrensCount *= 1000;    //
3358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Print remainder of samples to match sample's output
3368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (sumOfChildrensCount < sampleCount) {
3378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        printf("    ");
3388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        while (indentLevel--)
3398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            printf("  ");
3408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        printf("%.0f %s\n", sampleCount - sumOfChildrensCount, functionName().UTF8String().c_str());
3428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return m_actualTotalTime;
3458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
3478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace JSC
349