Avoid memory protection races on JIT Cache
This commit is contained in:
parent
eaa734b8e6
commit
6b42189d05
1 changed files with 18 additions and 16 deletions
|
@ -3,7 +3,6 @@ using ARMeilleure.Memory;
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
|
||||
namespace ARMeilleure.Translation
|
||||
{
|
||||
|
@ -22,6 +21,8 @@ namespace ARMeilleure.Translation
|
|||
|
||||
private static List<JitCacheEntry> _cacheEntries;
|
||||
|
||||
private static object _lock;
|
||||
|
||||
static JitCache()
|
||||
{
|
||||
_basePointer = MemoryManagement.Allocate(CacheSize);
|
||||
|
@ -35,12 +36,16 @@ namespace ARMeilleure.Translation
|
|||
}
|
||||
|
||||
_cacheEntries = new List<JitCacheEntry>();
|
||||
|
||||
_lock = new object();
|
||||
}
|
||||
|
||||
public static IntPtr Map(CompiledFunction func)
|
||||
{
|
||||
byte[] code = func.Code;
|
||||
|
||||
lock (_lock)
|
||||
{
|
||||
int funcOffset = Allocate(code.Length);
|
||||
|
||||
IntPtr funcPtr = _basePointer + funcOffset;
|
||||
|
@ -53,6 +58,7 @@ namespace ARMeilleure.Translation
|
|||
|
||||
return funcPtr;
|
||||
}
|
||||
}
|
||||
|
||||
private static void ReprotectRange(int offset, int size)
|
||||
{
|
||||
|
@ -87,11 +93,11 @@ namespace ARMeilleure.Translation
|
|||
{
|
||||
codeSize = checked(codeSize + (CodeAlignment - 1)) & ~(CodeAlignment - 1);
|
||||
|
||||
int newOffset = Interlocked.Add(ref _offset, codeSize);
|
||||
int allocOffset = _offset;
|
||||
|
||||
int allocOffset = newOffset - codeSize;
|
||||
_offset += codeSize;
|
||||
|
||||
if ((ulong)(uint)newOffset > CacheSize)
|
||||
if ((ulong)(uint)_offset > CacheSize)
|
||||
{
|
||||
throw new OutOfMemoryException();
|
||||
}
|
||||
|
@ -100,17 +106,13 @@ namespace ARMeilleure.Translation
|
|||
}
|
||||
|
||||
private static void Add(JitCacheEntry entry)
|
||||
{
|
||||
// TODO: Use concurrent collection.
|
||||
lock (_cacheEntries)
|
||||
{
|
||||
_cacheEntries.Add(entry);
|
||||
}
|
||||
}
|
||||
|
||||
public static bool TryFind(int offset, out JitCacheEntry entry)
|
||||
{
|
||||
lock (_cacheEntries)
|
||||
lock (_lock)
|
||||
{
|
||||
foreach (JitCacheEntry cacheEntry in _cacheEntries)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue