Example #1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="MethodCompiler" /> class.
        /// </summary>
        /// <param name="compiler">The assembly compiler.</param>
        /// <param name="method">The method to compile by this instance.</param>
        /// <param name="basicBlocks">The basic blocks.</param>
        /// <param name="threadID">The thread identifier.</param>
        public MethodCompiler(Compiler compiler, MosaMethod method, BasicBlocks basicBlocks, int threadID)
        {
            Stopwatch = Stopwatch.StartNew();

            Compiler        = compiler;
            Method          = method;
            MethodScheduler = compiler.MethodScheduler;
            Architecture    = compiler.Architecture;
            TypeSystem      = compiler.TypeSystem;
            TypeLayout      = compiler.TypeLayout;
            Linker          = compiler.Linker;
            MethodScanner   = compiler.MethodScanner;
            CompilerHooks   = compiler.CompilerHooks;

            NotifyTraceLogHandler = GetMethodInstructionTraceHandler();
            Statistics            = compiler.Statistics;
            IsInSSAForm           = false;

            BasicBlocks      = basicBlocks ?? new BasicBlocks();
            LocalStack       = new List <Operand>();
            VirtualRegisters = new VirtualRegisters();

            Parameters = new Operand[method.Signature.Parameters.Count + (method.HasThis || method.HasExplicitThis ? 1 : 0)];

            ConstantZero32 = CreateConstant((uint)0);
            ConstantZero64 = CreateConstant((ulong)0);
            ConstantZeroR4 = CreateConstant(0.0f);
            ConstantZeroR8 = CreateConstant(0.0d);

            ConstantZero = Architecture.Is32BitPlatform ? ConstantZero32 : ConstantZero64;              // FUTURE: This could just be Constant64 or Constant32 once the caling stage uses the method signature intead of the operand types

            LocalVariables = emptyOperandList;
            ThreadID       = threadID;

            IsStopped           = false;
            IsExecutePipeline   = true;
            IsMethodInlined     = false;
            IsCILStream         = !Method.IsCompilerGenerated;
            HasProtectedRegions = Method.ExceptionHandlers.Count != 0;

            MethodData = Compiler.GetMethodData(Method);

            MethodData.Counters.Reset();
            MethodData.HasCode = false;
            MethodData.Version++;
            MethodData.IsMethodImplementationReplaced = IsMethodPlugged;

            IsStackFrameRequired = MethodData.StackFrameRequired;

            if (Symbol == null)
            {
                Symbol            = Linker.DefineSymbol(Method.FullName, SectionKind.Text, 0, 0);
                Symbol.MethodData = MethodData;             // for debugging
                Symbol.MosaMethod = Method;                 // for debugging
            }
            else
            {
                Symbol.RemovePatches();
            }

            var methodInfo = TypeLayout.__GetMethodInfo(Method);

            MethodData.ParameterSizes     = methodInfo.ParameterSizes;
            MethodData.ParameterOffsets   = methodInfo.ParameterOffsets;
            MethodData.ParameterStackSize = methodInfo.ParameterStackSize;
            MethodData.ReturnSize         = methodInfo.ReturnSize;
            MethodData.ReturnInRegister   = methodInfo.ReturnInRegister;

            EvaluateParameterOperands();

            MethodData.Counters.NewCountSkipLock("ExecutionTime.Setup.Ticks", (int)Stopwatch.ElapsedTicks);
        }