aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ARMeilleure/Translation/PTC/Ptc.cs2
-rw-r--r--src/ARMeilleure/Translation/PTC/PtcFormatter.cs20
-rw-r--r--src/ARMeilleure/Translation/PTC/PtcProfiler.cs46
-rw-r--r--src/Ryujinx.HLE/Loaders/Processes/Extensions/FileSystemExtensions.cs5
-rw-r--r--src/Ryujinx.HLE/Loaders/Processes/ProcessLoaderHelper.cs7
5 files changed, 63 insertions, 17 deletions
diff --git a/src/ARMeilleure/Translation/PTC/Ptc.cs b/src/ARMeilleure/Translation/PTC/Ptc.cs
index ce653383..6f6dfcad 100644
--- a/src/ARMeilleure/Translation/PTC/Ptc.cs
+++ b/src/ARMeilleure/Translation/PTC/Ptc.cs
@@ -29,7 +29,7 @@ namespace ARMeilleure.Translation.PTC
private const string OuterHeaderMagicString = "PTCohd\0\0";
private const string InnerHeaderMagicString = "PTCihd\0\0";
- private const uint InternalVersion = 5502; //! To be incremented manually for each change to the ARMeilleure project.
+ private const uint InternalVersion = 5518; //! To be incremented manually for each change to the ARMeilleure project.
private const string ActualDir = "0";
private const string BackupDir = "1";
diff --git a/src/ARMeilleure/Translation/PTC/PtcFormatter.cs b/src/ARMeilleure/Translation/PTC/PtcFormatter.cs
index ddac3133..60953dcd 100644
--- a/src/ARMeilleure/Translation/PTC/PtcFormatter.cs
+++ b/src/ARMeilleure/Translation/PTC/PtcFormatter.cs
@@ -28,6 +28,26 @@ namespace ARMeilleure.Translation.PTC
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Dictionary<TKey, TValue> DeserializeAndUpdateDictionary<TKey, TValue>(Stream stream, Func<Stream, TValue> valueFunc, Func<TKey, TValue, (TKey, TValue)> updateFunc) where TKey : struct
+ {
+ Dictionary<TKey, TValue> dictionary = new();
+
+ int count = DeserializeStructure<int>(stream);
+
+ for (int i = 0; i < count; i++)
+ {
+ TKey key = DeserializeStructure<TKey>(stream);
+ TValue value = valueFunc(stream);
+
+ (key, value) = updateFunc(key, value);
+
+ dictionary.Add(key, value);
+ }
+
+ return dictionary;
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static List<T> DeserializeList<T>(Stream stream) where T : struct
{
List<T> list = new();
diff --git a/src/ARMeilleure/Translation/PTC/PtcProfiler.cs b/src/ARMeilleure/Translation/PTC/PtcProfiler.cs
index 3a4bfcec..0fe78eda 100644
--- a/src/ARMeilleure/Translation/PTC/PtcProfiler.cs
+++ b/src/ARMeilleure/Translation/PTC/PtcProfiler.cs
@@ -9,10 +9,13 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
+using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading;
+using System.Timers;
using static ARMeilleure.Translation.PTC.PtcFormatter;
+using Timer = System.Timers.Timer;
namespace ARMeilleure.Translation.PTC
{
@@ -20,7 +23,11 @@ namespace ARMeilleure.Translation.PTC
{
private const string OuterHeaderMagicString = "Pohd\0\0\0\0";
- private const uint InternalVersion = 1866; //! Not to be incremented manually for each change to the ARMeilleure project.
+ private const uint InternalVersion = 5518; //! Not to be incremented manually for each change to the ARMeilleure project.
+
+ private static readonly uint[] _migrateInternalVersions = {
+ 1866,
+ };
private const int SaveInterval = 30; // Seconds.
@@ -28,7 +35,7 @@ namespace ARMeilleure.Translation.PTC
private readonly Ptc _ptc;
- private readonly System.Timers.Timer _timer;
+ private readonly Timer _timer;
private readonly ulong _outerHeaderMagic;
@@ -51,7 +58,7 @@ namespace ARMeilleure.Translation.PTC
{
_ptc = ptc;
- _timer = new System.Timers.Timer((double)SaveInterval * 1000d);
+ _timer = new Timer(SaveInterval * 1000d);
_timer.Elapsed += PreSave;
_outerHeaderMagic = BinaryPrimitives.ReadUInt64LittleEndian(EncodingCache.UTF8NoBOM.GetBytes(OuterHeaderMagicString).AsSpan());
@@ -168,7 +175,7 @@ namespace ARMeilleure.Translation.PTC
return false;
}
- if (outerHeader.InfoFileVersion != InternalVersion)
+ if (outerHeader.InfoFileVersion != InternalVersion && !_migrateInternalVersions.Contains(outerHeader.InfoFileVersion))
{
InvalidateCompressedStream(compressedStream);
@@ -211,7 +218,19 @@ namespace ARMeilleure.Translation.PTC
return false;
}
- ProfiledFuncs = Deserialize(stream);
+ switch (outerHeader.InfoFileVersion)
+ {
+ case InternalVersion:
+ ProfiledFuncs = Deserialize(stream);
+ break;
+ case 1866:
+ ProfiledFuncs = Deserialize(stream, (address, profile) => (address + 0x500000UL, profile));
+ break;
+ default:
+ Logger.Error?.Print(LogClass.Ptc, $"No migration path for {nameof(outerHeader.InfoFileVersion)} '{outerHeader.InfoFileVersion}'. Discarding cache.");
+ InvalidateCompressedStream(compressedStream);
+ return false;
+ }
Debug.Assert(stream.Position == stream.Length);
@@ -225,9 +244,14 @@ namespace ARMeilleure.Translation.PTC
return true;
}
- private static Dictionary<ulong, FuncProfile> Deserialize(Stream stream)
+ private static Dictionary<ulong, FuncProfile> Deserialize(Stream stream, Func<ulong, FuncProfile, (ulong, FuncProfile)> migrateEntryFunc = null)
{
- return DeserializeDictionary<ulong, FuncProfile>(stream, (stream) => DeserializeStructure<FuncProfile>(stream));
+ if (migrateEntryFunc != null)
+ {
+ return DeserializeAndUpdateDictionary(stream, DeserializeStructure<FuncProfile>, migrateEntryFunc);
+ }
+
+ return DeserializeDictionary<ulong, FuncProfile>(stream, DeserializeStructure<FuncProfile>);
}
private static ReadOnlySpan<byte> GetReadOnlySpan(MemoryStream memoryStream)
@@ -240,7 +264,7 @@ namespace ARMeilleure.Translation.PTC
compressedStream.SetLength(0L);
}
- private void PreSave(object source, System.Timers.ElapsedEventArgs e)
+ private void PreSave(object source, ElapsedEventArgs e)
{
_waitEvent.Reset();
@@ -277,7 +301,7 @@ namespace ARMeilleure.Translation.PTC
{
Debug.Assert(stream.Seek(0L, SeekOrigin.Begin) == 0L && stream.Length == 0L);
- stream.Seek((long)Unsafe.SizeOf<Hash128>(), SeekOrigin.Begin);
+ stream.Seek(Unsafe.SizeOf<Hash128>(), SeekOrigin.Begin);
lock (_lock)
{
@@ -288,7 +312,7 @@ namespace ARMeilleure.Translation.PTC
Debug.Assert(stream.Position == stream.Length);
- stream.Seek((long)Unsafe.SizeOf<Hash128>(), SeekOrigin.Begin);
+ stream.Seek(Unsafe.SizeOf<Hash128>(), SeekOrigin.Begin);
Hash128 hash = XXHash128.ComputeHash(GetReadOnlySpan(stream));
stream.Seek(0L, SeekOrigin.Begin);
@@ -332,7 +356,7 @@ namespace ARMeilleure.Translation.PTC
private static void Serialize(Stream stream, Dictionary<ulong, FuncProfile> profiledFuncs)
{
- SerializeDictionary(stream, profiledFuncs, (stream, structure) => SerializeStructure(stream, structure));
+ SerializeDictionary(stream, profiledFuncs, SerializeStructure);
}
[StructLayout(LayoutKind.Sequential, Pack = 1/*, Size = 29*/)]
diff --git a/src/Ryujinx.HLE/Loaders/Processes/Extensions/FileSystemExtensions.cs b/src/Ryujinx.HLE/Loaders/Processes/Extensions/FileSystemExtensions.cs
index 040d1143..07bbaf12 100644
--- a/src/Ryujinx.HLE/Loaders/Processes/Extensions/FileSystemExtensions.cs
+++ b/src/Ryujinx.HLE/Loaders/Processes/Extensions/FileSystemExtensions.cs
@@ -89,9 +89,6 @@ namespace Ryujinx.HLE.Loaders.Processes.Extensions
Logger.Warning?.Print(LogClass.Ptc, "Detected unsupported ExeFs modifications. PTC disabled.");
}
- // We allow it for nx-hbloader because it can be used to launch homebrew.
- bool allowCodeMemoryForJit = programId == 0x010000000000100DUL || isHomebrew;
-
string programName = "";
if (!isHomebrew && programId > 0x010000000000FFFF)
@@ -119,7 +116,7 @@ namespace Ryujinx.HLE.Loaders.Processes.Extensions
metaLoader,
nacpData,
enablePtc,
- allowCodeMemoryForJit,
+ true,
programName,
metaLoader.GetProgramId(),
null,
diff --git a/src/Ryujinx.HLE/Loaders/Processes/ProcessLoaderHelper.cs b/src/Ryujinx.HLE/Loaders/Processes/ProcessLoaderHelper.cs
index d14a013a..292a5c12 100644
--- a/src/Ryujinx.HLE/Loaders/Processes/ProcessLoaderHelper.cs
+++ b/src/Ryujinx.HLE/Loaders/Processes/ProcessLoaderHelper.cs
@@ -28,6 +28,11 @@ namespace Ryujinx.HLE.Loaders.Processes
{
static class ProcessLoaderHelper
{
+ // NOTE: If you want to change this value make sure to increment the InternalVersion of Ptc and PtcProfiler.
+ // You also need to add a new migration path and adjust the existing ones.
+ // TODO: Remove this workaround when ASLR is implemented.
+ private const ulong CodeStartOffset = 0x500000UL;
+
public static LibHac.Result RegisterProgramMapInfo(Switch device, PartitionFileSystem partitionFileSystem)
{
ulong applicationId = 0;
@@ -242,7 +247,7 @@ namespace Ryujinx.HLE.Loaders.Processes
ulong argsStart = 0;
uint argsSize = 0;
- ulong codeStart = (meta.Flags & 1) != 0 ? 0x8000000UL : 0x200000UL;
+ ulong codeStart = ((meta.Flags & 1) != 0 ? 0x8000000UL : 0x200000UL) + CodeStartOffset;
uint codeSize = 0;
var buildIds = executables.Select(e => (e switch