Author: [email protected]
Date: Wed Jul  8 23:39:38 2009
New Revision: 2407

Added:
    branches/bleeding_edge/test/mjsunit/tools/tickprocessor-test.default
    branches/bleeding_edge/test/mjsunit/tools/tickprocessor-test.gc-state
     
branches/bleeding_edge/test/mjsunit/tools/tickprocessor-test.ignore-unknown
    branches/bleeding_edge/test/mjsunit/tools/tickprocessor-test.log
    branches/bleeding_edge/test/mjsunit/tools/tickprocessor-test.separate-ic
    branches/bleeding_edge/test/mjsunit/tools/tickprocessor.js
    branches/bleeding_edge/tools/tickprocessor-driver.js
Modified:
    branches/bleeding_edge/test/mjsunit/testcfg.py
    branches/bleeding_edge/tools/linux-tick-processor
    branches/bleeding_edge/tools/test.py
    branches/bleeding_edge/tools/tickprocessor.js
    branches/bleeding_edge/tools/windows-tick-processor.bat

Log:
Add automatic tests for Tick Processor, take two.

Now tests can be run from any directory. Location of test data is now  
determined using test file location provided by 'testcfg.py' script.

Tested under Linux, Mac, and Windows.

Review URL: http://codereview.chromium.org/155161


Modified: branches/bleeding_edge/test/mjsunit/testcfg.py
==============================================================================
--- branches/bleeding_edge/test/mjsunit/testcfg.py      (original)
+++ branches/bleeding_edge/test/mjsunit/testcfg.py      Wed Jul  8 23:39:38 2009
@@ -29,10 +29,12 @@
  import os
  from os.path import join, dirname, exists
  import re
+import tempfile


  FLAGS_PATTERN = re.compile(r"//\s+Flags:(.*)")
  FILES_PATTERN = re.compile(r"//\s+Files:(.*)")
+SELF_SCRIPT_PATTERN = re.compile(r"//\s+Env: TEST_FILE_NAME")


  class MjsunitTestCase(test.TestCase):
@@ -42,6 +44,7 @@
      self.file = file
      self.config = config
      self.mode = mode
+    self.self_script = False

    def GetLabel(self):
      return "%s %s" % (self.mode, self.GetName())
@@ -55,19 +58,43 @@
      flags_match = FLAGS_PATTERN.search(source)
      if flags_match:
        result += flags_match.group(1).strip().split()
-    files_match = FILES_PATTERN.search(source);
      additional_files = []
-    if files_match:
-      additional_files += files_match.group(1).strip().split()
+    files_match = FILES_PATTERN.search(source);
+    # Accept several lines of 'Files:'
+    while True:
+      if files_match:
+        additional_files += files_match.group(1).strip().split()
+        files_match = FILES_PATTERN.search(source, files_match.end())
+      else:
+        break
      for a_file in additional_files:
        result.append(join(dirname(self.config.root), '..', a_file))
      framework = join(dirname(self.config.root), 'mjsunit', 'mjsunit.js')
+    if SELF_SCRIPT_PATTERN.search(source):
+      result.append(self.CreateSelfScript())
      result += [framework, self.file]
      return result

    def GetSource(self):
      return open(self.file).read()

+  def CreateSelfScript(self):
+    (fd_self_script, self_script) = tempfile.mkstemp(suffix=".js")
+    def MakeJsConst(name, value):
+      return "var %(name)s=\'%(value)s\';\n" % \
+             {'name': name, \
+              'value': value.replace('\\', '\\\\').replace('\'', '\\\'') }
+    try:
+      os.write(fd_self_script, MakeJsConst('TEST_FILE_NAME', self.file))
+    except IOError, e:
+      test.PrintError("write() " + str(e))
+    os.close(fd_self_script)
+    self.self_script = self_script
+    return self_script
+
+  def Cleanup(self):
+    if self.self_script:
+      test.CheckedUnlink(self.self_script)

  class MjsunitTestConfiguration(test.TestConfiguration):


