예제 #1
0
 public TraceLog(TraceType type, MosaMethod method, string stage, bool active)
     : this(type)
 {
     this.Stage = stage;
     this.Method = method;
     this.Active = active;
 }
예제 #2
0
 public bool IsScheduled(MosaMethod method)
 {
     lock (methods)
     {
         return methods.Contains(method);
     }
 }
예제 #3
0
 public TraceLog(TraceType type, MosaMethod method, string stage, TraceFilter filter)
     : this(type)
 {
     this.Stage = stage;
     this.Method = method;
     this.Active = filter.IsMatch(this.Method, this.Stage);
 }
        /// <summary>
        /// Initializes a new instance of the <see cref="BaseMethodCompiler" /> 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>
        protected BaseMethodCompiler(BaseCompiler compiler, MosaMethod method, BasicBlocks basicBlocks, int threadID)
        {
            Compiler = compiler;
            Method = method;
            Type = method.DeclaringType;
            Scheduler = compiler.CompilationScheduler;
            Architecture = compiler.Architecture;
            TypeSystem = compiler.TypeSystem;
            TypeLayout = compiler.TypeLayout;
            Trace = compiler.CompilerTrace;
            Linker = compiler.Linker;
            BasicBlocks = basicBlocks ?? new BasicBlocks();
            Pipeline = new CompilerPipeline();
            StackLayout = new StackLayout(Architecture, method.Signature.Parameters.Count + (method.HasThis || method.HasExplicitThis ? 1 : 0));
            VirtualRegisters = new VirtualRegisters(Architecture);
            LocalVariables = emptyOperandList;
            ThreadID = threadID;
            DominanceAnalysis = new Dominance(Compiler.CompilerOptions.DominanceAnalysisFactory, BasicBlocks);
            PluggedMethod = compiler.PlugSystem.GetPlugMethod(Method);
            stop = false;

            MethodData = compiler.CompilerData.GetCompilerMethodData(Method);
            MethodData.Counters.Clear();

            EvaluateParameterOperands();
        }
예제 #5
0
        /// <summary>
        /// Initializes a new instance of the <see cref="SimMethodCompiler" /> class.
        /// </summary>
        /// <param name="compiler">The compiler.</param>
        /// <param name="method">The method.</param>
        /// <param name="simAdapter">The sim adapter.</param>
        /// <param name="basicBlocks">The basic blocks.</param>
        /// <param name="instructionSet">The instruction set.</param>
        public SimMethodCompiler(SimCompiler compiler, MosaMethod method, ISimAdapter simAdapter, BasicBlocks basicBlocks, InstructionSet instructionSet)
            : base(compiler, method, basicBlocks, instructionSet)
        {
            var compilerOptions = Compiler.CompilerOptions;

            // Populate the pipeline
            Pipeline.Add(new IMethodCompilerStage[] {
                new CILDecodingStage(),
                new BasicBlockBuilderStage(),
                new StackSetupStage(),
                new ExceptionPrologueStage(),
                new OperandAssignmentStage(),
                //new SingleUseMarkerStage(),
                //new OperandUsageAnalyzerStage(),
                new StaticAllocationResolutionStage(),
                new CILTransformationStage(),
                new ConvertCompoundMoveStage(),
                //new CheckIROperandCountStage(),
                (compilerOptions.EnableSSA) ? new PromoteLocalVariablesStage() : null,
                (compilerOptions.EnableSSA) ? new EdgeSplitStage() : null,
                (compilerOptions.EnableSSA) ? new PhiPlacementStage() : null,
                (compilerOptions.EnableSSA) ? new EnterSSAStage() : null,
                (compilerOptions.EnableSSA && compilerOptions.EnableSSAOptimizations) ? new SSAOptimizations() : null,
                (compilerOptions.EnableSSA) ? new LeaveSSA() : null,
                (compilerOptions.EnableSSA) ? new ConvertCompoundMoveStage() : null,
                new PlatformStubStage(),
                //new CheckPlatformOperandCountStage(),
                new	PlatformEdgeSplitStage(),
                new GreedyRegisterAllocatorStage(),
                new StackLayoutStage(),
                new EmptyBlockRemovalStage(),
                new BlockOrderingStage(),
                new SimCodeGeneratorStage(simAdapter),
            });
        }
예제 #6
0
 public TraceLog(TraceType type, MosaMethod method, string stage, TraceFilter filter)
     : this(type)
 {
     Stage = stage;
     Method = method;
     Active = filter.IsMatch(Method, Stage);
 }
예제 #7
0
        /// <summary>
        /// Initializes a new instance of the <see cref="AotMethodCompiler" /> class.
        /// </summary>
        /// <param name="compiler">The compiler.</param>
        /// <param name="method">The method.</param>
        /// <param name="basicBlocks">The basic blocks.</param>
        /// <param name="instructionSet">The instruction set.</param>
        public AotMethodCompiler(BaseCompiler compiler, MosaMethod method, BasicBlocks basicBlocks, InstructionSet instructionSet)
            : base(compiler, method, basicBlocks, instructionSet)
        {
            var compilerOptions = compiler.CompilerOptions;

            Pipeline.Add(new IMethodCompilerStage[] {
                new CILDecodingStage(),
                new BasicBlockBuilderStage(),
                new StackSetupStage(),
                new ExceptionPrologueStage(),
                new OperandAssignmentStage(),
                new StaticAllocationResolutionStage(),
                new CILTransformationStage(),
                new ConvertCompoundMoveStage(),
                (compilerOptions.EnableSSA) ? new PromoteLocalVariablesStage() : null,
                (compilerOptions.EnableSSA) ? new EdgeSplitStage() : null,
                (compilerOptions.EnableSSA) ? new PhiPlacementStage() : null,
                (compilerOptions.EnableSSA) ? new EnterSSAStage() : null,
                (compilerOptions.EnableSSA && compilerOptions.EnableSSAOptimizations) ? new SSAOptimizations() : null,
                (compilerOptions.EnableSSA) ? new LeaveSSA() : null,
                (compilerOptions.EnableSSA) ? new ConvertCompoundMoveStage() : null,
                new PlatformStubStage(),
                new	PlatformEdgeSplitStage(),
                new GreedyRegisterAllocatorStage(),
                new StackLayoutStage(),
                new EmptyBlockRemovalStage(),
                new BlockOrderingStage(),
                new CodeGenerationStage(),
            });
        }
예제 #8
0
        public bool IsMatch(MosaMethod method, string stage)
        {
            if (!Active)
                return false;

            return IsMatch(method.DeclaringType.Name, method.Name, stage);
        }
        /// <summary>
        /// Calculates the stack size for parameters.
        /// </summary>
        /// <param name="typeLayout">The type layouts.</param>
        /// <param name="operands">The operands.</param>
        /// <param name="method">The method.</param>
        /// <returns></returns>
        protected static int CalculateStackSizeForParameters(MosaTypeLayout typeLayout, BaseArchitecture architecture, List<Operand> operands, MosaMethod method)
        {
            Debug.Assert((method.Signature.Parameters.Count + (method.HasThis ? 1 : 0) == operands.Count) ||
            (method.DeclaringType.IsDelegate && method.Signature.Parameters.Count == operands.Count), method.FullName);

            int offset = method.Signature.Parameters.Count - operands.Count;
            int result = 0;

            for (int index = operands.Count - 1; index >= 0; index--)
            {
                Operand operand = operands[index];

                int size, alignment;
                architecture.GetTypeRequirements(typeLayout, operand.Type, out size, out alignment);

                var param = (index + offset >= 0) ? method.Signature.Parameters[index + offset] : null;

                if (param != null && operand.IsR8 && param.ParameterType.IsR4)
                {
                    //  adjust for parameter size on stack when method parameter is R4 while the calling variable is R8
                    architecture.GetTypeRequirements(typeLayout, param.ParameterType, out size, out alignment);
                }

                result = (int)Alignment.AlignUp(result, (uint)alignment) + size;
            }

            return result;
        }
