diff --git a/Source/Core/Common/CMakeLists.txt b/Source/Core/Common/CMakeLists.txt
index 9a0d508f4c..ef0df028d4 100644
--- a/Source/Core/Common/CMakeLists.txt
+++ b/Source/Core/Common/CMakeLists.txt
@@ -6,6 +6,7 @@ set(SRCS BreakPoints.cpp
GekkoDisassembler.cpp
Hash.cpp
IniFile.cpp
+ JitRegister.cpp
MathUtil.cpp
MemArena.cpp
MemoryUtil.cpp
diff --git a/Source/Core/Common/Common.vcxproj b/Source/Core/Common/Common.vcxproj
index 5d7a31904d..8b192642b5 100644
--- a/Source/Core/Common/Common.vcxproj
+++ b/Source/Core/Common/Common.vcxproj
@@ -62,6 +62,7 @@
+
@@ -97,6 +98,7 @@
+
diff --git a/Source/Core/Common/JitRegister.cpp b/Source/Core/Common/JitRegister.cpp
new file mode 100644
index 0000000000..3dafaac5d7
--- /dev/null
+++ b/Source/Core/Common/JitRegister.cpp
@@ -0,0 +1,115 @@
+// Copyright 2014 Dolphin Emulator Project
+// Licensed under GPLv2
+// Refer to the license.txt file included.
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "Common/CommonTypes.h"
+#include "Common/FileUtil.h"
+#include "Common/JitRegister.h"
+#include "Common/StringUtil.h"
+
+#ifdef _WIN32
+#include
+#else
+#include
+#endif
+
+#if defined USE_OPROFILE && USE_OPROFILE
+#include
+#endif
+
+#if defined USE_VTUNE
+#include
+#pragma comment(lib, "libittnotify.lib")
+#pragma comment(lib, "jitprofiling.lib")
+#endif
+
+#if defined USE_OPROFILE && USE_OPROFILE
+static op_agent_t s_agent = nullptr;
+#endif
+
+static File::IOFile s_perf_map_file;
+
+namespace JitRegister
+{
+
+void Init()
+{
+#if defined USE_OPROFILE && USE_OPROFILE
+ s_agent = op_open_agent();
+#endif
+
+ const char* perf_dir = getenv("DOLPHIN_PERF_DIR");
+ if (perf_dir && perf_dir[0])
+ {
+ std::string filename = StringFromFormat("%s/perf-%d.map", perf_dir, getpid());
+ s_perf_map_file.Open(filename, "w");
+ // Disable buffering in order to avoid missing some mappings
+ // if the event of a crash:
+ std::setvbuf(s_perf_map_file.GetHandle(), NULL, _IONBF, 0);
+ }
+}
+
+void Shutdown()
+{
+#if defined USE_OPROFILE && USE_OPROFILE
+ op_close_agent(s_agent);
+ s_agent = nullptr;
+#endif
+
+#ifdef USE_VTUNE
+ iJIT_NotifyEvent(iJVM_EVENT_TYPE_SHUTDOWN, nullptr);
+#endif
+
+ if (s_perf_map_file.IsOpen())
+ s_perf_map_file.Close();
+}
+
+void Register(const void* base_address, u32 code_size,
+ const char* name, u32 original_address)
+{
+#if !(defined USE_OPROFILE && USE_OPROFILE) && !defined(USE_VTUNE)
+ if (!s_perf_map_file.IsOpen())
+ return;
+#endif
+
+ std::string symbol_name;
+ if (original_address)
+ symbol_name = StringFromFormat("%s_%x", name, original_address);
+ else
+ symbol_name = name;
+
+#if defined USE_OPROFILE && USE_OPROFILE
+ op_write_native_code(s_agent, symbol_name.data(), (u64)base_address,
+ base_address, code_size);
+#endif
+
+#ifdef USE_VTUNE
+ iJIT_Method_Load jmethod = {0};
+ jmethod.method_id = iJIT_GetNewMethodID();
+ jmethod.class_file_name = "";
+ jmethod.source_file_name = __FILE__;
+ jmethod.method_load_address = base_address;
+ jmethod.method_size = code_size;
+ jmethod.line_number_size = 0;
+ jmethod.method_name = symbol_name.data();
+ iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED, (void*)&jmethod);
+#endif
+
+ // Linux perf /tmp/perf-$pid.map:
+ if (s_perf_map_file.IsOpen())
+ {
+ std::string entry = StringFromFormat(
+ "%" PRIx64 " %x %s\n",
+ (u64)base_address, code_size, symbol_name.data());
+ s_perf_map_file.WriteBytes(entry.data(), entry.size());
+ }
+}
+
+}
diff --git a/Source/Core/Common/JitRegister.h b/Source/Core/Common/JitRegister.h
new file mode 100644
index 0000000000..68e2687d8b
--- /dev/null
+++ b/Source/Core/Common/JitRegister.h
@@ -0,0 +1,15 @@
+// Copyright 2014 Dolphin Emulator Project
+// Licensed under GPLv2
+// Refer to the license.txt file included.
+
+#pragma once
+
+namespace JitRegister
+{
+
+void Init();
+void Shutdown();
+void Register(const void* base_address, u32 code_size,
+ const char* name, u32 original_address=0);
+
+}
diff --git a/Source/Core/Core/PowerPC/JitCommon/JitCache.cpp b/Source/Core/Core/PowerPC/JitCommon/JitCache.cpp
index 0c680dc020..e9b0f52961 100644
--- a/Source/Core/Core/PowerPC/JitCommon/JitCache.cpp
+++ b/Source/Core/Core/PowerPC/JitCommon/JitCache.cpp
@@ -9,17 +9,10 @@
// performance hit, it's not enabled by default, but it's useful for
// locating performance issues.
-#include
-
-#ifdef _WIN32
-#include
-#else
-#include
-#endif
-
#include "disasm.h"
#include "Common/CommonTypes.h"
+#include "Common/JitRegister.h"
#include "Common/MemoryUtil.h"
#include "Core/PowerPC/JitInterface.h"
#include "Core/PowerPC/JitCommon/JitBase.h"
@@ -28,18 +21,6 @@
#include
#endif
-#if defined USE_OPROFILE && USE_OPROFILE
-#include
-
-op_agent_t agent;
-#endif
-
-#if defined USE_VTUNE
-#include
-#pragma comment(lib, "libittnotify.lib")
-#pragma comment(lib, "jitprofiling.lib")
-#endif
-
using namespace Gen;
bool JitBaseBlockCache::IsFull() const
@@ -55,17 +36,7 @@ using namespace Gen;
return;
}
-#if defined USE_OPROFILE && USE_OPROFILE
- agent = op_open_agent();
-#endif
-
- const char* perf_dir = getenv("DOLPHIN_PERF_DIR");
- if (perf_dir && perf_dir[0])
- {
- std::string filename = StringFromFormat("%s/perf-%d.map",
- perf_dir, getpid());
- m_perf_map_file.open(filename, std::ios::trunc);
- }
+ JitRegister::Init();
iCache.fill(JIT_ICACHE_INVALID_BYTE);
iCacheEx.fill(JIT_ICACHE_INVALID_BYTE);
@@ -79,16 +50,8 @@ using namespace Gen;
{
num_blocks = 0;
m_initialized = false;
-#if defined USE_OPROFILE && USE_OPROFILE
- op_close_agent(agent);
-#endif
-#ifdef USE_VTUNE
- iJIT_NotifyEvent(iJVM_EVENT_TYPE_SHUTDOWN, nullptr);
-#endif
-
- if (m_perf_map_file.is_open())
- m_perf_map_file.close();
+ JitRegister::Shutdown();
}
// This clears the JIT cache. It's called from JitCache.cpp when the JIT cache
@@ -178,34 +141,8 @@ using namespace Gen;
LinkBlockExits(block_num);
}
-#if defined USE_OPROFILE && USE_OPROFILE
- char buf[100];
- sprintf(buf, "EmuCode%x", b.originalAddress);
- const u8* blockStart = blockCodePointers[block_num];
- op_write_native_code(agent, buf, (uint64_t)blockStart,
- blockStart, b.codeSize);
-#endif
-
-#ifdef USE_VTUNE
- sprintf(b.blockName, "EmuCode_0x%08x", b.originalAddress);
-
- iJIT_Method_Load jmethod = {0};
- jmethod.method_id = iJIT_GetNewMethodID();
- jmethod.class_file_name = "";
- jmethod.source_file_name = __FILE__;
- jmethod.method_load_address = (void*)blockCodePointers[block_num];
- jmethod.method_size = b.codeSize;
- jmethod.line_number_size = 0;
- jmethod.method_name = b.blockName;
- iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED, (void*)&jmethod);
-#endif
-
- if (m_perf_map_file.is_open())
- {
- m_perf_map_file << StringFromFormat(
- "%" PRIx64 " %x EmuCode_%x\n",
- (u64)blockCodePointers[block_num], b.codeSize, b.originalAddress);
- }
+ JitRegister::Register(blockCodePointers[block_num], b.codeSize,
+ "JIT_PPC", b.originalAddress);
}
const u8 **JitBaseBlockCache::GetCodePointers()
diff --git a/Source/Core/Core/PowerPC/JitCommon/JitCache.h b/Source/Core/Core/PowerPC/JitCommon/JitCache.h
index d53fa16d43..21984c8a70 100644
--- a/Source/Core/Core/PowerPC/JitCommon/JitCache.h
+++ b/Source/Core/Core/PowerPC/JitCommon/JitCache.h
@@ -6,7 +6,6 @@
#include
#include
-#include
#include