private static void CallVirtualMethodForDevirtualization(DerivedForDevirtualization obj, int count = 1)
 {
     for (int i = 0; i < count; ++i)
     {
         s_expectedCallSequence.Append("vd ");
         obj.VirtualMethodForDevirtualization();
     }
 }
    private static int Main()
    {
        const int Pass = 100, Fail = 101;

        var baseObj    = new Base();
        var derivedObj = new Derived();
        var derivedForDevirtualizationObj = new DerivedForDevirtualization();

        PromoteToTier1(
            () => CallVirtualMethod(baseObj),
            () => CallVirtualMethod(derivedObj),
            () => CallGenericVirtualMethodWithValueType(baseObj),
            () => CallGenericVirtualMethodWithValueType(derivedObj),
            () => CallGenericVirtualMethodWithReferenceType(baseObj),
            () => CallGenericVirtualMethodWithReferenceType(derivedObj),
            () => CallVirtualMethodForDevirtualization(derivedForDevirtualizationObj),
            () => CallInterfaceVirtualMethodPolymorhpic(baseObj),
            () => CallInterfaceVirtualMethodPolymorhpic(derivedObj));

        for (int i = 0; i < 4; ++i)
        {
            CallVirtualMethod(baseObj, CallCountPerIteration);
            CallVirtualMethod(derivedObj, CallCountPerIteration);
            CallGenericVirtualMethodWithValueType(baseObj, CallCountPerIteration);
            CallGenericVirtualMethodWithValueType(derivedObj, CallCountPerIteration);
            CallGenericVirtualMethodWithReferenceType(baseObj, CallCountPerIteration);
            CallGenericVirtualMethodWithReferenceType(derivedObj, CallCountPerIteration);
            CallVirtualMethodForDevirtualization(derivedForDevirtualizationObj, CallCountPerIteration);
            CallInterfaceVirtualMethodMonomorphicOnBase(baseObj, CallCountPerIteration);
            CallInterfaceVirtualMethodMonomorphicOnDerived(derivedObj, CallCountPerIteration);
            CallInterfaceVirtualMethodPolymorhpic(baseObj, CallCountPerIteration);
            CallInterfaceVirtualMethodPolymorhpic(derivedObj, CallCountPerIteration);

            for (int j = 0; j < 2; ++j)
            {
                RunCollectibleIterations();

                GC.Collect();
                GC.WaitForPendingFinalizers();
                GC.WaitForPendingFinalizers();
            }
        }

        if (s_actualCallSequence.Equals(s_expectedCallSequence))
        {
            return(Pass);
        }

        Console.WriteLine($"Expected:  {s_expectedCallSequence}");
        Console.WriteLine($"Actual:    {s_actualCallSequence}");
        return(Fail);
    }