예제 #10
0
 public CompilerTrace(IInternalTrace internalTrace, MosaMethod method, string stage)
     : this(internalTrace)
 {
     this.Stage = stage;
     this.Method = method;
     this.Active = internalTrace.TraceFilter.IsMatch(this.Method, this.Stage);
 }
예제 #11
0
        /// <summary>
        /// Initializes a new instance of the <see cref="BaseMethodCompiler" /> 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="instructionSet">The instruction set.</param>
        protected BaseMethodCompiler(BaseCompiler compiler, MosaMethod method, BasicBlocks basicBlocks, InstructionSet instructionSet)
        {
            this.Compiler = compiler;
            this.Method = method;
            this.Type = method.DeclaringType;
            this.Scheduler = compiler.CompilationScheduler;
            this.Architecture = compiler.Architecture;
            this.TypeSystem = compiler.TypeSystem;
            this.TypeLayout = Compiler.TypeLayout;
            this.InternalTrace = Compiler.InternalTrace;
            this.Linker = compiler.Linker;
            this.BasicBlocks = basicBlocks ?? new BasicBlocks();
            this.InstructionSet = instructionSet ?? new InstructionSet(256);
            this.Pipeline = new CompilerPipeline();
            this.StackLayout = new StackLayout(Architecture, method.Signature.Parameters.Count + (method.HasThis || method.HasExplicitThis ? 1 : 0));
            this.VirtualRegisters = new VirtualRegisters(Architecture);
            this.LocalVariables = emptyOperandList;
            this.DominanceAnalysis = new DominanceAnalysis(Compiler.CompilerOptions.DominanceAnalysisFactory, this.BasicBlocks);

            EvaluateParameterOperands();

            this.stop = false;

            Debug.Assert(this.Linker != null);
        }
예제 #12
0
 public TraceLog(TraceType type, MosaMethod method, string stage, string section, bool active)
     : this(type)
 {
     Stage = stage;
     Section = section;
     Method = method;
     Active = active;
 }
예제 #13
0
        /// <summary>
        /// Gets the plug.
        /// </summary>
        /// <param name="method">The method.</param>
        /// <returns></returns>
        public MosaMethod GetPlugMethod(MosaMethod method)
        {
            MosaMethod plug = null;

            plugMethods.TryGetValue(method, out plug);

            return plug;
        }
예제 #14
0
        public CompilerMethodData(MosaMethod mosaMethod)
        {
            if (mosaMethod == null)
                throw new ArgumentNullException("mosaMethod");

            Method = mosaMethod;

            this.Calls = new List<MosaMethod>();
            this.CalledBy = new List<MosaMethod>();
            this.CompileCount = 0;
        }
예제 #15
0
        void ITraceListener.SubmitInstructionTraceInformation(MosaMethod method, string stage, string log)
        {
            if (string.IsNullOrEmpty(MethodPipelineExportDirectory))
                return;

            string filename = (method.FullName + ".txt").Replace("<", "[").Replace(">", "]");

            if (filename.Length > 200)
                filename = filename.Substring(0, 200);

            string fullname = Path.Combine(MethodPipelineExportDirectory, filename);

            File.AppendAllText(fullname, "[" + stage + "]" + Environment.NewLine + Environment.NewLine + log + Environment.NewLine);
        }
예제 #16
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ExplorerMethodCompiler" /> class.
        /// </summary>
        /// <param name="compiler">The compiler.</param>
        /// <param name="method">The method.</param>
        /// <param name="basicBlocks">The basic blocks.</param>
        /// <param name="threadID">The thread identifier.</param>
        public ExplorerMethodCompiler(ExplorerCompiler compiler, MosaMethod method, BasicBlocks basicBlocks, int threadID)
            : base(compiler, method, basicBlocks, threadID)
        {
            var compilerOptions = Compiler.CompilerOptions;

            // Populate the pipeline
            Pipeline.Add(new IMethodCompilerStage[] {
                new CILDecodingStage(),
                new ExceptionPrologueStage(),
                new OperandAssignmentStage(),
                new StackSetupStage(),

                new CILProtectedRegionStage(),
                new ExceptionStage(),
                new StaticAllocationResolutionStage(),
                new CILTransformationStage(),
                new UnboxValueTypeStage(),

                (compilerOptions.EnableInlinedMethods) ? new InlineStage() : null,
                (compilerOptions.EnableSSA) ? new EdgeSplitStage() : null,
                (compilerOptions.EnableSSA) ? new PhiPlacementStage() : null,
                (compilerOptions.EnableSSA) ? new EnterSSAStage() : null,

                (compilerOptions.EnableSparseConditionalConstantPropagation && compilerOptions.EnableSSA) ? new SparseConditionalConstantPropagationStage() : null,
                (compilerOptions.EnableOptimizations) ? new IROptimizationStage() : null,

                //(compilerOptions.TwoPassOptimizationStages && compilerOptions.EnableOptimizations && compilerOptions.EnableSparseConditionalConstantPropagation && compilerOptions.EnableSSA) ? new SparseConditionalConstantPropagationStage() : null,
                //(compilerOptions.TwoPassOptimizationStages && compilerOptions.EnableOptimizations && compilerOptions.EnableSparseConditionalConstantPropagation && compilerOptions.EnableSSA) ? new IROptimizationStage() : null,

                (compilerOptions.EnableSSA) ? new LeaveSSA() : null,
                new IRCleanupStage(),

                (compilerOptions.EnableInlinedMethods) ? new InlineEvaluationStage() : null,

                //new StopStage(),

                new PlatformStubStage(),
                new PlatformEdgeSplitStage(),
                new VirtualRegisterRenameStage(),
                new GreedyRegisterAllocatorStage(),
                new StackLayoutStage(),
                new EmptyBlockRemovalStage(),
                new BlockOrderingStage(),
                new CodeGenerationStage(compilerOptions.EmitBinary),
                new GraphVizStage(),
                (compilerOptions.EmitBinary) ? new ProtectedRegionLayoutStage() : null,
                (compilerOptions.EmitBinary) ? new DisassemblyStage() : null
            });
        }
예제 #17
0
        public CompilerMethodData GetCompilerMethodData(MosaMethod method)
        {
            lock (compilerMethods)
            {
                CompilerMethodData compilerMethod;

                if (!compilerMethods.TryGetValue(method, out compilerMethod))
                {
                    compilerMethod = new CompilerMethodData(method);
                    compilerMethods.Add(method, compilerMethod);
                }

                return compilerMethod;
            }
        }
예제 #18
0
        public MethodData GetMethodData(MosaMethod method, bool create)
        {
            lock (methodDataStore)
            {
                MethodData methodData = null;

                if (!methodDataStore.TryGetValue(method, out methodData))
                {
                    if (create)
                    {
                        methodData = new MethodData();
                        methodDataStore.Add(method, methodData);
                    }
                }
                return methodData;
            }
        }