Added: branches/bleeding_edge/test/mjsunit/tools/tickprocessor-test.default
==============================================================================
--- (empty file)
+++ branches/bleeding_edge/test/mjsunit/tools/tickprocessor-test.default        
 
Wed Jul  8 23:39:38 2009
@@ -0,0 +1,60 @@
+Statistical profiling result from v8.log, (13 ticks, 2 unaccounted, 0  
excluded).
+
+ [Unknown]:
+   ticks  total  nonlib   name
+      2   15.4%
+
+ [Shared libraries]:
+   ticks  total  nonlib   name
+      2   15.4%    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
+
+ [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
+
+ [GC]:
+   ticks  total  nonlib   name
+      0    0.0%
+
+ [Bottom up (heavy) profile]:
+  Note: percentage shows a share of a particular caller in the total
+  amount of its parent calls.
+  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
+
+      2   15.4%  /lib32/libm-2.7.so
+      2  100.0%    LazyCompile: exp native math.js:41
+      2  100.0%      Script: exp.js
+
+      1    7.7%   
v8::internal::JSObject::LocalLookupRealNamedProperty(v8::internal::String*,  
v8::internal::LookupResult*)
+      1  100.0%    Script: exp.js
+
+      1    7.7%   
v8::internal::HashTable<v8::internal::StringDictionaryShape,  
v8::internal::String*>::FindEntry(v8::internal::String*)
+      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
+      1  100.0%      Script: exp.js
+
+      1    7.7%  LazyCompile: exp native math.js:41
+      1  100.0%    Script: exp.js
+

Added: branches/bleeding_edge/test/mjsunit/tools/tickprocessor-test.gc-state
==============================================================================
--- (empty file)
+++ branches/bleeding_edge/test/mjsunit/tools/tickprocessor-test.gc-state       
 
Wed Jul  8 23:39:38 2009
@@ -0,0 +1,21 @@
+Statistical profiling result from v8.log, (13 ticks, 0 unaccounted, 13  
excluded).
+
+ [Shared libraries]:
+   ticks  total  nonlib   name
+
+ [JavaScript]:
+   ticks  total  nonlib   name
+
+ [C++]:
+   ticks  total  nonlib   name
+
+ [GC]:
+   ticks  total  nonlib   name
+      0    0.0%
+
+ [Bottom up (heavy) profile]:
+  Note: percentage shows a share of a particular caller in the total
+  amount of its parent calls.
+  Callers occupying less than 2.0% are not shown.
+
+   ticks parent  name

Added:  
branches/bleeding_edge/test/mjsunit/tools/tickprocessor-test.ignore-unknown
==============================================================================
--- (empty file)
+++  
branches/bleeding_edge/test/mjsunit/tools/tickprocessor-test.ignore-unknown     
 
Wed Jul  8 23:39:38 2009
@@ -0,0 +1,56 @@
+Statistical profiling result from v8.log, (13 ticks, 2 unaccounted, 0  
excluded).
+
+ [Shared libraries]:
+   ticks  total  nonlib   name
+      2   18.2%    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
+
+ [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
+
+ [GC]:
+   ticks  total  nonlib   name
+      0    0.0%
+
+ [Bottom up (heavy) profile]:
+  Note: percentage shows a share of a particular caller in the total
+  amount of its parent calls.
+  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
+
+      2   18.2%  /lib32/libm-2.7.so
+      2  100.0%    LazyCompile: exp native math.js:41
+      2  100.0%      Script: exp.js
+
+      1    9.1%   
v8::internal::JSObject::LocalLookupRealNamedProperty(v8::internal::String*,  
v8::internal::LookupResult*)
+      1  100.0%    Script: exp.js
+
+      1    9.1%   
v8::internal::HashTable<v8::internal::StringDictionaryShape,  
v8::internal::String*>::FindEntry(v8::internal::String*)
+      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
+      1  100.0%      Script: exp.js
+
+      1    9.1%  LazyCompile: exp native math.js:41
+      1  100.0%    Script: exp.js
+

Added: branches/bleeding_edge/test/mjsunit/tools/tickprocessor-test.log
==============================================================================
--- (empty file)
+++ branches/bleeding_edge/test/mjsunit/tools/tickprocessor-test.log    Wed  
Jul  8 23:39:38 2009
@@ -0,0 +1,24 @@
+shared-library,"shell",0x08048000,0x081ee000
+shared-library,"/lib32/libm-2.7.so",0xf7db6000,0xf7dd9000
+shared-library,"ffffe000-fffff000",0xffffe000,0xfffff000
+profiler,"begin",1
+code-creation,Stub,0xf540a100,474,"CEntryStub"
+code-creation,Script,0xf541cd80,736,"exp.js"
+code-creation,Stub,0xf541d0e0,47,"RuntimeStub_Math_exp"
+code-creation,LazyCompile,0xf541d120,145,"exp native math.js:41"
+code-creation,LoadIC,0xf541d280,117,"j"
+code-creation,LoadIC,0xf541d360,63,"i"
+tick,0x80f82d1,0xffdfe880,0,0xf541ce5c
+tick,0x80f89a1,0xffdfecf0,0,0xf541ce5c
+tick,0x8123b5c,0xffdff1a0,0,0xf541d1a1,0xf541ceea
+tick,0x8123b65,0xffdff1a0,0,0xf541d1a1,0xf541ceea
+tick,0xf541d2be,0xffdff1e4,0
+tick,0xf541d320,0xffdff1dc,0
+tick,0xf541d384,0xffdff1d8,0
+tick,0xf7db94da,0xffdff0ec,0,0xf541d1a1,0xf541ceea
+tick,0xf7db951c,0xffdff0f0,0,0xf541d1a1,0xf541ceea
+tick,0xf7dbc508,0xffdff14c,0,0xf541d1a1,0xf541ceea
+tick,0xf7dbff21,0xffdff198,0,0xf541d1a1,0xf541ceea
+tick,0xf7edec90,0xffdff0ec,0,0xf541d1a1,0xf541ceea
+tick,0xffffe402,0xffdff488,0
+profiler,"end"

Added:  
branches/bleeding_edge/test/mjsunit/tools/tickprocessor-test.separate-ic
==============================================================================
--- (empty file)
+++  
branches/bleeding_edge/test/mjsunit/tools/tickprocessor-test.separate-ic        
 
Wed Jul  8 23:39:38 2009
@@ -0,0 +1,66 @@
+Statistical profiling result from v8.log, (13 ticks, 2 unaccounted, 0  
excluded).
+
+ [Unknown]:
+   ticks  total  nonlib   name
+      2   15.4%
+
+ [Shared libraries]:
+   ticks  total  nonlib   name
+      2   15.4%    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
+
+ [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
+
+ [GC]:
+   ticks  total  nonlib   name
+      0    0.0%
+
+ [Bottom up (heavy) profile]:
+  Note: percentage shows a share of a particular caller in the total
+  amount of its parent calls.
+  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
+
+      2   15.4%  /lib32/libm-2.7.so
+      2  100.0%    LazyCompile: exp native math.js:41
+      2  100.0%      Script: exp.js
+
+      1    7.7%   
v8::internal::JSObject::LocalLookupRealNamedProperty(v8::internal::String*,  
v8::internal::LookupResult*)
+      1  100.0%    Script: exp.js
+
+      1    7.7%   
v8::internal::HashTable<v8::internal::StringDictionaryShape,  
v8::internal::String*>::FindEntry(v8::internal::String*)
+      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
+      1  100.0%      Script: exp.js
+
+      1    7.7%  LoadIC: j
+
+      1    7.7%  LoadIC: i
+
+      1    7.7%  LazyCompile: exp native math.js:41
+      1  100.0%    Script: exp.js
+

Added: branches/bleeding_edge/test/mjsunit/tools/tickprocessor.js
==============================================================================
--- (empty file)
+++ branches/bleeding_edge/test/mjsunit/tools/tickprocessor.js  Wed Jul  8  
23:39:38 2009
@@ -0,0 +1,268 @@
+// Copyright 2009 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Load implementations from <project root>/tools.
+// Files: tools/splaytree.js tools/codemap.js tools/csvparser.js
+// Files: tools/consarray.js tools/profile.js tools/profile_view.js
+// Files: tools/logreader.js tools/tickprocessor.js
+// Env: TEST_FILE_NAME
+
+(function testArgumentsProcessor() {
+  var p_default = new ArgumentsProcessor([]);
+  assertTrue(p_default.parse());
+  assertEquals(ArgumentsProcessor.DEFAULTS, p_default.result());
+
+  var p_logFile = new ArgumentsProcessor(['logfile.log']);
+  assertTrue(p_logFile.parse());
+  assertEquals('logfile.log', p_logFile.result().logFileName);
+
+  var p_platformAndLog = new  
ArgumentsProcessor(['--windows', 'winlog.log']);
+  assertTrue(p_platformAndLog.parse());
+  assertEquals('windows', p_platformAndLog.result().platform);
+  assertEquals('winlog.log', p_platformAndLog.result().logFileName);
+
+  var p_flags = new ArgumentsProcessor(['--gc', '--separate-ic']);
+  assertTrue(p_flags.parse());
+  assertEquals(TickProcessor.VmStates.GC, p_flags.result().stateFilter);
+  assertTrue(p_flags.result().separateIc);
+
+  var p_nmAndLog = new ArgumentsProcessor(['--nm=mn', 'nmlog.log']);
+  assertTrue(p_nmAndLog.parse());
+  assertEquals('mn', p_nmAndLog.result().nm);
+  assertEquals('nmlog.log', p_nmAndLog.result().logFileName);
+
+  var p_bad = new ArgumentsProcessor(['--unknown', 'badlog.log']);
+  assertFalse(p_bad.parse());
+})();
+
+
+(function testUnixCppEntriesProvider() {
+  var oldLoadSymbols = UnixCppEntriesProvider.prototype.loadSymbols;
+
+  // shell executable
+  UnixCppEntriesProvider.prototype.loadSymbols = function(libName) {
+    this.symbols = [[
+      '         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()',
+      '         w __gmon_start__',
+      '081f08a0 B stdout'
+    ].join('\n'), ''];
+  };
+
+  var shell_prov = new UnixCppEntriesProvider();
+  var shell_syms = [];
+  shell_prov.parseVmSymbols('shell', 0x08048000, 0x081ee000,
+      function (name, start, end) {
+        shell_syms.push(Array.prototype.slice.apply(arguments, [0]));
+      });
+  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]],
+      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'), ''];
+  };
+  var libc_prov = new UnixCppEntriesProvider();
+  var libc_syms = [];
+  libc_prov.parseVmSymbols('libc', 0xf7c5c000, 0xf7da5000,
+      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);
+
+  UnixCppEntriesProvider.prototype.loadSymbols = oldLoadSymbols;
+})();
+
+
+(function testWindowsCppEntriesProvider() {
+  var oldLoadSymbols = WindowsCppEntriesProvider.prototype.loadSymbols;
+
+  WindowsCppEntriesProvider.prototype.loadSymbols = function(libName) {
+    this.symbols = [
+      ' Start         Length     Name                   Class',
+      ' 0001:00000000 000ac902H .text                   CODE',
+      ' 0001:000ac910 000005e2H .text$yc                CODE',
+      '  Address         Publics by Value              Rva+Base        
Lib:Object',
+      ' 0000:00000000       __except_list              00000000      
<absolute>',
+      '  
0001:00000000       ?ReadFile@@ya?av?$han...@vstring@v8@@@v8@@p...@z  
00401000 f   shell.obj',
+      '  
0001:000000a0       ?Print@@ya?av?$han...@vvalue@v8@@@v8@@abvargume...@2@@Z  
004010a0 f   shell.obj',
+      ' 0001:00001230       ??1utf8buf...@internal@v8@@q...@xz 00402230 f    
v8_snapshot:scanner.obj',
+      ' 0001:00001230       ??1utf8va...@string@v8@@q...@xz 00402230 f    
v8_snapshot:api.obj',
+      ' 0001:000954ba       __fclose_nolock            004964ba f    
LIBCMT:fclose.obj',
+      ' 0002:00000000       __imp__setthreadprior...@8 004af000      
kernel32:KERNEL32.dll',
+      '  
0003:00000418       ?in_use_li...@preallocatedstorage@inter...@v8@@0v...@a  
00544418     v8_snapshot:allocation.obj',
+      ' Static symbols',
+      ' 0001:00000b70       ?defaultfatalerrorhand...@v8@@yaxp...@z  
00401b70 f   v8_snapshot:api.obj',
+      ' 0001:000010b0       ?ensureinitiali...@v8@@yax...@z 004020b0 f    
v8_snapshot:api.obj',
+      ' 0001:000ad17b       ??__fno...@?5???2@yap...@z@YAXXZ 004ae17b f    
LIBCMT:new.obj'
+    ].join('\r\n');
+  };
+  var shell_prov = new WindowsCppEntriesProvider();
+  var shell_syms = [];
+  shell_prov.parseVmSymbols('shell.exe', 0x00400000, 0x0057c000,
+      function (name, start, end) {
+        shell_syms.push(Array.prototype.slice.apply(arguments, [0]));
+      });
+  assertEquals(
+      [['ReadFile', 0x00401000, 0x004010a0],
+       ['Print', 0x004010a0, 0x00402230],
+       ['v8::String::?1Utf8Value', 0x00402230, 0x004964ba],
+       ['v8::DefaultFatalErrorHandler', 0x00401b70, 0x004020b0],
+       ['v8::EnsureInitialized', 0x004020b0, 0x0057c000]],
+      shell_syms);
+
+  WindowsCppEntriesProvider.prototype.loadSymbols = oldLoadSymbols;
+})();
+
+
+function CppEntriesProviderMock() {
+};
+
+
+CppEntriesProviderMock.prototype.parseVmSymbols = function(
+    name, startAddr, endAddr, symbolAdder) {
+  var symbols = {
+    'shell':
+         
[['v8::internal::JSObject::LocalLookupRealNamedProperty(v8::internal::String*,  
v8::internal::LookupResult*)', 0x080f8800, 0x080f8d90],
+         ['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]],
+    'ffffe000-fffff000': []};
+  assertTrue(name in symbols);
+  var syms = symbols[name];
+  for (var i = 0; i < syms.length; ++i) {
+    symbolAdder.apply(null, syms[i]);
+  }
+};
+
+
+function PrintMonitor(outputOrFileName) {
+  var expectedOut = typeof outputOrFileName == 'string' ?
+      this.loadExpectedOutput(outputOrFileName) : outputOrFileName;
+  var outputPos = 0;
+  var diffs = this.diffs = [];
+  var realOut = this.realOut = [];
+
+  this.oldPrint = print;
+  print = function(str) {
+    var strSplit = str.split('\n');
+    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');
+      }
+      outputPos++;
+    }
+  };
+};
+
+
+PrintMonitor.prototype.loadExpectedOutput = function(fileName) {
+  var output = readFile(fileName);
+  return output.split('\n');
+};
+
+
+PrintMonitor.prototype.finish = function() {
+  print = this.oldPrint;
+  if (this.diffs.length > 0) {
+    print(this.realOut.join('\n'));
+    assertEquals([], this.diffs);
+  }
+};
+
+
+function driveTickProcessorTest(
+    separateIc, ignoreUnknown, stateFilter, logInput, refOutput) {
+  // TEST_FILE_NAME must be provided by test runner.
+  assertEquals('string', typeof TEST_FILE_NAME);
+  var pathLen = TEST_FILE_NAME.lastIndexOf('/');
+  if (pathLen == -1) {
+    pathLen = TEST_FILE_NAME.lastIndexOf('\\');
+  }
+  assertTrue(pathLen != -1);
+  var testsPath = TEST_FILE_NAME.substr(0, pathLen + 1);
+  var tp = new TickProcessor(
+      new CppEntriesProviderMock(), separateIc, ignoreUnknown,  
stateFilter);
+  var pm = new PrintMonitor(testsPath + refOutput);
+  tp.processLogFile(testsPath + logInput);
+  // Hack file name to avoid dealing with platform specifics.
+  tp.lastLogFileName_ = 'v8.log';
+  tp.printStatistics();
+  pm.finish();
+};
+
+
+(function testProcessing() {
+  var testData = {
+    'Default': [
+      false, false, null,
+      'tickprocessor-test.log', 'tickprocessor-test.default'],
+    'SeparateIc': [
+      true, false, null,
+      'tickprocessor-test.log', 'tickprocessor-test.separate-ic'],
+    'IgnoreUnknown': [
+      false, true, null,
+      'tickprocessor-test.log', 'tickprocessor-test.ignore-unknown'],
+    'GcState': [
+      false, false, TickProcessor.VmStates.GC,
+      'tickprocessor-test.log', 'tickprocessor-test.gc-state']
+  };
+  for (var testName in testData) {
+    print('=== testProcessing-' + testName + ' ===');
+    driveTickProcessorTest.apply(null, testData[testName]);
+  }
+})();

