aboutsummaryrefslogtreecommitdiff
path: root/ARMeilleure/Instructions
diff options
context:
space:
mode:
Diffstat (limited to 'ARMeilleure/Instructions')
-rw-r--r--ARMeilleure/Instructions/InstEmitMemoryHelper.cs23
-rw-r--r--ARMeilleure/Instructions/NativeInterface.cs14
2 files changed, 18 insertions, 19 deletions
diff --git a/ARMeilleure/Instructions/InstEmitMemoryHelper.cs b/ARMeilleure/Instructions/InstEmitMemoryHelper.cs
index 390d167d..fd5c5bca 100644
--- a/ARMeilleure/Instructions/InstEmitMemoryHelper.cs
+++ b/ARMeilleure/Instructions/InstEmitMemoryHelper.cs
@@ -391,23 +391,22 @@ namespace ARMeilleure.Instructions
if (lblSlowPath != null)
{
- context.BranchIf(lblSlowPath, pte, Const(0L), Comparison.LessOrEqual);
+ ulong protection = (write ? 3UL : 1UL) << 48;
+ context.BranchIfTrue(lblSlowPath, context.BitwiseAnd(pte, Const(protection)));
}
else
{
// When no label is provided to jump to a slow path if the address is invalid,
// we do the validation ourselves, and throw if needed.
- if (write)
- {
- Operand lblNotWatched = Label();
- // Is the page currently being monitored for modifications? If so we need to call MarkRegionAsModified.
- context.BranchIf(lblNotWatched, pte, Const(0L), Comparison.GreaterOrEqual, BasicBlockFrequency.Cold);
+ Operand lblNotWatched = Label();
- // Mark the region as modified. Size here doesn't matter as address is assumed to be size aligned here.
- context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.MarkRegionAsModified)), address, Const(1UL));
- context.MarkLabel(lblNotWatched);
- }
+ // Is the page currently being tracked for read/write? If so we need to call MarkRegionAsModified.
+ context.BranchIf(lblNotWatched, pte, Const(0L), Comparison.GreaterOrEqual, BasicBlockFrequency.Cold);
+
+ // Mark the region as modified. Size here doesn't matter as address is assumed to be size aligned here.
+ context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SignalMemoryTracking)), address, Const(1UL), Const(write ? 1 : 0));
+ context.MarkLabel(lblNotWatched);
Operand lblNonNull = Label();
@@ -417,10 +416,10 @@ namespace ARMeilleure.Instructions
// The call is not expected to return (it should throw).
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ThrowInvalidMemoryAccess)), address);
context.MarkLabel(lblNonNull);
-
- pte = context.BitwiseAnd(pte, Const(0xffffffffffffUL));
}
+ pte = context.BitwiseAnd(pte, Const(0xffffffffffffUL)); // Ignore any software protection bits. (they are still used by c# memory access)
+
Operand pageOffset = context.BitwiseAnd(address, Const(address.Type, PageMask));
if (pageOffset.Type == OperandType.I32)
diff --git a/ARMeilleure/Instructions/NativeInterface.cs b/ARMeilleure/Instructions/NativeInterface.cs
index b4afcc02..8fb98df8 100644
--- a/ARMeilleure/Instructions/NativeInterface.cs
+++ b/ARMeilleure/Instructions/NativeInterface.cs
@@ -163,27 +163,27 @@ namespace ARMeilleure.Instructions
#region "Read"
public static byte ReadByte(ulong address)
{
- return GetMemoryManager().Read<byte>(address);
+ return GetMemoryManager().ReadTracked<byte>(address);
}
public static ushort ReadUInt16(ulong address)
{
- return GetMemoryManager().Read<ushort>(address);
+ return GetMemoryManager().ReadTracked<ushort>(address);
}
public static uint ReadUInt32(ulong address)
{
- return GetMemoryManager().Read<uint>(address);
+ return GetMemoryManager().ReadTracked<uint>(address);
}
public static ulong ReadUInt64(ulong address)
{
- return GetMemoryManager().Read<ulong>(address);
+ return GetMemoryManager().ReadTracked<ulong>(address);
}
public static V128 ReadVector128(ulong address)
{
- return GetMemoryManager().Read<V128>(address);
+ return GetMemoryManager().ReadTracked<V128>(address);
}
#endregion
@@ -214,9 +214,9 @@ namespace ARMeilleure.Instructions
}
#endregion
- public static void MarkRegionAsModified(ulong address, ulong size)
+ public static void SignalMemoryTracking(ulong address, ulong size, bool write)
{
- GetMemoryManager().MarkRegionAsModified(address, size);
+ GetMemoryManager().SignalMemoryTracking(address, size, write);
}
public static void ThrowInvalidMemoryAccess(ulong address)