예제 #19
0
        protected override void Run()
        {
            Debug.Assert(setupMethod == null, "SSE setup method already generated!");

            setupMethod = Compiler.CreateLinkerMethod("SSEInit");

            var eax = Operand.CreateCPURegister(TypeSystem.BuiltIn.U4, GeneralPurposeRegister.EAX);
            var cr0 = Operand.CreateCPURegister(TypeSystem.BuiltIn.U4, ControlRegister.CR0);
            var cr4 = Operand.CreateCPURegister(TypeSystem.BuiltIn.U4, ControlRegister.CR4);

            var basicBlocks = new BasicBlocks();
            var block = basicBlocks.CreateBlock();
            basicBlocks.AddHeadBlock(block);
            var ctx = new Context(block);

            /*
               ;enable SSE and the like
                mov eax, cr0
                and ax, 0xFFFB		;clear coprocessor emulation CR0.EM
                or ax, 0x2			;set coprocessor monitoring  CR0.MP
                mov cr0, eax
                mov eax, cr4
                or ax, 3 << 9		;set CR4.OSFXSR and CR4.OSXMMEXCPT at the same time
                mov cr4, eax
                ret
            */

            ctx.AppendInstruction(X86.MovCR, eax, cr0);
            ctx.AppendInstruction(X86.And, eax, eax, Operand.CreateConstant(TypeSystem.BuiltIn.U4, 0xFFFB));
            ctx.AppendInstruction(X86.Or, eax, eax, Operand.CreateConstant(TypeSystem.BuiltIn.U4, 0x2));
            ctx.AppendInstruction(X86.MovCR, cr0, eax);

            ctx.AppendInstruction(X86.MovCR, eax, cr4);
            ctx.AppendInstruction(X86.Or, eax, eax, Operand.CreateConstant(TypeSystem.BuiltIn.U4, 0x600));
            ctx.AppendInstruction(X86.MovCR, cr4, eax);

            ctx.AppendInstruction(X86.Ret);

            Compiler.CompileMethod(setupMethod, basicBlocks, 0);

            var typeInitializerSchedulerStage = Compiler.PostCompilePipeline.FindFirst<TypeInitializerSchedulerStage>();
            typeInitializerSchedulerStage.Schedule(setupMethod);
        }
예제 #20
0
        public static void Run(IInternalTrace internalLog, string stage, MosaMethod method, InstructionSet instructionSet, BasicBlocks basicBlocks)
        {
            if (internalLog == null)
                return;

            if (internalLog.TraceListener == null)
                return;

            if (!internalLog.TraceFilter.IsMatch(method, stage))
                return;

            StringBuilder text = new StringBuilder();

            text.AppendLine(String.Format("IR representation of method {0} after stage {1}:", method.FullName, stage));
            text.AppendLine();

            if (basicBlocks.Count > 0)
            {
                foreach (BasicBlock block in basicBlocks)
                {
                    text.AppendFormat("Block #{0} - Label L_{1:X4}", block.Sequence, block.Label);
                    if (basicBlocks.IsHeaderBlock(block))
                        text.Append(" [Header]");
                    text.AppendLine();

                    text.AppendFormat("  Prev: ");
                    text.AppendLine(ListBlocks(block.PreviousBlocks));

                    LogInstructions(text, new Context(instructionSet, block));

                    text.AppendFormat("  Next: ");
                    text.AppendLine(ListBlocks(block.NextBlocks));

                    text.AppendLine();
                }
            }
            else
            {
                LogInstructions(text, new Context(instructionSet, 0));
            }

            internalLog.TraceListener.SubmitInstructionTraceInformation(method, stage, text.ToString());
        }
예제 #21
0
        /// <summary>
        /// Initializes a new instance of the <see cref="AotMethodCompiler" /> class.
        /// </summary>
        /// <param name="compiler">The compiler.</param>
        /// <param name="method">The method.</param>
        /// <param name="basicBlocks">The basic blocks.</param>
        /// <param name="threadID">The thread identifier.</param>
        public AotMethodCompiler(BaseCompiler compiler, MosaMethod method, BasicBlocks basicBlocks, int threadID)
            : base(compiler, method, basicBlocks, threadID)
        {
            var compilerOptions = compiler.CompilerOptions;

            // Populate the pipeline
            Pipeline.Add(new IMethodCompilerStage[] {
                new CILDecodingStage(),
                new ExceptionPrologueStage(),
                new OperandAssignmentStage(),
                new StackSetupStage(),
                new CILProtectedRegionStage(),
                new ExceptionStage(),
                new StaticAllocationResolutionStage(),
                new CILTransformationStage(),
                new ConvertCompoundStage(),
                new UnboxValueTypeStage(),
                (compilerOptions.EnableInlinedMethods) ? new InlineStage() : null,
                (compilerOptions.EnableVariablePromotion) ? new PromoteTempVariablesStage() : null,
                (compilerOptions.EnableSSA) ? new EdgeSplitStage() : null,
                (compilerOptions.EnableSSA) ? new PhiPlacementStage() : null,
                (compilerOptions.EnableSSA) ? new EnterSSAStage() : null,
                (compilerOptions.EnableOptimizations && compilerOptions.EnableSparseConditionalConstantPropagation && compilerOptions.EnableSSA) ? new SparseConditionalConstantPropagationStage() : null,
                (compilerOptions.EnableOptimizations) ? new IROptimizationStage() : null,

                (compilerOptions.TwoPassOptimizationStages && compilerOptions.EnableOptimizations && compilerOptions.EnableSparseConditionalConstantPropagation && compilerOptions.EnableSSA) ? new SparseConditionalConstantPropagationStage() : null,
                (compilerOptions.TwoPassOptimizationStages && compilerOptions.EnableOptimizations && compilerOptions.EnableSparseConditionalConstantPropagation && compilerOptions.EnableSSA) ? new IROptimizationStage() : null,

                (compilerOptions.EnableSSA) ? new LeaveSSA() : null,
                new IRCleanupStage(),
                (compilerOptions.EnableInlinedMethods) ? new InlineEvaluationStage() : null,
                new PlatformStubStage(),
                new PlatformEdgeSplitStage(),
                new GreedyRegisterAllocatorStage(),
                new StackLayoutStage(),
                new EmptyBlockRemovalStage(),
                new BlockOrderingStage(),
                new CodeGenerationStage(),
                new ProtectedRegionLayoutStage(),
            });
        }
        public static void Run(CompilerTrace compilerTrace, string stage, MosaMethod method, BasicBlocks basicBlocks)
        {
            if (compilerTrace == null)
                return;

            if (!compilerTrace.TraceFilter.IsMatch(method, stage))
                return;

            var traceLog = new TraceLog(TraceType.InstructionList, method, stage, true);

            traceLog.Log(String.Format("IR representation of method {0} after stage {1}:", method.FullName, stage));
            traceLog.Log();

            if (basicBlocks.Count > 0)
            {
                foreach (var block in basicBlocks)
                {
                    traceLog.Log(String.Format("Block #{0} - Label L_{1:X4}", block.Sequence, block.Label)
                        + (basicBlocks.IsHeadBlock(block) ? " [Header]" : string.Empty));

                    traceLog.Log("  Prev: " + ListBlocks(block.PreviousBlocks));

                    LogInstructions(traceLog, block.First);

                    traceLog.Log("  Next: " + ListBlocks(block.NextBlocks));

                    traceLog.Log();
                }
            }
            else
            {
                traceLog.Log("No instructions.");
            }

            compilerTrace.NewTraceLog(traceLog);
        }
