diff options
| author | LDj3SNuD <35856442+LDj3SNuD@users.noreply.github.com> | 2020-12-17 20:32:09 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-12-17 20:32:09 +0100 |
| commit | b5c215111de665ef8d18b38405ac55e17996e30e (patch) | |
| tree | 3fd285d43f466dbe10b80510b20b2076391555b4 /ARMeilleure/Translation/Cache/JumpTable.cs | |
| parent | 10aa11ce13291cf2ea2aeb751838c65c45fdc0ba (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.cs | 59 |
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(); |
