public CacheBucket(TranslatedSub subroutine, LinkedListNode <long> node, int size) { Subroutine = subroutine; Size = size; UpdateNode(node); }
public bool TryGetSubroutine(long position, out TranslatedSub subroutine) { if (_cache.TryGetValue(position, out CacheBucket bucket)) { if (bucket.CallCount++ > MinCallCountForUpdate) { if (Monitor.TryEnter(_sortedCache)) { try { bucket.CallCount = 0; _sortedCache.Remove(bucket.Node); bucket.UpdateNode(_sortedCache.AddLast(position)); } finally { Monitor.Exit(_sortedCache); } } } subroutine = bucket.Subroutine; return(true); } subroutine = default(TranslatedSub); return(false); }
private TranslatedSub TranslateTier0(CpuThreadState state, MemoryManager memory, long position) { Block block = Decoder.DecodeBasicBlock(state, memory, position); Block[] graph = new Block[] { block }; string subName = GetSubroutineName(position); ILEmitterCtx context = new ILEmitterCtx(_cache, graph, block, subName); do { context.EmitOpCode(); }while (context.AdvanceOpCode()); TranslatedSub subroutine = context.GetSubroutine(); subroutine.SetType(TranslatedSubType.SubTier0); _cache.AddOrUpdate(position, subroutine, block.OpCodes.Count); OpCode64 lastOp = block.GetLastOp(); return(subroutine); }
private TranslatedSub TranslateTier0(MemoryManager memory, long position, ExecutionMode mode) { Block block = Decoder.DecodeBasicBlock(memory, position, mode); ILEmitterCtx context = new ILEmitterCtx(_cache, block); string subName = GetSubroutineName(position); ILMethodBuilder ilMthdBuilder = new ILMethodBuilder(context.GetILBlocks(), subName); TranslatedSub subroutine = ilMthdBuilder.GetSubroutine(); subroutine.SetType(TranslatedSubType.SubTier0); _cache.AddOrUpdate(position, subroutine, block.OpCodes.Count); return(subroutine); }
public bool TryGetSubroutine(long position, out TranslatedSub subroutine) { if (_cache.TryGetValue(position, out CacheBucket bucket)) { if (bucket.CallCount++ > MinCallCountForUpdate) { if (Monitor.TryEnter(_sortedCache)) { try { //The bucket value on the dictionary may have changed between the //time we get the value from the dictionary, and we acquire the //lock. So we need to ensure we are working with the latest value, //we can do that by getting the value again, inside the lock. if (_cache.TryGetValue(position, out CacheBucket latestBucket)) { latestBucket.CallCount = 0; _sortedCache.Remove(latestBucket.Node); latestBucket.UpdateNode(_sortedCache.AddLast(position)); } } finally { Monitor.Exit(_sortedCache); } } } subroutine = bucket.Subroutine; return(true); } subroutine = default(TranslatedSub); return(false); }
public void AddOrUpdate(long position, TranslatedSub subroutine, int size) { ClearCacheIfNeeded(); lock (_sortedCache) { _totalSize += size; LinkedListNode <long> node = _sortedCache.AddLast(position); CacheBucket newBucket = new CacheBucket(subroutine, node, size); _cache.AddOrUpdate(position, newBucket, (key, bucket) => { _totalSize -= bucket.Size; _sortedCache.Remove(bucket.Node); return(newBucket); }); } }
private void TranslateTier1(MemoryManager memory, long position, ExecutionMode mode) { Block graph = Decoder.DecodeSubroutine(_cache, memory, position, mode); ILEmitterCtx context = new ILEmitterCtx(_cache, graph); ILBlock[] ilBlocks = context.GetILBlocks(); string subName = GetSubroutineName(position); ILMethodBuilder ilMthdBuilder = new ILMethodBuilder(ilBlocks, subName); TranslatedSub subroutine = ilMthdBuilder.GetSubroutine(); subroutine.SetType(TranslatedSubType.SubTier1); int ilOpCount = 0; foreach (ILBlock ilBlock in ilBlocks) { ilOpCount += ilBlock.Count; } _cache.AddOrUpdate(position, subroutine, ilOpCount); //Mark all methods that calls this method for ReJiting, //since we can now call it directly which is faster. if (_cache.TryGetSubroutine(position, out TranslatedSub oldSub)) { foreach (long callerPos in oldSub.GetCallerPositions()) { if (_cache.TryGetSubroutine(position, out TranslatedSub callerSub)) { callerSub.MarkForReJit(); } } } }
private void TranslateTier1(CpuThreadState state, MemoryManager memory, long position) { (Block[] graph, Block root) = Decoder.DecodeSubroutine(_cache, state, memory, position); string subName = GetSubroutineName(position); ILEmitterCtx context = new ILEmitterCtx(_cache, graph, root, subName); if (context.CurrBlock.Position != position) { context.Emit(OpCodes.Br, context.GetLabel(position)); } do { context.EmitOpCode(); }while (context.AdvanceOpCode()); //Mark all methods that calls this method for ReJiting, //since we can now call it directly which is faster. if (_cache.TryGetSubroutine(position, out TranslatedSub oldSub)) { foreach (long callerPos in oldSub.GetCallerPositions()) { if (_cache.TryGetSubroutine(position, out TranslatedSub callerSub)) { callerSub.MarkForReJit(); } } } TranslatedSub subroutine = context.GetSubroutine(); subroutine.SetType(TranslatedSubType.SubTier1); _cache.AddOrUpdate(position, subroutine, GetGraphInstCount(graph)); }