예제 #23
0
        /// <summary>
        /// Schedules the specified method for invocation in the main.
        /// </summary>
        /// <param name="method">The method.</param>
        private void Schedule(MosaMethod method)
        {
            var symbol = Operand.CreateSymbolFromMethod(method, TypeSystem);

            start.AppendInstruction(IRInstruction.CallStatic, null, symbol);
        }
        /// <summary>
        /// Calculates the stack size for parameters.
        /// </summary>
        /// <param name="typeLayout">The type layouts.</param>
        /// <param name="operands">The operands.</param>
        /// <param name="method">The method.</param>
        /// <returns></returns>
        protected static int CalculateStackSizeForParameters(MosaTypeLayout typeLayout, BaseArchitecture architecture, List <Operand> operands, MosaMethod method)
        {
            Debug.Assert((method.Signature.Parameters.Count + (method.HasThis ? 1 : 0) == operands.Count) ||
                         (method.DeclaringType.IsDelegate && method.Signature.Parameters.Count == operands.Count), method.FullName);

            int offset = method.Signature.Parameters.Count - operands.Count;
            int result = 0;

            for (int index = operands.Count - 1; index >= 0; index--)
            {
                Operand operand = operands[index];

                int size, alignment;
                architecture.GetTypeRequirements(typeLayout, operand.Type, out size, out alignment);

                var param = (index + offset >= 0) ? method.Signature.Parameters[index + offset] : null;

                if (param != null && operand.IsR8 && param.ParameterType.IsR4)
                {
                    //  adjust for parameter size on stack when method parameter is R4 while the calling variable is R8
                    architecture.GetTypeRequirements(typeLayout, param.ParameterType, out size, out alignment);
                }

                result = (int)Alignment.AlignUp(result, (uint)alignment) + size;
            }

            return(result);
        }
예제 #25
0
 private void treeView_BeforeSelect(object sender, TreeViewCancelEventArgs e)
 {
     CurrentMethodSelected = GetCurrentMethod();
 }
예제 #26
0
 /// <summary>
 /// Gets the method table offset.
 /// </summary>
 /// <param name="method">The method.</param>
 /// <returns></returns>
 public int GetMethodTableOffset(MosaMethod method)
 {
     ResolveType(method.DeclaringType);
     return(methodTableOffsets[method]);
 }
예제 #27
0
 public void Schedule(MosaMethod method)
 {
     Setup();
     Compiler.MethodScheduler.Schedule(method);
 }
예제 #28
0
        private string GetMethodNameConsiderPlug(MosaMethod method)
        {
            var plugMethod = Compiler.PlugSystem.GetReplacement(method);

            return((plugMethod == null) ? method.FullName : plugMethod.FullName);
        }
예제 #29
0
 /// <summary>
 /// Appends the instruction.
 /// </summary>
 /// <param name="instruction">The instruction.</param>
 /// <param name="target">The target.</param>
 public void AppendInstruction(BaseInstruction instruction, MosaMethod target)
 {
     AppendInstruction();
     Node.SetInstruction(instruction, target);
 }
예제 #30
0
        private void ResolveMethod(MosaMethod method)
        {
            GenericArgumentResolver resolver = new GenericArgumentResolver();
            bool hasOpening = method.DeclaringType.HasOpenGenericParams;

            if (method.DeclaringType.GenericArguments.Count > 0)
            {
                foreach (var i in method.DeclaringType.GenericArguments.GetGenericArguments())
                    hasOpening |= i.HasOpenGenericParameter();
                resolver.PushTypeGenericArguments(method.DeclaringType.GenericArguments.GetGenericArguments());
            }

            if (method.GenericArguments.Count > 0)
            {
                foreach (var i in method.GenericArguments.GetGenericArguments())
                    hasOpening |= i.HasOpenGenericParameter();
                resolver.PushMethodGenericArguments(method.GenericArguments.GetGenericArguments());
            }

            using (var mosaMethod = metadata.Controller.MutateMethod(method))
            {
                var desc = method.GetUnderlyingObject<UnitDesc<MethodDef, MethodSig>>();

                MosaType returnType = metadata.Loader.GetType(resolver.Resolve(desc.Signature.RetType));
                hasOpening |= returnType.HasOpenGenericParams;
                List<MosaParameter> pars = new List<MosaParameter>();

                Debug.Assert(desc.Signature.GetParamCount() + (desc.Signature.HasThis ? 1 : 0) == desc.Definition.Parameters.Count);
                foreach (var param in desc.Definition.Parameters)
                {
                    if (!param.IsNormalMethodParameter)
                        continue;
                    var paramType = metadata.Loader.GetType(resolver.Resolve(desc.Signature.Params[param.MethodSigIndex]));
                    var parameter = metadata.Controller.CreateParameter();

                    using (var mosaParameter = metadata.Controller.MutateParameter(parameter))
                    {
                        mosaParameter.Name = param.Name;
                        mosaParameter.ParameterAttributes = (MosaParameterAttributes)param.ParamDef.Attributes;
                        mosaParameter.ParameterType = paramType;
                        mosaParameter.DeclaringMethod = method;
                        ResolveCustomAttributes(mosaParameter, param.ParamDef);
                    }

                    pars.Add(parameter);
                    hasOpening |= paramType.HasOpenGenericParams;
                }

                mosaMethod.Signature = new MosaMethodSignature(returnType, pars);

                foreach (var methodImpl in desc.Definition.Overrides)
                {
                    Debug.Assert(methodImpl.MethodBody == desc.Definition);
                    mosaMethod.Overrides.Add(ResolveMethodOperand(methodImpl.MethodDeclaration, null));
                }

                if (desc.Definition.HasBody)
                    ResolveBody(desc.Definition, mosaMethod, desc.Definition.Body, resolver);

                mosaMethod.HasOpenGenericParams = hasOpening;

                ResolveCustomAttributes(mosaMethod, desc.Definition);
            }
        }
예제 #31
0
 private void Patch(MosaMethod targetMethod, MosaMethod method)
 {
     Trace(InternalTrace.CompilerEvent.Plug, targetMethod.FullName + " with " + method.FullName);
     Compiler.PlugSystem.CreatePlug(method, targetMethod);
 }
