Пример #1
0
        public bool TryGetSubroutine(long Position, out ATranslatedSub 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(ATranslatedSub);

            return(false);
        }
Пример #2
0
        private ATranslatedSub TranslateTier0(AThreadState State, AMemory Memory, long Position)
        {
            ABlock Block = ADecoder.DecodeBasicBlock(State, Memory, Position);

            ABlock[] Graph = new ABlock[] { Block };

            string SubName = GetSubroutineName(Position);

            AILEmitterCtx Context = new AILEmitterCtx(Cache, Graph, Block, SubName);

            do
            {
                Context.EmitOpCode();
            }while (Context.AdvanceOpCode());

            ATranslatedSub Subroutine = Context.GetSubroutine();

            Subroutine.SetType(ATranslatedSubType.SubTier0);

            Cache.AddOrUpdate(Position, Subroutine, Block.OpCodes.Count);

            AOpCode LastOp = Block.GetLastOp();

            return(Subroutine);
        }
Пример #3
0
            public CacheBucket(ATranslatedSub Subroutine, LinkedListNode <long> Node, int Size)
            {
                this.Subroutine = Subroutine;
                this.Size       = Size;

                UpdateNode(Node);
            }
Пример #4
0
        internal bool TryGetCachedSub(AOpCode OpCode, out ATranslatedSub Sub)
        {
            if (OpCode.Emitter != AInstEmit.Bl)
            {
                Sub = null;

                return(false);
            }

            return(TryGetCachedSub(((AOpCodeBImmAl)OpCode).Imm, out Sub));
        }
Пример #5
0
        private ATranslatedSub TranslateTier0(AMemory Memory, long Position)
        {
            ABlock Block = ADecoder.DecodeBasicBlock(this, Memory, Position);

            ABlock[] Graph = new ABlock[] { Block };

            string SubName = GetSubName(Position);

            AILEmitterCtx Context = new AILEmitterCtx(this, Graph, Block, SubName);

            do
            {
                Context.EmitOpCode();
            }while (Context.AdvanceOpCode());

            ATranslatedSub Subroutine = Context.GetSubroutine();

            lock (SubBlocks)
            {
                if (SubBlocks.Contains(Position))
                {
                    SubBlocks.Remove(Position);

                    Subroutine.SetType(ATranslatedSubType.SubBlock);
                }
                else
                {
                    Subroutine.SetType(ATranslatedSubType.SubTier0);
                }
            }

            CachedSubs.AddOrUpdate(Position, Subroutine, (Key, OldVal) => Subroutine);

            AOpCode LastOp = Block.GetLastOp();

            lock (SubBlocks)
            {
                if (LastOp.Emitter != AInstEmit.Ret &&
                    LastOp.Emitter != AInstEmit.Br)
                {
                    SubBlocks.Add(LastOp.Position + 4);
                }
            }

            return(Subroutine);
        }
Пример #6
0
        private ATranslatedSub TranslateSubroutine(AMemory Memory, long Position)
        {
            (ABlock[] Graph, ABlock Root)Cfg = ADecoder.DecodeSubroutine(this, Memory, Position);

            string SubName = SymbolTable.GetOrAdd(Position, $"Sub{Position:x16}");

            PropagateName(Cfg.Graph, SubName);

            AILEmitterCtx Context = new AILEmitterCtx(
                this,
                Cfg.Graph,
                Cfg.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.
            foreach (ATranslatedSub TS in CachedSubs.Values)
            {
                if (TS.SubCalls.Contains(Position))
                {
                    TS.MarkForReJit();
                }
            }

            ATranslatedSub Subroutine = Context.GetSubroutine();

            CachedSubs.AddOrUpdate(Position, Subroutine, (Key, OldVal) => Subroutine);

            return(Subroutine);
        }
Пример #7
0
        private void TranslateTier1(AThreadState State, AMemory Memory, long Position)
        {
            (ABlock[] Graph, ABlock Root)Cfg = ADecoder.DecodeSubroutine(State, this, Memory, Position);

            string SubName = GetSubName(Position);

            PropagateName(Cfg.Graph, SubName);

            AILEmitterCtx Context = new AILEmitterCtx(this, Cfg.Graph, Cfg.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 (CachedSubs.TryGetValue(Position, out ATranslatedSub OldSub))
            {
                foreach (long CallerPos in OldSub.GetCallerPositions())
                {
                    if (CachedSubs.TryGetValue(Position, out ATranslatedSub CallerSub))
                    {
                        CallerSub.MarkForReJit();
                    }
                }
            }

            ATranslatedSub Subroutine = Context.GetSubroutine();

            Subroutine.SetType(ATranslatedSubType.SubTier1);

            CachedSubs.AddOrUpdate(Position, Subroutine, (Key, OldVal) => Subroutine);
        }
Пример #8
0
        public void AddOrUpdate(long Position, ATranslatedSub Subroutine, int Size)
        {
            ClearCacheIfNeeded();

            TotalSize += Size;

            lock (SortedCache)
            {
                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);
                });
            }
        }
Пример #9
0
        private ATranslatedSub TranslateSubroutine(long Position)
        {
            (ABlock[] Graph, ABlock Root)Cfg = ADecoder.DecodeSubroutine(this, Position);

            AILEmitterCtx Context = new AILEmitterCtx(
                this,
                Cfg.Graph,
                Cfg.Root);

            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.
            foreach (ATranslatedSub TS in CachedSubs.Values)
            {
                if (TS.SubCalls.Contains(Position))
                {
                    TS.MarkForReJit();
                }
            }

            ATranslatedSub Subroutine = Context.GetSubroutine();

            if (!CachedSubs.TryAdd(Position, Subroutine))
            {
                CachedSubs[Position] = Subroutine;
            }

            return(Subroutine);
        }
Пример #10
0
 internal bool TryGetCachedSub(long Position, out ATranslatedSub Sub)
 {
     return(CachedSubs.TryGetValue(Position, out Sub));
 }