aboutsummaryrefslogtreecommitdiff
path: root/ARMeilleure/Translation/PTC/PtcJumpTable.cs
diff options
context:
space:
mode:
Diffstat (limited to 'ARMeilleure/Translation/PTC/PtcJumpTable.cs')
-rw-r--r--ARMeilleure/Translation/PTC/PtcJumpTable.cs182
1 files changed, 42 insertions, 140 deletions
diff --git a/ARMeilleure/Translation/PTC/PtcJumpTable.cs b/ARMeilleure/Translation/PTC/PtcJumpTable.cs
index d52d0874..75dcba50 100644
--- a/ARMeilleure/Translation/PTC/PtcJumpTable.cs
+++ b/ARMeilleure/Translation/PTC/PtcJumpTable.cs
@@ -6,15 +6,18 @@ using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
+using static ARMeilleure.Translation.PTC.PtcFormatter;
+
namespace ARMeilleure.Translation.PTC
{
class PtcJumpTable
{
+ [StructLayout(LayoutKind.Sequential, Pack = 1/*, Size = 16*/)]
public struct TableEntry<TAddress>
{
public int EntryIndex;
public long GuestAddress;
- public TAddress HostAddress;
+ public TAddress HostAddress; // int
public TableEntry(int entryIndex, long guestAddress, TAddress hostAddress)
{
@@ -24,14 +27,14 @@ namespace ARMeilleure.Translation.PTC
}
}
- public enum DirectHostAddress
+ public enum DirectHostAddress : int
{
CallStub = 0,
TailCallStub = 1,
Host = 2
}
- public enum IndirectHostAddress
+ public enum IndirectHostAddress : int
{
CallStub = 0,
TailCallStub = 1
@@ -66,152 +69,40 @@ namespace ARMeilleure.Translation.PTC
Owners = owners;
}
- public static PtcJumpTable Deserialize(MemoryStream stream)
+ public static PtcJumpTable Deserialize(Stream stream)
{
- using (BinaryReader reader = new BinaryReader(stream, EncodingCache.UTF8NoBOM, true))
- {
- var jumpTable = new List<TableEntry<DirectHostAddress>>();
-
- int jumpTableCount = reader.ReadInt32();
-
- for (int i = 0; i < jumpTableCount; i++)
- {
- int entryIndex = reader.ReadInt32();
- long guestAddress = reader.ReadInt64();
- DirectHostAddress hostAddress = (DirectHostAddress)reader.ReadInt32();
-
- jumpTable.Add(new TableEntry<DirectHostAddress>(entryIndex, guestAddress, hostAddress));
- }
-
- var dynamicTable = new List<TableEntry<IndirectHostAddress>>();
-
- int dynamicTableCount = reader.ReadInt32();
-
- for (int i = 0; i < dynamicTableCount; i++)
- {
- int entryIndex = reader.ReadInt32();
- long guestAddress = reader.ReadInt64();
- IndirectHostAddress hostAddress = (IndirectHostAddress)reader.ReadInt32();
-
- dynamicTable.Add(new TableEntry<IndirectHostAddress>(entryIndex, guestAddress, hostAddress));
- }
-
- var targets = new List<ulong>();
-
- int targetsCount = reader.ReadInt32();
-
- for (int i = 0; i < targetsCount; i++)
- {
- ulong address = reader.ReadUInt64();
-
- targets.Add(address);
- }
-
- var dependants = new Dictionary<ulong, List<int>>();
-
- int dependantsCount = reader.ReadInt32();
-
- for (int i = 0; i < dependantsCount; i++)
- {
- ulong address = reader.ReadUInt64();
-
- var entries = new List<int>();
-
- int entriesCount = reader.ReadInt32();
-
- for (int j = 0; j < entriesCount; j++)
- {
- int entry = reader.ReadInt32();
-
- entries.Add(entry);
- }
-
- dependants.Add(address, entries);
- }
-
- var owners = new Dictionary<ulong, List<int>>();
-
- int ownersCount = reader.ReadInt32();
-
- for (int i = 0; i < ownersCount; i++)
- {
- ulong address = reader.ReadUInt64();
-
- var entries = new List<int>();
+ var jumpTable = DeserializeList<TableEntry<DirectHostAddress>>(stream);
+ var dynamicTable = DeserializeList<TableEntry<IndirectHostAddress>>(stream);
- int entriesCount = reader.ReadInt32();
+ var targets = DeserializeList<ulong>(stream);
+ var dependants = DeserializeDictionary<ulong, List<int>>(stream, (stream) => DeserializeList<int>(stream));
+ var owners = DeserializeDictionary<ulong, List<int>>(stream, (stream) => DeserializeList<int>(stream));
- for (int j = 0; j < entriesCount; j++)
- {
- int entry = reader.ReadInt32();
-
- entries.Add(entry);
- }
-
- owners.Add(address, entries);
- }
-
- return new PtcJumpTable(jumpTable, dynamicTable, targets, dependants, owners);
- }
+ return new PtcJumpTable(jumpTable, dynamicTable, targets, dependants, owners);
}
- public static void Serialize(MemoryStream stream, PtcJumpTable ptcJumpTable)
+ public static int GetSerializeSize(PtcJumpTable ptcJumpTable)
{
- using (BinaryWriter writer = new BinaryWriter(stream, EncodingCache.UTF8NoBOM, true))
- {
- writer.Write((int)ptcJumpTable._jumpTable.Count);
-
- foreach (var tableEntry in ptcJumpTable._jumpTable)
- {
- writer.Write((int)tableEntry.EntryIndex);
- writer.Write((long)tableEntry.GuestAddress);
- writer.Write((int)tableEntry.HostAddress);
- }
-
- writer.Write((int)ptcJumpTable._dynamicTable.Count);
-
- foreach (var tableEntry in ptcJumpTable._dynamicTable)
- {
- writer.Write((int)tableEntry.EntryIndex);
- writer.Write((long)tableEntry.GuestAddress);
- writer.Write((int)tableEntry.HostAddress);
- }
-
- writer.Write((int)ptcJumpTable.Targets.Count);
-
- foreach (ulong address in ptcJumpTable.Targets)
- {
- writer.Write((ulong)address);
- }
-
- writer.Write((int)ptcJumpTable.Dependants.Count);
+ int size = 0;
- foreach (var kv in ptcJumpTable.Dependants)
- {
- writer.Write((ulong)kv.Key); // address
+ size += GetSerializeSizeList(ptcJumpTable._jumpTable);
+ size += GetSerializeSizeList(ptcJumpTable._dynamicTable);
- writer.Write((int)kv.Value.Count);
+ size += GetSerializeSizeList(ptcJumpTable.Targets);
+ size += GetSerializeSizeDictionary(ptcJumpTable.Dependants, (list) => GetSerializeSizeList(list));
+ size += GetSerializeSizeDictionary(ptcJumpTable.Owners, (list) => GetSerializeSizeList(list));
- foreach (int entry in kv.Value)
- {
- writer.Write((int)entry);
- }
- }
-
- writer.Write((int)ptcJumpTable.Owners.Count);
-
- foreach (var kv in ptcJumpTable.Owners)
- {
- writer.Write((ulong)kv.Key); // address
+ return size;
+ }
- writer.Write((int)kv.Value.Count);
+ public static void Serialize(Stream stream, PtcJumpTable ptcJumpTable)
+ {
+ SerializeList(stream, ptcJumpTable._jumpTable);
+ SerializeList(stream, ptcJumpTable._dynamicTable);
- foreach (int entry in kv.Value)
- {
- writer.Write((int)entry);
- }
- }
- }
+ SerializeList(stream, ptcJumpTable.Targets);
+ SerializeDictionary(stream, ptcJumpTable.Dependants, (stream, list) => SerializeList(stream, list));
+ SerializeDictionary(stream, ptcJumpTable.Owners, (stream, list) => SerializeList(stream, list));
}
public void Initialize(JumpTable jumpTable)
@@ -270,14 +161,25 @@ namespace ARMeilleure.Translation.PTC
Owners.Remove(guestAddress);
}
- public void Clear()
+ public void ClearIfNeeded()
{
+ if (_jumpTable.Count == 0 && _dynamicTable.Count == 0 &&
+ Targets.Count == 0 && Dependants.Count == 0 && Owners.Count == 0)
+ {
+ return;
+ }
+
_jumpTable.Clear();
+ _jumpTable.TrimExcess();
_dynamicTable.Clear();
+ _dynamicTable.TrimExcess();
Targets.Clear();
+ Targets.TrimExcess();
Dependants.Clear();
+ Dependants.TrimExcess();
Owners.Clear();
+ Owners.TrimExcess();
}
public void WriteJumpTable(JumpTable jumpTable, ConcurrentDictionary<ulong, TranslatedFunction> funcs)
@@ -307,7 +209,7 @@ namespace ARMeilleure.Translation.PTC
}
else
{
- if (!PtcProfiler.ProfiledFuncs.TryGetValue((ulong)guestAddress, out var value) || !value.highCq)
+ if (!PtcProfiler.ProfiledFuncs.TryGetValue((ulong)guestAddress, out var value) || !value.HighCq)
{
throw new KeyNotFoundException($"({nameof(guestAddress)} = 0x{(ulong)guestAddress:X16})");
}