Beispiel #1
0
        void PrewarmBody(HashSet <ILMethod> alreadyPrewarmed)
        {
            //当前方法用到的IType,提前InitializeMethods()。各个子调用,提前InitParameters()
            var body = Body;

            foreach (var ins in body)
            {
                switch (ins.Code)
                {
                case OpCodeEnum.Call:
                case OpCodeEnum.Newobj:
                case OpCodeEnum.Ldftn:
                case OpCodeEnum.Ldvirtftn:
                case OpCodeEnum.Callvirt:
                {
                    var m = appdomain.GetMethod(ins.TokenInteger);
                    if (m is ILMethod)
                    {
                        ILMethod ilm = (ILMethod)m;
                        //如果参数alreadyPrewarmed不为空,则不仅prewarm当前方法,还会递归prewarm所有子调用
                        //如果参数alreadyPrewarmed为空,则只prewarm当前方法
                        if (alreadyPrewarmed != null)
                        {
                            ilm.Prewarm(alreadyPrewarmed);
                        }
                    }
                    else if (m is CLRMethod)
                    {
                        CLRMethod clrm = (CLRMethod)m;
                        ILRuntime.CLR.Utils.Extensions.GetTypeFlags(clrm.DeclearingType.TypeForCLR);
                    }
                }
                break;

                case OpCodeEnum.Ldfld:
                case OpCodeEnum.Stfld:
                case OpCodeEnum.Ldflda:
                case OpCodeEnum.Ldsfld:
                case OpCodeEnum.Ldsflda:
                case OpCodeEnum.Stsfld:
                case OpCodeEnum.Ldtoken:
                {
                    //提前InitializeBaseType()
                    var t = appdomain.GetType((int)(ins.TokenLong >> 32));
                    if (t != null)
                    {
                        var baseType = t.BaseType;
                    }
                }
                break;
                }
            }
        }
Beispiel #2
0
        unsafe void InitToken(ref OpCode code, object token, Dictionary <Mono.Cecil.Cil.Instruction, int> addr)
        {
            switch (code.Code)
            {
            case OpCodeEnum.Leave:
            case OpCodeEnum.Leave_S:
            case OpCodeEnum.Br:
            case OpCodeEnum.Br_S:
            case OpCodeEnum.Brtrue:
            case OpCodeEnum.Brtrue_S:
            case OpCodeEnum.Brfalse:
            case OpCodeEnum.Brfalse_S:
            //比较流程控制
            case OpCodeEnum.Beq:
            case OpCodeEnum.Beq_S:
            case OpCodeEnum.Bne_Un:
            case OpCodeEnum.Bne_Un_S:
            case OpCodeEnum.Bge:
            case OpCodeEnum.Bge_S:
            case OpCodeEnum.Bge_Un:
            case OpCodeEnum.Bge_Un_S:
            case OpCodeEnum.Bgt:
            case OpCodeEnum.Bgt_S:
            case OpCodeEnum.Bgt_Un:
            case OpCodeEnum.Bgt_Un_S:
            case OpCodeEnum.Ble:
            case OpCodeEnum.Ble_S:
            case OpCodeEnum.Ble_Un:
            case OpCodeEnum.Ble_Un_S:
            case OpCodeEnum.Blt:
            case OpCodeEnum.Blt_S:
            case OpCodeEnum.Blt_Un:
            case OpCodeEnum.Blt_Un_S:
                code.TokenInteger = addr[(Mono.Cecil.Cil.Instruction)token];
                break;

            case OpCodeEnum.Ldc_I4:
                code.TokenInteger = (int)token;
                break;

            case OpCodeEnum.Ldc_I4_S:
                code.TokenInteger = (sbyte)token;
                break;

            case OpCodeEnum.Ldc_I8:
                code.TokenLong = (long)token;
                break;

            case OpCodeEnum.Ldc_R4:
            {
                float val = (float)token;
                code.TokenInteger = *(int *)&val;
            }
            break;

            case OpCodeEnum.Ldc_R8:
            {
                double val = (double)token;
                code.TokenLong = *(long *)&val;
            }
            break;

            case OpCodeEnum.Stloc:
            case OpCodeEnum.Stloc_S:
            case OpCodeEnum.Ldloc:
            case OpCodeEnum.Ldloc_S:
            case OpCodeEnum.Ldloca:
            case OpCodeEnum.Ldloca_S:
            {
                Mono.Cecil.Cil.VariableDefinition vd = (Mono.Cecil.Cil.VariableDefinition)token;
                code.TokenInteger = vd.Index;
            }
            break;

            case OpCodeEnum.Ldarg_S:
            case OpCodeEnum.Ldarg:
            case OpCodeEnum.Ldarga:
            case OpCodeEnum.Ldarga_S:
            case OpCodeEnum.Starg:
            case OpCodeEnum.Starg_S:
            {
                Mono.Cecil.ParameterDefinition vd = (Mono.Cecil.ParameterDefinition)token;
                code.TokenInteger = vd.Index;
                if (HasThis)
                {
                    code.TokenInteger++;
                }
            }
            break;

            case OpCodeEnum.Call:
            case OpCodeEnum.Newobj:
            case OpCodeEnum.Ldftn:
            case OpCodeEnum.Ldvirtftn:
            case OpCodeEnum.Callvirt:
            {
                bool invalidToken;
                var  m = appdomain.GetMethod(token, declaringType, this, out invalidToken);
                if (m != null)
                {
                    if (invalidToken)
                    {
                        code.TokenInteger = m.GetHashCode();
                    }
                    else
                    {
                        code.TokenInteger = token.GetHashCode();
                    }
                }
                else
                {
                    //Cannot find method or the method is dummy
                    MethodReference _ref     = (MethodReference)token;
                    int             paramCnt = _ref.HasParameters ? _ref.Parameters.Count : 0;
                    if (_ref.HasThis)
                    {
                        paramCnt++;
                    }
                    code.TokenLong = paramCnt;
                }
            }
            break;

            case OpCodeEnum.Constrained:
            case OpCodeEnum.Box:
            case OpCodeEnum.Unbox_Any:
            case OpCodeEnum.Unbox:
            case OpCodeEnum.Initobj:
            case OpCodeEnum.Isinst:
            case OpCodeEnum.Newarr:
            case OpCodeEnum.Stobj:
            case OpCodeEnum.Ldobj:
            {
                code.TokenInteger = GetTypeTokenHashCode(token);
            }
            break;

            case OpCodeEnum.Stfld:
            case OpCodeEnum.Ldfld:
            case OpCodeEnum.Ldflda:
            {
                code.TokenLong = appdomain.GetStaticFieldIndex(token, declaringType, this);
            }
            break;

            case OpCodeEnum.Stsfld:
            case OpCodeEnum.Ldsfld:
            case OpCodeEnum.Ldsflda:
            {
                code.TokenLong = appdomain.GetStaticFieldIndex(token, declaringType, this);
            }
            break;

            case OpCodeEnum.Ldstr:
            {
                long hashCode = appdomain.CacheString(token);
                code.TokenLong = hashCode;
            }
            break;

            case OpCodeEnum.Ldtoken:
            {
                if (token is FieldReference)
                {
                    code.TokenInteger = 0;
                    code.TokenLong    = appdomain.GetStaticFieldIndex(token, declaringType, this);
                }
                else if (token is TypeReference)
                {
                    code.TokenInteger = 1;
                    code.TokenLong    = GetTypeTokenHashCode(token);
                }
                else
                {
                    throw new NotImplementedException();
                }
            }
            break;

            case OpCodeEnum.Switch:
            {
                PrepareJumpTable(token, addr);
                code.TokenInteger = token.GetHashCode();
            }
            break;
            }
        }
