Author: mikhail.naga...@gmail.com Date: Tue Jul 14 02:47:44 2009 New Revision: 2455
Modified: branches/bleeding_edge/test/mjsunit/tools/codemap.js branches/bleeding_edge/test/mjsunit/tools/profile.js branches/bleeding_edge/test/mjsunit/tools/tickprocessor-test.default branches/bleeding_edge/test/mjsunit/tools/tickprocessor-test.ignore-unknown branches/bleeding_edge/test/mjsunit/tools/tickprocessor-test.separate-ic branches/bleeding_edge/test/mjsunit/tools/tickprocessor.js branches/bleeding_edge/tools/codemap.js branches/bleeding_edge/tools/profile.js branches/bleeding_edge/tools/tickprocessor.js Log: TickProcessor: more accurate mapping of statically compiled code on Linux. 'nm' is now called with an option to report function code sizes. Static code entries are restricted to the sizes reported, and the remaining unnamed code is attributed to a library as a whole. This makes reports more accurate, as some functions are tiny, but has chunks of unnamed code behind them. This change doesn't affect reporting on Windows, as in .map files function code sizes aren't specified. Review URL: http://codereview.chromium.org/149513 Modified: branches/bleeding_edge/test/mjsunit/tools/codemap.js ============================================================================== --- branches/bleeding_edge/test/mjsunit/tools/codemap.js (original) +++ branches/bleeding_edge/test/mjsunit/tools/codemap.js Tue Jul 14 02:47:44 2009 @@ -46,11 +46,11 @@ }; -(function testStaticCode() { +(function testLibrariesAndStaticCode() { var codeMap = new devtools.profiler.CodeMap(); - codeMap.addStaticCode(0x1500, newCodeEntry(0x3000, 'lib1')); - codeMap.addStaticCode(0x15500, newCodeEntry(0x5000, 'lib2')); - codeMap.addStaticCode(0x155500, newCodeEntry(0x10000, 'lib3')); + codeMap.addLibrary(0x1500, newCodeEntry(0x3000, 'lib1')); + codeMap.addLibrary(0x15500, newCodeEntry(0x5000, 'lib2')); + codeMap.addLibrary(0x155500, newCodeEntry(0x10000, 'lib3')); assertNoEntry(codeMap, 0); assertNoEntry(codeMap, 0x1500 - 1); assertEntry(codeMap, 'lib1', 0x1500); @@ -71,6 +71,28 @@ assertEntry(codeMap, 'lib3', 0x155500 + 0x10000 - 1); assertNoEntry(codeMap, 0x155500 + 0x10000); assertNoEntry(codeMap, 0xFFFFFFFF); + + codeMap.addStaticCode(0x1510, newCodeEntry(0x30, 'lib1-f1')); + codeMap.addStaticCode(0x1600, newCodeEntry(0x50, 'lib1-f2')); + codeMap.addStaticCode(0x15520, newCodeEntry(0x100, 'lib2-f1')); + assertEntry(codeMap, 'lib1', 0x1500); + assertEntry(codeMap, 'lib1', 0x1510 - 1); + assertEntry(codeMap, 'lib1-f1', 0x1510); + assertEntry(codeMap, 'lib1-f1', 0x1510 + 0x15); + assertEntry(codeMap, 'lib1-f1', 0x1510 + 0x30 - 1); + assertEntry(codeMap, 'lib1', 0x1510 + 0x30); + assertEntry(codeMap, 'lib1', 0x1600 - 1); + assertEntry(codeMap, 'lib1-f2', 0x1600); + assertEntry(codeMap, 'lib1-f2', 0x1600 + 0x30); + assertEntry(codeMap, 'lib1-f2', 0x1600 + 0x50 - 1); + assertEntry(codeMap, 'lib1', 0x1600 + 0x50); + assertEntry(codeMap, 'lib2', 0x15500); + assertEntry(codeMap, 'lib2', 0x15520 - 1); + assertEntry(codeMap, 'lib2-f1', 0x15520); + assertEntry(codeMap, 'lib2-f1', 0x15520 + 0x80); + assertEntry(codeMap, 'lib2-f1', 0x15520 + 0x100 - 1); + assertEntry(codeMap, 'lib2', 0x15520 + 0x100); + })(); Modified: branches/bleeding_edge/test/mjsunit/tools/profile.js ============================================================================== --- branches/bleeding_edge/test/mjsunit/tools/profile.js (original) +++ branches/bleeding_edge/test/mjsunit/tools/profile.js Tue Jul 14 02:47:44 2009 @@ -72,10 +72,10 @@ ProfileTestDriver.prototype.addFunctions_ = function() { - this.profile.addStaticCode('lib1', 0x11000, 0x12000); + this.profile.addLibrary('lib1', 0x11000, 0x12000); this.profile.addStaticCode('lib1-f1', 0x11100, 0x11900); this.profile.addStaticCode('lib1-f2', 0x11200, 0x11500); - this.profile.addStaticCode('lib2', 0x21000, 0x22000); + this.profile.addLibrary('lib2', 0x21000, 0x22000); this.profile.addStaticCode('lib2-f1', 0x21100, 0x21900); this.profile.addStaticCode('lib2-f2', 0x21200, 0x21500); this.profile.addCode('T', 'F1', 0x50100, 0x100); Modified: branches/bleeding_edge/test/mjsunit/tools/tickprocessor-test.default ============================================================================== --- branches/bleeding_edge/test/mjsunit/tools/tickprocessor-test.default (original) +++ branches/bleeding_edge/test/mjsunit/tools/tickprocessor-test.default Tue Jul 14 02:47:44 2009 @@ -6,20 +6,19 @@ [Shared libraries]: ticks total nonlib name - 2 15.4% 0.0% /lib32/libm-2.7.so + 3 23.1% 0.0% /lib32/libm-2.7.so 1 7.7% 0.0% ffffe000-fffff000 [JavaScript]: ticks total nonlib name - 1 7.7% 10.0% LazyCompile: exp native math.js:41 + 1 7.7% 11.1% LazyCompile: exp native math.js:41 [C++]: ticks total nonlib name - 2 15.4% 20.0% v8::internal::Runtime_Math_exp(v8::internal::Arguments) - 1 7.7% 10.0% v8::internal::JSObject::LocalLookupRealNamedProperty(v8::internal::String*, v8::internal::LookupResult*) - 1 7.7% 10.0% v8::internal::HashTable<v8::internal::StringDictionaryShape, v8::internal::String*>::FindEntry(v8::internal::String*) - 1 7.7% 10.0% fegetexcept - 1 7.7% 10.0% exp + 2 15.4% 22.2% v8::internal::Runtime_Math_exp(v8::internal::Arguments) + 1 7.7% 11.1% v8::internal::JSObject::LocalLookupRealNamedProperty(v8::internal::String*, v8::internal::LookupResult*) + 1 7.7% 11.1% v8::internal::HashTable<v8::internal::StringDictionaryShape, v8::internal::String*>::FindEntry(v8::internal::String*) + 1 7.7% 11.1% exp [GC]: ticks total nonlib name @@ -31,11 +30,11 @@ Callers occupying less than 2.0% are not shown. ticks parent name - 2 15.4% v8::internal::Runtime_Math_exp(v8::internal::Arguments) - 2 100.0% LazyCompile: exp native math.js:41 - 2 100.0% Script: exp.js + 3 23.1% /lib32/libm-2.7.so + 3 100.0% LazyCompile: exp native math.js:41 + 3 100.0% Script: exp.js - 2 15.4% /lib32/libm-2.7.so + 2 15.4% v8::internal::Runtime_Math_exp(v8::internal::Arguments) 2 100.0% LazyCompile: exp native math.js:41 2 100.0% Script: exp.js @@ -46,10 +45,6 @@ 1 100.0% Script: exp.js 1 7.7% ffffe000-fffff000 - - 1 7.7% fegetexcept - 1 100.0% LazyCompile: exp native math.js:41 - 1 100.0% Script: exp.js 1 7.7% exp 1 100.0% LazyCompile: exp native math.js:41 Modified: branches/bleeding_edge/test/mjsunit/tools/tickprocessor-test.ignore-unknown ============================================================================== --- branches/bleeding_edge/test/mjsunit/tools/tickprocessor-test.ignore-unknown (original) +++ branches/bleeding_edge/test/mjsunit/tools/tickprocessor-test.ignore-unknown Tue Jul 14 02:47:44 2009 @@ -2,20 +2,19 @@ [Shared libraries]: ticks total nonlib name - 2 18.2% 0.0% /lib32/libm-2.7.so + 3 27.3% 0.0% /lib32/libm-2.7.so 1 9.1% 0.0% ffffe000-fffff000 [JavaScript]: ticks total nonlib name - 1 9.1% 12.5% LazyCompile: exp native math.js:41 + 1 9.1% 14.3% LazyCompile: exp native math.js:41 [C++]: ticks total nonlib name - 2 18.2% 25.0% v8::internal::Runtime_Math_exp(v8::internal::Arguments) - 1 9.1% 12.5% v8::internal::JSObject::LocalLookupRealNamedProperty(v8::internal::String*, v8::internal::LookupResult*) - 1 9.1% 12.5% v8::internal::HashTable<v8::internal::StringDictionaryShape, v8::internal::String*>::FindEntry(v8::internal::String*) - 1 9.1% 12.5% fegetexcept - 1 9.1% 12.5% exp + 2 18.2% 28.6% v8::internal::Runtime_Math_exp(v8::internal::Arguments) + 1 9.1% 14.3% v8::internal::JSObject::LocalLookupRealNamedProperty(v8::internal::String*, v8::internal::LookupResult*) + 1 9.1% 14.3% v8::internal::HashTable<v8::internal::StringDictionaryShape, v8::internal::String*>::FindEntry(v8::internal::String*) + 1 9.1% 14.3% exp [GC]: ticks total nonlib name @@ -27,11 +26,11 @@ Callers occupying less than 2.0% are not shown. ticks parent name - 2 18.2% v8::internal::Runtime_Math_exp(v8::internal::Arguments) - 2 100.0% LazyCompile: exp native math.js:41 - 2 100.0% Script: exp.js + 3 27.3% /lib32/libm-2.7.so + 3 100.0% LazyCompile: exp native math.js:41 + 3 100.0% Script: exp.js - 2 18.2% /lib32/libm-2.7.so + 2 18.2% v8::internal::Runtime_Math_exp(v8::internal::Arguments) 2 100.0% LazyCompile: exp native math.js:41 2 100.0% Script: exp.js @@ -42,10 +41,6 @@ 1 100.0% Script: exp.js 1 9.1% ffffe000-fffff000 - - 1 9.1% fegetexcept - 1 100.0% LazyCompile: exp native math.js:41 - 1 100.0% Script: exp.js 1 9.1% exp 1 100.0% LazyCompile: exp native math.js:41 Modified: branches/bleeding_edge/test/mjsunit/tools/tickprocessor-test.separate-ic ============================================================================== --- branches/bleeding_edge/test/mjsunit/tools/tickprocessor-test.separate-ic (original) +++ branches/bleeding_edge/test/mjsunit/tools/tickprocessor-test.separate-ic Tue Jul 14 02:47:44 2009 @@ -6,22 +6,21 @@ [Shared libraries]: ticks total nonlib name - 2 15.4% 0.0% /lib32/libm-2.7.so + 3 23.1% 0.0% /lib32/libm-2.7.so 1 7.7% 0.0% ffffe000-fffff000 [JavaScript]: ticks total nonlib name - 1 7.7% 10.0% LoadIC: j - 1 7.7% 10.0% LoadIC: i - 1 7.7% 10.0% LazyCompile: exp native math.js:41 + 1 7.7% 11.1% LoadIC: j + 1 7.7% 11.1% LoadIC: i + 1 7.7% 11.1% LazyCompile: exp native math.js:41 [C++]: ticks total nonlib name - 2 15.4% 20.0% v8::internal::Runtime_Math_exp(v8::internal::Arguments) - 1 7.7% 10.0% v8::internal::JSObject::LocalLookupRealNamedProperty(v8::internal::String*, v8::internal::LookupResult*) - 1 7.7% 10.0% v8::internal::HashTable<v8::internal::StringDictionaryShape, v8::internal::String*>::FindEntry(v8::internal::String*) - 1 7.7% 10.0% fegetexcept - 1 7.7% 10.0% exp + 2 15.4% 22.2% v8::internal::Runtime_Math_exp(v8::internal::Arguments) + 1 7.7% 11.1% v8::internal::JSObject::LocalLookupRealNamedProperty(v8::internal::String*, v8::internal::LookupResult*) + 1 7.7% 11.1% v8::internal::HashTable<v8::internal::StringDictionaryShape, v8::internal::String*>::FindEntry(v8::internal::String*) + 1 7.7% 11.1% exp [GC]: ticks total nonlib name @@ -33,11 +32,11 @@ Callers occupying less than 2.0% are not shown. ticks parent name - 2 15.4% v8::internal::Runtime_Math_exp(v8::internal::Arguments) - 2 100.0% LazyCompile: exp native math.js:41 - 2 100.0% Script: exp.js + 3 23.1% /lib32/libm-2.7.so + 3 100.0% LazyCompile: exp native math.js:41 + 3 100.0% Script: exp.js - 2 15.4% /lib32/libm-2.7.so + 2 15.4% v8::internal::Runtime_Math_exp(v8::internal::Arguments) 2 100.0% LazyCompile: exp native math.js:41 2 100.0% Script: exp.js @@ -48,10 +47,6 @@ 1 100.0% Script: exp.js 1 7.7% ffffe000-fffff000 - - 1 7.7% fegetexcept - 1 100.0% LazyCompile: exp native math.js:41 - 1 100.0% Script: exp.js 1 7.7% exp 1 100.0% LazyCompile: exp native math.js:41 Modified: branches/bleeding_edge/test/mjsunit/tools/tickprocessor.js ============================================================================== --- branches/bleeding_edge/test/mjsunit/tools/tickprocessor.js (original) +++ branches/bleeding_edge/test/mjsunit/tools/tickprocessor.js Tue Jul 14 02:47:44 2009 @@ -31,6 +31,7 @@ // Files: tools/logreader.js tools/tickprocessor.js // Env: TEST_FILE_NAME + (function testArgumentsProcessor() { var p_default = new ArgumentsProcessor([]); assertTrue(p_default.parse()); @@ -69,12 +70,12 @@ ' U operator delete[](void*)@@GLIBCXX_3.4', '08049790 T _init', '08049f50 T _start', - '08139150 t v8::internal::Runtime_StringReplaceRegExpWithString(v8::internal::Arguments)', - '08139ca0 T v8::internal::Runtime::GetElementOrCharAt(v8::internal::Handle<v8::internal::Object>, unsigned int)', - '0813a0b0 t v8::internal::Runtime_DebugGetPropertyDetails(v8::internal::Arguments)', - '08181d30 W v8::internal::RegExpMacroAssemblerIrregexp::stack_limit_slack()', + '08139150 00000b4b t v8::internal::Runtime_StringReplaceRegExpWithString(v8::internal::Arguments)', + '08139ca0 000003f1 T v8::internal::Runtime::GetElementOrCharAt(v8::internal::Handle<v8::internal::Object>, unsigned int)', + '0813a0b0 00000855 t v8::internal::Runtime_DebugGetPropertyDetails(v8::internal::Arguments)', + '0818b220 00000036 W v8::internal::RegExpMacroAssembler::CheckPosition(int, v8::internal::Label*)', ' w __gmon_start__', - '081f08a0 B stdout' + '081f08a0 00000004 B stdout\n' ].join('\n'), '']; }; @@ -87,22 +88,22 @@ assertEquals( [['_init', 0x08049790, 0x08049f50], ['_start', 0x08049f50, 0x08139150], - ['v8::internal::Runtime_StringReplaceRegExpWithString(v8::internal::Arguments)', 0x08139150, 0x08139ca0], - ['v8::internal::Runtime::GetElementOrCharAt(v8::internal::Handle<v8::internal::Object>, unsigned int)', 0x08139ca0, 0x0813a0b0], - ['v8::internal::Runtime_DebugGetPropertyDetails(v8::internal::Arguments)', 0x0813a0b0, 0x08181d30], - ['v8::internal::RegExpMacroAssemblerIrregexp::stack_limit_slack()', 0x08181d30, 0x081ee000]], + ['v8::internal::Runtime_StringReplaceRegExpWithString(v8::internal::Arguments)', 0x08139150, 0x08139150 + 0xb4b], + ['v8::internal::Runtime::GetElementOrCharAt(v8::internal::Handle<v8::internal::Object>, unsigned int)', 0x08139ca0, 0x08139ca0 + 0x3f1], + ['v8::internal::Runtime_DebugGetPropertyDetails(v8::internal::Arguments)', 0x0813a0b0, 0x0813a0b0 + 0x855], + ['v8::internal::RegExpMacroAssembler::CheckPosition(int, v8::internal::Label*)', 0x0818b220, 0x0818b220 + 0x36]], shell_syms); // libc library UnixCppEntriesProvider.prototype.loadSymbols = function(libName) { this.symbols = [[ - '000162a0 T __libc_init_first', - '0002a5f0 T __isnan', - '0002a5f0 W isnan', - '0002aaa0 W scalblnf', - '0002aaa0 W scalbnf', - '0011a340 T __libc_thread_freeres', - '00128860 R _itoa_lower_digits'].join('\n'), '']; + '000162a0 00000005 T __libc_init_first', + '0002a5f0 0000002d T __isnan', + '0002a5f0 0000002d W isnan', + '0002aaa0 0000000d W scalblnf', + '0002aaa0 0000000d W scalbnf', + '0011a340 00000048 T __libc_thread_freeres', + '00128860 00000024 R _itoa_lower_digits\n'].join('\n'), '']; }; var libc_prov = new UnixCppEntriesProvider(); var libc_syms = []; @@ -110,17 +111,81 @@ function (name, start, end) { libc_syms.push(Array.prototype.slice.apply(arguments, [0])); }); - assertEquals( - [['__libc_init_first', 0xf7c5c000 + 0x000162a0, 0xf7c5c000 + 0x0002a5f0], - ['isnan', 0xf7c5c000 + 0x0002a5f0, 0xf7c5c000 + 0x0002aaa0], - ['scalbnf', 0xf7c5c000 + 0x0002aaa0, 0xf7c5c000 + 0x0011a340], - ['__libc_thread_freeres', 0xf7c5c000 + 0x0011a340, 0xf7da5000]], - libc_syms); + var libc_ref_syms = [['__libc_init_first', 0x000162a0, 0x000162a0 + 0x5], + ['__isnan', 0x0002a5f0, 0x0002a5f0 + 0x2d], + ['scalblnf', 0x0002aaa0, 0x0002aaa0 + 0xd], + ['__libc_thread_freeres', 0x0011a340, 0x0011a340 + 0x48]]; + for (var i = 0; i < libc_ref_syms.length; ++i) { + libc_ref_syms[i][1] += 0xf7c5c000; + libc_ref_syms[i][2] += 0xf7c5c000; + } + assertEquals(libc_ref_syms, libc_syms); UnixCppEntriesProvider.prototype.loadSymbols = oldLoadSymbols; })(); +(function testMacCppEntriesProvider() { + var oldLoadSymbols = MacCppEntriesProvider.prototype.loadSymbols; + + // shell executable + MacCppEntriesProvider.prototype.loadSymbols = function(libName) { + this.symbols = [[ + ' U operator delete[]', + '00001000 A __mh_execute_header', + '00001b00 T start', + '00001b40 t dyld_stub_binding_helper', + '0011b710 T v8::internal::RegExpMacroAssembler::CheckPosition', + '00134250 t v8::internal::Runtime_StringReplaceRegExpWithString', + '00137220 T v8::internal::Runtime::GetElementOrCharAt', + '00137400 t v8::internal::Runtime_DebugGetPropertyDetails', + '001c1a80 b _private_mem\n' + ].join('\n'), '']; + }; + + var shell_prov = new MacCppEntriesProvider(); + var shell_syms = []; + shell_prov.parseVmSymbols('shell', 0x00001b00, 0x00163156, + function (name, start, end) { + shell_syms.push(Array.prototype.slice.apply(arguments, [0])); + }); + assertEquals( + [['start', 0x00001b00, 0x00001b40], + ['dyld_stub_binding_helper', 0x00001b40, 0x0011b710], + ['v8::internal::RegExpMacroAssembler::CheckPosition', 0x0011b710, 0x00134250], + ['v8::internal::Runtime_StringReplaceRegExpWithString', 0x00134250, 0x00137220], + ['v8::internal::Runtime::GetElementOrCharAt', 0x00137220, 0x00137400], + ['v8::internal::Runtime_DebugGetPropertyDetails', 0x00137400, 0x00163156]], + shell_syms); + + // stdc++ library + MacCppEntriesProvider.prototype.loadSymbols = function(libName) { + this.symbols = [[ + '0000107a T __gnu_cxx::balloc::__mini_vector<std::pair<__gnu_cxx::bitmap_allocator<char>::_Alloc_block*, __gnu_cxx::bitmap_allocator<char>::_Alloc_block*> >::__mini_vector', + '0002c410 T std::basic_streambuf<char, std::char_traits<char> >::pubseekoff', + '0002c488 T std::basic_streambuf<char, std::char_traits<char> >::pubseekpos', + '000466aa T ___cxa_pure_virtual\n'].join('\n'), '']; + }; + var stdc_prov = new MacCppEntriesProvider(); + var stdc_syms = []; + stdc_prov.parseVmSymbols('stdc++', 0x95728fb4, 0x95770005, + function (name, start, end) { + stdc_syms.push(Array.prototype.slice.apply(arguments, [0])); + }); + var stdc_ref_syms = [['__gnu_cxx::balloc::__mini_vector<std::pair<__gnu_cxx::bitmap_allocator<char>::_Alloc_block*, __gnu_cxx::bitmap_allocator<char>::_Alloc_block*> >::__mini_vector', 0x0000107a, 0x0002c410], + ['std::basic_streambuf<char, std::char_traits<char> >::pubseekoff', 0x0002c410, 0x0002c488], + ['std::basic_streambuf<char, std::char_traits<char> >::pubseekpos', 0x0002c488, 0x000466aa], + ['___cxa_pure_virtual', 0x000466aa, 0x95770005 - 0x95728fb4]]; + for (var i = 0; i < stdc_ref_syms.length; ++i) { + stdc_ref_syms[i][1] += 0x95728fb4; + stdc_ref_syms[i][2] += 0x95728fb4; + } + assertEquals(stdc_ref_syms, stdc_syms); + + MacCppEntriesProvider.prototype.loadSymbols = oldLoadSymbols; +})(); + + (function testWindowsCppEntriesProvider() { var oldLoadSymbols = WindowsCppEntriesProvider.prototype.loadSymbols; @@ -174,8 +239,8 @@ ['v8::internal::HashTable<v8::internal::StringDictionaryShape, v8::internal::String*>::FindEntry(v8::internal::String*)', 0x080f8210, 0x080f8800], ['v8::internal::Runtime_Math_exp(v8::internal::Arguments)', 0x08123b20, 0x08123b80]], '/lib32/libm-2.7.so': - [['exp', startAddr + 0x00009e80, startAddr + 0x00009f30], - ['fegetexcept', startAddr + 0x000061e0, startAddr + 0x00008b10]], + [['exp', startAddr + 0x00009e80, startAddr + 0x00009e80 + 0xa3], + ['fegetexcept', startAddr + 0x000061e0, startAddr + 0x000061e0 + 0x15]], 'ffffe000-fffff000': []}; assertTrue(name in symbols); var syms = symbols[name]; @@ -191,6 +256,7 @@ var outputPos = 0; var diffs = this.diffs = []; var realOut = this.realOut = []; + var unexpectedOut = this.unexpectedOut = null; this.oldPrint = print; print = function(str) { @@ -198,13 +264,15 @@ for (var i = 0; i < strSplit.length; ++i) { s = strSplit[i]; realOut.push(s); - assertTrue(outputPos < expectedOut.length, - 'unexpected output: "' + s + '"'); - if (expectedOut[outputPos] != s) { - diffs.push('line ' + outputPos + ': expected <' + - expectedOut[outputPos] + '> found <' + s + '>\n'); + if (outputPos < expectedOut.length) { + if (expectedOut[outputPos] != s) { + diffs.push('line ' + outputPos + ': expected <' + + expectedOut[outputPos] + '> found <' + s + '>\n'); + } + outputPos++; + } else { + unexpectedOut = true; } - outputPos++; } }; }; @@ -218,9 +286,10 @@ PrintMonitor.prototype.finish = function() { print = this.oldPrint; - if (this.diffs.length > 0) { + if (this.diffs.length > 0 || this.unexpectedOut != null) { print(this.realOut.join('\n')); assertEquals([], this.diffs); + assertNull(this.unexpectedOut); } }; Modified: branches/bleeding_edge/tools/codemap.js ============================================================================== --- branches/bleeding_edge/tools/codemap.js (original) +++ branches/bleeding_edge/tools/codemap.js Tue Jul 14 02:47:44 2009 @@ -48,11 +48,16 @@ this.dynamicsNameGen_ = new devtools.profiler.CodeMap.NameGenerator(); /** - * Static code entries. Used for libraries code. + * Static code entries. Used for statically compiled code. */ this.statics_ = new goog.structs.SplayTree(); /** + * Libraries entries. Used for the whole static code libraries. + */ + this.libraries_ = new goog.structs.SplayTree(); + + /** * Map of memory pages occupied with static code. */ this.pages_ = []; @@ -108,6 +113,19 @@ /** + * Adds a library entry. + * + * @param {number} start The starting address. + * @param {devtools.profiler.CodeMap.CodeEntry} codeEntry Code entry object. + */ +devtools.profiler.CodeMap.prototype.addLibrary = function( + start, codeEntry) { + this.markPages_(start, start + codeEntry.size); + this.libraries_.insert(start, codeEntry); +}; + + +/** * Adds a static code entry. * * @param {number} start The starting address. @@ -115,7 +133,6 @@ */ devtools.profiler.CodeMap.prototype.addStaticCode = function( start, codeEntry) { - this.markPages_(start, start + codeEntry.size); this.statics_.insert(start, codeEntry); }; @@ -157,7 +174,10 @@ devtools.profiler.CodeMap.prototype.findEntry = function(addr) { var pageAddr = addr >>> devtools.profiler.CodeMap.PAGE_ALIGNMENT; if (pageAddr in this.pages_) { - return this.findInTree_(this.statics_, addr); + // Static code entries can contain "holes" of unnamed code. + // In this case, the whole library is assigned to this address. + return this.findInTree_(this.statics_, addr) || + this.findInTree_(this.libraries_, addr); } var min = this.dynamics_.findMin(); var max = this.dynamics_.findMax(); @@ -176,7 +196,7 @@ /** - * Returns an array of all dynamic code entries, including deleted ones. + * Returns an array of all dynamic code entries. */ devtools.profiler.CodeMap.prototype.getAllDynamicEntries = function() { return this.dynamics_.exportValues(); @@ -188,6 +208,14 @@ */ devtools.profiler.CodeMap.prototype.getAllStaticEntries = function() { return this.statics_.exportValues(); +}; + + +/** + * Returns an array of all libraries entries. + */ +devtools.profiler.CodeMap.prototype.getAllLibrariesEntries = function() { + return this.libraries_.exportValues(); }; Modified: branches/bleeding_edge/tools/profile.js ============================================================================== --- branches/bleeding_edge/tools/profile.js (original) +++ branches/bleeding_edge/tools/profile.js Tue Jul 14 02:47:44 2009 @@ -86,7 +86,23 @@ /** - * Registers static (library) code entry. + * Registers a library. + * + * @param {string} name Code entry name. + * @param {number} startAddr Starting address. + * @param {number} endAddr Ending address. + */ +devtools.profiler.Profile.prototype.addLibrary = function( + name, startAddr, endAddr) { + var entry = new devtools.profiler.CodeMap.CodeEntry( + endAddr - startAddr, name); + this.codeMap_.addLibrary(startAddr, entry); + return entry; +}; + + +/** + * Registers statically compiled code entry. * * @param {string} name Code entry name. * @param {number} startAddr Starting address. Modified: branches/bleeding_edge/tools/tickprocessor.js ============================================================================== --- branches/bleeding_edge/tools/tickprocessor.js (original) +++ branches/bleeding_edge/tools/tickprocessor.js Tue Jul 14 02:47:44 2009 @@ -174,7 +174,7 @@ TickProcessor.prototype.processSharedLibrary = function( name, startAddr, endAddr) { - var entry = this.profile_.addStaticCode(name, startAddr, endAddr); + var entry = this.profile_.addLibrary(name, startAddr, endAddr); this.setCodeType(entry.getName(), 'SHARED_LIB'); var self = this; @@ -380,14 +380,21 @@ var prevEntry; - function addPrevEntry(end) { + function addEntry(funcInfo) { // Several functions can be mapped onto the same address. To avoid // creating zero-sized entries, skip such duplicates. // Also double-check that function belongs to the library address space. - if (prevEntry && prevEntry.start < end && - prevEntry.start >= libStart && end <= libEnd) { - processorFunc(prevEntry.name, prevEntry.start, end); + if (prevEntry && !prevEntry.end && + prevEntry.start < funcInfo.start && + prevEntry.start >= libStart && funcInfo.start <= libEnd) { + processorFunc(prevEntry.name, prevEntry.start, funcInfo.start); } + if (funcInfo.end && + (!prevEntry || prevEntry.start != funcInfo.start) && + funcInfo.start >= libStart && funcInfo.end <= libEnd) { + processorFunc(funcInfo.name, funcInfo.start, funcInfo.end); + } + prevEntry = funcInfo; } while (true) { @@ -400,10 +407,12 @@ if (funcInfo.start < libStart && funcInfo.start < libEnd - libStart) { funcInfo.start += libStart; } - addPrevEntry(funcInfo.start); - prevEntry = funcInfo; + if (funcInfo.size) { + funcInfo.end = funcInfo.start + funcInfo.size; + } + addEntry(funcInfo); } - addPrevEntry(libEnd); + addEntry({name: '', start: libEnd}); }; @@ -420,7 +429,7 @@ this.symbols = []; this.parsePos = 0; this.nmExec = nmExec; - this.FUNC_RE = /^([0-9a-fA-F]{8}) [tTwW] (.*)$/; + this.FUNC_RE = /^([0-9a-fA-F]{8}) ([0-9a-fA-F]{8} )?[tTwW] (.*)$/; }; inherits(UnixCppEntriesProvider, CppEntriesProvider); @@ -429,8 +438,8 @@ this.parsePos = 0; try { this.symbols = [ - os.system(this.nmExec, ['-C', '-n', libName], -1, -1), - os.system(this.nmExec, ['-C', '-n', '-D', libName], -1, -1) + os.system(this.nmExec, ['-C', '-n', '-S', libName], -1, -1), + os.system(this.nmExec, ['-C', '-n', '-S', '-D', libName], -1, -1) ]; } catch (e) { // If the library cannot be found on this system let's not panic. @@ -453,13 +462,21 @@ var line = this.symbols[0].substring(this.parsePos, lineEndPos); this.parsePos = lineEndPos + 1; var fields = line.match(this.FUNC_RE); - return fields ? { name: fields[2], start: parseInt(fields[1], 16) } : null; + var funcInfo = null; + if (fields) { + funcInfo = { name: fields[3], start: parseInt(fields[1], 16) }; + if (fields[2]) { + funcInfo.size = parseInt(fields[2], 16); + } + } + return funcInfo; }; function MacCppEntriesProvider(nmExec) { UnixCppEntriesProvider.call(this, nmExec); - this.FUNC_RE = /^([0-9a-fA-F]{8}) [iItT] (.*)$/; + // Note an empty group. It is required, as UnixCppEntriesProvider expects 3 groups. + this.FUNC_RE = /^([0-9a-fA-F]{8}) ()[iItT] (.*)$/; }; inherits(MacCppEntriesProvider, UnixCppEntriesProvider); --~--~---------~--~----~------------~-------~--~----~ v8-dev mailing list v8-dev@googlegroups.com http://groups.google.com/group/v8-dev -~----------~----~----~----~------~----~------~--~---