Author: [email protected]
Date: Thu Mar  5 02:53:08 2009
New Revision: 1426

Added:
    branches/bleeding_edge/src/oprofile-agent.cc
    branches/bleeding_edge/src/oprofile-agent.h
Modified:
    branches/bleeding_edge/SConstruct
    branches/bleeding_edge/src/SConscript
    branches/bleeding_edge/src/compiler.cc
    branches/bleeding_edge/src/flag-definitions.h
    branches/bleeding_edge/src/log.cc
    branches/bleeding_edge/src/log.h
    branches/bleeding_edge/src/objects.h
    branches/bleeding_edge/src/v8.cc

Log:
Adding support for reporting addresses of JIT compiled code to OProfile.

Please be warned that current gHardy versions have OProfile 0.9.3
which doesn't have JIT API. You need to install OProfile 0.9.4
with a 32-bit version of opagent library. Instructions are on the
internal Wiki page: http://wiki/Main/V8UsingOProfile

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


Modified: branches/bleeding_edge/SConstruct
==============================================================================
--- branches/bleeding_edge/SConstruct   (original)
+++ branches/bleeding_edge/SConstruct   Thu Mar  5 02:53:08 2009
@@ -68,6 +68,9 @@
      'wordsize:64': {
        'CCFLAGS':      ['-m32'],
        'LINKFLAGS':    ['-m32']
+    },
+    'prof:oprofile': {
+      'CPPDEFINES':   ['ENABLE_OPROFILE_AGENT']
      }
    },
    'msvc': {
@@ -249,6 +252,10 @@
      },
      'mode:debug': {
        'CCFLAGS':      ['-g', '-O0']
+    },
+    'prof:oprofile': {
+      'LIBPATH': ['/usr/lib32', '/usr/lib32/oprofile'],
+      'LIBS': ['opagent']
      }
    },
    'msvc': {
@@ -362,7 +369,7 @@
      'help': 'build using snapshots for faster start-up'
    },
    'prof': {
-    'values': ['on', 'off'],
+    'values': ['on', 'off', 'oprofile'],
      'default': 'off',
      'help': 'enable profiling of build target'
    },
@@ -435,6 +442,8 @@
      return False
    if env['os'] == 'win32' and env['library'] == 'shared' and env['prof']  
== 'on':
      Abort("Profiling on windows only supported for static library.")
+  if env['prof'] == 'oprofile' and env['os'] != 'linux':
+    Abort("OProfile is only supported on Linux.")
    for (name, option) in SIMPLE_OPTIONS.iteritems():
      if (not option.get('default')) and (name not in ARGUMENTS):
        message = ("A value for option %s must be specified (%s)." %

Modified: branches/bleeding_edge/src/SConscript
==============================================================================
--- branches/bleeding_edge/src/SConscript       (original)
+++ branches/bleeding_edge/src/SConscript       Thu Mar  5 02:53:08 2009
@@ -67,7 +67,7 @@
    ],
    'simulator:arm': ['simulator-arm.cc'],
    'os:freebsd': ['platform-freebsd.cc'],
-  'os:linux':   ['platform-linux.cc'],
+  'os:linux':   ['platform-linux.cc', 'oprofile-agent.cc'],
    'os:macos':   ['platform-macos.cc'],
    'os:nullos':  ['platform-nullos.cc'],
    'os:win32':   ['platform-win32.cc'],

Modified: branches/bleeding_edge/src/compiler.cc
==============================================================================
--- branches/bleeding_edge/src/compiler.cc      (original)
+++ branches/bleeding_edge/src/compiler.cc      Thu Mar  5 02:53:08 2009
@@ -35,6 +35,7 @@
  #include "scopes.h"
  #include "rewriter.h"
  #include "usage-analyzer.h"
