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 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)); }