Add support for running low level profiler on Android.
authorulan@chromium.org <ulan@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 6 Sep 2012 15:01:20 +0000 (15:01 +0000)
committerulan@chromium.org <ulan@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 6 Sep 2012 15:01:20 +0000 (15:01 +0000)
R=mstarzinger@chromium.org

Review URL: https://chromiumcodereview.appspot.com/10908122

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12469 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/flag-definitions.h
src/platform-linux.cc
src/platform-openbsd.cc
tools/android-ll-prof.sh [new file with mode: 0755]
tools/ll_prof.py

index 9e54e46..cb4dd5b 100644 (file)
@@ -633,7 +633,8 @@ DEFINE_bool(sliding_state_window, false,
             "Update sliding state window counters.")
 DEFINE_string(logfile, "v8.log", "Specify the name of the log file.")
 DEFINE_bool(ll_prof, false, "Enable low-level linux profiler.")
-
+DEFINE_string(gc_fake_mmap, "/tmp/__v8_gc__",
+              "Specify the name of the file for fake gc mmap used in ll_prof")
 
 //
 // Disassembler only flags
index d022448..606d102 100644 (file)
@@ -512,9 +512,6 @@ void OS::LogSharedLibraryAddresses() {
 }
 
 
-static const char kGCFakeMmap[] = "/tmp/__v8_gc__";
-
-
 void OS::SignalCodeMovingGC() {
   // Support for ll_prof.py.
   //
@@ -525,7 +522,7 @@ void OS::SignalCodeMovingGC() {
   // by the kernel and allows us to synchronize V8 code log and the
   // kernel log.
   int size = sysconf(_SC_PAGESIZE);
-  FILE* f = fopen(kGCFakeMmap, "w+");
+  FILE* f = fopen(FLAG_gc_fake_mmap, "w+");
   void* addr = mmap(OS::GetRandomMmapAddr(),
                     size,
                     PROT_READ | PROT_EXEC,
index ba33a84..408d4dc 100644 (file)
@@ -323,9 +323,6 @@ void OS::LogSharedLibraryAddresses() {
 }
 
 
-static const char kGCFakeMmap[] = "/tmp/__v8_gc__";
-
-
 void OS::SignalCodeMovingGC() {
   // Support for ll_prof.py.
   //
@@ -336,7 +333,7 @@ void OS::SignalCodeMovingGC() {
   // by the kernel and allows us to synchronize V8 code log and the
   // kernel log.
   int size = sysconf(_SC_PAGESIZE);
-  FILE* f = fopen(kGCFakeMmap, "w+");
+  FILE* f = fopen(FLAG_gc_fake_mmap, "w+");
   void* addr = mmap(NULL, size, PROT_READ | PROT_EXEC, MAP_PRIVATE,
                     fileno(f), 0);
   ASSERT(addr != MAP_FAILED);
diff --git a/tools/android-ll-prof.sh b/tools/android-ll-prof.sh
new file mode 100755 (executable)
index 0000000..78790ec
--- /dev/null
@@ -0,0 +1,69 @@
+#!/bin/bash
+# Copyright 2012 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.
+
+# Runs d8 with the given arguments on the device under 'perf' and
+# processes the profiler trace and v8 logs using ll_prof.py.
+# 
+# Usage:
+# > ./tools/android-ll-prof.sh (debug|release) "args to d8" "args to ll_prof.py"
+#
+# The script creates deploy directory deploy/data/local/tmp/v8, copies there
+# the d8 binary either from out/android_arm.release or out/android_arm.debug,
+# and then sync the deploy directory with /data/local/tmp/v8 on the device.
+# You can put JS files in the deploy directory before running the script.
+# Note: $ANDROID_NDK_ROOT must be set.
+
+MODE=$1
+RUN_ARGS=$2
+LL_PROF_ARGS=$3
+
+BASE=`cd $(dirname "$0")/..; pwd`
+DEPLOY="$BASE/deploy"
+
+set +e
+mkdir -p "$DEPLOY/data/local/tmp/v8"
+
+cp "$BASE/out/android_arm.$MODE/d8" "$DEPLOY/data/local/tmp/v8/d8"
+
+adb -p "$DEPLOY" sync data
+
+adb shell "cd /data/local/tmp/v8;\
+           perf record -R -e cycles -c 10000 -f -i \
+           ./d8 --ll_prof --gc-fake-mmap=/data/local/tmp/__v8_gc__ $RUN_ARGS"
+
+adb pull /data/local/tmp/v8/v8.log .
+adb pull /data/local/tmp/v8/v8.log.ll .
+adb pull /data/perf.data .
+
+ARCH=arm-linux-androideabi-4.4.3
+TOOLCHAIN="${ANDROID_NDK_ROOT}/toolchains/$ARCH/prebuilt/linux-x86/bin"
+
+$BASE/tools/ll_prof.py --host-root="$BASE/deploy" \
+                       --gc-fake-mmap=/data/local/tmp/__v8_gc__ \
+                       --objdump="$TOOLCHAIN/arm-linux-androideabi-objdump" \
+                       $LL_PROF_ARGS
index 51ba672..3afe179 100755 (executable)
@@ -68,15 +68,9 @@ Examples:
 """
 
 
-# Must match kGcFakeMmap.
-V8_GC_FAKE_MMAP = "/tmp/__v8_gc__"
-
 JS_ORIGIN = "js"
 JS_SNAPSHOT_ORIGIN = "js-snapshot"
 
-OBJDUMP_BIN = disasm.OBJDUMP_BIN
-
-
 class Code(object):
   """Code object."""
 
@@ -639,7 +633,7 @@ class TraceReader(object):
     # Read null-terminated filename.
     filename = self.trace[offset + self.header_size + ctypes.sizeof(mmap_info):
                           offset + header.size]
-    mmap_info.filename = filename[:filename.find(chr(0))]
+    mmap_info.filename = HOST_ROOT + filename[:filename.find(chr(0))]
     return mmap_info
 
   def ReadSample(self, header, offset):
@@ -858,6 +852,15 @@ if __name__ == "__main__":
                     default=False,
                     action="store_true",
                     help="no auxiliary messages [default: %default]")
+  parser.add_option("--gc-fake-mmap",
+                    default="/tmp/__v8_gc__",
+                    help="gc fake mmap file [default: %default]")
+  parser.add_option("--objdump",
+                    default="/usr/bin/objdump",
+                    help="objdump tool to use [default: %default]")
+  parser.add_option("--host-root",
+                    default="",
+                    help="Path to the host root [default: %default]")
   options, args = parser.parse_args()
 
   if not options.quiet:
@@ -869,6 +872,14 @@ if __name__ == "__main__":
       print "V8 log: %s, %s.ll (no snapshot)" % (options.log, options.log)
     print "Perf trace file: %s" % options.trace
 
+  V8_GC_FAKE_MMAP = options.gc_fake_mmap
+  HOST_ROOT = options.host_root
+  if os.path.exists(options.objdump):
+    disasm.OBJDUMP_BIN = options.objdump
+    OBJDUMP_BIN = options.objdump
+  else:
+    print "Cannot find %s, falling back to default objdump" % options.objdump
+
   # Stats.
   events = 0
   ticks = 0
@@ -905,7 +916,7 @@ if __name__ == "__main__":
     if header.type == PERF_RECORD_MMAP:
       start = time.time()
       mmap_info = trace_reader.ReadMmap(header, offset)
-      if mmap_info.filename == V8_GC_FAKE_MMAP:
+      if mmap_info.filename == HOST_ROOT + V8_GC_FAKE_MMAP:
         log_reader.ReadUpToGC()
       else:
         library_repo.Load(mmap_info, code_map, options)