+#include "oprofile-agent.h"

  namespace v8 { namespace internal {

@@ -123,16 +124,20 @@
      return Handle<JSFunction>::null();
    }

-#ifdef ENABLE_LOGGING_AND_PROFILING
+#if defined ENABLE_LOGGING_AND_PROFILING || defined ENABLE_OPROFILE_AGENT
    // Log the code generation for the script. Check explicit whether  
logging is
    // to avoid allocating when not required.
-  if (Logger::is_enabled()) {
+  if (Logger::is_enabled() || OProfileAgent::is_enabled()) {
      if (script->name()->IsString()) {
        SmartPointer<char> data =
            String::cast(script->name())->ToCString(DISALLOW_NULLS);
        LOG(CodeCreateEvent(is_eval ? "Eval" : "Script", *code, *data));
+      OProfileAgent::CreateNativeCodeRegion(*data, code->address(),
+                                            code->ExecutableSize());
      } else {
        LOG(CodeCreateEvent(is_eval ? "Eval" : "Script", *code, ""));
+      OProfileAgent::CreateNativeCodeRegion(is_eval ? "Eval" : "Script",
+          code->address(), code->ExecutableSize());
      }
    }
  #endif
@@ -306,11 +311,11 @@
      return false;
    }

-#ifdef ENABLE_LOGGING_AND_PROFILING
+#if defined ENABLE_LOGGING_AND_PROFILING || defined ENABLE_OPROFILE_AGENT
    // Log the code generation. If source information is available include  
script
    // name and line number. Check explicit whether logging is enabled as  
finding
    // the line number is not for free.
-  if (Logger::is_enabled()) {
+  if (Logger::is_enabled() || OProfileAgent::is_enabled()) {
      if (script->name()->IsString()) {
        int line_num = script->GetLineNumber(start_position);
        if (line_num > 0) {
@@ -318,8 +323,14 @@
        }
        LOG(CodeCreateEvent("LazyCompile", *code, *lit->name(),
                            String::cast(script->name()), line_num));
+      OProfileAgent::CreateNativeCodeRegion(*lit->name(),
+                                            String::cast(script->name()),
+                                            line_num, code->address(),
+                                            code->ExecutableSize());
      } else {
        LOG(CodeCreateEvent("LazyCompile", *code, *lit->name()));
+      OProfileAgent::CreateNativeCodeRegion(*lit->name(), code->address(),
+                                            code->ExecutableSize());
      }
    }
  #endif

Modified: branches/bleeding_edge/src/flag-definitions.h
==============================================================================
--- branches/bleeding_edge/src/flag-definitions.h       (original)
+++ branches/bleeding_edge/src/flag-definitions.h       Thu Mar  5 02:53:08 2009
@@ -334,6 +334,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(oprofile, false,
+            "Enable JIT agent for OProfile.")

  //
  // Disassembler only flags

Modified: branches/bleeding_edge/src/log.cc
==============================================================================
--- branches/bleeding_edge/src/log.cc   (original)
+++ branches/bleeding_edge/src/log.cc   Thu Mar  5 02:53:08 2009
@@ -711,24 +711,13 @@
  }


-#ifdef ENABLE_LOGGING_AND_PROFILING
-int Logger::CodeObjectSize(Code* code) {
-  // Check that the assumptions about the layout of the code object holds.
-  ASSERT_EQ(reinterpret_cast<unsigned int>(code->instruction_start()) -
-            reinterpret_cast<unsigned int>(code->address()),
-            Code::kHeaderSize);
-  return code->instruction_size() + Code::kHeaderSize;
-}
-#endif
-
-
  void Logger::CodeCreateEvent(const char* tag, Code* code, const char*  
comment) {
  #ifdef ENABLE_LOGGING_AND_PROFILING
    if (logfile_ == NULL || !FLAG_log_code) return;
    LogMessageBuilder msg;
    msg.Append("code-creation,%s,0x%x,%d,\"", tag,
               reinterpret_cast<unsigned int>(code->address()),
-             CodeObjectSize(code));
+             code->ExecutableSize());
    for (const char* p = comment; *p != '\0'; p++) {
      if (*p == '"') {
        msg.Append('\\');
@@ -750,7 +739,7 @@
        name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
    msg.Append("code-creation,%s,0x%x,%d,\"%s\"\n", tag,
               reinterpret_cast<unsigned int>(code->address()),
-             CodeObjectSize(code), *str);
+             code->ExecutableSize(), *str);
    msg.WriteToLogFile();
  #endif
  }
@@ -767,7 +756,7 @@
        source->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
    msg.Append("code-creation,%s,0x%x,%d,\"%s %s:%d\"\n", tag,
               reinterpret_cast<unsigned int>(code->address()),
-             CodeObjectSize(code),
+             code->ExecutableSize(),
               *str, *sourcestr, line);
    msg.WriteToLogFile();
  #endif
@@ -780,7 +769,7 @@
    LogMessageBuilder msg;
    msg.Append("code-creation,%s,0x%x,%d,\"args_count: %d\"\n", tag,
               reinterpret_cast<unsigned int>(code->address()),
-             CodeObjectSize(code),
+             code->ExecutableSize(),
               args_count);
    msg.WriteToLogFile();
  #endif

Modified: branches/bleeding_edge/src/log.h
==============================================================================
--- branches/bleeding_edge/src/log.h    (original)
+++ branches/bleeding_edge/src/log.h    Thu Mar  5 02:53:08 2009
@@ -215,10 +215,6 @@

   private:

-  // Calculate the size of the code object to report for log events. This  
takes
-  // the layout of the code object into account.
-  static int CodeObjectSize(Code* code);
-
    // Emits the source code of a regexp. Used by regexp events.
    static void LogRegExpSource(Handle<JSRegExp> regexp);

@@ -268,6 +264,8 @@
    friend class Profiler;
    friend class SlidingStateWindow;
    friend class VMState;
+#else
+  static bool is_enabled() { return false; }
  #endif
  };


