[opt] 大幅优化Native2Managed方向桥接函数传参性能

main
walon 2023-08-24 19:26:50 +08:00
parent 9eb6dda71b
commit 69d3303f3d
2 changed files with 48 additions and 4 deletions

View File

@ -40,6 +40,8 @@ namespace HybridCLR.Editor.ABI
public bool IsStruct => PorType == ParamOrReturnType.STRUCT; public bool IsStruct => PorType == ParamOrReturnType.STRUCT;
public bool IsPrimitiveType => PorType <= ParamOrReturnType.U;
private readonly int _typeId; private readonly int _typeId;
public int TypeId => _typeId; public int TypeId => _typeId;

View File

@ -539,14 +539,55 @@ static void __M2N_{method.CreateCallSigName()}(const MethodInfo* method, uint16_
"); ");
} }
public string GenerateArgumentSizeAndOffset(List<ParamInfo> paramInfos)
{
StringBuilder s = new StringBuilder();
int index = 0;
foreach (var param in paramInfos)
{
s.AppendLine($"\tconstexpr int __ARG_OFFSET_{index}__ = {(index > 0 ? $"__ARG_OFFSET_{index - 1}__ + __ARG_SIZE_{index-1}__" : "0")};");
s.AppendLine($"\tconstexpr int __ARG_SIZE_{index}__ = (sizeof(__arg{index}) + 7)/8;");
index++;
}
s.AppendLine($"\tconstexpr int __TOTAL_ARG_SIZE__ = {(paramInfos.Count > 0 ? $"__ARG_OFFSET_{index-1}__ + __ARG_SIZE_{index-1}__" : "1")};");
return s.ToString();
}
public string GenerateCopyArgumentToInterpreterStack(List<ParamInfo> paramInfos, bool adjustorThunk)
{
StringBuilder s = new StringBuilder();
int index = 0;
foreach (var param in paramInfos)
{
if (param.Type.IsPrimitiveType)
{
if (param.Type.NeedExpandValue())
{
s.AppendLine($"\targs[__ARG_OFFSET_{index}__].u64 = {(index == 0 && adjustorThunk ? $"(uint64_t)((uintptr_t)__arg{index} + sizeof(Il2CppObject))" : $"__arg{index}")};");
}
else
{
s.AppendLine($"\t*({param.Type.GetTypeName()}*)(args + __ARG_OFFSET_{index}__) = {(index == 0 && adjustorThunk ? $"(uintptr_t)__arg{index} + sizeof(Il2CppObject)" : $"__arg{index}")};");
}
}
else
{
s.AppendLine($"\t*({param.Type.GetTypeName()}*)(args + __ARG_OFFSET_{index}__) = __arg{index};");
}
index++;
}
return s.ToString();
}
public void GenerateNative2ManagedMethod(MethodDesc method, List<string> lines) public void GenerateNative2ManagedMethod(MethodDesc method, List<string> lines)
{ {
string paramListStr = string.Join(", ", method.ParamInfos.Select(p => $"{p.Type.GetTypeName()} __arg{p.Index}").Concat(new string[] { "const MethodInfo* method" })); string paramListStr = string.Join(", ", method.ParamInfos.Select(p => $"{p.Type.GetTypeName()} __arg{p.Index}").Concat(new string[] { "const MethodInfo* method" }));
lines.Add($@" lines.Add($@"
static {method.ReturnInfo.Type.GetTypeName()} __N2M_{method.CreateCallSigName()}({paramListStr}) static {method.ReturnInfo.Type.GetTypeName()} __N2M_{method.CreateCallSigName()}({paramListStr})
{{ {{
StackObject args[{Math.Max(1, method.ParamInfos.Count)}] = {{{string.Join(", ", method.ParamInfos.Select(p => GetNative2ManagedPassParam(p.Type, $"__arg{p.Index}")))} }}; {GenerateArgumentSizeAndOffset(method.ParamInfos)}
StackObject args[__TOTAL_ARG_SIZE__];
{GenerateCopyArgumentToInterpreterStack(method.ParamInfos, false)}
{(method.ReturnInfo.IsVoid ? "Interpreter::Execute(method, args, nullptr);" : $"{method.ReturnInfo.Type.GetTypeName()} ret; Interpreter::Execute(method, args, &ret); return ret;")} {(method.ReturnInfo.IsVoid ? "Interpreter::Execute(method, args, nullptr);" : $"{method.ReturnInfo.Type.GetTypeName()} ret; Interpreter::Execute(method, args, &ret); return ret;")}
}} }}
"); ");
@ -554,13 +595,14 @@ static {method.ReturnInfo.Type.GetTypeName()} __N2M_{method.CreateCallSigName()}
public void GenerateAdjustThunkMethod(MethodDesc method, List<string> lines) public void GenerateAdjustThunkMethod(MethodDesc method, List<string> lines)
{ {
int totalQuadWordNum = method.ParamInfos.Count;
string paramListStr = string.Join(", ", method.ParamInfos.Select(p => $"{p.Type.GetTypeName()} __arg{p.Index}").Concat(new string[] { "const MethodInfo* method" })); string paramListStr = string.Join(", ", method.ParamInfos.Select(p => $"{p.Type.GetTypeName()} __arg{p.Index}").Concat(new string[] { "const MethodInfo* method" }));
lines.Add($@" lines.Add($@"
static {method.ReturnInfo.Type.GetTypeName()} __N2M_AdjustorThunk_{method.CreateCallSigName()}({paramListStr}) static {method.ReturnInfo.Type.GetTypeName()} __N2M_AdjustorThunk_{method.CreateCallSigName()}({paramListStr})
{{ {{
StackObject args[] = {{{string.Join(", ", method.ParamInfos.Select(p => (p.Index == 0 ? $"(uint64_t)(*(uint8_t**)&__arg{p.Index} + sizeof(Il2CppObject))" : GetNative2ManagedPassParam(p.Type, $"__arg{p.Index}"))))} }}; {GenerateArgumentSizeAndOffset(method.ParamInfos)}
StackObject args[__TOTAL_ARG_SIZE__];
{GenerateCopyArgumentToInterpreterStack(method.ParamInfos, true)}
{(method.ReturnInfo.IsVoid ? "Interpreter::Execute(method, args, nullptr);" : $"{method.ReturnInfo.Type.GetTypeName()} ret; Interpreter::Execute(method, args, &ret); return ret;")} {(method.ReturnInfo.IsVoid ? "Interpreter::Execute(method, args, nullptr);" : $"{method.ReturnInfo.Type.GetTypeName()} ret; Interpreter::Execute(method, args, &ret); return ret;")}
}} }}
"); ");