Beispiel #1
0
 private static void EmitTypeHandleCheck(ILGenerator g, GenericShape genericShape, GenericTypeParameterBuilder[] typeParamArr, string scenario)
 {
     if (genericShape == GenericShape.NotGeneric)
     {
         return;
     }
     g.Emit(OpCodes.Ldtoken, typeParamArr[0]);
     g.Emit(OpCodes.Ldstr, scenario);
     if (genericShape == GenericShape.GenericOverReferenceType)
     {
         g.Emit(OpCodes.Call, s_isTypeHandleObject);
     }
     if (genericShape == GenericShape.GenericOverValueType)
     {
         g.Emit(OpCodes.Call, s_isTypeHandleInt);
     }
 }
        public void Can_Dispatch_To_Closed_Generic_Types()
        {
            IShape generic = new GenericShape<int>();

            Assert.AreEqual("GenericShape<Int32> x GenericShape<Int32>", generic.Intersect(generic));
        }
Beispiel #3
0
        private static bool DoStubCall(int callerIndex, bool staticMethod, bool onValueType, GenericShape typeGenericShape, GenericShape methodGenericShape)
        {
            string        callerNameSeed = Config.InstantiatingStubPrefix + "Caller" + callerIndex; // Use a consistent seed value here so that the various various of unboxing/instantiating stubs are generated with the same arg shape
            string        callerName     = callerNameSeed + (staticMethod ? "Static" : "Instance") + (onValueType ? "Class" : "ValueType") + typeGenericShape.ToString() + methodGenericShape.ToString();
            Random        rand           = new Random(GetSeed(callerNameSeed));
            List <TypeEx> pms;

            do
            {
                pms = RandomParameters(s_allTypes, rand);
            } while (pms.Count > 16);

            Type delegateType = GetDelegateType(pms, typeof(int));

            Callee callee = new Callee(callerName + "Callee", pms);// CreateCallee(Config.PInvokeePrefix + calleeIndex, s_allTypes);

            callee.Emit();

            Delegate calleeDelegate = callee.Method.CreateDelegate(delegateType);

            int newStubCount = Interlocked.Increment(ref s_stubTypesCreated);

            if ((s_stubTypesModule == null) || (newStubCount % 1000) == 0)
            {
                AssemblyBuilder stubsAssembly = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("ABIStress_Stubs" + newStubCount), AssemblyBuilderAccess.RunAndCollect);
                s_stubTypesModule = stubsAssembly.DefineDynamicModule("ABIStress_Stubs" + newStubCount);
            }

            // This code is based on DelegateHelpers.cs in System.Linq.Expressions.Compiler
            TypeBuilder tb =
                s_stubTypesModule.DefineType(
                    $"{callerName}_GenericTarget",
                    TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.Sealed | TypeAttributes.AutoClass,
                    onValueType ? typeof(object) : typeof(ValueType));

            GenericTypeParameterBuilder[] typeParamsType = null;
            if (typeGenericShape != GenericShape.NotGeneric)
            {
                typeParamsType = tb.DefineGenericParameters(new string[] { "T" });
            }

            FieldInfo fieldDeclaration = tb.DefineField("MagicValue", typeof(int), FieldAttributes.Public);

            Type      typeofInstantiatedType;
            FieldInfo fieldInfoMagicValueField;

            if (typeGenericShape == GenericShape.NotGeneric)
            {
                typeofInstantiatedType   = tb;
                fieldInfoMagicValueField = fieldDeclaration;
            }
            else
            {
                typeofInstantiatedType   = tb.MakeGenericType(typeParamsType[0]);
                fieldInfoMagicValueField = TypeBuilder.GetField(typeofInstantiatedType, fieldDeclaration);
            }

            ConstructorBuilder cb = tb.DefineConstructor(
                MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.RTSpecialName,
                CallingConventions.Standard,
                new Type[] { typeof(int) });

            cb.SetImplementationFlags(MethodImplAttributes.Managed);

            ILGenerator g = cb.GetILGenerator();

            g.Emit(OpCodes.Ldarg, 0);
            g.Emit(OpCodes.Call, typeof(object).GetConstructor(Array.Empty <Type>()));
            g.Emit(OpCodes.Ldarg, 0);
            g.Emit(OpCodes.Ldarg_1);
            g.Emit(OpCodes.Stfld, fieldInfoMagicValueField);
            g.Emit(OpCodes.Ret);

            MethodAttributes methodAttributes = MethodAttributes.Public | MethodAttributes.HideBySig;

            if (staticMethod)
            {
                methodAttributes |= MethodAttributes.Static;
            }

            MethodBuilder mbInstance = tb.DefineMethod(
                "Method",
                methodAttributes,
                callee.Method.ReturnType,
                callee.Parameters.Select(t => t.Type).ToArray());

            GenericTypeParameterBuilder[] typeParamsMethod = null;
            if (methodGenericShape != GenericShape.NotGeneric)
            {
                typeParamsMethod = mbInstance.DefineGenericParameters(new string[] { "T" });
            }

            mbInstance.SetImplementationFlags(MethodImplAttributes.Managed);

            int magicNumberEmbeddedInObject = rand.Next();

            GCHandle gchCallee       = GCHandle.Alloc(callee.Method.CreateDelegate(delegateType));
            IntPtr   gchCalleeIntPtr = GCHandle.ToIntPtr(gchCallee);

            g = mbInstance.GetILGenerator();

            if (!staticMethod)
            {
                // Verify random number made it intact, and this parameter was handled correctly

                g.Emit(OpCodes.Ldarg_0);
                g.Emit(OpCodes.Ldfld, fieldInfoMagicValueField);
                g.Emit(OpCodes.Ldc_I4, magicNumberEmbeddedInObject);
                g.Emit(OpCodes.Call, s_compareNumbers);
            }

            // Verify generic args are as expected
            EmitTypeHandleCheck(g, typeGenericShape, typeParamsType, "type");
            EmitTypeHandleCheck(g, methodGenericShape, typeParamsMethod, "method");

            // Make the call to callee
            LocalBuilder gcHandleLocal = g.DeclareLocal(typeof(GCHandle));

            // Load GCHandle of callee delegate
            g.Emit(OpCodes.Ldc_I8, (long)gchCalleeIntPtr);
            g.Emit(OpCodes.Conv_I);
            g.Emit(OpCodes.Call, s_gcHandleFromIntPtr);
            g.Emit(OpCodes.Stloc, gcHandleLocal);
            // Resolve to target
            g.Emit(OpCodes.Ldloca, gcHandleLocal);
            g.Emit(OpCodes.Call, s_gcHandle_getTarget);
            // Cast to delegate type
            g.Emit(OpCodes.Castclass, delegateType);
            // Load all args
            int argOffset = 1;

            if (staticMethod)
            {
                argOffset = 0;
            }
            for (int i = 0; i < pms.Count; i++)
            {
                g.Emit(OpCodes.Ldarg, argOffset + i);
            }

            // Call delegate invoke method
            g.Emit(OpCodes.Callvirt, delegateType.GetMethod("Invoke"));
            // ret
            g.Emit(OpCodes.Ret);
            Type calleeTypeOpen = tb.CreateType();
            Type calleeType;

            switch (typeGenericShape)
            {
            case GenericShape.NotGeneric:
                calleeType = calleeTypeOpen;
                break;

            case GenericShape.GenericOverReferenceType:
                calleeType = calleeTypeOpen.MakeGenericType(typeof(object));
                break;

            case GenericShape.GenericOverValueType:
                calleeType = calleeTypeOpen.MakeGenericType(typeof(int));
                break;

            default:
                throw new Exception("Unknown case");
            }

            MethodInfo targetMethodOpen = calleeType.GetMethod("Method");
            MethodInfo targetMethod;

            switch (methodGenericShape)
            {
            case GenericShape.NotGeneric:
                targetMethod = targetMethodOpen;
                break;

            case GenericShape.GenericOverReferenceType:
                targetMethod = targetMethodOpen.MakeGenericMethod(typeof(object));
                break;

            case GenericShape.GenericOverValueType:
                targetMethod = targetMethodOpen.MakeGenericMethod(typeof(int));
                break;

            default:
                throw new Exception("Unknown case");
            }

            Delegate targetMethodToCallDel;

            if (staticMethod)
            {
                targetMethodToCallDel = targetMethod.CreateDelegate(delegateType);
            }
            else
            {
                targetMethodToCallDel = targetMethod.CreateDelegate(delegateType, Activator.CreateInstance(calleeType, magicNumberEmbeddedInObject));
            }

            GCHandle gchTargetMethod = GCHandle.Alloc(targetMethodToCallDel);

            // CALLER Dynamic method
            DynamicMethod caller = new DynamicMethod(
                callerName, typeof(int), pms.Select(t => t.Type).ToArray(), typeof(Program).Module);

            g = caller.GetILGenerator();

            // Create the args to pass to the callee from the caller.
            List <Value> args = GenCallerToCalleeArgs(pms, callee.Parameters, rand);

            if (Config.Verbose)
            {
                EmitDumpValues("Caller's incoming args", g, pms.Select((p, i) => new ArgValue(p, i)));
            }

            if (Config.Verbose)
            {
                EmitDumpValues($"Caller's args to {callerName} call", g, args);
            }

            gcHandleLocal = g.DeclareLocal(typeof(GCHandle));
            g.Emit(OpCodes.Ldc_I8, (long)GCHandle.ToIntPtr(gchTargetMethod));
            g.Emit(OpCodes.Conv_I);
            g.Emit(OpCodes.Call, s_gcHandleFromIntPtr);
            g.Emit(OpCodes.Stloc, gcHandleLocal);
            // Resolve to target
            g.Emit(OpCodes.Ldloca, gcHandleLocal);
            g.Emit(OpCodes.Call, s_gcHandle_getTarget);
            // Cast to delegate type
            g.Emit(OpCodes.Castclass, delegateType);

            foreach (Value v in args)
            {
                v.Emit(g);
            }

            // Call delegate invoke method
            g.Emit(OpCodes.Callvirt, delegateType.GetMethod("Invoke"));
            // ret
            g.Emit(OpCodes.Ret);

            (object callerResult, object calleeResult) = InvokeCallerCallee(caller, pms, callee.Method, args, rand);

            gchCallee.Free();
            gchTargetMethod.Free();
            if (callerResult.Equals(calleeResult))
            {
                return(true);
            }

            Console.WriteLine("Mismatch in stub call: expected {0}, got {1}", calleeResult, callerResult);
            Console.WriteLine(callerName);
            WriteSignature(caller);
            WriteSignature(callee.Method);
            return(false);
        }
Beispiel #4
0
        /// <summary>
        /// The main class method.
        /// </summary>
        /// <param name="args">
        /// The args.
        /// </param>
        private static void Main(string[] args)
        {
            var square    = new GenericShape <SingletonSquare>(SingletonSquare.Squareingleton);
            var rectangle = new GenericShape <SingletonRectangle>(SingletonRectangle.RectangleSingleton);

            var singletonTestRunner = new SingletonTests();

            Console.WriteLine("------------------------------------------------------------------");
            Console.WriteLine("Base Singleton");
            singletonTestRunner.SingletonPerformanceTest(Singleton.Instance);
            Console.WriteLine("------------------------------------------------------------------");

            Console.WriteLine("Singleton with lock");
            singletonTestRunner.SingletonPerformanceTest(SingletonWithLock.Instance);
            Console.WriteLine("------------------------------------------------------------------");

            var serializeTestCaseWithLock = false;

            Console.WriteLine("Singleton without lock - serialize test");
            singletonTestRunner.SerializableTest(serializeTestCaseWithLock);
            Console.WriteLine("------------------------------------------------------------------");
            serializeTestCaseWithLock = true;
            Console.WriteLine("Singleton ***WITH*** lock - serialize test");
            singletonTestRunner.SerializableTest(serializeTestCaseWithLock);
            Console.WriteLine("------------------------------------------------------------------");
            Console.WriteLine("Singleton inheritance test");

            var       singletonParent    = Singleton.Instance;
            Singleton squareSingleton    = SingletonSquare.Squareingleton;
            Singleton rectangleSingleton = SingletonRectangle.RectangleSingleton;

            Console.WriteLine("------------------------------------------------------------------");
            Console.WriteLine("Call GetName Function from main class:");
            Console.WriteLine($"name: {singletonParent.GetName()},\n type: {singletonParent.GetType()}\n");
            Console.WriteLine("------------------------------------------------------------------");
            Console.WriteLine("Call GetName Function from derived class square:");
            Console.WriteLine($"name: {squareSingleton.GetName()},\n type: {squareSingleton.GetType()} \n");
            Console.WriteLine("Call GetName Function from derived class rectangle:");
            Console.WriteLine($"name: {rectangleSingleton.GetName()},\ntype: {rectangleSingleton.GetType()} \n");
            Console.WriteLine("------------------------------------------------------------------");
            Console.WriteLine("Call GetName Function from derived class'GenericShape'\nwhich inherit from main class.\nIt has generic functionality derived from class that inherit from Singleton. 'CurrentType.GetName()'\n");
            Console.WriteLine("******************************************************************");
            Console.WriteLine($"name : {square.GetName()},\n type: {square.GetType()}\n");
            Console.WriteLine($"name : {rectangle.GetName()},\n type: {rectangle.GetType()}\n");
            Console.WriteLine("------------------------------------------------------------------");
            Console.WriteLine("\n\nTask Test run");

            var t1 = new SingletonThreadTest("1.");
            var t2 = new SingletonThreadTest("2.");
            var t3 = new SingletonThreadTest("3.");
            var t4 = new SingletonThreadTest("4.");
            var t5 = new SingletonThreadTest("5.");
            var t6 = new SingletonThreadTest("6.");
            var t7 = new SingletonThreadTest("7.");
            var t8 = new SingletonThreadTest("8.");
            var t9 = new SingletonThreadTest("9.");

            t1.Run();
            t2.Run();
            t3.Run();
            t4.Run();
            t5.Run();
            t6.Run();
            t7.Run();
            t8.Run();
            t9.Run();

            Console.WriteLine("------------------------------------------------------------------");

            t1.RunWithoutTaskWait();
            t2.RunWithoutTaskWait();
            t3.RunWithoutTaskWait();
            t4.RunWithoutTaskWait();
            t5.RunWithoutTaskWait();
            t6.RunWithoutTaskWait();
            t7.RunWithoutTaskWait();
            t8.RunWithoutTaskWait();
            t9.RunWithoutTaskWait();
            Thread.Sleep(10);
            Console.BackgroundColor = ConsoleColor.Black;
            Console.ForegroundColor = ConsoleColor.DarkGreen;
            Console.WriteLine("OK!\npozdrowienia.");
        }