예제 #32
0
        protected override void RunPreCompile()
        {
            foreach (var type in TypeSystem.AllTypes)
            {
                string plugTypeTarget = null;

                var typeAttribute = type.FindCustomAttribute(PlugTypeAttribute);

                if (typeAttribute != null)
                {
                    plugTypeTarget = (string)typeAttribute.Arguments[0].Value;
                }

                foreach (var method in type.Methods)
                {
                    if (!method.IsStatic)
                    {
                        continue;
                    }

                    string plugMethodTarget = null;

                    var methodAttribute = method.FindCustomAttribute(PlugMethodAttribute);

                    if (methodAttribute != null)
                    {
                        plugMethodTarget = (string)methodAttribute.Arguments[0].Value;
                    }

                    if (plugTypeTarget != null || plugMethodTarget != null)
                    {
                        string targetAssemblyName;
                        string targetFullTypeName;
                        string targetMethodName;

                        if (plugMethodTarget != null)
                        {
                            targetAssemblyName = ParseAssembly(plugMethodTarget);
                            targetFullTypeName = ParseFullTypeName(plugMethodTarget);
                            targetMethodName   = ParseMethod(plugMethodTarget);
                        }
                        else
                        {
                            targetAssemblyName = ParseAssembly(plugTypeTarget);
                            targetFullTypeName = RemoveModule(plugTypeTarget);
                            targetMethodName   = method.Name;
                        }

                        string targetNameSpace = ParseNameSpace(targetFullTypeName);
                        string targetTypeName  = ParseType(targetFullTypeName);

                        MosaType targetType;

                        if (targetAssemblyName != null)
                        {
                            targetType = TypeSystem.GetTypeByName(TypeSystem.GetModuleByAssembly(targetAssemblyName), targetNameSpace, targetTypeName);
                        }
                        else
                        {
                            targetType = TypeSystem.GetTypeByName(targetNameSpace, targetTypeName);
                        }

                        if (targetType == null)
                        {
                            NewCompilerTraceEvent(CompilerEvent.Warning,
                                                  String.Format("Plug target type {0} not found. Ignoring plug.",
                                                                targetAssemblyName != null ? (targetFullTypeName + "(in " + targetAssemblyName + ")") : targetFullTypeName));
                            continue;
                        }

                        MosaMethod targetMethod = null;

                        foreach (var targetMethodCandidate in targetType.Methods)
                        {
                            if (targetMethodCandidate.Name == targetMethodName)
                            {
                                if (targetMethodCandidate.IsStatic)
                                {
                                    if (targetMethodCandidate.Equals(method))
                                    {
                                        targetMethod = targetMethodCandidate;
                                        break;
                                    }
                                }
                                else
                                {
                                    if (MatchesWithStaticThis(targetMethodCandidate, method))
                                    {
                                        targetMethod = targetMethodCandidate;
                                        break;
                                    }
                                }
                            }
                        }

                        if (targetMethod != null)
                        {
                            Patch(targetMethod, method);
                        }
                        else
                        {
                            NewCompilerTraceEvent(CompilerEvent.Warning,
                                                  String.Format("No matching plug target method {0} found in type {1}. Ignoring plug.",
                                                                targetMethodName, targetType.ToString()));
                        }
                    }
                }
            }
        }
예제 #33
0
 public MethodData GetMethodData(MosaMethod method)
 {
     return(CompilerData.GetMethodData(method));
 }
예제 #34
0
 private void TreeView_AfterSelect(object sender, TreeViewEventArgs e)
 {
     CurrentMethodSelected = GetCurrentMethod();
     NodeSelected();
 }
예제 #35
0
 protected void UpdateTree(MosaMethod method)
 {
     typeSystemTree.Update(method);
 }
예제 #36
0
 public void CreatePlug(MosaMethod plug, MosaMethod methodToPlug)
 {
     plugMethods.Add(methodToPlug, plug);
 }
예제 #37
0
        private TreeNode GetOrCreateNode(MosaMethod method)
        {
            if (map.TryGetValue(method, out TreeNode methodNode))
            {
                return(methodNode);
            }

            var type = method.DeclaringType;

            if (!map.TryGetValue(type, out TreeNode typeNode))
            {
                typeNode = GetOrCreateNode(type);
            }

            if (method.ShortName.StartsWith("set_") || method.ShortName.StartsWith("get_"))
            {
                return(null);
            }

            // find "Methods" node
            TreeNode methodsNode = null;

            foreach (var node in typeNode.Nodes)
            {
                if (((TreeNode)node).Text == "Methods")
                {
                    methodsNode = (TreeNode)node;
                    break;
                }
            }

            if (methodsNode == null)
            {
                methodsNode = new TreeNode("Methods");
                typeNode.Nodes.Add(methodsNode);
            }

            methodNode = new TreeNode(method.ShortName)
            {
                Tag = method
            };

            map.Add(method, methodNode);

            AddToTree(methodNode, methodsNode);

            if (method.IsStatic)
            {
                methodNode.Text += " [Static]";
            }

            if (method.IsAbstract)
            {
                methodNode.Text += " [Abstract]";
            }

            if (method.IsNewSlot)
            {
                methodNode.Text += " [NewSlot]";
            }

            if (method.IsVirtual)
            {
                methodNode.Text += " [Virtual]";
            }

            if (method.IsFinal)
            {
                methodNode.Text += " [Final]";
            }

            if (method.IsSpecialName)
            {
                methodNode.Text += " [SpecialName]";
            }

            if (method.IsRTSpecialName)
            {
                methodNode.Text += " [RTSpecialName]";
            }

            if (method.GenericArguments.Count != 0)
            {
                var genericParameterNodes = new TreeNode("Generic Arguments Types");
                methodNode.Nodes.Add(genericParameterNodes);

                foreach (var genericParameter in method.GenericArguments)
                {
                    var GenericParameterNode = new TreeNode(genericParameter.Name);
                    genericParameterNodes.Nodes.Add(GenericParameterNode);
                }
            }

            return(methodNode);
        }
예제 #38
0
 public void TrackMethodInvoked(MosaMethod method)
 {
 }
예제 #39
0
 /// <summary>
 /// Sets the instruction.
 /// </summary>
 /// <param name="instruction">The instruction.</param>
 /// <param name="target">The target.</param>
 public void SetInstruction(BaseInstruction instruction, MosaMethod target)
 {
     Node.SetInstruction(instruction, target);
 }
예제 #40
0
 public void TrackMethodInvoked(MosaMethod method)
 {
 }
