objects.cc
oprofile-agent.cc
parser.cc
+ profile-generator.cc
property.cc
regexp-macro-assembler-irregexp.cc
regexp-macro-assembler.cc
--- /dev/null
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef V8_PROFILE_GENERATOR_INL_H_
+#define V8_PROFILE_GENERATOR_INL_H_
+
+#include "profile-generator.h"
+
+namespace v8 {
+namespace internal {
+
+
+bool CodeEntry::is_js_function() {
+ return tag_ == Logger::FUNCTION_TAG
+ || tag_ == Logger::LAZY_COMPILE_TAG
+ || tag_ == Logger::SCRIPT_TAG;
+}
+
+
+StaticNameCodeEntry::StaticNameCodeEntry(Logger::LogEventsAndTags tag,
+ const char* name)
+ : CodeEntry(tag),
+ name_(name) {
+}
+
+
+ManagedNameCodeEntry::ManagedNameCodeEntry(Logger::LogEventsAndTags tag,
+ String* name,
+ const char* resource_name,
+ int line_number)
+ : CodeEntry(tag),
+ name_(name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL).Detach()),
+ resource_name_(resource_name),
+ line_number_(line_number) {
+}
+
+
+ProfileNode::ProfileNode(CodeEntry* entry)
+ : entry_(entry),
+ total_ticks_(0),
+ self_ticks_(0),
+ children_(CodeEntriesMatch) {
+}
+
+
+void CodeMap::AddCode(Address addr, CodeEntry* entry, unsigned size) {
+ CodeTree::Locator locator;
+ tree_.Insert(addr, &locator);
+ locator.set_value(CodeEntryInfo(entry, size));
+}
+
+
+void CodeMap::MoveCode(Address from, Address to) {
+ tree_.Move(from, to);
+}
+
+void CodeMap::DeleteCode(Address addr) {
+ tree_.Remove(addr);
+}
+
+
+} } // namespace v8::internal
+
+#endif // V8_PROFILE_GENERATOR_INL_H_
--- /dev/null
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "v8.h"
+
+#include "profile-generator-inl.h"
+
+
+namespace v8 {
+namespace internal {
+
+
+ProfileNode* ProfileNode::FindChild(CodeEntry* entry) {
+ HashMap::Entry* map_entry =
+ children_.Lookup(entry, CodeEntryHash(entry), false);
+ return map_entry != NULL ?
+ reinterpret_cast<ProfileNode*>(map_entry->value) : NULL;
+}
+
+
+ProfileNode* ProfileNode::FindOrAddChild(CodeEntry* entry) {
+ HashMap::Entry* map_entry =
+ children_.Lookup(entry, CodeEntryHash(entry), true);
+ if (map_entry->value == NULL) {
+ // New node added.
+ map_entry->value = new ProfileNode(entry);
+ }
+ return reinterpret_cast<ProfileNode*>(map_entry->value);
+}
+
+
+void ProfileNode::Print(int indent) {
+ OS::Print("%4u %4u %*c %s\n",
+ total_ticks_, self_ticks_,
+ indent, ' ',
+ entry_ != NULL ? entry_->name() : "");
+ for (HashMap::Entry* p = children_.Start();
+ p != NULL;
+ p = children_.Next(p)) {
+ reinterpret_cast<ProfileNode*>(p->value)->Print(indent + 2);
+ }
+}
+
+
+namespace {
+
+class DeleteNodesCallback {
+ public:
+ void AfterAllChildrenTraversed(ProfileNode* node) {
+ delete node;
+ }
+
+ void AfterChildTraversed(ProfileNode*, ProfileNode*) { }
+};
+
+} // namespace
+
+
+ProfileTree::~ProfileTree() {
+ DeleteNodesCallback cb;
+ TraverseBreadthFirstPostOrder(&cb);
+}
+
+
+void ProfileTree::AddPathFromEnd(const Vector<CodeEntry*>& path) {
+ ProfileNode* node = root_;
+ for (CodeEntry** entry = path.start() + path.length() - 1;
+ entry != path.start() - 1;
+ --entry) {
+ if (*entry != NULL) {
+ node = node->FindOrAddChild(*entry);
+ }
+ }
+ node->IncrementSelfTicks();
+}
+
+
+void ProfileTree::AddPathFromStart(const Vector<CodeEntry*>& path) {
+ ProfileNode* node = root_;
+ for (CodeEntry** entry = path.start();
+ entry != path.start() + path.length();
+ ++entry) {
+ if (*entry != NULL) {
+ node = node->FindOrAddChild(*entry);
+ }
+ }
+ node->IncrementSelfTicks();
+}
+
+
+namespace {
+
+struct Position {
+ Position(ProfileNode* a_node, HashMap::Entry* a_p)
+ : node(a_node), p(a_p) { }
+ INLINE(ProfileNode* current_child()) {
+ return reinterpret_cast<ProfileNode*>(p->value);
+ }
+ ProfileNode* node;
+ HashMap::Entry* p;
+};
+
+} // namespace
+
+
+template <typename Callback>
+void ProfileTree::TraverseBreadthFirstPostOrder(Callback* callback) {
+ List<Position> stack(10);
+ stack.Add(Position(root_, root_->children_.Start()));
+ do {
+ Position& current = stack.last();
+ if (current.p != NULL) {
+ stack.Add(Position(current.current_child(),
+ current.current_child()->children_.Start()));
+ } else {
+ callback->AfterAllChildrenTraversed(current.node);
+ if (stack.length() > 1) {
+ Position& parent = stack[stack.length() - 2];
+ callback->AfterChildTraversed(parent.node, current.node);
+ parent.p = parent.node->children_.Next(parent.p);
+ // Remove child from the stack.
+ stack.RemoveLast();
+ }
+ }
+ } while (stack.length() > 1 || stack.last().p != NULL);
+}
+
+
+namespace {
+
+class CalculateTotalTicksCallback {
+ public:
+ void AfterAllChildrenTraversed(ProfileNode* node) {
+ node->IncreaseTotalTicks(node->self_ticks());
+ }
+
+ void AfterChildTraversed(ProfileNode* parent, ProfileNode* child) {
+ parent->IncreaseTotalTicks(child->total_ticks());
+ }
+};
+
+} // namespace
+
+
+// Non-recursive implementation of breadth-first tree traversal.
+void ProfileTree::CalculateTotalTicks() {
+ CalculateTotalTicksCallback cb;
+ TraverseBreadthFirstPostOrder(&cb);
+}
+
+
+void ProfileTree::ShortPrint() {
+ OS::Print("root: %u %u\n", root_->total_ticks(), root_->self_ticks());
+}
+
+
+void CpuProfile::AddPath(const Vector<CodeEntry*>& path) {
+ top_down_.AddPathFromEnd(path);
+ bottom_up_.AddPathFromStart(path);
+}
+
+
+void CpuProfile::CalculateTotalTicks() {
+ top_down_.CalculateTotalTicks();
+ bottom_up_.CalculateTotalTicks();
+}
+
+
+void CpuProfile::ShortPrint() {
+ OS::Print("top down ");
+ top_down_.ShortPrint();
+ OS::Print("bottom up ");
+ bottom_up_.ShortPrint();
+}
+
+
+void CpuProfile::Print() {
+ OS::Print("[Top down]:\n");
+ top_down_.Print();
+ OS::Print("[Bottom up]:\n");
+ bottom_up_.Print();
+}
+
+
+const CodeMap::CodeTreeConfig::Key CodeMap::CodeTreeConfig::kNoKey = NULL;
+const CodeMap::CodeTreeConfig::Value CodeMap::CodeTreeConfig::kNoValue =
+ CodeMap::CodeEntryInfo(NULL, 0);
+
+
+void CodeMap::AddAlias(Address alias, Address addr) {
+ CodeTree::Locator locator;
+ if (tree_.Find(addr, &locator)) {
+ const CodeEntryInfo& entry_info = locator.value();
+ tree_.Insert(alias, &locator);
+ locator.set_value(entry_info);
+ }
+}
+
+
+CodeEntry* CodeMap::FindEntry(Address addr) {
+ CodeTree::Locator locator;
+ if (tree_.FindGreatestLessThan(addr, &locator)) {
+ // locator.key() <= addr. Need to check that addr is within entry.
+ const CodeEntryInfo& entry = locator.value();
+ if (addr < (locator.key() + entry.size))
+ return entry.entry;
+ }
+ return NULL;
+}
+
+
+ProfileGenerator::ProfileGenerator()
+ : resource_names_(StringsMatch) {
+}
+
+
+static void CodeEntriesDeleter(CodeEntry** entry_ptr) {
+ delete *entry_ptr;
+}
+
+
+ProfileGenerator::~ProfileGenerator() {
+ for (HashMap::Entry* p = resource_names_.Start();
+ p != NULL;
+ p = resource_names_.Next(p)) {
+ DeleteArray(reinterpret_cast<const char*>(p->value));
+ }
+
+ code_entries_.Iterate(CodeEntriesDeleter);
+}
+
+
+CodeEntry* ProfileGenerator::NewCodeEntry(
+ Logger::LogEventsAndTags tag,
+ String* name,
+ String* resource_name, int line_number) {
+ const char* cached_resource_name = NULL;
+ if (resource_name->IsString()) {
+ // As we copy contents of resource names, and usually they are repeated,
+ // we cache names by string hashcode.
+ HashMap::Entry* cache_entry =
+ resource_names_.Lookup(resource_name,
+ StringEntryHash(resource_name),
+ true);
+ if (cache_entry->value == NULL) {
+ // New entry added.
+ cache_entry->value =
+ resource_name->ToCString(DISALLOW_NULLS,
+ ROBUST_STRING_TRAVERSAL).Detach();
+ }
+ cached_resource_name = reinterpret_cast<const char*>(cache_entry->value);
+ }
+
+ CodeEntry* entry = new ManagedNameCodeEntry(tag,
+ name,
+ cached_resource_name,
+ line_number);
+ code_entries_.Add(entry);
+ return entry;
+}
+
+
+CodeEntry* ProfileGenerator::NewCodeEntry(
+ Logger::LogEventsAndTags tag,
+ const char* name) {
+ CodeEntry* entry = new StaticNameCodeEntry(tag, name);
+ code_entries_.Add(entry);
+ return entry;
+}
+
+} } // namespace v8::internal
--- /dev/null
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef V8_PROFILE_GENERATOR_H_
+#define V8_PROFILE_GENERATOR_H_
+
+#include "hashmap.h"
+
+namespace v8 {
+namespace internal {
+
+
+class CodeEntry {
+ public:
+ virtual ~CodeEntry() { }
+
+ virtual const char* name() = 0;
+ INLINE(bool is_js_function());
+
+ protected:
+ INLINE(explicit CodeEntry(Logger::LogEventsAndTags tag))
+ : tag_(tag) { }
+
+ private:
+ Logger::LogEventsAndTags tag_;
+
+ DISALLOW_COPY_AND_ASSIGN(CodeEntry);
+};
+
+
+class StaticNameCodeEntry : public CodeEntry {
+ public:
+ INLINE(StaticNameCodeEntry(Logger::LogEventsAndTags tag,
+ const char* name));
+
+ INLINE(virtual const char* name()) { return name_ != NULL ? name_ : ""; }
+
+ private:
+ const char* name_;
+
+ DISALLOW_COPY_AND_ASSIGN(StaticNameCodeEntry);
+};
+
+
+class ManagedNameCodeEntry : public CodeEntry {
+ public:
+ INLINE(ManagedNameCodeEntry(Logger::LogEventsAndTags tag,
+ String* name,
+ const char* resource_name, int line_number));
+
+ INLINE(virtual const char* name()) { return !name_.is_empty() ? *name_ : ""; }
+
+ private:
+ SmartPointer<char> name_;
+ const char* resource_name_;
+ int line_number_;
+
+ DISALLOW_COPY_AND_ASSIGN(ManagedNameCodeEntry);
+};
+
+
+class ProfileNode {
+ public:
+ INLINE(explicit ProfileNode(CodeEntry* entry));
+
+ ProfileNode* FindChild(CodeEntry* entry);
+ ProfileNode* FindOrAddChild(CodeEntry* entry);
+ INLINE(void IncrementSelfTicks()) { ++self_ticks_; }
+ INLINE(void IncreaseTotalTicks(unsigned amount)) { total_ticks_ += amount; }
+
+ INLINE(unsigned total_ticks()) { return total_ticks_; }
+ INLINE(unsigned self_ticks()) { return self_ticks_; }
+
+ void Print(int indent);
+
+ private:
+ INLINE(static bool CodeEntriesMatch(void* key1, void* key2)) {
+ return key1 == key2;
+ }
+
+ INLINE(static bool CodeEntryHash(CodeEntry* entry)) {
+ return static_cast<int32_t>(reinterpret_cast<intptr_t>(entry));
+ }
+
+ CodeEntry* entry_;
+ unsigned total_ticks_;
+ unsigned self_ticks_;
+ // CodeEntry* -> ProfileNode*
+ HashMap children_;
+
+ friend class ProfileTree;
+
+ DISALLOW_COPY_AND_ASSIGN(ProfileNode);
+};
+
+
+class ProfileTree BASE_EMBEDDED {
+ public:
+ ProfileTree() : root_(new ProfileNode(NULL)) { }
+ ~ProfileTree();
+
+ void AddPathFromEnd(const Vector<CodeEntry*>& path);
+ void AddPathFromStart(const Vector<CodeEntry*>& path);
+ void CalculateTotalTicks();
+
+ ProfileNode* root() { return root_; }
+
+ void ShortPrint();
+ void Print() {
+ root_->Print(0);
+ }
+
+ private:
+ template <typename Callback>
+ void TraverseBreadthFirstPostOrder(Callback* callback);
+
+ ProfileNode* root_;
+
+ DISALLOW_COPY_AND_ASSIGN(ProfileTree);
+};
+
+
+class CpuProfile BASE_EMBEDDED {
+ public:
+ CpuProfile() { }
+ // Add pc -> ... -> main() call path to the profile.
+ void AddPath(const Vector<CodeEntry*>& path);
+ void CalculateTotalTicks();
+
+ void ShortPrint();
+ void Print();
+
+ private:
+ ProfileTree top_down_;
+ ProfileTree bottom_up_;
+
+ DISALLOW_COPY_AND_ASSIGN(CpuProfile);
+};
+
+
+class CodeMap BASE_EMBEDDED {
+ public:
+ CodeMap() { }
+ INLINE(void AddCode(Address addr, CodeEntry* entry, unsigned size));
+ INLINE(void MoveCode(Address from, Address to));
+ INLINE(void DeleteCode(Address addr));
+ void AddAlias(Address alias, Address addr);
+ CodeEntry* FindEntry(Address addr);
+
+ private:
+ struct CodeEntryInfo {
+ CodeEntryInfo(CodeEntry* an_entry, unsigned a_size)
+ : entry(an_entry), size(a_size) { }
+ CodeEntry* entry;
+ unsigned size;
+ };
+
+ struct CodeTreeConfig {
+ typedef Address Key;
+ typedef CodeEntryInfo Value;
+ static const Key kNoKey;
+ static const Value kNoValue;
+ static int Compare(const Key& a, const Key& b) {
+ return a < b ? -1 : (a > b ? 1 : 0);
+ }
+ };
+ typedef SplayTree<CodeTreeConfig> CodeTree;
+
+ CodeTree tree_;
+
+ DISALLOW_COPY_AND_ASSIGN(CodeMap);
+};
+
+
+class ProfileGenerator {
+ public:
+ ProfileGenerator();
+ ~ProfileGenerator();
+
+ CodeEntry* NewCodeEntry(Logger::LogEventsAndTags tag,
+ String* name, String* resource_name, int line_number);
+ CodeEntry* NewCodeEntry(Logger::LogEventsAndTags tag, const char* name);
+
+ INLINE(CpuProfile* profile()) { return &profile_; }
+ INLINE(CodeMap* code_map()) { return &code_map_; }
+
+ private:
+ INLINE(static bool StringsMatch(void* key1, void* key2)) {
+ return key1 == key2;
+ }
+
+ INLINE(static bool StringEntryHash(String* entry)) {
+ return entry->Hash();
+ }
+
+ CpuProfile profile_;
+ CodeMap code_map_;
+ typedef List<CodeEntry*> CodeEntryList;
+ CodeEntryList code_entries_;
+ // String::Hash -> const char*
+ HashMap resource_names_;
+
+ DISALLOW_COPY_AND_ASSIGN(ProfileGenerator);
+};
+
+
+} } // namespace v8::internal
+
+#endif // V8_PROFILE_GENERATOR_H_
}
// Insert the new node.
Node* node = new Node(key, Config::kNoValue);
- if (cmp > 0) {
- node->left_ = root_;
- node->right_ = root_->right_;
- root_->right_ = NULL;
- } else {
- node->right_ = root_;
- node->left_ = root_->left_;
- root_->left_ = NULL;
- }
- root_ = node;
+ InsertInternal(cmp, node);
}
locator->bind(root_);
return true;
template<typename Config, class Allocator>
-bool SplayTree<Config, Allocator>::Find(const Key& key, Locator* locator) {
+void SplayTree<Config, Allocator>::InsertInternal(int cmp, Node* node) {
+ if (cmp > 0) {
+ node->left_ = root_;
+ node->right_ = root_->right_;
+ root_->right_ = NULL;
+ } else {
+ node->right_ = root_;
+ node->left_ = root_->left_;
+ root_->left_ = NULL;
+ }
+ root_ = node;
+}
+
+
+template<typename Config, class Allocator>
+bool SplayTree<Config, Allocator>::FindInternal(const Key& key) {
if (is_empty())
return false;
Splay(key);
- if (Config::Compare(key, root_->key_) == 0) {
+ return Config::Compare(key, root_->key_) == 0;
+}
+
+
+template<typename Config, class Allocator>
+bool SplayTree<Config, Allocator>::Find(const Key& key, Locator* locator) {
+ if (FindInternal(key)) {
locator->bind(root_);
return true;
} else {
template<typename Config, class Allocator>
-bool SplayTree<Config, Allocator>::Remove(const Key& key) {
- // Bail if the tree is empty
- if (is_empty())
+bool SplayTree<Config, Allocator>::Move(const Key& old_key,
+ const Key& new_key) {
+ if (!FindInternal(old_key))
return false;
- // Splay on the key to move the node with the given key to the top.
- Splay(key);
- // Bail if the key is not in the tree
- if (Config::Compare(key, root_->key_) != 0)
+ Node* node_to_move = root_;
+ RemoveRootNode(old_key);
+ Splay(new_key);
+ int cmp = Config::Compare(new_key, root_->key_);
+ if (cmp == 0) {
+ // A node with the target key already exists.
+ delete node_to_move;
return false;
+ }
+ node_to_move->key_ = new_key;
+ InsertInternal(cmp, node_to_move);
+ return true;
+}
+
+
+template<typename Config, class Allocator>
+bool SplayTree<Config, Allocator>::Remove(const Key& key) {
+ if (!FindInternal(key))
+ return false;
+ Node* node_to_remove = root_;
+ RemoveRootNode(key);
+ delete node_to_remove;
+ return true;
+}
+
+
+template<typename Config, class Allocator>
+void SplayTree<Config, Allocator>::RemoveRootNode(const Key& key) {
if (root_->left_ == NULL) {
// No left child, so the new tree is just the right child.
root_ = root_->right_;
// root.
root_->right_ = right;
}
- return true;
}
// Find the mapping with the least key in this tree.
bool FindLeast(Locator* locator);
+ // Move the node from one key to another.
+ bool Move(const Key& old_key, const Key& new_key);
+
// Remove the node with the given key from the tree.
bool Remove(const Key& key);
void ResetRoot() { root_ = NULL; }
private:
+ // Search for a node with a given key. If found, root_ points
+ // to the node.
+ bool FindInternal(const Key& key);
+
+ // Inserts a node assuming that root_ is already set up.
+ void InsertInternal(int cmp, Node* node);
+
+ // Removes root_ node.
+ void RemoveRootNode(const Key& key);
template<class Callback>
class NodeToPairAdaptor BASE_EMBEDDED {
'test-log-utils.cc',
'test-mark-compact.cc',
'test-parsing.cc',
+ 'test-profile-generator.cc',
'test-regexp.cc',
'test-serialize.cc',
'test-sockets.cc',
--- /dev/null
+// Copyright 2010 the V8 project authors. All rights reserved.
+//
+// Tests of profiles generator and utilities.
+
+#include "v8.h"
+#include "profile-generator-inl.h"
+#include "cctest.h"
+
+namespace i = v8::internal;
+
+using i::CodeEntry;
+using i::CodeMap;
+using i::ProfileNode;
+using i::ProfileTree;
+using i::StaticNameCodeEntry;
+using i::Vector;
+
+
+TEST(ProfileNodeFindOrAddChild) {
+ ProfileNode node(NULL);
+ StaticNameCodeEntry entry1(i::Logger::FUNCTION_TAG, "aaa");
+ ProfileNode* childNode1 = node.FindOrAddChild(&entry1);
+ CHECK_NE(NULL, childNode1);
+ CHECK_EQ(childNode1, node.FindOrAddChild(&entry1));
+ StaticNameCodeEntry entry2(i::Logger::FUNCTION_TAG, "bbb");
+ ProfileNode* childNode2 = node.FindOrAddChild(&entry2);
+ CHECK_NE(NULL, childNode2);
+ CHECK_NE(childNode1, childNode2);
+ CHECK_EQ(childNode1, node.FindOrAddChild(&entry1));
+ CHECK_EQ(childNode2, node.FindOrAddChild(&entry2));
+ StaticNameCodeEntry entry3(i::Logger::FUNCTION_TAG, "ccc");
+ ProfileNode* childNode3 = node.FindOrAddChild(&entry3);
+ CHECK_NE(NULL, childNode3);
+ CHECK_NE(childNode1, childNode3);
+ CHECK_NE(childNode2, childNode3);
+ CHECK_EQ(childNode1, node.FindOrAddChild(&entry1));
+ CHECK_EQ(childNode2, node.FindOrAddChild(&entry2));
+ CHECK_EQ(childNode3, node.FindOrAddChild(&entry3));
+}
+
+
+namespace {
+
+class ProfileTreeTestHelper {
+ public:
+ explicit ProfileTreeTestHelper(ProfileTree* tree)
+ : tree_(tree) { }
+
+ ProfileNode* Walk(CodeEntry* entry1,
+ CodeEntry* entry2 = NULL,
+ CodeEntry* entry3 = NULL) {
+ ProfileNode* node = tree_->root();
+ node = node->FindChild(entry1);
+ if (node == NULL) return NULL;
+ if (entry2 != NULL) {
+ node = node->FindChild(entry2);
+ if (node == NULL) return NULL;
+ }
+ if (entry3 != NULL) {
+ node = node->FindChild(entry3);
+ }
+ return node;
+ }
+
+ private:
+ ProfileTree* tree_;
+};
+
+} // namespace
+
+TEST(ProfileTreeAddPathFromStart) {
+ StaticNameCodeEntry entry1(i::Logger::FUNCTION_TAG, "aaa");
+ StaticNameCodeEntry entry2(i::Logger::FUNCTION_TAG, "bbb");
+ StaticNameCodeEntry entry3(i::Logger::FUNCTION_TAG, "ccc");
+ ProfileTree tree;
+ ProfileTreeTestHelper helper(&tree);
+ CHECK_EQ(NULL, helper.Walk(&entry1));
+ CHECK_EQ(NULL, helper.Walk(&entry2));
+ CHECK_EQ(NULL, helper.Walk(&entry3));
+
+ CodeEntry* path[] = {NULL, &entry1, NULL, &entry2, NULL, NULL, &entry3, NULL};
+ Vector<CodeEntry*> path_vec(path, sizeof(path) / sizeof(path[0]));
+ tree.AddPathFromStart(path_vec);
+ CHECK_EQ(NULL, helper.Walk(&entry2));
+ CHECK_EQ(NULL, helper.Walk(&entry3));
+ ProfileNode* node1 = helper.Walk(&entry1);
+ CHECK_NE(NULL, node1);
+ CHECK_EQ(0, node1->total_ticks());
+ CHECK_EQ(0, node1->self_ticks());
+ CHECK_EQ(NULL, helper.Walk(&entry1, &entry1));
+ CHECK_EQ(NULL, helper.Walk(&entry1, &entry3));
+ ProfileNode* node2 = helper.Walk(&entry1, &entry2);
+ CHECK_NE(NULL, node2);
+ CHECK_NE(node1, node2);
+ CHECK_EQ(0, node2->total_ticks());
+ CHECK_EQ(0, node2->self_ticks());
+ CHECK_EQ(NULL, helper.Walk(&entry1, &entry2, &entry1));
+ CHECK_EQ(NULL, helper.Walk(&entry1, &entry2, &entry2));
+ ProfileNode* node3 = helper.Walk(&entry1, &entry2, &entry3);
+ CHECK_NE(NULL, node3);
+ CHECK_NE(node1, node3);
+ CHECK_NE(node2, node3);
+ CHECK_EQ(0, node3->total_ticks());
+ CHECK_EQ(1, node3->self_ticks());
+
+ tree.AddPathFromStart(path_vec);
+ CHECK_EQ(node1, helper.Walk(&entry1));
+ CHECK_EQ(node2, helper.Walk(&entry1, &entry2));
+ CHECK_EQ(node3, helper.Walk(&entry1, &entry2, &entry3));
+ CHECK_EQ(0, node1->total_ticks());
+ CHECK_EQ(0, node1->self_ticks());
+ CHECK_EQ(0, node2->total_ticks());
+ CHECK_EQ(0, node2->self_ticks());
+ CHECK_EQ(0, node3->total_ticks());
+ CHECK_EQ(2, node3->self_ticks());
+
+ CodeEntry* path2[] = {&entry1, &entry2, &entry2};
+ Vector<CodeEntry*> path2_vec(path2, sizeof(path2) / sizeof(path2[0]));
+ tree.AddPathFromStart(path2_vec);
+ CHECK_EQ(NULL, helper.Walk(&entry2));
+ CHECK_EQ(NULL, helper.Walk(&entry3));
+ CHECK_EQ(node1, helper.Walk(&entry1));
+ CHECK_EQ(NULL, helper.Walk(&entry1, &entry1));
+ CHECK_EQ(NULL, helper.Walk(&entry1, &entry3));
+ CHECK_EQ(node2, helper.Walk(&entry1, &entry2));
+ CHECK_EQ(NULL, helper.Walk(&entry1, &entry2, &entry1));
+ CHECK_EQ(node3, helper.Walk(&entry1, &entry2, &entry3));
+ CHECK_EQ(0, node3->total_ticks());
+ CHECK_EQ(2, node3->self_ticks());
+ ProfileNode* node4 = helper.Walk(&entry1, &entry2, &entry2);
+ CHECK_NE(NULL, node4);
+ CHECK_NE(node3, node4);
+ CHECK_EQ(0, node4->total_ticks());
+ CHECK_EQ(1, node4->self_ticks());
+}
+
+
+TEST(ProfileTreeAddPathFromEnd) {
+ StaticNameCodeEntry entry1(i::Logger::FUNCTION_TAG, "aaa");
+ StaticNameCodeEntry entry2(i::Logger::FUNCTION_TAG, "bbb");
+ StaticNameCodeEntry entry3(i::Logger::FUNCTION_TAG, "ccc");
+ ProfileTree tree;
+ ProfileTreeTestHelper helper(&tree);
+ CHECK_EQ(NULL, helper.Walk(&entry1));
+ CHECK_EQ(NULL, helper.Walk(&entry2));
+ CHECK_EQ(NULL, helper.Walk(&entry3));
+
+ CodeEntry* path[] = {NULL, &entry3, NULL, &entry2, NULL, NULL, &entry1, NULL};
+ Vector<CodeEntry*> path_vec(path, sizeof(path) / sizeof(path[0]));
+ tree.AddPathFromEnd(path_vec);
+ CHECK_EQ(NULL, helper.Walk(&entry2));
+ CHECK_EQ(NULL, helper.Walk(&entry3));
+ ProfileNode* node1 = helper.Walk(&entry1);
+ CHECK_NE(NULL, node1);
+ CHECK_EQ(0, node1->total_ticks());
+ CHECK_EQ(0, node1->self_ticks());
+ CHECK_EQ(NULL, helper.Walk(&entry1, &entry1));
+ CHECK_EQ(NULL, helper.Walk(&entry1, &entry3));
+ ProfileNode* node2 = helper.Walk(&entry1, &entry2);
+ CHECK_NE(NULL, node2);
+ CHECK_NE(node1, node2);
+ CHECK_EQ(0, node2->total_ticks());
+ CHECK_EQ(0, node2->self_ticks());
+ CHECK_EQ(NULL, helper.Walk(&entry1, &entry2, &entry1));
+ CHECK_EQ(NULL, helper.Walk(&entry1, &entry2, &entry2));
+ ProfileNode* node3 = helper.Walk(&entry1, &entry2, &entry3);
+ CHECK_NE(NULL, node3);
+ CHECK_NE(node1, node3);
+ CHECK_NE(node2, node3);
+ CHECK_EQ(0, node3->total_ticks());
+ CHECK_EQ(1, node3->self_ticks());
+
+ tree.AddPathFromEnd(path_vec);
+ CHECK_EQ(node1, helper.Walk(&entry1));
+ CHECK_EQ(node2, helper.Walk(&entry1, &entry2));
+ CHECK_EQ(node3, helper.Walk(&entry1, &entry2, &entry3));
+ CHECK_EQ(0, node1->total_ticks());
+ CHECK_EQ(0, node1->self_ticks());
+ CHECK_EQ(0, node2->total_ticks());
+ CHECK_EQ(0, node2->self_ticks());
+ CHECK_EQ(0, node3->total_ticks());
+ CHECK_EQ(2, node3->self_ticks());
+
+ CodeEntry* path2[] = {&entry2, &entry2, &entry1};
+ Vector<CodeEntry*> path2_vec(path2, sizeof(path2) / sizeof(path2[0]));
+ tree.AddPathFromEnd(path2_vec);
+ CHECK_EQ(NULL, helper.Walk(&entry2));
+ CHECK_EQ(NULL, helper.Walk(&entry3));
+ CHECK_EQ(node1, helper.Walk(&entry1));
+ CHECK_EQ(NULL, helper.Walk(&entry1, &entry1));
+ CHECK_EQ(NULL, helper.Walk(&entry1, &entry3));
+ CHECK_EQ(node2, helper.Walk(&entry1, &entry2));
+ CHECK_EQ(NULL, helper.Walk(&entry1, &entry2, &entry1));
+ CHECK_EQ(node3, helper.Walk(&entry1, &entry2, &entry3));
+ CHECK_EQ(0, node3->total_ticks());
+ CHECK_EQ(2, node3->self_ticks());
+ ProfileNode* node4 = helper.Walk(&entry1, &entry2, &entry2);
+ CHECK_NE(NULL, node4);
+ CHECK_NE(node3, node4);
+ CHECK_EQ(0, node4->total_ticks());
+ CHECK_EQ(1, node4->self_ticks());
+}
+
+
+TEST(ProfileTreeCalculateTotalTicks) {
+ ProfileTree empty_tree;
+ CHECK_EQ(0, empty_tree.root()->total_ticks());
+ CHECK_EQ(0, empty_tree.root()->self_ticks());
+ empty_tree.CalculateTotalTicks();
+ CHECK_EQ(0, empty_tree.root()->total_ticks());
+ CHECK_EQ(0, empty_tree.root()->self_ticks());
+ empty_tree.root()->IncrementSelfTicks();
+ CHECK_EQ(0, empty_tree.root()->total_ticks());
+ CHECK_EQ(1, empty_tree.root()->self_ticks());
+ empty_tree.CalculateTotalTicks();
+ CHECK_EQ(1, empty_tree.root()->total_ticks());
+ CHECK_EQ(1, empty_tree.root()->self_ticks());
+
+ StaticNameCodeEntry entry1(i::Logger::FUNCTION_TAG, "aaa");
+ StaticNameCodeEntry entry2(i::Logger::FUNCTION_TAG, "bbb");
+ CodeEntry* e1_path[] = {&entry1};
+ Vector<CodeEntry*> e1_path_vec(
+ e1_path, sizeof(e1_path) / sizeof(e1_path[0]));
+ CodeEntry* e1_e2_path[] = {&entry1, &entry2};
+ Vector<CodeEntry*> e1_e2_path_vec(
+ e1_e2_path, sizeof(e1_e2_path) / sizeof(e1_e2_path[0]));
+
+ ProfileTree flat_tree;
+ ProfileTreeTestHelper flat_helper(&flat_tree);
+ flat_tree.AddPathFromStart(e1_path_vec);
+ flat_tree.AddPathFromStart(e1_path_vec);
+ flat_tree.AddPathFromStart(e1_e2_path_vec);
+ flat_tree.AddPathFromStart(e1_e2_path_vec);
+ flat_tree.AddPathFromStart(e1_e2_path_vec);
+ // Results in {root,0,0} -> {entry1,0,2} -> {entry2,0,3}
+ CHECK_EQ(0, flat_tree.root()->total_ticks());
+ CHECK_EQ(0, flat_tree.root()->self_ticks());
+ ProfileNode* node1 = flat_helper.Walk(&entry1);
+ CHECK_NE(NULL, node1);
+ CHECK_EQ(0, node1->total_ticks());
+ CHECK_EQ(2, node1->self_ticks());
+ ProfileNode* node2 = flat_helper.Walk(&entry1, &entry2);
+ CHECK_NE(NULL, node2);
+ CHECK_EQ(0, node2->total_ticks());
+ CHECK_EQ(3, node2->self_ticks());
+ flat_tree.CalculateTotalTicks();
+ // Must calculate {root,5,0} -> {entry1,5,2} -> {entry2,3,3}
+ CHECK_EQ(5, flat_tree.root()->total_ticks());
+ CHECK_EQ(0, flat_tree.root()->self_ticks());
+ CHECK_EQ(5, node1->total_ticks());
+ CHECK_EQ(2, node1->self_ticks());
+ CHECK_EQ(3, node2->total_ticks());
+ CHECK_EQ(3, node2->self_ticks());
+
+ CodeEntry* e2_path[] = {&entry2};
+ Vector<CodeEntry*> e2_path_vec(
+ e2_path, sizeof(e2_path) / sizeof(e2_path[0]));
+ StaticNameCodeEntry entry3(i::Logger::FUNCTION_TAG, "ccc");
+ CodeEntry* e3_path[] = {&entry3};
+ Vector<CodeEntry*> e3_path_vec(
+ e3_path, sizeof(e3_path) / sizeof(e3_path[0]));
+
+ ProfileTree wide_tree;
+ ProfileTreeTestHelper wide_helper(&wide_tree);
+ wide_tree.AddPathFromStart(e1_path_vec);
+ wide_tree.AddPathFromStart(e1_path_vec);
+ wide_tree.AddPathFromStart(e1_e2_path_vec);
+ wide_tree.AddPathFromStart(e2_path_vec);
+ wide_tree.AddPathFromStart(e2_path_vec);
+ wide_tree.AddPathFromStart(e2_path_vec);
+ wide_tree.AddPathFromStart(e3_path_vec);
+ wide_tree.AddPathFromStart(e3_path_vec);
+ wide_tree.AddPathFromStart(e3_path_vec);
+ wide_tree.AddPathFromStart(e3_path_vec);
+ // Results in -> {entry1,0,2} -> {entry2,0,1}
+ // {root,0,0} -> {entry2,0,3}
+ // -> {entry3,0,4}
+ CHECK_EQ(0, wide_tree.root()->total_ticks());
+ CHECK_EQ(0, wide_tree.root()->self_ticks());
+ node1 = wide_helper.Walk(&entry1);
+ CHECK_NE(NULL, node1);
+ CHECK_EQ(0, node1->total_ticks());
+ CHECK_EQ(2, node1->self_ticks());
+ ProfileNode* node1_2 = wide_helper.Walk(&entry1, &entry2);
+ CHECK_NE(NULL, node1_2);
+ CHECK_EQ(0, node1_2->total_ticks());
+ CHECK_EQ(1, node1_2->self_ticks());
+ node2 = wide_helper.Walk(&entry2);
+ CHECK_NE(NULL, node2);
+ CHECK_EQ(0, node2->total_ticks());
+ CHECK_EQ(3, node2->self_ticks());
+ ProfileNode* node3 = wide_helper.Walk(&entry3);
+ CHECK_NE(NULL, node3);
+ CHECK_EQ(0, node3->total_ticks());
+ CHECK_EQ(4, node3->self_ticks());
+ wide_tree.CalculateTotalTicks();
+ // Calculates -> {entry1,3,2} -> {entry2,1,1}
+ // {root,10,0} -> {entry2,3,3}
+ // -> {entry3,4,4}
+ CHECK_EQ(10, wide_tree.root()->total_ticks());
+ CHECK_EQ(0, wide_tree.root()->self_ticks());
+ CHECK_EQ(3, node1->total_ticks());
+ CHECK_EQ(2, node1->self_ticks());
+ CHECK_EQ(1, node1_2->total_ticks());
+ CHECK_EQ(1, node1_2->self_ticks());
+ CHECK_EQ(3, node2->total_ticks());
+ CHECK_EQ(3, node2->self_ticks());
+ CHECK_EQ(4, node3->total_ticks());
+ CHECK_EQ(4, node3->self_ticks());
+}
+
+
+static inline i::Address ToAddress(int n) {
+ return reinterpret_cast<i::Address>(n);
+}
+
+TEST(CodeMapAddCode) {
+ CodeMap code_map;
+ StaticNameCodeEntry entry1(i::Logger::FUNCTION_TAG, "aaa");
+ StaticNameCodeEntry entry2(i::Logger::FUNCTION_TAG, "bbb");
+ StaticNameCodeEntry entry3(i::Logger::FUNCTION_TAG, "ccc");
+ StaticNameCodeEntry entry4(i::Logger::FUNCTION_TAG, "ddd");
+ code_map.AddCode(ToAddress(0x1500), &entry1, 0x200);
+ code_map.AddCode(ToAddress(0x1700), &entry2, 0x100);
+ code_map.AddCode(ToAddress(0x1900), &entry3, 0x50);
+ code_map.AddCode(ToAddress(0x1950), &entry4, 0x10);
+ CHECK_EQ(NULL, code_map.FindEntry(0));
+ CHECK_EQ(NULL, code_map.FindEntry(ToAddress(0x1500 - 1)));
+ CHECK_EQ(&entry1, code_map.FindEntry(ToAddress(0x1500)));
+ CHECK_EQ(&entry1, code_map.FindEntry(ToAddress(0x1500 + 0x100)));
+ CHECK_EQ(&entry1, code_map.FindEntry(ToAddress(0x1500 + 0x200 - 1)));
+ CHECK_EQ(&entry2, code_map.FindEntry(ToAddress(0x1700)));
+ CHECK_EQ(&entry2, code_map.FindEntry(ToAddress(0x1700 + 0x50)));
+ CHECK_EQ(&entry2, code_map.FindEntry(ToAddress(0x1700 + 0x100 - 1)));
+ CHECK_EQ(NULL, code_map.FindEntry(ToAddress(0x1700 + 0x100)));
+ CHECK_EQ(NULL, code_map.FindEntry(ToAddress(0x1900 - 1)));
+ CHECK_EQ(&entry3, code_map.FindEntry(ToAddress(0x1900)));
+ CHECK_EQ(&entry3, code_map.FindEntry(ToAddress(0x1900 + 0x28)));
+ CHECK_EQ(&entry4, code_map.FindEntry(ToAddress(0x1950)));
+ CHECK_EQ(&entry4, code_map.FindEntry(ToAddress(0x1950 + 0x7)));
+ CHECK_EQ(&entry4, code_map.FindEntry(ToAddress(0x1950 + 0x10 - 1)));
+ CHECK_EQ(NULL, code_map.FindEntry(ToAddress(0x1950 + 0x10)));
+ CHECK_EQ(NULL, code_map.FindEntry(ToAddress(0xFFFFFFFF)));
+}
+
+
+TEST(CodeMapMoveAndDeleteCode) {
+ CodeMap code_map;
+ StaticNameCodeEntry entry1(i::Logger::FUNCTION_TAG, "aaa");
+ StaticNameCodeEntry entry2(i::Logger::FUNCTION_TAG, "bbb");
+ code_map.AddCode(ToAddress(0x1500), &entry1, 0x200);
+ code_map.AddCode(ToAddress(0x1700), &entry2, 0x100);
+ CHECK_EQ(&entry1, code_map.FindEntry(ToAddress(0x1500)));
+ CHECK_EQ(&entry2, code_map.FindEntry(ToAddress(0x1700)));
+ code_map.MoveCode(ToAddress(0x1500), ToAddress(0x1800));
+ CHECK_EQ(NULL, code_map.FindEntry(ToAddress(0x1500)));
+ CHECK_EQ(&entry2, code_map.FindEntry(ToAddress(0x1700)));
+ CHECK_EQ(&entry1, code_map.FindEntry(ToAddress(0x1800)));
+ code_map.DeleteCode(ToAddress(0x1700));
+ CHECK_EQ(NULL, code_map.FindEntry(ToAddress(0x1700)));
+ CHECK_EQ(&entry1, code_map.FindEntry(ToAddress(0x1800)));
+}
'../../src/prettyprinter.h',
'../../src/property.cc',
'../../src/property.h',
+ '../../src/profile-generator-inl.h',
+ '../../src/profile-generator.cc',
+ '../../src/profile-generator.h',
'../../src/regexp-macro-assembler-irregexp-inl.h',
'../../src/regexp-macro-assembler-irregexp.cc',
'../../src/regexp-macro-assembler-irregexp.h',
9F11D9A1105AF0A300EBE5B2 /* heap-profiler.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9F11D99E105AF0A300EBE5B2 /* heap-profiler.cc */; };
9F4B7B890FCC877A00DC4117 /* log-utils.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9F4B7B870FCC877A00DC4117 /* log-utils.cc */; };
9F4B7B8A0FCC877A00DC4117 /* log-utils.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9F4B7B870FCC877A00DC4117 /* log-utils.cc */; };
+ 9F73E3B1114E61A100F84A5A /* profile-generator.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9F73E3AF114E61A100F84A5A /* profile-generator.cc */; };
+ 9F73E3B2114E61A100F84A5A /* profile-generator.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9F73E3AF114E61A100F84A5A /* profile-generator.cc */; };
9F92FAA90F8F28AD0089F02C /* func-name-inferrer.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9F92FAA70F8F28AD0089F02C /* func-name-inferrer.cc */; };
9F92FAAA0F8F28AD0089F02C /* func-name-inferrer.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9F92FAA70F8F28AD0089F02C /* func-name-inferrer.cc */; };
9FBE03DE10BD409900F8BFBA /* fast-codegen.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FBE03DC10BD409900F8BFBA /* fast-codegen.cc */; };
9F11D99F105AF0A300EBE5B2 /* heap-profiler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "heap-profiler.h"; sourceTree = "<group>"; };
9F4B7B870FCC877A00DC4117 /* log-utils.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "log-utils.cc"; sourceTree = "<group>"; };
9F4B7B880FCC877A00DC4117 /* log-utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "log-utils.h"; sourceTree = "<group>"; };
+ 9F73E3AE114E61A100F84A5A /* profile-generator-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "profile-generator-inl.h"; sourceTree = "<group>"; };
+ 9F73E3AF114E61A100F84A5A /* profile-generator.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "profile-generator.cc"; sourceTree = "<group>"; };
+ 9F73E3B0114E61A100F84A5A /* profile-generator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "profile-generator.h"; sourceTree = "<group>"; };
9F92FAA70F8F28AD0089F02C /* func-name-inferrer.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "func-name-inferrer.cc"; sourceTree = "<group>"; };
9F92FAA80F8F28AD0089F02C /* func-name-inferrer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "func-name-inferrer.h"; sourceTree = "<group>"; };
9FBE03DC10BD409900F8BFBA /* fast-codegen.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "fast-codegen.cc"; sourceTree = "<group>"; };
897FF16A0E719B8F00D62E90 /* platform.h */,
897FF16B0E719B8F00D62E90 /* prettyprinter.cc */,
897FF16C0E719B8F00D62E90 /* prettyprinter.h */,
+ 9F73E3AE114E61A100F84A5A /* profile-generator-inl.h */,
+ 9F73E3AF114E61A100F84A5A /* profile-generator.cc */,
+ 9F73E3B0114E61A100F84A5A /* profile-generator.h */,
897FF16D0E719B8F00D62E90 /* property.cc */,
897FF16E0E719B8F00D62E90 /* property.h */,
89A15C700EE466D000B48DEB /* regexp-macro-assembler-arm.cc */,
9F11D9A0105AF0A300EBE5B2 /* heap-profiler.cc in Sources */,
9FBE03DE10BD409900F8BFBA /* fast-codegen.cc in Sources */,
9FBE03E210BD40EA00F8BFBA /* fast-codegen-ia32.cc in Sources */,
+ 9F73E3B2114E61A100F84A5A /* profile-generator.cc in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
9F11D9A1105AF0A300EBE5B2 /* heap-profiler.cc in Sources */,
9FBE03DF10BD409900F8BFBA /* fast-codegen.cc in Sources */,
9FBE03E510BD412600F8BFBA /* fast-codegen-arm.cc in Sources */,
+ 9F73E3B1114E61A100F84A5A /* profile-generator.cc in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
RelativePath="..\..\src\parser.h"
>
</File>
+ <File
+ RelativePath="..\..\src\profile-generator.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\profile-generator.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\profile-generator-inl.h"
+ >
+ </File>
<File
RelativePath="..\..\src\platform-win32.cc"
>
RelativePath="..\..\src\parser.h"
>
</File>
+ <File
+ RelativePath="..\..\src\profile-generator.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\profile-generator.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\profile-generator-inl.h"
+ >
+ </File>
<File
RelativePath="..\..\src\platform-win32.cc"
>
RelativePath="..\..\src\parser.h"
>
</File>
+ <File
+ RelativePath="..\..\src\profile-generator.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\profile-generator.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\profile-generator-inl.h"
+ >
+ </File>
<File
RelativePath="..\..\src\platform-win32.cc"
>