#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