Esempio n. 1
0
        /// <summary>
        /// Default ctor
        /// </summary>
        public RegisterMapper(MethodBody body, InvocationFrame frame)
        {
            this.frame = frame;
            // Select all non-argument registers that are in use.
            Dictionary<Register, RegisterFlags> used;
            int maxOutgoingRegisters;
            bool largeInvokeInsFound;
            GetUsedArgumentRegisters(body, out used, out maxOutgoingRegisters, out largeInvokeInsFound);
            //var used = body.Registers.Where(x => (x.Category != RCategory.Argument) && body.Instructions.Uses(x)).ToList();
            var sorted = used.OrderBy(x => x.Value).ThenBy(x => x.Key.Index).Select(x => x.Key).ToList();
            AddKeepWithNext(sorted, body);
            // Collect argument registers
            var arguments = body.Registers.Where(x => x.Category == RCategory.Argument).ToList();

            // Prepare various decisions
            //var maxOutgoingRegisters = body.Instructions.Max(x => x.Code.IsInvoke() ? x.Registers.Count : 0);
            var required = sorted.Count + arguments.Count;
            //var largeInvokeInsFound = body.Instructions.Any(x => x.Code.IsInvoke() && x.Registers.Count > 5);

            // Allocate Dex registers for each
            var index = 0;

            // Allocate spill registers (if needed)
            if ((required >= 16) || (largeInvokeInsFound && (required + maxOutgoingRegisters >= 16)))
            {
                spillRangeRegisters = new DexLib.Instructions.Register[MaxSpillRegisters];
                for (var i = 0; i < MaxSpillRegisters; i++)
                {
                    spillRangeRegisters[i] = new DexLib.Instructions.Register(index++);                    
                }
            }

            // Allocate Dex registers for each temp register.
            foreach (var r in sorted)
            {
                var dreg = new DexLib.Instructions.Register(index++);
                map[r] = dreg;
                dRegisterTypes[dreg] = r.Type;
            }

            // Allocate outgoing invocation frame (if needed)
            if ((required >= 16) || largeInvokeInsFound)
            {
                invokeRangeRegisters = new DexLib.Instructions.Register[maxOutgoingRegisters];
                for (var i = 0; i < maxOutgoingRegisters; i++)
                {
                    invokeRangeRegisters[i] = new DexLib.Instructions.Register(index++);
                }
            }

            // Allocate Dex registers for each argument
            foreach (var r in arguments)
            {
                var dreg = new DexLib.Instructions.Register(index++);
                map[r] = dreg;
                dRegisterTypes[dreg] = r.Type;
            }
            ArgumentCount = arguments.Count;
        }
Esempio n. 2
0
        /// <summary>
        /// Default ctor
        /// </summary>
        public RegisterMapper(MethodBody body, InvocationFrame frame)
        {
            this.frame = frame;
            // Select all non-argument registers that are in use.
            Dictionary <Register, RegisterFlags> used;
            int  maxOutgoingRegisters;
            bool largeInvokeInsFound;

            GetUsedArgumentRegisters(body, out used, out maxOutgoingRegisters, out largeInvokeInsFound);
            //var used = body.Registers.Where(x => (x.Category != RCategory.Argument) && body.Instructions.Uses(x)).ToList();
            var sorted = used.OrderBy(x => x.Value).ThenBy(x => x.Key.Index).Select(x => x.Key).ToList();

            AddKeepWithNext(sorted, body);
            // Collect argument registers
            var arguments = body.Registers.Where(x => x.Category == RCategory.Argument).ToList();

            // Prepare various decisions
            //var maxOutgoingRegisters = body.Instructions.Max(x => x.Code.IsInvoke() ? x.Registers.Count : 0);
            var required = sorted.Count + arguments.Count;
            //var largeInvokeInsFound = body.Instructions.Any(x => x.Code.IsInvoke() && x.Registers.Count > 5);

            // Allocate Dex registers for each
            var index = 0;

            // Allocate spill registers (if needed)
            if ((required >= 16) || (largeInvokeInsFound && (required + maxOutgoingRegisters >= 16)))
            {
                spillRangeRegisters = new DexLib.Instructions.Register[MaxSpillRegisters];
                for (var i = 0; i < MaxSpillRegisters; i++)
                {
                    spillRangeRegisters[i] = new DexLib.Instructions.Register(index++);
                }
            }

            // Allocate Dex registers for each temp register.
            foreach (var r in sorted)
            {
                var dreg = new DexLib.Instructions.Register(index++);
                map[r] = dreg;
                dRegisterTypes[dreg] = r.Type;
            }

            // Allocate outgoing invocation frame (if needed)
            if ((required >= 16) || largeInvokeInsFound)
            {
                invokeRangeRegisters = new DexLib.Instructions.Register[maxOutgoingRegisters];
                for (var i = 0; i < maxOutgoingRegisters; i++)
                {
                    invokeRangeRegisters[i] = new DexLib.Instructions.Register(index++);
                }
            }

            // Allocate Dex registers for each argument
            foreach (var r in arguments)
            {
                var dreg = new DexLib.Instructions.Register(index++);
                map[r] = dreg;
                dRegisterTypes[dreg] = r.Type;
            }
            ArgumentCount = arguments.Count;
        }
Esempio n. 3
0
 /// <summary>
 /// Gets the type of the value in the given register.
 /// </summary>
 public RType GetType(DexLib.Instructions.Register register)
 {
     return(dRegisterTypes[register]);
 }