2016-04-18 11:46:22 +00:00
|
|
|
# Copyright 2016 the V8 project authors. All rights reserved.
|
|
|
|
# Use of this source code is governed by a BSD-style license that can be
|
|
|
|
# found in the LICENSE file.
|
|
|
|
|
|
|
|
import linux_perf_report as ipr
|
|
|
|
import StringIO
|
|
|
|
import unittest
|
|
|
|
|
|
|
|
|
|
|
|
PERF_SCRIPT_OUTPUT = """
|
|
|
|
# This line is a comment
|
|
|
|
# This should be ignored too
|
|
|
|
#
|
|
|
|
# cdefab01 aRandomSymbol::Name(to, be, ignored)
|
|
|
|
|
|
|
|
00000000 firstSymbol
|
|
|
|
00000123 secondSymbol
|
|
|
|
|
|
|
|
01234567 foo
|
|
|
|
abcdef76 BytecodeHandler:bar
|
|
|
|
76543210 baz
|
|
|
|
|
|
|
|
# Indentation shouldn't matter (neither should this line)
|
|
|
|
|
|
|
|
01234567 foo
|
|
|
|
abcdef76 BytecodeHandler:bar
|
|
|
|
76543210 baz
|
|
|
|
|
|
|
|
01234567 beep
|
|
|
|
abcdef76 BytecodeHandler:bar
|
|
|
|
76543210 baz
|
|
|
|
|
|
|
|
01234567 hello
|
|
|
|
abcdef76 v8::internal::Compiler
|
|
|
|
00000000 Stub:CEntryStub
|
|
|
|
76543210 world
|
|
|
|
11111111 BytecodeHandler:nope
|
|
|
|
|
|
|
|
00000000 Lost
|
|
|
|
11111111 Builtin:InterpreterEntryTrampoline
|
|
|
|
22222222 bar
|
|
|
|
|
2016-11-08 10:37:21 +00:00
|
|
|
00000000 hello
|
|
|
|
11111111 LazyCompile:~Foo
|
|
|
|
|
2016-04-18 11:46:22 +00:00
|
|
|
11111111 Builtin:InterpreterEntryTrampoline
|
|
|
|
22222222 bar
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
class LinuxPerfReportTest(unittest.TestCase):
|
|
|
|
def test_collapsed_callchains_generator(self):
|
|
|
|
perf_stream = StringIO.StringIO(PERF_SCRIPT_OUTPUT)
|
|
|
|
callchains = list(ipr.collapsed_callchains_generator(perf_stream))
|
|
|
|
self.assertListEqual(callchains, [
|
2016-11-08 10:37:21 +00:00
|
|
|
['firstSymbol', 'secondSymbol', '[other]'],
|
|
|
|
["foo", "BytecodeHandler:bar", "[interpreter]"],
|
|
|
|
["foo", "BytecodeHandler:bar", "[interpreter]"],
|
|
|
|
["beep", "BytecodeHandler:bar", "[interpreter]"],
|
|
|
|
["hello", "v8::internal::Compiler", "Stub:CEntryStub", "[compiler]"],
|
|
|
|
["Lost", "[misattributed]"],
|
|
|
|
["hello", "LazyCompile:~Foo", "[jit]"],
|
2016-04-18 11:46:22 +00:00
|
|
|
["[entry trampoline]"],
|
|
|
|
])
|
|
|
|
|
2016-11-08 10:37:21 +00:00
|
|
|
def test_collapsed_callchains_generator_hide_other(self):
|
2016-04-18 11:46:22 +00:00
|
|
|
perf_stream = StringIO.StringIO(PERF_SCRIPT_OUTPUT)
|
|
|
|
callchains = list(ipr.collapsed_callchains_generator(perf_stream,
|
2016-11-08 10:37:21 +00:00
|
|
|
hide_other=True,
|
|
|
|
hide_compiler=True,
|
|
|
|
hide_jit=True))
|
2016-04-18 11:46:22 +00:00
|
|
|
self.assertListEqual(callchains, [
|
2016-11-08 10:37:21 +00:00
|
|
|
["foo", "BytecodeHandler:bar", "[interpreter]"],
|
|
|
|
["foo", "BytecodeHandler:bar", "[interpreter]"],
|
|
|
|
["beep", "BytecodeHandler:bar", "[interpreter]"],
|
2016-04-18 11:46:22 +00:00
|
|
|
["Lost", "[misattributed]"],
|
|
|
|
["[entry trampoline]"],
|
|
|
|
])
|
|
|
|
|
|
|
|
def test_calculate_samples_count_per_callchain(self):
|
|
|
|
counters = ipr.calculate_samples_count_per_callchain([
|
|
|
|
["foo", "BytecodeHandler:bar"],
|
|
|
|
["foo", "BytecodeHandler:bar"],
|
|
|
|
["beep", "BytecodeHandler:bar"],
|
|
|
|
["hello", "v8::internal::Compiler", "[compiler]"],
|
|
|
|
])
|
|
|
|
self.assertItemsEqual(counters, [
|
|
|
|
('BytecodeHandler:bar;foo', 2),
|
|
|
|
('BytecodeHandler:bar;beep', 1),
|
|
|
|
('[compiler];v8::internal::Compiler;hello', 1),
|
|
|
|
])
|
|
|
|
|
|
|
|
def test_calculate_samples_count_per_callchain(self):
|
|
|
|
counters = ipr.calculate_samples_count_per_callchain([
|
|
|
|
["foo", "BytecodeHandler:bar"],
|
|
|
|
["foo", "BytecodeHandler:bar"],
|
|
|
|
["beep", "BytecodeHandler:bar"],
|
|
|
|
])
|
|
|
|
self.assertItemsEqual(counters, [
|
|
|
|
('BytecodeHandler:bar;foo', 2),
|
|
|
|
('BytecodeHandler:bar;beep', 1),
|
|
|
|
])
|
|
|
|
|
|
|
|
def test_calculate_samples_count_per_handler_show_compile(self):
|
|
|
|
counters = ipr.calculate_samples_count_per_handler([
|
|
|
|
["foo", "BytecodeHandler:bar"],
|
|
|
|
["foo", "BytecodeHandler:bar"],
|
|
|
|
["beep", "BytecodeHandler:bar"],
|
|
|
|
["hello", "v8::internal::Compiler", "[compiler]"],
|
|
|
|
])
|
|
|
|
self.assertItemsEqual(counters, [
|
|
|
|
("bar", 3),
|
|
|
|
("[compiler]", 1)
|
|
|
|
])
|
|
|
|
|
|
|
|
def test_calculate_samples_count_per_handler_(self):
|
|
|
|
counters = ipr.calculate_samples_count_per_handler([
|
|
|
|
["foo", "BytecodeHandler:bar"],
|
|
|
|
["foo", "BytecodeHandler:bar"],
|
|
|
|
["beep", "BytecodeHandler:bar"],
|
|
|
|
])
|
|
|
|
self.assertItemsEqual(counters, [("bar", 3)])
|
|
|
|
|
|
|
|
def test_multiple_handlers(self):
|
|
|
|
perf_stream = StringIO.StringIO("""
|
|
|
|
0000 foo(bar)
|
|
|
|
1234 BytecodeHandler:first
|
|
|
|
5678 a::random::call<to>(something, else)
|
|
|
|
9abc BytecodeHandler:second
|
|
|
|
def0 otherIrrelevant(stuff)
|
|
|
|
1111 entrypoint
|
|
|
|
""")
|
|
|
|
callchains = list(ipr.collapsed_callchains_generator(perf_stream, False))
|
|
|
|
self.assertListEqual(callchains, [
|
2016-11-08 10:37:21 +00:00
|
|
|
["foo", "BytecodeHandler:first", "[interpreter]"],
|
2016-04-18 11:46:22 +00:00
|
|
|
])
|
|
|
|
|
|
|
|
def test_compiler_symbols_regex(self):
|
|
|
|
compiler_symbols = [
|
|
|
|
"v8::internal::Parser",
|
|
|
|
"v8::internal::(anonymous namespace)::Compile",
|
|
|
|
"v8::internal::Compiler::foo",
|
|
|
|
]
|
|
|
|
for compiler_symbol in compiler_symbols:
|
|
|
|
self.assertTrue(ipr.COMPILER_SYMBOLS_RE.match(compiler_symbol))
|
|
|
|
|
2016-11-08 10:37:21 +00:00
|
|
|
def test_jit_code_symbols_regex(self):
|
|
|
|
jit_code_symbols = [
|
|
|
|
"LazyCompile:~Foo blah.js",
|
|
|
|
"Eval:*",
|
|
|
|
"Script:*Bar tmp.js",
|
|
|
|
]
|
|
|
|
for jit_code_symbol in jit_code_symbols:
|
|
|
|
self.assertTrue(ipr.JIT_CODE_SYMBOLS_RE.match(jit_code_symbol))
|
|
|
|
|
2016-04-18 11:46:22 +00:00
|
|
|
def test_strip_function_parameters(self):
|
|
|
|
def should_match(signature, name):
|
|
|
|
self.assertEqual(ipr.strip_function_parameters(signature), name)
|
|
|
|
|
|
|
|
should_match("foo(bar)", "foo"),
|
|
|
|
should_match("Foo(foomatic::(anonymous)::bar(baz))", "Foo"),
|
|
|
|
should_match("v8::(anonymous ns)::bar<thing(with, parentheses)>(baz, poe)",
|
|
|
|
"v8::(anonymous ns)::bar<thing(with, parentheses)>")
|
2016-11-08 10:37:21 +00:00
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
unittest.main()
|