diff --git a/src/profile-generator.cc b/src/profile-generator.cc index fb89a221aa..44163a0568 100644 --- a/src/profile-generator.cc +++ b/src/profile-generator.cc @@ -86,6 +86,37 @@ void TokenEnumerator::TokenRemoved(Object** token_location) { } +StringsStorage::StringsStorage() + : names_(StringsMatch) { +} + + +StringsStorage::~StringsStorage() { + for (HashMap::Entry* p = names_.Start(); + p != NULL; + p = names_.Next(p)) { + DeleteArray(reinterpret_cast(p->value)); + } +} + + +const char* StringsStorage::GetName(String* name) { + if (name->IsString()) { + char* c_name = + name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL).Detach(); + HashMap::Entry* cache_entry = names_.Lookup(c_name, name->Hash(), true); + if (cache_entry->value == NULL) { + // New entry added. + cache_entry->value = c_name; + } else { + DeleteArray(c_name); + } + return reinterpret_cast(cache_entry->value); + } + return ""; +} + + const char* CodeEntry::kEmptyNamePrefix = ""; unsigned CodeEntry::next_call_uid_ = 1; @@ -438,8 +469,7 @@ void CodeMap::Print() { CpuProfilesCollection::CpuProfilesCollection() - : function_and_resource_names_(StringsMatch), - profiles_uids_(UidsMatch), + : profiles_uids_(UidsMatch), current_profiles_semaphore_(OS::CreateSemaphore(1)) { // Create list of unabridged profiles. profiles_by_token_.Add(new List()); @@ -470,11 +500,6 @@ CpuProfilesCollection::~CpuProfilesCollection() { profiles_by_token_.Iterate(DeleteProfilesList); code_entries_.Iterate(DeleteCodeEntry); args_count_names_.Iterate(DeleteArgsCountName); - for (HashMap::Entry* p = function_and_resource_names_.Start(); - p != NULL; - p = function_and_resource_names_.Next(p)) { - DeleteArray(reinterpret_cast(p->value)); - } } @@ -666,27 +691,6 @@ CodeEntry* CpuProfilesCollection::NewCodeEntry(int security_token_id) { } -const char* CpuProfilesCollection::GetName(String* name) { - if (name->IsString()) { - char* c_name = - name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL).Detach(); - HashMap::Entry* cache_entry = - function_and_resource_names_.Lookup(c_name, - name->Hash(), - true); - if (cache_entry->value == NULL) { - // New entry added. - cache_entry->value = c_name; - } else { - DeleteArray(c_name); - } - return reinterpret_cast(cache_entry->value); - } else { - return ""; - } -} - - const char* CpuProfilesCollection::GetName(int args_count) { ASSERT(args_count >= 0); if (args_count_names_.length() <= args_count) { diff --git a/src/profile-generator.h b/src/profile-generator.h index d39974ed0e..be0e94ea19 100644 --- a/src/profile-generator.h +++ b/src/profile-generator.h @@ -56,6 +56,28 @@ class TokenEnumerator { }; +// Provides a storage of strings allocated in C++ heap, to hold them +// forever, even if they disappear from JS heap or external storage. +class StringsStorage { + public: + StringsStorage(); + ~StringsStorage(); + + const char* GetName(String* name); + + private: + INLINE(static bool StringsMatch(void* key1, void* key2)) { + return strcmp(reinterpret_cast(key1), + reinterpret_cast(key2)) == 0; + } + + // String::Hash -> const char* + HashMap names_; + + DISALLOW_COPY_AND_ASSIGN(StringsStorage); +}; + + class CodeEntry { public: explicit INLINE(CodeEntry(int security_token_id)); @@ -258,10 +280,12 @@ class CpuProfilesCollection { String* title, double actual_sampling_rate); List* Profiles(int security_token_id); + const char* GetName(String* name) { + return function_and_resource_names_.GetName(name); + } CpuProfile* GetProfile(int security_token_id, unsigned uid); inline bool is_last_profile(); - const char* GetName(String* name); CodeEntry* NewCodeEntry(Logger::LogEventsAndTags tag, String* name, String* resource_name, int line_number); CodeEntry* NewCodeEntry(Logger::LogEventsAndTags tag, const char* name); @@ -280,17 +304,11 @@ class CpuProfilesCollection { List* GetProfilesList(int security_token_id); int TokenToIndex(int security_token_id); - INLINE(static bool StringsMatch(void* key1, void* key2)) { - return strcmp(reinterpret_cast(key1), - reinterpret_cast(key2)) == 0; - } - INLINE(static bool UidsMatch(void* key1, void* key2)) { return key1 == key2; } - // String::Hash -> const char* - HashMap function_and_resource_names_; + StringsStorage function_and_resource_names_; // args_count -> char* List args_count_names_; List code_entries_;