예제 #41
0
        private LinkerSymbol CreateMethodDefinition(MosaMethod method)
        {
            // Emit method name
            var methodNameSymbol = EmitStringWithLength(Metadata.NameString + method.FullName, method.FullName);

            // Emit method table
            var methodTableSymbol = Linker.DefineSymbol(Metadata.MethodDefinition + method.FullName, SectionKind.ROData, TypeLayout.NativePointerAlignment, (method.Signature.Parameters.Count + 9) * TypeLayout.NativePointerSize);
            var writer            = new EndianAwareBinaryWriter(methodTableSymbol.Stream, Architecture.Endianness);

            // 1. Pointer to Name
            Linker.Link(LinkType.AbsoluteAddress, NativePatchType, methodTableSymbol, writer.Position, methodNameSymbol, 0);
            writer.WriteZeroBytes(TypeLayout.NativePointerSize);

            // 2. Pointer to Custom Attributes
            if (method.CustomAttributes.Count > 0)
            {
                var customAttributeListSymbol = CreateCustomAttributesTable(method);
                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, methodTableSymbol, writer.Position, customAttributeListSymbol, 0);
            }
            writer.WriteZeroBytes(TypeLayout.NativePointerSize);

            // 3. Attributes
            writer.Write((uint)method.MethodAttributes, TypeLayout.NativePointerSize);

            // 4. Local Stack Size (16 Bits) && Parameter Stack Size (16 Bits)
            var methodData = Compiler.CompilerData.GetMethodData(method);
            int value      = methodData.LocalMethodStackSize | (methodData.ParameterStackSize << 16);

            writer.Write(value, TypeLayout.NativePointerSize);

            // 5. Pointer to Method
            if (method.HasImplementation && !method.HasOpenGenericParams && !method.DeclaringType.HasOpenGenericParams /*&& !methodData.Inlined*/)              // TODO: Inline
            {
                if (Compiler.MethodScanner.IsMethodInvoked(method))
                {
                    Linker.Link(LinkType.AbsoluteAddress, NativePatchType, methodTableSymbol, writer.Position, GetMethodNameConsiderPlug(method), 0);
                }
            }
            writer.WriteZeroBytes(TypeLayout.NativePointerSize);

            // 6. Pointer to return type
            Linker.Link(LinkType.AbsoluteAddress, NativePatchType, methodTableSymbol, writer.Position, Metadata.TypeDefinition + method.Signature.ReturnType.FullName, 0);
            writer.WriteZeroBytes(TypeLayout.NativePointerSize);

            // 7. Pointer to Exception Handler Table
            if (method.ExceptionHandlers.Count != 0 && Compiler.MethodScanner.IsMethodInvoked(method))
            {
                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, methodTableSymbol, writer.Position, Metadata.ProtectedRegionTable + method.FullName, 0);
            }
            writer.WriteZeroBytes(TypeLayout.NativePointerSize);

            // 8. Pointer to GC Tracking information
            // TODO: This has yet to be designed.
            writer.WriteZeroBytes(TypeLayout.NativePointerSize);

            // 9. Number of Parameters
            writer.Write((uint)method.Signature.Parameters.Count, TypeLayout.NativePointerSize);

            // 10. Pointers to Parameter Definitions
            foreach (var parameter in method.Signature.Parameters)
            {
                // Create definition and get the symbol
                var parameterDefinitionSymbol = CreateParameterDefinition(parameter);

                // Link
                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, methodTableSymbol, writer.Position, parameterDefinitionSymbol, 0);
                writer.WriteZeroBytes(TypeLayout.NativePointerSize);
            }

            return(methodTableSymbol);
        }
예제 #42
0
 public MosaMethod CompileMethod(MosaMethod method)
 {
     return(CompileMethod(method, 0));
 }
예제 #43
0
 /// <summary>
 /// Creates a method compiler
 /// </summary>
 /// <param name="method">The method to compile.</param>
 /// <param name="basicBlocks">The basic blocks.</param>
 /// <param name="threadID"></param>
 /// <returns>
 /// An instance of a MethodCompilerBase for the given type/method pair.
 /// </returns>
 protected override BaseMethodCompiler CreateMethodCompiler(MosaMethod method, BasicBlocks basicBlocks, int threadID)
 {
     return(new SimMethodCompiler(this, method, simAdapter, basicBlocks, threadID));
 }
예제 #44
0
 /// <summary>
 /// Creates a method compiler
 /// </summary>
 /// <param name="method">The method to compile.</param>
 /// <param name="basicBlocks">The basic blocks.</param>
 /// <param name="instructionSet">The instruction set.</param>
 /// <returns>
 /// An instance of a MethodCompilerBase for the given type/method pair.
 /// </returns>
 protected override BaseMethodCompiler CreateMethodCompiler(MosaMethod method, BasicBlocks basicBlocks, int threadID)
 {
     return(new ExplorerMethodCompiler(this, method, basicBlocks, threadID));
 }
예제 #45
0
        /// <summary>
        /// Expands method call instruction represented by the context to perform the method call.
        /// </summary>
        /// <param name="compiler">The compiler.</param>
        /// <param name="context">The context.</param>
        public override void MakeCall(BaseMethodCompiler compiler, Context context)
        {
            /*
             * Calling convention is right-to-left, pushed on the stack. Return value in EAX for integral
             * types 4 bytes or less, XMM0 for floating point and EAX:EDX for 64-bit. If this is a method
             * of a type, the this argument is moved to ECX right before the call.
             * If return value is value type, a stack local is allocated as a hidden parameter in caller
             * stack, the callee will then store the return value in the allocated space
             * The return value is the first parameter (even before this)
             * The callee will place the address of the return value into EAX and the caller will then
             * either retrieve the return value using compound move or will let one of the callers higher
             * in the caller chain handle the retrieval of the return value using compound move.
             */

            Operand    target = context.Operand1;
            Operand    result = context.Result;
            MosaMethod method = context.InvokeMethod;

            //Debug.Assert(method != null, context.ToString());

            Operand scratch = Operand.CreateCPURegister(compiler.TypeLayout.TypeSystem.BuiltIn.Pointer, scratchRegister);

            var operands = BuildOperands(context);

            context.Empty();

            int stackSize  = 0;
            int returnSize = 0;

            if (method != null)
            {
                stackSize  = CalculateStackSizeForParameters(compiler.TypeLayout, architecture, operands, method);
                returnSize = CalculateReturnSize(compiler, method);
            }
            else
            {
                stackSize  = CalculateStackSizeForParameters(compiler.TypeLayout, architecture, operands);
                returnSize = CalculateReturnSize(compiler, result);
            }

            if (stackSize != 0 || returnSize != 0)
            {
                ReserveStackSizeForCall(compiler, context, returnSize + stackSize, scratch);

                if (method != null)
                {
                    PushOperands(compiler, context, method, operands, returnSize + stackSize, scratch);
                }
                else
                {
                    PushOperands(compiler, context, operands, returnSize + stackSize, scratch);
                }
            }

            // the mov/call two-instructions combo is to help facilitate the register allocator
            architecture.InsertMoveInstruction(context, scratch, target);
            architecture.InsertCallInstruction(context, scratch);

            CleanupReturnValue(compiler, context, result);
            FreeStackAfterCall(compiler, context, returnSize + stackSize);
        }
예제 #46
0
        public MosaMethod LoadGenericMethodInstance(IMethodDefOrRef method, IList <TypeSig> genericArguments, GenericArgumentResolver resolver)
        {
            var declType = GetType(resolver.Resolve(method.DeclaringType.ToTypeSig()));

            MDToken token;

            if (method is MethodDef)
            {
                token = ((MethodDef)method).MDToken;
            }
            else
            {
                token = ((MemberRef)method).ResolveMethodThrow().MDToken;
            }

            MosaMethod mosaMethod = null;
            UnitDesc <MethodDef, MethodSig> desc = null;

            foreach (var m in declType.Methods)
            {
                desc = m.GetUnderlyingObject <UnitDesc <MethodDef, MethodSig> >();
                if (desc.Token.Token == token)
                {
                    mosaMethod = m;
                    break;
                }
            }

            if (mosaMethod == null)
            {
                throw new AssemblyLoadException();
            }

            var resolvedGenericArguments = new List <TypeSig>();

            foreach (var genericArg in genericArguments)
            {
                resolvedGenericArguments.Add(resolver.Resolve(genericArg));
            }

            resolver.PushMethodGenericArguments(resolvedGenericArguments);

            // Check for existing generic method instance
            var newSig = resolver.Resolve(method.MethodSig);

            // Need to make sure we pop otherwise it will cause bugs
            resolver.PopMethodGenericArguments();

            var comparer = new SigComparer();

            foreach (var m in declType.Methods)
            {
                var mDesc = m.GetUnderlyingObject <UnitDesc <MethodDef, MethodSig> >();
                if (mDesc.Definition != desc.Definition || !comparer.Equals(mDesc.Signature, newSig))
                {
                    continue;
                }

                if (m.GenericArguments.Count != resolvedGenericArguments.Count)
                {
                    continue;
                }

                if (m.GenericArguments.Count > 0)
                {
                    var failedGenericArgumentMatch = false;
                    for (var i = 0; i < m.GenericArguments.Count; i++)
                    {
                        if (comparer.Equals(resolvedGenericArguments[i], m.GenericArguments[i].GetTypeSig()))
                        {
                            continue;
                        }

                        failedGenericArgumentMatch = true;
                        break;
                    }

                    if (failedGenericArgumentMatch)
                    {
                        continue;
                    }
                }

                return(m);
            }

            mosaMethod = metadata.Controller.CreateMethod(mosaMethod);

            using (var _mosaMethod = metadata.Controller.MutateMethod(mosaMethod))
            {
                bool hasOpening = mosaMethod.DeclaringType.HasOpenGenericParams;
                _mosaMethod.GenericArguments.Clear();
                foreach (var resolvedGenericArg in resolvedGenericArguments)
                {
                    hasOpening |= resolvedGenericArg.HasOpenGenericParameter();
                    var t = GetType(resolvedGenericArg);
                    _mosaMethod.GenericArguments.Add(t);
                }

                _mosaMethod.UnderlyingObject = desc.Clone(newSig);
                _mosaMethod.DeclaringType    = declType;

                _mosaMethod.HasOpenGenericParams = hasOpening;
            }

            using (var decl = metadata.Controller.MutateType(declType))
                decl.Methods.Add(mosaMethod);

            metadata.Resolver.EnqueueForResolve(mosaMethod);

            return(mosaMethod);
        }
