A game about forced loneliness, made by TACStudios
1#if UNITY_EDITOR
2using System;
3using System.Diagnostics;
4using System.Reflection;
5using System.Text;
6
7namespace Unity.Burst.Editor
8{
9 [DebuggerDisplay("{GetDisplayName(),nq}")]
10 internal class BurstCompileTarget
11 {
12 public BurstCompileTarget(MethodInfo method, Type jobType, Type interfaceType, bool isStaticMethod)
13 {
14 Method = method ?? throw new ArgumentNullException(nameof(method));
15 JobType = jobType ?? throw new ArgumentNullException(nameof(jobType));
16 JobInterfaceType = interfaceType; // can be null
17 // This is important to clone the options as we don't want to modify the global instance
18 Options = BurstCompiler.Options.Clone();
19 Options.EnableBurstCompilation = true;
20 // Enable safety checks by default to match inspector default behavior
21 Options.EnableBurstSafetyChecks = true;
22 TargetCpu = BurstTargetCpu.Auto;
23 // The BurstCompilerAttribute can be either on the type or on the method
24 IsStaticMethod = isStaticMethod;
25 }
26
27 /// <summary>
28 /// <c>true</c> if the <see cref="Method"/> is directly tagged with a [BurstCompile] attribute
29 /// </summary>
30 public readonly bool IsStaticMethod;
31
32 /// <summary>
33 /// The Execute method of the target's producer type.
34 /// </summary>
35 public readonly MethodInfo Method;
36
37 /// <summary>
38 /// The type of the actual job (i.e. BoidsSimulationJob).
39 /// </summary>
40 public readonly Type JobType;
41
42 /// <summary>
43 /// The interface of the job (IJob, IJobParallelFor...)
44 /// </summary>
45 public readonly Type JobInterfaceType;
46
47 /// <summary>
48 /// The default compiler options
49 /// </summary>
50 public readonly BurstCompilerOptions Options;
51
52 public BurstTargetCpu TargetCpu { get; set; }
53
54 /// <summary>
55 /// Set to true if burst compilation is actually requested via proper `[BurstCompile]` attribute:
56 /// - On the job if it is a job only
57 /// - On the method and parent class it if is a static method
58 /// </summary>
59 public bool HasRequiredBurstCompileAttributes => BurstCompilerOptions.HasBurstCompileAttribute(JobType) && (!IsStaticMethod || BurstCompilerOptions.HasBurstCompileAttribute(Method));
60
61 /// <summary>
62 /// Generated raw disassembly (IR, IL, ASM...), or null if disassembly failed (only valid for the current TargetCpu)
63 /// </summary>
64 public string RawDisassembly;
65
66 /// <summary>
67 /// Formatted disassembly for the associated <see cref="RawDisassembly"/>, currently only valid for <see cref="Unity.Burst.Editor.DisassemblyKind.Asm"/>
68 /// </summary>
69 public string FormattedDisassembly;
70
71 public DisassemblyKind DisassemblyKind;
72
73 public bool IsDarkMode { get; set; }
74
75 public bool IsBurstError { get; set; }
76
77 public bool IsLoading = false;
78
79 public bool JustLoaded = false;
80
81 public string GetDisplayName()
82 {
83 var displayName = IsStaticMethod ? Pretty(Method) : $"{Pretty(JobType)} - ({Pretty(JobInterfaceType)})";
84
85 // Remove the '<>c__DisplayClass_' part of the name - this is only added for C# Entities.ForEach jobs to trick the C# debugging tools into
86 // treating them like lambdas. This is removed wherever possible from user facing tools (like the Unity profiler), so we should do the same.
87 return displayName.Replace("<>c__DisplayClass_", "");
88 }
89
90 private static string Pretty(MethodInfo method)
91 {
92 var builder = new StringBuilder();
93 builder.Append(Pretty(method.DeclaringType));
94 builder.Append(".");
95 builder.Append(method.Name);
96 builder.Append("(");
97 var parameters = method.GetParameters();
98 for (var i = 0; i < parameters.Length; i++)
99 {
100 var param = parameters[i];
101 if (i > 0) builder.Append(", ");
102 builder.Append(Pretty(param.ParameterType));
103 }
104
105 builder.Append(")");
106 return builder.ToString();
107 }
108
109 internal static string Pretty(Type type)
110 {
111 if (type == typeof(bool))
112 {
113 return "bool";
114 }
115 if (type == typeof(int))
116 {
117 return "int";
118 }
119 if (type == typeof(long))
120 {
121 return "long";
122 }
123 if (type == typeof(uint))
124 {
125 return "uint";
126 }
127 if (type == typeof(ulong))
128 {
129 return "ulong";
130 }
131 if (type == typeof(short))
132 {
133 return "short";
134 }
135 if (type == typeof(ushort))
136 {
137 return "ushort";
138 }
139 if (type == typeof(byte))
140 {
141 return "byte";
142 }
143 if (type == typeof(sbyte))
144 {
145 return "sbyte";
146 }
147 if (type == typeof(float))
148 {
149 return "float";
150 }
151 if (type == typeof(double))
152 {
153 return "double";
154 }
155 if (type == typeof(string))
156 {
157 return "string";
158 }
159 if (type == typeof(object))
160 {
161 return "object";
162 }
163 if (type == typeof(char))
164 {
165 return "char";
166 }
167
168 // When displaying job interface type, display the interface name of Unity.Jobs namespace
169 var typeName = type.IsInterface && type.Name.StartsWith("IJob") ? type.Name : type.ToString();
170 return typeName.Replace("+", ".");
171 }
172 }
173
174 internal enum DisassemblyKind
175 {
176 Asm = 0,
177 IL = 1,
178 UnoptimizedIR = 2,
179 OptimizedIR = 3,
180 IRPassAnalysis = 4
181 }
182}
183#endif