Modified: branches/bleeding_edge/src/objects.h
==============================================================================
--- branches/bleeding_edge/src/objects.h        (original)
+++ branches/bleeding_edge/src/objects.h        Thu Mar  5 02:53:08 2009
@@ -2258,6 +2258,16 @@
      return RoundUp(kHeaderSize + body_size + sinfo_size, kCodeAlignment);
    }

+  // Calculate the size of the code object to report for log events. This  
takes
+  // the layout of the code object into account.
+  int ExecutableSize() {
+    // Check that the assumptions about the layout of the code object  
holds.
+    ASSERT_EQ(reinterpret_cast<unsigned int>(instruction_start()) -
+              reinterpret_cast<unsigned int>(address()),
+              Code::kHeaderSize);
+    return instruction_size() + Code::kHeaderSize;
+  }
+
    // Locating source position.
    int SourcePosition(Address pc);
    int SourceStatementPosition(Address pc);

Added: branches/bleeding_edge/src/oprofile-agent.cc
==============================================================================
--- (empty file)
+++ branches/bleeding_edge/src/oprofile-agent.cc        Thu Mar  5 02:53:08 2009
@@ -0,0 +1,111 @@
+// Copyright 2006-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.
+
+#include "v8.h"
+
+#include "oprofile-agent.h"
+
+namespace v8 { namespace internal {
+
+#ifdef ENABLE_OPROFILE_AGENT
+op_agent_t OProfileAgent::handle_ = NULL;
+#endif
+
+
+bool OProfileAgent::Initialize() {
+#ifdef ENABLE_OPROFILE_AGENT
+  if (FLAG_oprofile) {
+    if (handle_ != NULL) return false;
+
+    // Disable code moving by GC.
+    FLAG_always_compact = false;
+    FLAG_never_compact = true;
+
+    handle_ = op_open_agent();
+    return (handle_ != NULL);
+  } else {
+    return true;
+  }
+#else
+  return true;
+#endif
+}
+
+
+void OProfileAgent::TearDown() {
+#ifdef ENABLE_OPROFILE_AGENT
+  if (handle_ != NULL) {
+    op_close_agent(handle_);
+  }
+#endif
+}
+
+
+void OProfileAgent::CreateNativeCodeRegion(const char* name,
+    const void* ptr, unsigned int size) {
+#ifdef ENABLE_OPROFILE_AGENT
+  if (handle_ == NULL) return;
+  op_write_native_code(handle_, name, (uint64_t)ptr, ptr, size);
+#endif
+}
+
+
+void OProfileAgent::CreateNativeCodeRegion(String* name,
+    const void* ptr, unsigned int size) {
+#ifdef ENABLE_OPROFILE_AGENT
+  if (handle_ != NULL) {
+    const char* func_name;
+    SmartPointer<char> str =
+        name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
+    func_name = name->length() > 0 ? *str : "<anonymous>";
+    CreateNativeCodeRegion(func_name, ptr, size);
+  }
+#endif
+}
+
+
+void OProfileAgent::CreateNativeCodeRegion(String* name, String* source,
+    int line_num, const void* ptr, unsigned int size) {
+#ifdef ENABLE_OPROFILE_AGENT
+  if (handle_ != NULL) {
+    Vector<char> buf =  
Vector<char>::New(OProfileAgent::kFormattingBufSize);
+    const char* func_name;
+    SmartPointer<char> str =
+        name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
+    func_name = name->length() > 0 ? *str : "<anonymous>";
+    SmartPointer<char> source_str =
+        source->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
+    if (v8::internal::OS::SNPrintF(buf, "%s %s:%d",
+                                   func_name, *source_str, line_num) !=  
-1) {
+      CreateNativeCodeRegion(buf.start(), ptr, size);
+    } else {
+      CreateNativeCodeRegion("<script/func name too long>", ptr, size);
+    }
+  }
+#endif
+}
+} }