예제 #47
0
 protected string FormatRuntimeMember(MosaMethod method)
 {
     return method.Name;
 }
예제 #48
0
 private void Patch(MosaMethod targetMethod, MosaMethod method)
 {
     NewCompilerTraceEvent(CompilerEvent.Plug, targetMethod.FullName + " with " + method.FullName);
     Compiler.PlugSystem.CreatePlug(method, targetMethod);
 }
예제 #49
0
 private void UpdateMethodInformation(MosaMethod method)
 {
     UpdateStages();
     UpdateDebugStages();
     UpdateCounters();
 }
예제 #50
0
        /// <summary>
        /// Calculates the remaining space.
        /// </summary>
        /// <param name="compiler">The compiler.</param>
        /// <param name="typeLayout">The type layouts.</param>
        /// <param name="context">The context.</param>
        /// <param name="method">The method.</param>
        /// <param name="operands">The operand stack.</param>
        /// <param name="space">The space.</param>
        /// <param name="scratch">The scratch.</param>
        private void PushOperands(BaseMethodCompiler compiler, MosaTypeLayout typeLayout, Context context, MosaMethod method, List <Operand> operands, int space, Operand scratch)
        {
            Debug.Assert((method.Signature.Parameters.Count + (method.HasThis ? 1 : 0) == operands.Count) ||
                         (method.DeclaringType.IsDelegate && method.Signature.Parameters.Count == operands.Count));

            int offset = method.Signature.Parameters.Count - operands.Count;

            for (int index = operands.Count - 1; index >= 0; index--)
            {
                Operand operand = operands[index];

                MosaType param = (index + offset >= 0) ? method.Signature.Parameters[index + offset].ParameterType : null;

                int size, alignment;

                if (param != null && operand.IsR8 && param.IsR4)
                {
                    architecture.GetTypeRequirements(typeLayout, param, out size, out alignment);
                }
                else
                {
                    architecture.GetTypeRequirements(typeLayout, operand.Type, out size, out alignment);
                }

                size = Alignment.AlignUp(size, alignment);

                space -= size;

                Push(compiler, typeLayout, context, operand, space, size, scratch);
            }
        }
예제 #51
0
 /// <summary>
 /// Creates a new symbol <see cref="Operand" /> for the given symbol name.
 /// </summary>
 /// <param name="typeSystem">The type system.</param>
 /// <param name="method">The method.</param>
 /// <returns></returns>
 public static Operand CreateSymbolFromMethod(TypeSystem typeSystem, MosaMethod method)
 {
     var operand = CreateUnmanagedSymbolPointer(typeSystem, method.FullName);
     operand.Method = method;
     return operand;
 }
예제 #52
0
        private void ResolveMethod(MosaMethod method)
        {
            GenericArgumentResolver resolver = new GenericArgumentResolver();
            bool hasOpening = method.DeclaringType.HasOpenGenericParams;

            if (method.DeclaringType.GenericArguments.Count > 0)
            {
                foreach (var i in method.DeclaringType.GenericArguments.GetGenericArguments())
                {
                    hasOpening |= i.HasOpenGenericParameter();
                }
                resolver.PushTypeGenericArguments(method.DeclaringType.GenericArguments.GetGenericArguments());
            }

            if (method.GenericArguments.Count > 0)
            {
                foreach (var i in method.GenericArguments.GetGenericArguments())
                {
                    hasOpening |= i.HasOpenGenericParameter();
                }
                resolver.PushMethodGenericArguments(method.GenericArguments.GetGenericArguments());
            }

            using (var mosaMethod = metadata.Controller.MutateMethod(method))
            {
                var desc = method.GetUnderlyingObject <UnitDesc <MethodDef, MethodSig> >();

                MosaType returnType = metadata.Loader.GetType(resolver.Resolve(desc.Signature.RetType));
                hasOpening |= returnType.HasOpenGenericParams;
                List <MosaParameter> pars = new List <MosaParameter>();

                Debug.Assert(desc.Signature.GetParamCount() + (desc.Signature.HasThis ? 1 : 0) == desc.Definition.Parameters.Count);
                foreach (var param in desc.Definition.Parameters)
                {
                    if (!param.IsNormalMethodParameter)
                    {
                        continue;
                    }
                    var paramType = metadata.Loader.GetType(resolver.Resolve(desc.Signature.Params[param.MethodSigIndex]));
                    var parameter = metadata.Controller.CreateParameter();

                    using (var mosaParameter = metadata.Controller.MutateParameter(parameter))
                    {
                        mosaParameter.Name = param.Name;
                        mosaParameter.ParameterAttributes = (MosaParameterAttributes)param.ParamDef.Attributes;
                        mosaParameter.ParameterType       = paramType;
                        mosaParameter.DeclaringMethod     = method;
                        ResolveCustomAttributes(mosaParameter, param.ParamDef);
                    }

                    pars.Add(parameter);
                    hasOpening |= paramType.HasOpenGenericParams;
                }

                mosaMethod.Signature = new MosaMethodSignature(returnType, pars);

                foreach (var methodImpl in desc.Definition.Overrides)
                {
                    Debug.Assert(methodImpl.MethodBody == desc.Definition);
                    mosaMethod.Overrides.Add(ResolveMethodOperand(methodImpl.MethodDeclaration, null));
                }

                if (desc.Definition.HasBody)
                {
                    ResolveBody(desc.Definition, mosaMethod, desc.Definition.Body, resolver);
                }

                mosaMethod.HasOpenGenericParams = hasOpening;

                ResolveCustomAttributes(mosaMethod, desc.Definition);
            }
        }