Beispiel #3
0
        private void Prewarm(HashSet <ILMethod> alreadyPrewarmed)
        {
            if (alreadyPrewarmed != null && alreadyPrewarmed.Add(this) == false)
            {
                return;
            }
            if (GenericParameterCount > 0 && !IsGenericInstance)
            {
                return;
            }
            //当前方法用到的IType,提前InitializeMethods()。各个子调用,提前InitParameters()
            var body = Body;

            //当前方法用到的CLR局部变量,提前InitializeFields()、GetTypeFlags()
            for (int i = 0; i < LocalVariableCount; i++)
            {
                var   v  = Variables[i];
                var   vt = v.VariableType;
                IType t;
                if (vt.IsGenericParameter)
                {
                    t = FindGenericArgument(vt.Name);
                }
                else
                {
                    t = appdomain.GetType(v.VariableType, DeclearingType, this);
                }
                if (t is CLRType ct)
                {
                    var fields = ct.Fields;
                    ILRuntime.CLR.Utils.Extensions.GetTypeFlags(ct.TypeForCLR);
                }
            }
            foreach (var ins in body)
            {
                switch (ins.Code)
                {
                case OpCodeEnum.Call:
                case OpCodeEnum.Newobj:
                case OpCodeEnum.Ldftn:
                case OpCodeEnum.Ldvirtftn:
                case OpCodeEnum.Callvirt:
                {
                    var m = appdomain.GetMethod(ins.TokenInteger);
                    if (m is ILMethod ilm)
                    {
                        //如果参数alreadyPrewarmed不为空,则不仅prewarm当前方法,还会递归prewarm所有子调用
                        //如果参数alreadyPrewarmed为空,则只prewarm当前方法
                        if (alreadyPrewarmed != null)
                        {
                            ilm.Prewarm(alreadyPrewarmed);
                        }
                    }
                    else if (m is CLRMethod clrm)
                    {
                        ILRuntime.CLR.Utils.Extensions.GetTypeFlags(clrm.DeclearingType.TypeForCLR);
                    }
                }
                break;

                case OpCodeEnum.Ldfld:
                case OpCodeEnum.Stfld:
                case OpCodeEnum.Ldflda:
                case OpCodeEnum.Ldsfld:
                case OpCodeEnum.Ldsflda:
                case OpCodeEnum.Stsfld:
                case OpCodeEnum.Ldtoken:
                {
                    //提前InitializeBaseType()
                    var t = appdomain.GetType((int)(ins.TokenLong >> 32));
                    if (t != null)
                    {
                        var baseType = t.BaseType;
                    }
                }
                break;
                }
            }
        }