diff options
Diffstat (limited to 'Source/JavaScriptCore/tools/ProfileTreeNode.h')
-rw-r--r-- | Source/JavaScriptCore/tools/ProfileTreeNode.h | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/Source/JavaScriptCore/tools/ProfileTreeNode.h b/Source/JavaScriptCore/tools/ProfileTreeNode.h new file mode 100644 index 000000000..6c5fdc185 --- /dev/null +++ b/Source/JavaScriptCore/tools/ProfileTreeNode.h @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef ProfileTreeNode_h +#define ProfileTreeNode_h + +namespace JSC { + +class ProfileTreeNode { + typedef HashMap<String, ProfileTreeNode> Map; + typedef std::pair<String, ProfileTreeNode> MapEntry; + +public: + ProfileTreeNode() + : m_count(0) + , m_children(0) + { + } + + ~ProfileTreeNode() + { + delete m_children; + } + + ProfileTreeNode* sampleChild(const char* name) + { + if (!m_children) + m_children = new Map(); + + ProfileTreeNode newEntry; + pair<Map::iterator, bool> result = m_children->add(String(name), newEntry); + ProfileTreeNode* childInMap = &result.first->second; + ++childInMap->m_count; + return childInMap; + } + + void dump() + { + dumpInternal(0); + } + + uint64_t count() + { + return m_count; + } + + uint64_t childCount() + { + if (!m_children) + return 0; + uint64_t childCount = 0; + for (Map::iterator it = m_children->begin(); it != m_children->end(); ++it) + childCount += it->second.count(); + return childCount; + } + +private: + void dumpInternal(unsigned indent) + { + if (!m_children) + return; + + // Copy pointers to all children into a vector, and sort the vector by sample count. + Vector<MapEntry*> entries; + for (Map::iterator it = m_children->begin(); it != m_children->end(); ++it) + entries.append(&*it); + qsort(entries.begin(), entries.size(), sizeof(MapEntry*), compareEntries); + + // Iterate over the children in sample-frequency order. + for (size_t e = 0; e < entries.size(); ++e) { + MapEntry* entry = entries[e]; + + // Print the number of samples, the name of this node, and the number of samples that are stack-top + // in this node (samples directly within this node, excluding samples in children. + for (unsigned i = 0; i < indent; ++i) + fprintf(stdout, " "); + fprintf(stdout, "% 8lld: %s (%lld stack top)\n", + static_cast<long long>(entry->second.count()), + entry->first.utf8().data(), + static_cast<long long>(entry->second.count() - entry->second.childCount())); + + // Recursively dump the child nodes. + entry->second.dumpInternal(indent + 1); + } + } + + static int compareEntries(const void* a, const void* b) + { + uint64_t da = (*static_cast<MapEntry* const *>(a))->second.count(); + uint64_t db = (*static_cast<MapEntry* const *>(b))->second.count(); + return (da < db) - (da > db); + } + + uint64_t m_count; + Map* m_children; +}; + +} + +#endif // ProfileTreeNode_h + |