예제 #53
0
        private bool MatchesWithStaticThis(MosaMethod targetMethod, MosaMethod plugMethod)
        {
            if (!targetMethod.Signature.ReturnType.Equals(plugMethod.Signature.ReturnType))
                return false;

            if (targetMethod.Signature.Parameters.Count != plugMethod.Signature.Parameters.Count - 1)
                return false;

            if (plugMethod.Signature.Parameters[0].Type.IsValueType && !plugMethod.Signature.Parameters[0].Type.IsManagedPointer)
                return false;

            // TODO: Compare plug.Parameters[0].Type to the target's type

            for (int i = 0; i < targetMethod.Signature.Parameters.Count; i++)
            {
                if (!targetMethod.Signature.Parameters[i].Equals(plugMethod.Signature.Parameters[i + 1]))
                    return false;
            }

            return true;
        }
예제 #54
0
 void ITraceListener.OnMethodCompiled(MosaMethod method)
 {
 }
예제 #55
0
        private void ResolveBody(MethodDef methodDef, MosaMethod.Mutator method, CilBody body, GenericArgumentResolver resolver)
        {
            method.LocalVariables.Clear();
            int index = 0;
            foreach (var variable in body.Variables)
            {
                method.LocalVariables.Add(new MosaLocal(
                    variable.Name ?? "V_" + index,
                    metadata.Loader.GetType(resolver.Resolve(variable.Type)),
                    variable.Type.IsPinned));
                index++;
            }

            method.ExceptionBlocks.Clear();
            foreach (var eh in body.ExceptionHandlers)
            {
                method.ExceptionBlocks.Add(new MosaExceptionHandler(
                    (ExceptionHandlerType)eh.HandlerType,
                    ResolveOffset(body, eh.TryStart),
                    ResolveOffset(body, eh.TryEnd),
                    ResolveOffset(body, eh.HandlerStart),
                    ResolveOffset(body, eh.HandlerEnd),
                    eh.CatchType == null ? null : metadata.Loader.GetType(resolver.Resolve(eh.CatchType.ToTypeSig())),
                    eh.FilterStart == null ? null : (int?)eh.FilterStart.Offset
                ));
            }

            method.MaxStack = methodDef.Body.MaxStack;

            method.Code.Clear();
            for (int i = 0; i < body.Instructions.Count; i++)
            {
                method.Code.Add(ResolveInstruction(methodDef, body, i, resolver));
            }
        }
예제 #56
0
        private static void MeasureCompileTime(Stopwatch stopwatch, MosaCompiler compiler, MosaMethod method, int iterations)
        {
            Console.WriteLine($"Method: {method}");

            double min   = double.MaxValue;
            double max   = double.MinValue;
            double total = 0;

            for (int i = 0; i < iterations; i++)
            {
                var start = stopwatch.Elapsed.TotalMilliseconds;

                compiler.CompileSingleMethod(method);

                var elapsed = stopwatch.Elapsed.TotalMilliseconds - start;

                min    = Math.Min(min, elapsed);
                max    = Math.Max(max, elapsed);
                total += elapsed;

                //Console.WriteLine($"Elapsed: {elapsed.ToString("F2")} ms");
            }

            double avg = total / iterations;

            Console.WriteLine($"Elapsed: {max.ToString("F2")} ms (worst)");
            Console.WriteLine($"Elapsed: {avg.ToString("F2")} ms (average)");
            Console.WriteLine($"Elapsed: {min.ToString("F2")} ms (best)");
        }
예제 #57
0
        public void Schedule(MosaMethod method)
        {
            if (method.IsAbstract || method.HasOpenGenericParams)
                return;

            if (method.IsLinkerGenerated)
                return;

            queue.Enqueue(method);

            lock (methods)
            {
                if (!methods.Contains(method))
                {
                    methods.Add(method);
                }
            }
        }
예제 #58
0
 private int CalculateInterfaceSlotOffset(MosaMethod invokeTarget)
 {
     return(CalculateInterfaceSlot(invokeTarget.DeclaringType) * NativePointerSize);
 }
예제 #59
0
        private int CalculateMethodTableOffset(MosaMethod invokeTarget)
        {
            int slot = TypeLayout.GetMethodSlot(invokeTarget);

            return(NativePointerSize * slot);
        }
예제 #60
0
        private LinkerSymbol CreateMethodDefinition(MosaMethod method)
        {
            // Emit method name
            var methodNameSymbol = EmitStringWithLength(method.FullName + Metadata.NameString, method.FullName);

            // Emit method table
            var methodTableSymbol = Linker.CreateSymbol(method.FullName + Metadata.MethodDefinition, SectionKind.ROData, TypeLayout.NativePointerAlignment, 0);
            var writer1           = new EndianAwareBinaryWriter(methodTableSymbol.Stream, Architecture.Endianness);

            // 1. Pointer to Name
            Linker.Link(LinkType.AbsoluteAddress, NativePatchType, methodTableSymbol, (int)writer1.Position, methodNameSymbol, 0);
            writer1.WriteZeroBytes(TypeLayout.NativePointerSize);

            // 2. Pointer to Custom Attributes
            if (method.CustomAttributes.Count > 0)
            {
                var customAttributeListSymbol = CreateCustomAttributesTable(method);
                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, methodTableSymbol, (int)writer1.Position, customAttributeListSymbol, 0);
            }
            writer1.WriteZeroBytes(TypeLayout.NativePointerSize);

            // 3. Attributes
            writer1.Write((uint)method.MethodAttributes, TypeLayout.NativePointerSize);

            // 4. Local Stack Size (16 Bits) && Parameter Stack Size (16 Bits)
            var methodData = Compiler.CompilerData.GetCompilerMethodData(method);
            int value      = methodData.LocalMethodStackSize | (methodData.ParameterStackSize << 16);

            writer1.Write(value, TypeLayout.NativePointerSize);

            // 5. Pointer to Method
            if (!method.IsAbstract)
            {
                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, methodTableSymbol, (int)writer1.Position, SectionKind.Text, method.FullName, 0);
            }
            writer1.WriteZeroBytes(TypeLayout.NativePointerSize);

            // 6. Pointer to return type
            Linker.Link(LinkType.AbsoluteAddress, NativePatchType, methodTableSymbol, (int)writer1.Position, SectionKind.ROData, method.Signature.ReturnType.FullName + Metadata.TypeDefinition, 0);
            writer1.WriteZeroBytes(TypeLayout.NativePointerSize);

            // 7. Pointer to Exception Handler Table
            if (method.ExceptionHandlers.Count != 0)
            {
                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, methodTableSymbol, (int)writer1.Position, SectionKind.ROData, method.FullName + Metadata.ProtectedRegionTable, 0);
            }
            writer1.WriteZeroBytes(TypeLayout.NativePointerSize);

            // 8. Pointer to GC Tracking information
            // TODO: This has yet to be designed.
            writer1.WriteZeroBytes(TypeLayout.NativePointerSize);

            // 9. Number of Parameters
            writer1.Write((uint)method.Signature.Parameters.Count, TypeLayout.NativePointerSize);

            // 10. Pointers to Parameter Definitions
            foreach (var parameter in method.Signature.Parameters)
            {
                // Create definition and get the symbol
                var parameterDefinitionSymbol = CreateParameterDefinition(parameter);

                // Link
                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, methodTableSymbol, (int)writer1.Position, parameterDefinitionSymbol, 0);
                writer1.WriteZeroBytes(TypeLayout.NativePointerSize);
            }

            // Return methodTableSymbol for linker usage
            return(methodTableSymbol);
        }