Index: src/profile-generator.cc |
diff --git a/src/profile-generator.cc b/src/profile-generator.cc |
index 5c64d362c36268e5951d5ab2f43f15e5e0d9836f..9d7c3461cd3eaa790de955389d94f97bd5a77fb8 100644 |
--- a/src/profile-generator.cc |
+++ b/src/profile-generator.cc |
@@ -233,63 +233,143 @@ CodeEntry* CodeMap::FindEntry(Address addr) { |
} |
-ProfileGenerator::ProfileGenerator() |
- : resource_names_(StringsMatch) { |
+CpuProfilesCollection::CpuProfilesCollection() |
+ : function_and_resource_names_(StringsMatch) { |
} |
-static void CodeEntriesDeleter(CodeEntry** entry_ptr) { |
+static void DeleteArgsCountName(char** name_ptr) { |
+ DeleteArray(*name_ptr); |
+} |
+ |
+ |
+static void DeleteCodeEntry(CodeEntry** entry_ptr) { |
delete *entry_ptr; |
} |
+static void DeleteCpuProfile(CpuProfile** profile_ptr) { |
+ delete *profile_ptr; |
+} |
+ |
-ProfileGenerator::~ProfileGenerator() { |
- for (HashMap::Entry* p = resource_names_.Start(); |
+CpuProfilesCollection::~CpuProfilesCollection() { |
+ profiles_.Iterate(DeleteCpuProfile); |
+ code_entries_.Iterate(DeleteCodeEntry); |
+ args_count_names_.Iterate(DeleteArgsCountName); |
+ for (HashMap::Entry* p = function_and_resource_names_.Start(); |
p != NULL; |
- p = resource_names_.Next(p)) { |
+ p = function_and_resource_names_.Next(p)) { |
DeleteArray(reinterpret_cast<const char*>(p->value)); |
} |
+} |
- code_entries_.Iterate(CodeEntriesDeleter); |
+ |
+void CpuProfilesCollection::AddProfile(unsigned uid) { |
+ profiles_.Add(new CpuProfile()); |
+} |
+ |
+ |
+CodeEntry* CpuProfilesCollection::NewCodeEntry(Logger::LogEventsAndTags tag, |
+ String* name, |
+ String* resource_name, |
+ int line_number) { |
+ CodeEntry* entry = new CodeEntry(tag, |
+ GetName(name), |
+ GetName(resource_name), |
+ line_number); |
+ code_entries_.Add(entry); |
+ return entry; |
+} |
+ |
+ |
+CodeEntry* CpuProfilesCollection::NewCodeEntry(Logger::LogEventsAndTags tag, |
+ const char* name) { |
+ CodeEntry* entry = new CodeEntry(tag, name, "", 0); |
+ code_entries_.Add(entry); |
+ return entry; |
+} |
+ |
+ |
+CodeEntry* CpuProfilesCollection::NewCodeEntry(Logger::LogEventsAndTags tag, |
+ int args_count) { |
+ CodeEntry* entry = new CodeEntry(tag, GetName(args_count), "", 0); |
+ code_entries_.Add(entry); |
+ return entry; |
} |
-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. |
+const char* CpuProfilesCollection::GetName(String* name) { |
+ if (name->IsString()) { |
+ char* c_name = |
+ name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL).Detach(); |
HashMap::Entry* cache_entry = |
- resource_names_.Lookup(resource_name, |
- StringEntryHash(resource_name), |
- true); |
+ function_and_resource_names_.Lookup(c_name, |
+ name->Hash(), |
+ true); |
if (cache_entry->value == NULL) { |
// New entry added. |
- cache_entry->value = |
- resource_name->ToCString(DISALLOW_NULLS, |
- ROBUST_STRING_TRAVERSAL).Detach(); |
+ cache_entry->value = c_name; |
+ } else { |
+ DeleteArray(c_name); |
} |
- cached_resource_name = reinterpret_cast<const char*>(cache_entry->value); |
+ return reinterpret_cast<const char*>(cache_entry->value); |
+ } else { |
+ return ""; |
} |
+} |
- CodeEntry* entry = new ManagedNameCodeEntry(tag, |
- name, |
- cached_resource_name, |
- line_number); |
- code_entries_.Add(entry); |
- return entry; |
+ |
+const char* CpuProfilesCollection::GetName(int args_count) { |
+ ASSERT(args_count >= 0); |
+ if (args_count_names_.length() <= args_count) { |
+ args_count_names_.AddBlock( |
+ NULL, args_count - args_count_names_.length() + 1); |
+ } |
+ if (args_count_names_[args_count] == NULL) { |
+ const int kMaximumNameLength = 32; |
+ char* name = NewArray<char>(kMaximumNameLength); |
+ OS::SNPrintF(Vector<char>(name, kMaximumNameLength), |
+ "args_count: %d", args_count); |
+ args_count_names_[args_count] = name; |
+ } |
+ return args_count_names_[args_count]; |
} |
-CodeEntry* ProfileGenerator::NewCodeEntry( |
- Logger::LogEventsAndTags tag, |
- const char* name) { |
- CodeEntry* entry = new StaticNameCodeEntry(tag, name); |
- code_entries_.Add(entry); |
- return entry; |
+ProfileGenerator::ProfileGenerator(CpuProfilesCollection* profiles) |
+ : profiles_(profiles) { |
} |
+ |
+void ProfileGenerator::RecordTickSample(const TickSample& sample) { |
+ // Allocate space for stack frames + pc + function. |
+ ScopedVector<CodeEntry*> entries(sample.frames_count + 2); |
+ CodeEntry** entry = entries.start(); |
+ *entry++ = code_map_.FindEntry(sample.pc); |
+ |
+ if (sample.function != NULL) { |
+ *entry = code_map_.FindEntry(sample.function); |
+ if (*entry != NULL && !(*entry)->is_js_function()) { |
+ *entry = NULL; |
+ } else { |
+ CodeEntry* pc_entry = *entries.start(); |
+ if (pc_entry == NULL || pc_entry->is_js_function()) |
+ *entry = NULL; |
+ } |
+ entry++; |
+ } else { |
+ *entry++ = NULL; |
+ } |
+ |
+ for (const Address *stack_pos = sample.stack, |
+ *stack_end = stack_pos + sample.frames_count; |
+ stack_pos != stack_end; |
+ ++stack_pos) { |
+ *entry++ = code_map_.FindEntry(*stack_pos); |
+ } |
+ |
+ profile()->AddPath(entries); |
+} |
+ |
+ |
} } // namespace v8::internal |