Modified: branches/bleeding_edge/tools/linux-tick-processor
==============================================================================
--- branches/bleeding_edge/tools/linux-tick-processor   (original)
+++ branches/bleeding_edge/tools/linux-tick-processor   Wed Jul  8 23:39:38  
2009
@@ -20,4 +20,5 @@
  $d8_exec $tools_path/splaytree.js $tools_path/codemap.js \
    $tools_path/csvparser.js $tools_path/consarray.js \
    $tools_path/profile.js $tools_path/profile_view.js \
-  $tools_path/logreader.js $tools_path/tickprocessor.js -- $@ 2>/dev/null
+  $tools_path/logreader.js $tools_path/tickprocessor.js \
+  $tools_path/tickprocessor-driver.js -- $@ 2>/dev/null

Modified: branches/bleeding_edge/tools/test.py
==============================================================================
--- branches/bleeding_edge/tools/test.py        (original)
+++ branches/bleeding_edge/tools/test.py        Wed Jul  8 23:39:38 2009
@@ -356,11 +356,15 @@
    def RunCommand(self, command):
      full_command = self.context.processor(command)
      output = Execute(full_command, self.context, self.context.timeout)
+    self.Cleanup()
      return TestOutput(self, full_command, output)

    def Run(self):
      return self.RunCommand(self.GetCommand())

