/// <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; Trace = compiler.CompilerTrace; Linker = compiler.Linker; MethodScanner = compiler.MethodScanner; 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; LocalVariables = emptyOperandList; ThreadID = threadID; IsStopped = false; IsExecutePipeline = true; IsCILDecodeRequired = true; IsStackFrameRequired = true; IsMethodInlined = false; HasProtectedRegions = Method.ExceptionHandlers.Count != 0; MethodData = Compiler.GetMethodData(Method); MethodData.Counters.Reset(); MethodData.Version++; MethodData.IsMethodImplementationReplaced = IsMethodPlugged; 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(); } EvaluateParameterOperands(); CalculateMethodParameterSize(); MethodData.Counters.NewCountSkipLock("ExecutionTime.Setup.Ticks", (int)Stopwatch.ElapsedTicks); }
protected void ReplaceWithCall(Context context, string namespaceName, string typeName, string methodName) { var method = GetMethod(namespaceName, typeName, methodName); Debug.Assert(method != null, $"Cannot find method: {methodName}"); // FUTURE: throw compiler exception var symbol = Operand.CreateSymbolFromMethod(method, TypeSystem); if (context.OperandCount == 1) { context.SetInstruction(IRInstruction.CallStatic, context.Result, symbol, context.Operand1); } else if (context.OperandCount == 2) { context.SetInstruction(IRInstruction.CallStatic, context.Result, symbol, context.Operand1, context.Operand2); } else { // FUTURE: throw compiler exception } MethodScanner.MethodInvoked(method, Method); }
/// <summary> /// Executes the compiler post compiler stages. /// </summary> /// <remarks> /// The method iterates the compilation stage chain and runs each /// stage on the input. /// </remarks> internal void Finalization() { PostEvent(CompilerEvent.FinalizationStart); foreach (BaseCompilerStage stage in CompilerPipeline) { PostEvent(CompilerEvent.FinalizationStageStart, stage.Name); // Execute stage stage.ExecuteFinalization(); PostEvent(CompilerEvent.FinalizationStageEnd, stage.Name); } MethodScanner.Complete(); // Sum up the counters foreach (var methodData in CompilerData.MethodData) { GlobalCounters.Merge(methodData.Counters); } EmitCounters(); PostEvent(CompilerEvent.FinalizationEnd); PostEvent(CompilerEvent.CompileEnd); }
public Compiler(MosaCompiler mosaCompiler) { TypeSystem = mosaCompiler.TypeSystem; TypeLayout = mosaCompiler.TypeLayout; CompilerOptions = mosaCompiler.CompilerOptions; Linker = mosaCompiler.Linker; CompilerTrace = mosaCompiler.CompilerTrace; Architecture = CompilerOptions.Architecture; PostCompilerTraceEvent(CompilerEvent.CompilerStart); CompilerExtensions.AddRange(mosaCompiler.CompilerExtensions); MethodStagePipelines = new Pipeline <BaseMethodCompilerStage> [mosaCompiler.MaxThreads + 1]; MethodScheduler = new MethodScheduler(this); MethodScanner = new MethodScanner(this); foreach (var type in Assembly.GetExecutingAssembly().GetTypes()) { if (!type.IsClass) { continue; } foreach (var method in type.GetRuntimeMethods()) { // Now get all the IntrinsicMethodAttribute attributes var attributes = (IntrinsicMethodAttribute[])method.GetCustomAttributes(typeof(IntrinsicMethodAttribute), true); for (int i = 0; i < attributes.Length; i++) { var d = (InstrinsicMethodDelegate)Delegate.CreateDelegate(typeof(InstrinsicMethodDelegate), method); // Finally add the dictionary entry mapping the target name and the delegate InternalIntrinsicMethods.Add(attributes[i].Target, d); } } } PlugSystem = new PlugSystem(TypeSystem); PlatformInternalRuntimeType = GetPlatformInternalRuntimeType(); InternalRuntimeType = GeInternalRuntimeType(); // Build the default compiler pipeline CompilerPipeline.Add(GetDefaultCompilerPipeline(CompilerOptions)); foreach (var extension in CompilerExtensions) { extension.ExtendCompilerPipeline(CompilerPipeline); } Architecture.ExtendCompilerPipeline(CompilerPipeline, CompilerOptions); IsStopped = false; WorkCount = 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; Trace = compiler.CompilerTrace; Linker = compiler.Linker; MethodScanner = compiler.MethodScanner; BasicBlocks = basicBlocks ?? new BasicBlocks(); LocalStack = new List <Operand>(); VirtualRegisters = new VirtualRegisters(); StackFrame = Operand.CreateCPURegister(TypeSystem.BuiltIn.Pointer, Architecture.StackFrameRegister); StackPointer = Operand.CreateCPURegister(TypeSystem.BuiltIn.Pointer, Architecture.StackPointerRegister); Parameters = new Operand[method.Signature.Parameters.Count + (method.HasThis || method.HasExplicitThis ? 1 : 0)]; ConstantZero32 = CreateConstant((uint)0); ConstantZero64 = CreateConstant((ulong)0); ConstantZero = Architecture.Is32BitPlatform ? ConstantZero32 : ConstantZero64; LocalVariables = emptyOperandList; ThreadID = threadID; IsStopped = false; IsExecutePipeline = true; IsCILDecodeRequired = true; IsStackFrameRequired = true; IsMethodInlined = false; MethodData = compiler.CompilerData.GetMethodData(Method); MethodData.Counters.Reset(); // Both defines the symbol and also clears the data Symbol = Linker.DefineSymbol(Method.FullName, SectionKind.Text, 0, 0); EvaluateParameterOperands(); CalculateMethodParameterSize(); MethodData.Counters.NewCountSkipLock("ExecutionTime.Setup.Ticks", (int)Stopwatch.ElapsedTicks); }
/// <summary> /// Executes the compiler post compiler stages. /// </summary> /// <remarks> /// The method iterates the compilation stage chain and runs each /// stage on the input. /// </remarks> internal void PostCompile() { foreach (BaseCompilerStage stage in CompilerPipeline) { PostCompilerTraceEvent(CompilerEvent.PostCompileStageStart, stage.Name); // Execute stage stage.ExecutePostCompile(); PostCompilerTraceEvent(CompilerEvent.PostCompileStageEnd, stage.Name); } MethodScanner.Complete(); // Sum up the counters foreach (var methodData in CompilerData.MethodData) { GlobalCounters.Merge(methodData.Counters); } EmitCounters(); }
public Compiler(MosaCompiler mosaCompiler) { TypeSystem = mosaCompiler.TypeSystem; TypeLayout = mosaCompiler.TypeLayout; CompilerSettings = mosaCompiler.CompilerSettings; Architecture = mosaCompiler.Platform; CompilerHooks = mosaCompiler.CompilerHooks; TraceLevel = CompilerSettings.TraceLevel; Statistics = CompilerSettings.Statistics; Linker = new MosaLinker(this); ObjectHeaderSize = Architecture.NativePointerSize + 4 + 4; // Hash Value (32-bit) + Lock & Status (32-bit) + Method Table StackFrame = Operand.CreateCPURegister(TypeSystem.BuiltIn.Pointer, Architecture.StackFrameRegister); StackPointer = Operand.CreateCPURegister(TypeSystem.BuiltIn.Pointer, Architecture.StackPointerRegister); LinkRegister = Architecture.LinkRegister == null ? null : Operand.CreateCPURegister(TypeSystem.BuiltIn.Object, Architecture.LinkRegister); ProgramCounter = Architecture.ProgramCounter == null ? null : Operand.CreateCPURegister(TypeSystem.BuiltIn.Object, Architecture.ProgramCounter); ExceptionRegister = Operand.CreateCPURegister(TypeSystem.BuiltIn.Object, Architecture.ExceptionRegister); LeaveTargetRegister = Operand.CreateCPURegister(TypeSystem.BuiltIn.Object, Architecture.LeaveTargetRegister); PostEvent(CompilerEvent.CompileStart); MethodStagePipelines = new Pipeline <BaseMethodCompilerStage> [MaxThreads]; MethodScheduler = new MethodScheduler(this); MethodScanner = new MethodScanner(this); foreach (var type in Assembly.GetExecutingAssembly().GetTypes()) { if (!type.IsClass) { continue; } foreach (var method in type.GetRuntimeMethods()) { // Now get all the IntrinsicMethodAttribute attributes var intrinsicMethodAttributes = (IntrinsicMethodAttribute[])method.GetCustomAttributes(typeof(IntrinsicMethodAttribute), true); for (int i = 0; i < intrinsicMethodAttributes.Length; i++) { var d = (IntrinsicMethodDelegate)System.Delegate.CreateDelegate(typeof(IntrinsicMethodDelegate), method); // Finally add the dictionary entry mapping the target name and the delegate InternalIntrinsicMethods.Add(intrinsicMethodAttributes[i].Target, d); } // Now get all the StubMethodAttribute attributes var stubMethodAttributes = (StubMethodAttribute[])method.GetCustomAttributes(typeof(StubMethodAttribute), true); for (int i = 0; i < stubMethodAttributes.Length; i++) { var d = (StubMethodDelegate)System.Delegate.CreateDelegate(typeof(StubMethodDelegate), method); // Finally add the dictionary entry mapping the target name and the delegate InternalStubMethods.Add(stubMethodAttributes[i].Target, d); } } } PlugSystem = new PlugSystem(TypeSystem); PlatformInternalRuntimeType = GetPlatformInternalRuntimeType(); InternalRuntimeType = GeInternalRuntimeType(); // Build the default compiler pipeline CompilerPipeline.Add(GetDefaultCompilerPipeline(CompilerSettings, Architecture.Is64BitPlatform)); // Call hook to allow for the extension of the pipeline CompilerHooks.ExtendCompilerPipeline?.Invoke(CompilerPipeline); Architecture.ExtendCompilerPipeline(CompilerPipeline, CompilerSettings); IsStopped = false; }