focus-creative-games / dhe_demo

Differential Hybrid Execution demo project
28 stars 6 forks source link

ComputeClassVirtualTable的一些问题 #1

Closed AlanLiu90 closed 1 year ago

AlanLiu90 commented 1 year ago

测试环境

问题

修改HotUpdateMain.Start为下面代码,打包Win64,有报错:

void Start()
{

    Run("函数未变化,运行AOT版本", RunNotChangedMethod);
    Run("函数有变化,运行解释器版本", RunChangedMethod);

    var methodInfo = typeof(Application).GetMethod("HasProLicense");
    UnityEngine.Debug.Log(methodInfo.Invoke(null, null));
}

报错:

Exception: not find override method
HybridCLR.Editor.DHE.MethodCompareCache.FindOverrideMethodSlot (dnlib.DotNet.MethodDef method, dnlib.DotNet.TypeDef parentTypeDef) (at Packages/com.focus-creative-games.hybridclr_unity/Editor/DHE/MethodCompareCache.cs:269)
HybridCLR.Editor.DHE.MethodCompareCache.FindOverrideMethodSlot (dnlib.DotNet.MethodDef method, dnlib.DotNet.ITypeDefOrRef parentType) (at Packages/com.focus-creative-games.hybridclr_unity/Editor/DHE/MethodCompareCache.cs:206)
HybridCLR.Editor.DHE.MethodCompareCache.FindOverrideMethodSlot (dnlib.DotNet.MethodDef method, dnlib.DotNet.TypeDef parentTypeDef) (at Packages/com.focus-creative-games.hybridclr_unity/Editor/DHE/MethodCompareCache.cs:265)
HybridCLR.Editor.DHE.MethodCompareCache.FindOverrideMethodSlot (dnlib.DotNet.MethodDef method, dnlib.DotNet.ITypeDefOrRef parentType) (at Packages/com.focus-creative-games.hybridclr_unity/Editor/DHE/MethodCompareCache.cs:206)
HybridCLR.Editor.DHE.MethodCompareCache.ComputeClassVirtualTable (dnlib.DotNet.TypeDef type, System.Boolean isDHEClass) (at Packages/com.focus-creative-games.hybridclr_unity/Editor/DHE/MethodCompareCache.cs:334)
HybridCLR.Editor.DHE.MethodCompareCache.GetVirtualTableIndex (dnlib.DotNet.MethodDef method) (at Packages/com.focus-creative-games.hybridclr_unity/Editor/DHE/MethodCompareCache.cs:353)
HybridCLR.Editor.DHE.MethodCompareCache.IsSameVirtualTableIndex (dnlib.DotNet.MethodDef m1, dnlib.DotNet.MethodDef m2) (at Packages/com.focus-creative-games.hybridclr_unity/Editor/DHE/MethodCompareCache.cs:361)
HybridCLR.Editor.DHE.MethodCompareCache.CompareCallVirtualMethod (dnlib.DotNet.IMethod m1, dnlib.DotNet.IMethod m2, HybridCLR.Editor.DHE.MethodCompareData callerData) (at Packages/com.focus-creative-games.hybridclr_unity/Editor/DHE/MethodCompareCache.cs:399)
HybridCLR.Editor.DHE.MethodCompareCache.CompareInstruction (dnlib.DotNet.Emit.Instruction c1, dnlib.DotNet.Emit.Instruction c2, HybridCLR.Editor.DHE.MethodCompareData method) (at Packages/com.focus-creative-games.hybridclr_unity/Editor/DHE/MethodCompareCache.cs:601)
HybridCLR.Editor.DHE.MethodCompareCache.CompareMethodBody (dnlib.DotNet.MethodDef m1, dnlib.DotNet.MethodDef m2, HybridCLR.Editor.DHE.MethodCompareData data) (at Packages/com.focus-creative-games.hybridclr_unity/Editor/DHE/MethodCompareCache.cs:703)
HybridCLR.Editor.DHE.MethodCompareCache.CompareMethodImplements (HybridCLR.Editor.DHE.MethodCompareData mm) (at Packages/com.focus-creative-games.hybridclr_unity/Editor/DHE/MethodCompareCache.cs:717)
HybridCLR.Editor.DHE.MethodCompareCache.AddCompareMethod (dnlib.DotNet.MethodDef m1, dnlib.DotNet.MethodDef m2) (at Packages/com.focus-creative-games.hybridclr_unity/Editor/DHE/MethodCompareCache.cs:162)
HybridCLR.Editor.DHE.AssemblyOptionDataGenerator.ComputeUnchangeMethods () (at Packages/com.focus-creative-games.hybridclr_unity/Editor/DHE/AssemblyOptionDataGenerator.cs:298)
HybridCLR.Editor.DHE.AssemblyOptionDataGenerator.Generate () (at Packages/com.focus-creative-games.hybridclr_unity/Editor/DHE/AssemblyOptionDataGenerator.cs:157)
HybridCLR.Editor.Commands.DifferentialHybridExecutionCommand.GenerateAssemblyOptionDatas (UnityEditor.BuildTarget target) (at Packages/com.focus-creative-games.hybridclr_unity/Editor/Commands/DifferentialHybridExecutionCommand.cs:58)
HybridCLR.Editor.BuildAssetsCommand.BuildAndCopyABAOTHotUpdateDlls () (at Assets/Editor/HybridCLR/BuildAssetsCommand.cs:107)
HybridCLR.Editor.BuildPlayerCommand.Build_Win64 () (at Assets/Editor/HybridCLR/BuildPlayerCommand.cs:61)

看了下FindOverrideMethodSlot的实现,是IsMethodSignatureMatch认为子类实现的虚函数和基类对应的虚函数不匹配导致的

其他问题

看了下ComputeClassVirtualTable相关的代码,发现其他几个问题:

if (type.BaseType != null)
{
    TypeDef baseType;
    if (type.BaseType is TypeSpec ts)
    {
        baseType = ts.TryGetGenericInstSig().GenericType.TypeDef;
    }
    else
    {
                // 这里应该是 type.BaseType ?
        baseType = type.ResolveTypeDefThrow();
    }
    tvti.baseTypeVtableInfo = ComputeClassVirtualTable(baseType, IsDHEModule(baseType.Module));

        // 这里应该是 tvti.baseTypeVtableInfo.totalSlotCount ?
        slot = tvti.totalSlotCount;
}
private int FindOverrideMethodSlot(MethodDef method, TypeDef parentTypeDef)
{
    foreach (var m in parentTypeDef.Methods)
    {
        if (!m.IsNewSlot)
        {
            continue;
        }

               // 这里是否应该检查 Name 是否相同?另外一个处理泛型的同名函数,看起来也有同样的问题

        if (IsMethodSignatureMatch(method, m))
        {
            return GetVirtualTableIndex(m);
        }
    }
    // ...
}
pirunxi commented 1 year ago

这个问题我们修复了。 目前来看,得等我们跟合作伙伴测试完整,才能稳定下来

AlanLiu90 commented 1 year ago

你好,我有几个问题想咨询下:

  1. 在稳定前,是不是先不用提交issue了?
  2. 之后,DHE部分会考虑开源吗?还是说只提供商业版本?
pirunxi commented 1 year ago

可以提交issue,因为目前我们自己的测试仍然有较多疏漏。非常感谢。

DHE短期内只会提供商业版本。因为开源版本工作良好,我们现在遇到很大的生存困难。