+  def Cleanup(self):
+    return
+

  class TestOutput(object):

@@ -473,6 +477,13 @@
    sys.stderr.write('\n')


+def CheckedUnlink(name):
+  try:
+    os.unlink(name)
+  except OSError, e:
+    PrintError("os.unlink() " + str(e))
+
+
  def Execute(args, context, timeout=None):
    (fd_out, outname) = tempfile.mkstemp()
    (fd_err, errname) = tempfile.mkstemp()
@@ -487,11 +498,6 @@
    os.close(fd_err)
    output = file(outname).read()
    errors = file(errname).read()
-  def CheckedUnlink(name):
-    try:
-      os.unlink(name)
-    except OSError, e:
-      PrintError("os.unlink() " + str(e))
    CheckedUnlink(outname)
    CheckedUnlink(errname)
    return CommandOutput(exit_code, timed_out, output, errors)

Added: branches/bleeding_edge/tools/tickprocessor-driver.js
==============================================================================
--- (empty file)
+++ branches/bleeding_edge/tools/tickprocessor-driver.js        Wed Jul  8  
23:39:38 2009
@@ -0,0 +1,49 @@
+// Copyright 2009 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+// Tick Processor's code flow.
+
+function processArguments(args) {
+  var processor = new ArgumentsProcessor(args);
+  if (processor.parse()) {
+    return processor.result();
+  } else {
+    processor.printUsageAndExit();
+  }
+}
+
+
+var params = processArguments(arguments);
+var tickProcessor = new TickProcessor(
+  params.platform == 'unix' ? new UnixCppEntriesProvider(params.nm) :
+    new WindowsCppEntriesProvider(),
+  params.separateIc,
+  params.ignoreUnknown,
+  params.stateFilter);
+tickProcessor.processLogFile(params.logFileName);
+tickProcessor.printStatistics();