Added: branches/bleeding_edge/src/oprofile-agent.h
==============================================================================
--- (empty file)
+++ branches/bleeding_edge/src/oprofile-agent.h Thu Mar  5 02:53:08 2009
@@ -0,0 +1,68 @@
+// Copyright 2006-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.
+
+#ifndef V8_OPROFILE_AGENT_H_
+#define V8_OPROFILE_AGENT_H_
+
+#include <stdlib.h>
+
+#include "globals.h"
+
+#ifdef ENABLE_OPROFILE_AGENT
+// opagent.h uses uint64_t type, which can be missing in
+// system headers (they have __uint64_t), but is defined
+// in V8's headers.
+#include <opagent.h>  // NOLINT
+#endif
+
+namespace v8 { namespace internal {
+
+class OProfileAgent {
+ public:
+  static bool Initialize();
+  static void TearDown();
+  static void CreateNativeCodeRegion(const char* name,
+                                     const void* ptr, unsigned int size);
+  static void CreateNativeCodeRegion(String* name,
+                                     const void* ptr, unsigned int size);
+  static void CreateNativeCodeRegion(String* name, String* source, int  
line_num,
+                                     const void* ptr, unsigned int size);
+#ifdef ENABLE_OPROFILE_AGENT
+  static bool is_enabled() { return handle_ != NULL; }
+
+ private:
+  static op_agent_t handle_;
+
+  // Size of the buffer that is used for composing code areas names.
+  static const int kFormattingBufSize = 256;
+#else
+  static bool is_enabled() { return false; }
+#endif
+};
+} }
+
+#endif  // V8_OPROFILE_AGENT_H_

Modified: branches/bleeding_edge/src/v8.cc
==============================================================================
--- branches/bleeding_edge/src/v8.cc    (original)
+++ branches/bleeding_edge/src/v8.cc    Thu Mar  5 02:53:08 2009
@@ -31,6 +31,7 @@
  #include "debug.h"
  #include "serialize.h"
  #include "stub-cache.h"
+#include "oprofile-agent.h"

  namespace v8 { namespace internal {

@@ -85,6 +86,8 @@
    // objects in place for creating the code object used for probing.
    CPU::Setup();

+  OProfileAgent::Initialize();
+
    return true;
  }

@@ -92,6 +95,8 @@
  void V8::TearDown() {
    if (HasBeenDisposed()) return;
    if (!HasBeenSetup()) return;
+
+  OProfileAgent::TearDown();

    if (FLAG_preemption) {
      v8::Locker locker;

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

Reply via email to