aboutsummaryrefslogtreecommitdiff
path: root/ARMeilleure/Translation/Cache/JumpTable.cs
diff options
context:
space:
mode:
authorLDj3SNuD <35856442+LDj3SNuD@users.noreply.github.com>2020-12-17 20:32:09 +0100
committerGitHub <noreply@github.com>2020-12-17 20:32:09 +0100
commitb5c215111de665ef8d18b38405ac55e17996e30e (patch)
tree3fd285d43f466dbe10b80510b20b2076391555b4 /ARMeilleure/Translation/Cache/JumpTable.cs
parent10aa11ce13291cf2ea2aeb751838c65c45fdc0ba (diff)
PPTC Follow-up. (#1712)
* Added support for offline invalidation, via PPTC, of low cq translations replaced by high cq translations; both on a single run and between runs. Added invalidation of .cache files in the event of reuse on a different user operating system. Added .info and .cache files invalidation in case of a failed stream decompression. Nits. * InternalVersion = 1712; * Nits. * Address comment. * Get rid of BinaryFormatter. Nits. * Move Ptc.LoadTranslations(). Nits. * Nits. * Fixed corner cases (in case backup copies have to be used). Added save logs. * Not core fixes. * Complement to the previous commit. Added load logs. Removed BinaryFormatter leftovers. * Add LoadTranslations log. * Nits. * Removed the search and management of LowCq overlapping functions. * Final increment of .info and .cache flags. * Nit. * GetIndirectFunctionAddress(): Validate that writing actually takes place in dynamic table memory range (and not elsewhere). * Fix Ptc.UpdateInfo() due to rebase. * Nit for retrigger Checks. * Nit for retrigger Checks.
Diffstat (limited to 'ARMeilleure/Translation/Cache/JumpTable.cs')
-rw-r--r--ARMeilleure/Translation/Cache/JumpTable.cs59
1 files changed, 35 insertions, 24 deletions
diff --git a/ARMeilleure/Translation/Cache/JumpTable.cs b/ARMeilleure/Translation/Cache/JumpTable.cs
index 71a036d8..aa3b6caf 100644
--- a/ARMeilleure/Translation/Cache/JumpTable.cs
+++ b/ARMeilleure/Translation/Cache/JumpTable.cs
@@ -14,7 +14,7 @@ namespace ARMeilleure.Translation.Cache
// The jump table is a block of (guestAddress, hostAddress) function mappings.
// Each entry corresponds to one branch in a JIT compiled function. The entries are
// reserved specifically for each call.
- // The _dependants dictionary can be used to update the hostAddress for any functions that change.
+ // The Dependants dictionary can be used to update the hostAddress for any functions that change.
public const int JumpTableStride = 16; // 8 byte guest address, 8 byte host address.
@@ -42,7 +42,7 @@ namespace ARMeilleure.Translation.Cache
private const int DynamicTableSize = 1048576;
private const int DynamicTableByteSize = DynamicTableSize * DynamicTableStride;
- private const int DynamicEntryTag = 1 << 31;
+ public const int DynamicEntryTag = 1 << 31;
private readonly ReservedRegion _jumpRegion;
private readonly ReservedRegion _dynamicRegion;
@@ -87,14 +87,14 @@ namespace ARMeilleure.Translation.Cache
}
}
- foreach (var item in ptcJumpTable.Dependants)
+ foreach (var kv in ptcJumpTable.Dependants)
{
- Dependants.TryAdd(item.Key, new List<int>(item.Value));
+ Dependants.TryAdd(kv.Key, new List<int>(kv.Value));
}
- foreach (var item in ptcJumpTable.Owners)
+ foreach (var kv in ptcJumpTable.Owners)
{
- Owners.TryAdd(item.Key, new List<int>(item.Value));
+ Owners.TryAdd(kv.Key, new List<int>(kv.Value));
}
}
@@ -182,19 +182,25 @@ namespace ARMeilleure.Translation.Cache
// For future use.
public void RemoveFunctionEntries(ulong guestAddress)
{
- if (Owners.TryRemove(guestAddress, out List<int> list))
+ Targets.TryRemove(guestAddress, out _);
+ Dependants.TryRemove(guestAddress, out _);
+
+ if (Owners.TryRemove(guestAddress, out List<int> entries))
{
- for (int i = 0; i < list.Count; i++)
+ foreach (int entry in entries)
{
- int entry = list[i];
-
- bool isDynamic = (entry & DynamicEntryTag) != 0;
+ if ((entry & DynamicEntryTag) == 0)
+ {
+ IntPtr addr = GetEntryAddressJumpTable(entry);
- entry &= ~DynamicEntryTag;
+ Marshal.WriteInt64(addr, 0, 0L);
+ Marshal.WriteInt64(addr, 8, 0L);
- if (isDynamic)
+ Table.FreeEntry(entry);
+ }
+ else
{
- IntPtr addr = GetEntryAddressDynamicTable(entry);
+ IntPtr addr = GetEntryAddressDynamicTable(entry & ~DynamicEntryTag);
for (int j = 0; j < DynamicTableElems; j++)
{
@@ -202,16 +208,7 @@ namespace ARMeilleure.Translation.Cache
Marshal.WriteInt64(addr + j * JumpTableStride, 8, 0L);
}
- DynTable.FreeEntry(entry);
- }
- else
- {
- IntPtr addr = GetEntryAddressJumpTable(entry);
-
- Marshal.WriteInt64(addr, 0, 0L);
- Marshal.WriteInt64(addr, 8, 0L);
-
- Table.FreeEntry(entry);
+ DynTable.FreeEntry(entry & ~DynamicEntryTag);
}
}
}
@@ -259,6 +256,20 @@ namespace ARMeilleure.Translation.Cache
return _dynamicRegion.Pointer + entry * DynamicTableStride;
}
+ public bool CheckEntryFromAddressJumpTable(IntPtr entryAddress)
+ {
+ int entry = Math.DivRem((int)((ulong)entryAddress - (ulong)_jumpRegion.Pointer), JumpTableStride, out int rem);
+
+ return rem == 0 && Table.EntryIsValid(entry);
+ }
+
+ public bool CheckEntryFromAddressDynamicTable(IntPtr entryAddress)
+ {
+ int entry = Math.DivRem((int)((ulong)entryAddress - (ulong)_dynamicRegion.Pointer), DynamicTableStride, out int rem);
+
+ return rem == 0 && DynTable.EntryIsValid(entry);
+ }
+
public void Dispose()
{
_jumpRegion.Dispose();