Modified: branches/bleeding_edge/tools/tickprocessor.js
==============================================================================
--- branches/bleeding_edge/tools/tickprocessor.js       (original)
+++ branches/bleeding_edge/tools/tickprocessor.js       Wed Jul  8 23:39:38 2009
@@ -288,7 +288,11 @@
  function padLeft(s, len) {
    s = s.toString();
    if (s.length < len) {
-    s = (new Array(len - s.length + 1).join(' ')) + s;
+    var padLength = len - s.length;
+    if (!(padLength in padLeft)) {
+      padLeft[padLength] = new Array(padLength + 1).join(' ');
+    }
+    s = padLeft[padLength] + s;
    }
    return s;
  };
@@ -511,25 +515,11 @@
  };


-function padRight(s, len) {
-  s = s.toString();
-  if (s.length < len) {
-    s = s + (new Array(len - s.length + 1).join(' '));
-  }
-  return s;
-};
+function ArgumentsProcessor(args) {
+  this.args_ = args;
+  this.result_ = ArgumentsProcessor.DEFAULTS;

-
-function processArguments(args) {
-  var result = {
-    logFileName: 'v8.log',
-    platform: 'unix',
-    stateFilter: null,
-    ignoreUnknown: false,
-    separateIc: false,
-    nm: 'nm'
-  };
-  var argsDispatch = {
+  this.argsDispatch_ = {
      '-j': ['stateFilter', TickProcessor.VmStates.JS,
          'Show only ticks from JS VM state'],
      '-g': ['stateFilter', TickProcessor.VmStates.GC,
@@ -551,63 +541,82 @@
      '--nm': ['nm', 'nm',
          'Specify the \'nm\' executable to use (e.g. --nm=/my_dir/nm)']
    };
-  argsDispatch['--js'] = argsDispatch['-j'];
-  argsDispatch['--gc'] = argsDispatch['-g'];
-  argsDispatch['--compiler'] = argsDispatch['-c'];
-  argsDispatch['--other'] = argsDispatch['-o'];
-  argsDispatch['--external'] = argsDispatch['-e'];
-
-  function printUsageAndExit() {
-    print('Cmdline args: [options] [log-file-name]\n' +
-          'Default log file name is "v8.log".\n');
-    print('Options:');
-    for (var arg in argsDispatch) {
-      var synonims = [arg];
-      var dispatch = argsDispatch[arg];
-      for (var synArg in argsDispatch) {
-        if (arg !== synArg && dispatch === argsDispatch[synArg]) {
-          synonims.push(synArg);
-          delete argsDispatch[synArg];
-        }
-      }
-      print('  ' + padRight(synonims.join(', '), 20) + dispatch[2]);
-    }
-    quit(2);
-  }
+  this.argsDispatch_['--js'] = this.argsDispatch_['-j'];
+  this.argsDispatch_['--gc'] = this.argsDispatch_['-g'];
+  this.argsDispatch_['--compiler'] = this.argsDispatch_['-c'];
+  this.argsDispatch_['--other'] = this.argsDispatch_['-o'];
+  this.argsDispatch_['--external'] = this.argsDispatch_['-e'];
+};
+
+
+ArgumentsProcessor.DEFAULTS = {
+  logFileName: 'v8.log',
+  platform: 'unix',
+  stateFilter: null,
+  ignoreUnknown: false,
+  separateIc: false,
+  nm: 'nm'
+};

-  while (args.length) {
-    var arg = args[0];
+
+ArgumentsProcessor.prototype.parse = function() {
+  while (this.args_.length) {
+    var arg = this.args_[0];
      if (arg.charAt(0) != '-') {
        break;
      }
-    args.shift();
+    this.args_.shift();
      var userValue = null;
      var eqPos = arg.indexOf('=');
      if (eqPos != -1) {
        userValue = arg.substr(eqPos + 1);
        arg = arg.substr(0, eqPos);
      }
-    if (arg in argsDispatch) {
-      var dispatch = argsDispatch[arg];
-      result[dispatch[0]] = userValue == null ? dispatch[1] : userValue;
+    if (arg in this.argsDispatch_) {
+      var dispatch = this.argsDispatch_[arg];
+      this.result_[dispatch[0]] = userValue == null ? dispatch[1] :  
userValue;
      } else {
-      printUsageAndExit();
+      return false;
      }
    }

-  if (args.length >= 1) {
-      result.logFileName = args.shift();
+  if (this.args_.length >= 1) {
+      this.result_.logFileName = this.args_.shift();
    }
-  return result;
+  return true;
+};
+
+
+ArgumentsProcessor.prototype.result = function() {
+  return this.result_;
  };


-var params = processArguments(arguments);
-var tickProcessor = new TickProcessor(
-    params.platform == 'unix' ? new UnixCppEntriesProvider(params.nm) :
-        new WindowsCppEntriesProvider(),
-    params.separateIc,
-    params.ignoreUnknown,
-    params.stateFilter);
-tickProcessor.processLogFile(params.logFileName);
-tickProcessor.printStatistics();
+ArgumentsProcessor.prototype.printUsageAndExit = function() {
+
+  function padRight(s, len) {
+    s = s.toString();
+    if (s.length < len) {
+      s = s + (new Array(len - s.length + 1).join(' '));
+    }
+    return s;
+  }
+
+  print('Cmdline args: [options] [log-file-name]\n' +
+        'Default log file name is "' +
+        ArgumentsProcessor.DEFAULTS.logFileName + '".\n');
+  print('Options:');
+  for (var arg in this.argsDispatch_) {
+    var synonims = [arg];
+    var dispatch = this.argsDispatch_[arg];
+    for (var synArg in this.argsDispatch_) {
+      if (arg !== synArg && dispatch === this.argsDispatch_[synArg]) {
+        synonims.push(synArg);
+        delete this.argsDispatch_[synArg];
+      }
+    }
+    print('  ' + padRight(synonims.join(', '), 20) + dispatch[2]);
+  }
+  quit(2);
+};
+

Modified: branches/bleeding_edge/tools/windows-tick-processor.bat
==============================================================================
--- branches/bleeding_edge/tools/windows-tick-processor.bat     (original)
+++ branches/bleeding_edge/tools/windows-tick-processor.bat     Wed Jul  8  
23:39:38 2009
@@ -2,4 +2,4 @@

  SET tools_dir=%~dp0

-%tools_dir%..\d8 %tools_dir%splaytree.js %tools_dir%codemap.js 
%tools_dir%csvparser.js %tools_dir%consarray.js %tools_dir%profile.js 
%tools_dir%profile_view.js %tools_dir%logreader.js %tools_dir%tickprocessor.js  
--  
--windows %*
+%tools_dir%..\d8 %tools_dir%splaytree.js %tools_dir%codemap.js 
%tools_dir%csvparser.js %tools_dir%consarray.js %tools_dir%profile.js 
%tools_dir%profile_view.js %tools_dir%logreader.js %tools_dir%tickprocessor.js 
%tools_dir%tickprocessor-driver.js  
--  
--windows %*

--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---

Reply via email to