#if UNITY_EDITOR using System; using System.Diagnostics; using System.Reflection; using System.Text; namespace Unity.Burst.Editor { [DebuggerDisplay("{GetDisplayName(),nq}")] internal class BurstCompileTarget { public BurstCompileTarget(MethodInfo method, Type jobType, Type interfaceType, bool isStaticMethod) { Method = method ?? throw new ArgumentNullException(nameof(method)); JobType = jobType ?? throw new ArgumentNullException(nameof(jobType)); JobInterfaceType = interfaceType; // can be null // This is important to clone the options as we don't want to modify the global instance Options = BurstCompiler.Options.Clone(); Options.EnableBurstCompilation = true; // Enable safety checks by default to match inspector default behavior Options.EnableBurstSafetyChecks = true; TargetCpu = BurstTargetCpu.Auto; // The BurstCompilerAttribute can be either on the type or on the method IsStaticMethod = isStaticMethod; } /// /// true if the is directly tagged with a [BurstCompile] attribute /// public readonly bool IsStaticMethod; /// /// The Execute method of the target's producer type. /// public readonly MethodInfo Method; /// /// The type of the actual job (i.e. BoidsSimulationJob). /// public readonly Type JobType; /// /// The interface of the job (IJob, IJobParallelFor...) /// public readonly Type JobInterfaceType; /// /// The default compiler options /// public readonly BurstCompilerOptions Options; public BurstTargetCpu TargetCpu { get; set; } /// /// Set to true if burst compilation is actually requested via proper `[BurstCompile]` attribute: /// - On the job if it is a job only /// - On the method and parent class it if is a static method /// public bool HasRequiredBurstCompileAttributes => BurstCompilerOptions.HasBurstCompileAttribute(JobType) && (!IsStaticMethod || BurstCompilerOptions.HasBurstCompileAttribute(Method)); /// /// Generated raw disassembly (IR, IL, ASM...), or null if disassembly failed (only valid for the current TargetCpu) /// public string RawDisassembly; /// /// Formatted disassembly for the associated , currently only valid for /// public string FormattedDisassembly; public DisassemblyKind DisassemblyKind; public bool IsDarkMode { get; set; } public string GetDisplayName() { var displayName = IsStaticMethod ? Pretty(Method) : $"{Pretty(JobType)} - ({Pretty(JobInterfaceType)})"; // Remove the '<>c__DisplayClass_' part of the name - this is only added for C# Entities.ForEach jobs to trick the C# debugging tools into // treating them like lambdas. This is removed wherever possible from user facing tools (like the Unity profiler), so we should do the same. return displayName.Replace("<>c__DisplayClass_", ""); } private static string Pretty(MethodInfo method) { var builder = new StringBuilder(); builder.Append(Pretty(method.DeclaringType)); builder.Append("."); builder.Append(method.Name); builder.Append("("); var parameters = method.GetParameters(); for (var i = 0; i < parameters.Length; i++) { var param = parameters[i]; if (i > 0) builder.Append(", "); builder.Append(Pretty(param.ParameterType)); } builder.Append(")"); return builder.ToString(); } private static string Pretty(Type type) { if (type == typeof(bool)) { return "bool"; } if (type == typeof(int)) { return "int"; } if (type == typeof(long)) { return "long"; } if (type == typeof(uint)) { return "uint"; } if (type == typeof(ulong)) { return "ulong"; } if (type == typeof(short)) { return "short"; } if (type == typeof(ushort)) { return "ushort"; } if (type == typeof(byte)) { return "byte"; } if (type == typeof(sbyte)) { return "sbyte"; } if (type == typeof(float)) { return "float"; } if (type == typeof(double)) { return "double"; } if (type == typeof(string)) { return "string"; } if (type == typeof(object)) { return "object"; } if (type == typeof(char)) { return "char"; } // When displaying job interface type, display the interface name of Unity.Jobs namespace var typeName = type.IsInterface && type.Name.StartsWith("IJob") ? type.Name : type.ToString(); return typeName.Replace("+", "."); } } internal enum DisassemblyKind { Asm = 0, IL = 1, UnoptimizedIR = 2, OptimizedIR = 3, IRPassAnalysis = 4 } } #endif