diff options
Diffstat (limited to 'ARMeilleure/Instructions')
| -rw-r--r-- | ARMeilleure/Instructions/InstEmitMemoryHelper.cs | 23 | ||||
| -rw-r--r-- | ARMeilleure/Instructions/NativeInterface.cs | 14 |
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) |
