Show RegExp calls in the profile.
It turns out they were filtered out. But when I unfiltered them, I discovered another issue: when DevTools run, regexp literals get recompiled each time they called (looks like this is concerned with switching to full compiler), so I ended up having multiple entries for the same regexp. To fix this, I changed the way of how code entries equivalence is considered. BUG=crbug/55999 TEST=cctest/test-profile-generator/ProfileNodeFindOrAddChildForSameFunction (the test isn't for the whole issue, but rather for equivalence testing) Review URL: http://codereview.chromium.org/3426008 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@5492 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
fc9915b770
commit
c1903ce332
@ -4433,7 +4433,7 @@ double CpuProfileNode::GetSelfSamplesCount() const {
|
|||||||
|
|
||||||
unsigned CpuProfileNode::GetCallUid() const {
|
unsigned CpuProfileNode::GetCallUid() const {
|
||||||
IsDeadCheck("v8::CpuProfileNode::GetCallUid");
|
IsDeadCheck("v8::CpuProfileNode::GetCallUid");
|
||||||
return reinterpret_cast<const i::ProfileNode*>(this)->entry()->call_uid();
|
return reinterpret_cast<const i::ProfileNode*>(this)->entry()->GetCallUid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -82,14 +82,11 @@ TickSample* ProfilerEventsProcessor::TickSampleEvent() {
|
|||||||
|
|
||||||
bool ProfilerEventsProcessor::FilterOutCodeCreateEvent(
|
bool ProfilerEventsProcessor::FilterOutCodeCreateEvent(
|
||||||
Logger::LogEventsAndTags tag) {
|
Logger::LogEventsAndTags tag) {
|
||||||
// In browser mode, leave only callbacks and non-native JS entries.
|
|
||||||
// We filter out regular expressions as currently we can't tell
|
|
||||||
// whether they origin from native scripts, so let's not confise people by
|
|
||||||
// showing them weird regexes they didn't wrote.
|
|
||||||
return FLAG_prof_browser_mode
|
return FLAG_prof_browser_mode
|
||||||
&& (tag != Logger::CALLBACK_TAG
|
&& (tag != Logger::CALLBACK_TAG
|
||||||
&& tag != Logger::FUNCTION_TAG
|
&& tag != Logger::FUNCTION_TAG
|
||||||
&& tag != Logger::LAZY_COMPILE_TAG
|
&& tag != Logger::LAZY_COMPILE_TAG
|
||||||
|
&& tag != Logger::REG_EXP_TAG
|
||||||
&& tag != Logger::SCRIPT_TAG);
|
&& tag != Logger::SCRIPT_TAG);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,8 +46,7 @@ const char* StringsStorage::GetFunctionName(const char* name) {
|
|||||||
|
|
||||||
|
|
||||||
CodeEntry::CodeEntry(int security_token_id)
|
CodeEntry::CodeEntry(int security_token_id)
|
||||||
: call_uid_(0),
|
: tag_(Logger::FUNCTION_TAG),
|
||||||
tag_(Logger::FUNCTION_TAG),
|
|
||||||
name_prefix_(kEmptyNamePrefix),
|
name_prefix_(kEmptyNamePrefix),
|
||||||
name_(""),
|
name_(""),
|
||||||
resource_name_(""),
|
resource_name_(""),
|
||||||
@ -62,8 +61,7 @@ CodeEntry::CodeEntry(Logger::LogEventsAndTags tag,
|
|||||||
const char* resource_name,
|
const char* resource_name,
|
||||||
int line_number,
|
int line_number,
|
||||||
int security_token_id)
|
int security_token_id)
|
||||||
: call_uid_(next_call_uid_++),
|
: tag_(tag),
|
||||||
tag_(tag),
|
|
||||||
name_prefix_(name_prefix),
|
name_prefix_(name_prefix),
|
||||||
name_(name),
|
name_(name),
|
||||||
resource_name_(resource_name),
|
resource_name_(resource_name),
|
||||||
|
@ -121,11 +121,9 @@ const char* StringsStorage::GetName(String* name) {
|
|||||||
|
|
||||||
|
|
||||||
const char* CodeEntry::kEmptyNamePrefix = "";
|
const char* CodeEntry::kEmptyNamePrefix = "";
|
||||||
unsigned CodeEntry::next_call_uid_ = 1;
|
|
||||||
|
|
||||||
|
|
||||||
void CodeEntry::CopyData(const CodeEntry& source) {
|
void CodeEntry::CopyData(const CodeEntry& source) {
|
||||||
call_uid_ = source.call_uid_;
|
|
||||||
tag_ = source.tag_;
|
tag_ = source.tag_;
|
||||||
name_prefix_ = source.name_prefix_;
|
name_prefix_ = source.name_prefix_;
|
||||||
name_ = source.name_;
|
name_ = source.name_;
|
||||||
@ -134,6 +132,26 @@ void CodeEntry::CopyData(const CodeEntry& source) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t CodeEntry::GetCallUid() const {
|
||||||
|
uint32_t hash = ComputeIntegerHash(tag_);
|
||||||
|
hash ^= static_cast<int32_t>(reinterpret_cast<intptr_t>(name_prefix_));
|
||||||
|
hash ^= static_cast<int32_t>(reinterpret_cast<intptr_t>(name_));
|
||||||
|
hash ^= static_cast<int32_t>(reinterpret_cast<intptr_t>(resource_name_));
|
||||||
|
hash ^= static_cast<int32_t>(line_number_);
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool CodeEntry::IsSameAs(CodeEntry* entry) const {
|
||||||
|
return this == entry
|
||||||
|
|| (tag_ == entry->tag_
|
||||||
|
&& name_prefix_ == entry->name_prefix_
|
||||||
|
&& name_ == entry->name_
|
||||||
|
&& resource_name_ == entry->resource_name_
|
||||||
|
&& line_number_ == entry->line_number_);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
ProfileNode* ProfileNode::FindChild(CodeEntry* entry) {
|
ProfileNode* ProfileNode::FindChild(CodeEntry* entry) {
|
||||||
HashMap::Entry* map_entry =
|
HashMap::Entry* map_entry =
|
||||||
children_.Lookup(entry, CodeEntryHash(entry), false);
|
children_.Lookup(entry, CodeEntryHash(entry), false);
|
||||||
|
@ -100,17 +100,17 @@ class CodeEntry {
|
|||||||
INLINE(const char* name() const) { return name_; }
|
INLINE(const char* name() const) { return name_; }
|
||||||
INLINE(const char* resource_name() const) { return resource_name_; }
|
INLINE(const char* resource_name() const) { return resource_name_; }
|
||||||
INLINE(int line_number() const) { return line_number_; }
|
INLINE(int line_number() const) { return line_number_; }
|
||||||
INLINE(unsigned call_uid() const) { return call_uid_; }
|
|
||||||
INLINE(int security_token_id() const) { return security_token_id_; }
|
INLINE(int security_token_id() const) { return security_token_id_; }
|
||||||
|
|
||||||
INLINE(static bool is_js_function_tag(Logger::LogEventsAndTags tag));
|
INLINE(static bool is_js_function_tag(Logger::LogEventsAndTags tag));
|
||||||
|
|
||||||
void CopyData(const CodeEntry& source);
|
void CopyData(const CodeEntry& source);
|
||||||
|
uint32_t GetCallUid() const;
|
||||||
|
bool IsSameAs(CodeEntry* entry) const;
|
||||||
|
|
||||||
static const char* kEmptyNamePrefix;
|
static const char* kEmptyNamePrefix;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
unsigned call_uid_;
|
|
||||||
Logger::LogEventsAndTags tag_;
|
Logger::LogEventsAndTags tag_;
|
||||||
const char* name_prefix_;
|
const char* name_prefix_;
|
||||||
const char* name_;
|
const char* name_;
|
||||||
@ -118,8 +118,6 @@ class CodeEntry {
|
|||||||
int line_number_;
|
int line_number_;
|
||||||
int security_token_id_;
|
int security_token_id_;
|
||||||
|
|
||||||
static unsigned next_call_uid_;
|
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(CodeEntry);
|
DISALLOW_COPY_AND_ASSIGN(CodeEntry);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -147,11 +145,12 @@ class ProfileNode {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
INLINE(static bool CodeEntriesMatch(void* entry1, void* entry2)) {
|
INLINE(static bool CodeEntriesMatch(void* entry1, void* entry2)) {
|
||||||
return entry1 == entry2;
|
return reinterpret_cast<CodeEntry*>(entry1)->IsSameAs(
|
||||||
|
reinterpret_cast<CodeEntry*>(entry2));
|
||||||
}
|
}
|
||||||
|
|
||||||
INLINE(static uint32_t CodeEntryHash(CodeEntry* entry)) {
|
INLINE(static uint32_t CodeEntryHash(CodeEntry* entry)) {
|
||||||
return static_cast<int32_t>(reinterpret_cast<intptr_t>(entry));
|
return entry->GetCallUid();
|
||||||
}
|
}
|
||||||
|
|
||||||
ProfileTree* tree_;
|
ProfileTree* tree_;
|
||||||
|
@ -89,6 +89,24 @@ TEST(ProfileNodeFindOrAddChild) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TEST(ProfileNodeFindOrAddChildForSameFunction) {
|
||||||
|
ProfileNode node(NULL, NULL);
|
||||||
|
CodeEntry entry1(i::Logger::FUNCTION_TAG, "", "aaa", "", 0,
|
||||||
|
TokenEnumerator::kNoSecurityToken);
|
||||||
|
ProfileNode* childNode1 = node.FindOrAddChild(&entry1);
|
||||||
|
CHECK_NE(NULL, childNode1);
|
||||||
|
CHECK_EQ(childNode1, node.FindOrAddChild(&entry1));
|
||||||
|
// The same function again.
|
||||||
|
CodeEntry entry2(i::Logger::FUNCTION_TAG, "", "aaa", "", 0,
|
||||||
|
TokenEnumerator::kNoSecurityToken);
|
||||||
|
CHECK_EQ(childNode1, node.FindOrAddChild(&entry2));
|
||||||
|
// Now with a different security token.
|
||||||
|
CodeEntry entry3(i::Logger::FUNCTION_TAG, "", "aaa", "", 0,
|
||||||
|
TokenEnumerator::kNoSecurityToken + 1);
|
||||||
|
CHECK_EQ(childNode1, node.FindOrAddChild(&entry3));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
class ProfileTreeTestHelper {
|
class ProfileTreeTestHelper {
|
||||||
|
Loading…
Reference in New Issue
Block a user