mirror of
https://github.com/libretro/parallel-gx1.git
synced 2026-11-07 04:26:01 -10:00
Every file the core touches goes through libretro-common's filestream, path and dirent layers, taken from RetroArch: vfs_hybrid opens local paths with libretro-common's own implementation and hands URI paths (and, on Android, anything a local open cannot reach) to the frontend's VFS. File::IOFile and File::DirectIOFile sit on RFILE, and FileUtil, FileSearch and the directory walks on path_stat, path_mkdir and retro_opendir. Dolphin's fopen, POSIX and Win32 file code, std::filesystem and std::fstream are gone, with the dual VFS paths and the core option that chose between them. Files opened for reading alone are memory-mapped where the platform can: reads copy straight out of the page cache, DirectIOFile's offset reads on one mapped object are thread safe, and GetMappedPtr(), View() and Prefetch() lend and warm without a copy. Text files are read a line at a time through File::LineReader, lent from the mapping or a window refilled a block at a time, never a byte at a time; JSON is parsed straight from the mapping. Ini files and the cheat file are built in memory and written once, an ini only when it changed and then atomically.
83 lines
1.8 KiB
C++
83 lines
1.8 KiB
C++
// Copyright 2014 Dolphin Emulator Project
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
#include "Common/JitRegister.h"
|
|
|
|
#include <cstdio>
|
|
#include <cstdlib>
|
|
#include <string>
|
|
|
|
#include <fmt/format.h>
|
|
|
|
#include "Common/CommonTypes.h"
|
|
#include "Common/IOFile.h"
|
|
|
|
#ifdef _WIN32
|
|
#include <process.h>
|
|
#else
|
|
#include <unistd.h>
|
|
#endif
|
|
|
|
#if defined USE_VTUNE
|
|
#include <jitprofiling.h>
|
|
#pragma comment(lib, "jitprofiling.lib")
|
|
#endif
|
|
|
|
static File::IOFile s_perf_map_file;
|
|
|
|
namespace Common::JitRegister
|
|
{
|
|
static bool s_is_enabled = false;
|
|
|
|
void Init(const std::string& perf_dir)
|
|
{
|
|
#ifdef USE_VTUNE
|
|
s_is_enabled = true;
|
|
#endif
|
|
|
|
if (!perf_dir.empty() || getenv("PERF_BUILDID_DIR"))
|
|
{
|
|
const std::string dir = perf_dir.empty() ? "/tmp" : perf_dir;
|
|
const std::string filename = fmt::format("{}/perf-{}.map", dir, getpid());
|
|
if (s_perf_map_file.Open(filename, "w"))
|
|
s_is_enabled = true;
|
|
}
|
|
}
|
|
|
|
void Shutdown()
|
|
{
|
|
#ifdef USE_VTUNE
|
|
iJIT_NotifyEvent(iJVM_EVENT_TYPE_SHUTDOWN, nullptr);
|
|
#endif
|
|
|
|
if (s_perf_map_file.IsOpen())
|
|
s_perf_map_file.Close();
|
|
|
|
s_is_enabled = false;
|
|
}
|
|
|
|
bool IsEnabled()
|
|
{
|
|
return s_is_enabled;
|
|
}
|
|
|
|
void Register(const void* base_address, u32 code_size, const std::string& symbol_name)
|
|
{
|
|
#ifdef USE_VTUNE
|
|
iJIT_Method_Load jmethod = {0};
|
|
jmethod.method_id = iJIT_GetNewMethodID();
|
|
jmethod.method_load_address = const_cast<void*>(base_address);
|
|
jmethod.method_size = code_size;
|
|
jmethod.method_name = const_cast<char*>(symbol_name.c_str());
|
|
iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED, (void*)&jmethod);
|
|
#endif
|
|
|
|
// Linux perf /tmp/perf-$pid.map:
|
|
if (!s_perf_map_file)
|
|
return;
|
|
|
|
const auto entry = fmt::format("{} {:x} {}\n", fmt::ptr(base_address), code_size, symbol_name);
|
|
s_perf_map_file.WriteBytes(entry.data(), entry.size());
|
|
}
|
|
} // namespace Common::JitRegister
|