'wordsize:64': {
'CCFLAGS': ['-m32'],
'LINKFLAGS': ['-m32']
+ },
+ 'prof:oprofile': {
+ 'CPPDEFINES': ['ENABLE_OPROFILE_AGENT']
}
},
'msvc': {
},
'mode:debug': {
'CCFLAGS': ['-g', '-O0']
+ },
+ 'prof:oprofile': {
+ 'LIBPATH': ['/usr/lib32', '/usr/lib32/oprofile'],
+ 'LIBS': ['opagent']
}
},
'msvc': {
'help': 'build using snapshots for faster start-up'
},
'prof': {
- 'values': ['on', 'off'],
+ 'values': ['on', 'off', 'oprofile'],
'default': 'off',
'help': 'enable profiling of build target'
},
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)." %
],
'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'],
#include "scopes.h"
#include "rewriter.h"
#include "usage-analyzer.h"
+#include "oprofile-agent.h"
namespace v8 { namespace internal {
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
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) {
}
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
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
}
-#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('\\');
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
}
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
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
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);
friend class Profiler;
friend class SlidingStateWindow;
friend class VMState;
+#else
+ static bool is_enabled() { return false; }
#endif
};
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);
--- /dev/null
+// 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
+}
+} }
--- /dev/null
+// 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_
#include "debug.h"
#include "serialize.h"
#include "stub-cache.h"
+#include "oprofile-agent.h"
namespace v8 { namespace internal {
// objects in place for creating the code object used for probing.
CPU::Setup();
+ OProfileAgent::Initialize();
+
return true;
}
if (HasBeenDisposed()) return;
if (!HasBeenSetup()) return;
+ OProfileAgent::TearDown();
+
if (FLAG_preemption) {
v8::Locker locker;
v8::Locker::StopPreemption();