diff options
Diffstat (limited to 'tests/src/Loader/classloader/TypeInitialization')
72 files changed, 8166 insertions, 0 deletions
diff --git a/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorOpenFile.cs b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorOpenFile.cs new file mode 100644 index 0000000000..29cd9ea2c1 --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorOpenFile.cs @@ -0,0 +1,81 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/* +Open and write to a file inside static class constructor of a class/struct (eager and beforefieldinit cases). +Access type's static field (which would trigger the .cctor) +Expected: Should get no exceptions. + +*/ + +using System; +using System.IO; + +public class MyClass +{ + public static int counter; + + static MyClass() + { + Console.WriteLine("Inside class cctor"); + + File.WriteAllText("file.txt", "inside MyClass.cctor"); + + counter++; + } +} + +public struct MyStruct +{ + + public static int counter; + + static MyStruct() + { + Console.WriteLine("Inside struct cctor"); + + File.WriteAllText("file.txt", "inside MyClass.cctor"); + + counter++; + } +} + + +public class Test +{ + public static int Main() + { + + int ret; + try + { + File.WriteAllText("file.txt", "inside Main"); + + + if (MyClass.counter == 1 && MyStruct.counter == 1) + { + Console.WriteLine("PASS"); + ret = 100; + } + else + { + Console.WriteLine("Fail: One of the .cctors wasn't called"); + ret = 101; + } + + if (File.Exists("file.txt")) + { + File.Delete("file.txt"); + } + + return ret; + } + catch (Exception e) + { + Console.WriteLine("FAIL: Caught unexpected exception: " + e); + return 102; + } + + } +} diff --git a/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorOpenFile.csproj b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorOpenFile.csproj new file mode 100644 index 0000000000..7b73adf9c7 --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorOpenFile.csproj @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> + <PropertyGroup> + <AssemblyName>CctorOpenFile</AssemblyName> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid> + <FileAlignment>512</FileAlignment> + <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> + <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp> + <AllowUnsafeBlocks>true</AllowUnsafeBlocks> + <ReferenceLocalMscorlib>false</ReferenceLocalMscorlib> + <OutputType>Exe</OutputType> + <CLRTestKind>BuildAndRun</CLRTestKind> + <CLRTestPriority>0</CLRTestPriority> + </PropertyGroup> + + <ItemGroup> + <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies"> + <Visible>False</Visible> + </CodeAnalysisDependentAssemblyPaths> + </ItemGroup> + + <ItemGroup> + <Compile Include="CctorOpenFile.cs" /> + </ItemGroup> + + <ItemGroup> + <None Include="app.config" /> + <None Include="project.json" /> + </ItemGroup> + + <ItemGroup> + <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" /> + </ItemGroup> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> +</Project> diff --git a/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowInlinedStatic.cs b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowInlinedStatic.cs new file mode 100644 index 0000000000..4a220d410b --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowInlinedStatic.cs @@ -0,0 +1,309 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/* + +A .cctor has only one chance to run in any appdomain. +If it fails, the 2nd time we try to access a static field we check if .cctor has been run. And it has, but failed so we fail again. + +Test throws an exception inside .cctor. +Try to access a static method twice for inlined and not inlined methods. +Expected: Should return the same exception. + +*/ + + +using System; +using System.IO; +using System.Runtime.CompilerServices; + +public class Foo +{ + public static void Meth_In() + { + // NotInlined.NotInlinedMeth is not inlined + NotInlined.NotInlinedMeth(); + } + + public static void Meth_NotIn() + { + // Inlined.InlinedMeth is inlined + Inlined.InlinedMeth(); + } + + public static void ValMeth_In() + { + // NotInlinedVal.NotInlinedValMeth is not inlined + NotInlinedVal.NotInlinedValMeth(); + } + + public static void ValMeth_NotIn() + { + // InlinedVal.InlinedValMeth is inlined + InlinedVal.InlinedValMeth(); + } +} + +public class NotInlined +{ + + static NotInlined() + { + Console.WriteLine("Inside NotInlined::.cctor"); + throw new Exception(); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void NotInlinedMeth() + { + } +} + + +public class Inlined +{ + + static Inlined() + { + Console.WriteLine("Inside Inlined::.cctor"); + throw new Exception(); + } + + public static void InlinedMeth() + { + } +} + + +public struct NotInlinedVal +{ + + static NotInlinedVal() + { + Console.WriteLine("Inside NotInlinedVal::.cctor"); + throw new Exception(); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void NotInlinedValMeth() + { + } +} + + +public class InlinedVal +{ + + static InlinedVal() + { + Console.WriteLine("Inside InlinedVal::.cctor"); + throw new Exception(); + } + + public static void InlinedValMeth() + { + } +} + +public class Test +{ + + + public static bool RunTest(int i) + { + bool result = true; + + switch (i) + { + case 1: + { + try + { + Console.WriteLine("Accessing class's inlined static method"); + Foo.Meth_In(); + Console.WriteLine("Did not catch expected TypeInitializationException exception"); + result = false; + } + catch (TypeInitializationException) + { + Console.WriteLine("Caught expected exception 1st time"); + } + catch (Exception e) + { + Console.WriteLine("Caught unexpected exception 1st time: " + e); + result = false; + } + + try + { + Foo.Meth_In(); + Console.WriteLine("Did not catch expected TypeInitializationException exception\n"); + result = false; + } + catch (TypeInitializationException) + { + Console.WriteLine("Caught expected exception 2nd time\n"); + } + catch (Exception e) + { + Console.WriteLine("Caught unexpected exception 2nd time: " + e); + result = false; + } + + return result; + } + case 2: + { + try + { + Console.WriteLine("Accessing struct's inlined static method"); + Foo.ValMeth_In(); + Console.WriteLine("Did not catch expected TypeInitializationException exception"); + result = false; + } + catch (TypeInitializationException) + { + Console.WriteLine("Caught expected exception 1st time"); + } + catch (Exception e) + { + Console.WriteLine("Caught unexpected exception 1st time: " + e); + result = false; + } + + try + { + Foo.ValMeth_In(); + Console.WriteLine("Did not catch expected TypeInitializationException exception"); + result = false; + } + catch (TypeInitializationException) + { + Console.WriteLine("Caught expected exception 2nd time\n"); + } + catch (Exception e) + { + Console.WriteLine("Caught unexpected exception 2nd time: " + e); + result = false; + } + + return result; + } + case 3: + { + try + { + Console.WriteLine("Accessing class's not inlined static method"); + + Foo.Meth_NotIn(); + + Console.WriteLine("Did not catch expected TypeInitializationException exception"); + result = false; + } + catch (TypeInitializationException) + { + Console.WriteLine("Caught expected exception 1st time"); + } + catch (Exception e) + { + Console.WriteLine("Caught unexpected exception 1st time: " + e); + result = false; + } + + try + { + Foo.Meth_NotIn(); + + Console.WriteLine("Did not catch expected TypeInitializationException exception"); + result = false; + } + catch (TypeInitializationException) + { + Console.WriteLine("Caught expected exception 2nd time\n"); + } + catch (Exception e) + { + Console.WriteLine("Caught unexpected exception 2nd time: " + e); + result = false; + } + + return result; + } + case 4: + { + try + { + Console.WriteLine("Accessing struct's not inlined static method"); + Foo.ValMeth_NotIn(); + + + Console.WriteLine("Did not catch expected TypeInitializationException exception"); + result = false; + } + catch (TypeInitializationException) + { + Console.WriteLine("Caught expected exception 1st time"); + } + catch (Exception e) + { + Console.WriteLine("Caught unexpected exception 1st time: " + e); + result = false; + } + + try + { + Foo.ValMeth_NotIn(); + + Console.WriteLine("Did not catch expected TypeInitializationException exception\n"); + result = false; + } + catch (TypeInitializationException) + { + Console.WriteLine("Caught expected exception 2nd time\n"); + } + catch (Exception e) + { + Console.WriteLine("Caught unexpected exception 2nd time: " + e); + result = false; + } + + return result; + } + + default : + return false; + } + } + + + public static int Main() + { + bool pass = true; + + // run tests + if (!RunTest(1)) + pass = false; + + if (!RunTest(2)) + pass = false; + + if (!RunTest(3)) + pass = false; + + if (!RunTest(4)) + pass = false; + + if (pass) + { + Console.WriteLine("PASS"); + return 100; + } + else + { + Console.WriteLine("FAIL"); + return 101; + } + + } +} diff --git a/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowInlinedStatic.csproj b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowInlinedStatic.csproj new file mode 100644 index 0000000000..503d666b9b --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowInlinedStatic.csproj @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> + <PropertyGroup> + <AssemblyName>CctorThrowInlinedStatic</AssemblyName> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid> + <FileAlignment>512</FileAlignment> + <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> + <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp> + <AllowUnsafeBlocks>true</AllowUnsafeBlocks> + <ReferenceLocalMscorlib>false</ReferenceLocalMscorlib> + <OutputType>Exe</OutputType> + <CLRTestKind>BuildAndRun</CLRTestKind> + <CLRTestPriority>0</CLRTestPriority> + </PropertyGroup> + + <ItemGroup> + <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies"> + <Visible>False</Visible> + </CodeAnalysisDependentAssemblyPaths> + </ItemGroup> + + <ItemGroup> + <Compile Include="CctorThrowInlinedStatic.cs" /> + </ItemGroup> + + <ItemGroup> + <None Include="app.config" /> + <None Include="project.json" /> + </ItemGroup> + + <ItemGroup> + <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" /> + </ItemGroup> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> +</Project> diff --git a/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowLDFTNStaticMethod.il b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowLDFTNStaticMethod.il new file mode 100644 index 0000000000..dc73aea0e7 --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowLDFTNStaticMethod.il @@ -0,0 +1,348 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +.assembly extern System.Console { } +// A .cctor has only one chance to run in any appdomain. +// If it fails, the 2nd time we try to access a static field we check if .cctor has been run. +// And it has, but failed so we fail again. + +// Test throws an exception inside .cctor. +// Try to access a static method using LDFTN op code +// Expected: Should return the same exception. + + + +// Metadata version: v2.0.50117 +.assembly extern mscorlib +{ + .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. + .ver 2:0:0:0 +} +.assembly CctorThrowLDFTNStaticMethod +{ + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module CctorThrowLDFTNStaticMethod.exe +// MVID: {DFA6FFCF-599E-4DF2-8538-B842C6A0AD10} +.imagebase 0x00400000 +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 // WINDOWS_CUI +.corflags 0x00000001 // ILONLY +// Image base: 0x03090000 + + +// =============== CLASS MEMBERS DECLARATION =================== + +.class public auto ansi A + extends [mscorlib]System.Object +{ + .method private hidebysig specialname rtspecialname static + void .cctor() cil managed + { + // Code size 18 (0x12) + .maxstack 8 + IL_0000: nop + IL_0001: ldstr "Inside A.cctor" + IL_0006: call void [System.Console]System.Console::WriteLine(string) + IL_000b: nop + IL_000c: newobj instance void [mscorlib]System.Exception::.ctor() + IL_0011: throw + } // end of method A::.cctor + + .method public hidebysig static void StaticMethod() cil managed + { + // Code size 2 (0x2) + .maxstack 8 + IL_0000: nop + IL_0001: ret + } // end of method A::StaticMethod + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method A::.ctor + +} // end of class A + +.class public sequential ansi sealed B + extends [mscorlib]System.ValueType +{ + .pack 0 + .size 1 + .method private hidebysig specialname rtspecialname static + void .cctor() cil managed + { + // Code size 18 (0x12) + .maxstack 8 + IL_0000: nop + IL_0001: ldstr "Inside B.cctor" + IL_0006: call void [System.Console]System.Console::WriteLine(string) + IL_000b: nop + IL_000c: newobj instance void [mscorlib]System.Exception::.ctor() + IL_0011: throw + } // end of method B::.cctor + + .method public hidebysig static void StaticMethod() cil managed + { + // Code size 2 (0x2) + .maxstack 8 + IL_0000: nop + IL_0001: ret + } // end of method B::StaticMethod + +} // end of class B + +.class public auto ansi beforefieldinit Test + extends [mscorlib]System.Object +{ + .method public hidebysig static int32 Main() cil managed + { + .entrypoint + // Code size 279 (0x117) + .maxstack 2 + .locals init (bool V_0, + class [mscorlib]System.Exception V_1, + int32 V_2, + bool V_3) + IL_0000: nop + IL_0001: ldc.i4.1 + IL_0002: stloc.0 + .try + { + IL_0003: nop + IL_0004: ldstr "LDFTN static method of a class" + IL_0009: call void [System.Console]System.Console::WriteLine(string) + IL_000e: nop + + + // LDFTN static method of a class + ldftn void A::StaticMethod() + calli void () + + + IL_000f: ldstr "Did not catch expected TypeInitializationException" + + " exception" + IL_0014: call void [System.Console]System.Console::WriteLine(string) + IL_0019: nop + IL_001a: ldc.i4.0 + IL_001b: stloc.0 + IL_001c: nop + IL_001d: leave.s IL_0047 + + } // end .try + catch [mscorlib]System.TypeInitializationException + { + IL_001f: pop + IL_0020: nop + IL_0021: ldstr "Caught expected exception 1st time" + IL_0026: call void [System.Console]System.Console::WriteLine(string) + IL_002b: nop + IL_002c: nop + IL_002d: leave.s IL_0047 + + } // end handler + catch [mscorlib]System.Exception + { + IL_002f: stloc.1 + IL_0030: nop + IL_0031: ldstr "Caught unexpected exception 1st time: " + IL_0036: ldloc.1 + IL_0037: call string [mscorlib]System.String::Concat(object, + object) + IL_003c: call void [System.Console]System.Console::WriteLine(string) + IL_0041: nop + IL_0042: ldc.i4.0 + IL_0043: stloc.0 + IL_0044: nop + IL_0045: leave.s IL_0047 + + } // end handler + IL_0047: nop + .try + { + IL_0048: nop + + // LDFTN static method of a class + ldftn void A::StaticMethod() + calli void () + + IL_0049: ldstr "Did not catch expected TypeInitializationException" + + " exception\n" + IL_004e: call void [System.Console]System.Console::WriteLine(string) + IL_0053: nop + IL_0054: ldc.i4.0 + IL_0055: stloc.0 + IL_0056: nop + IL_0057: leave.s IL_0081 + + } // end .try + catch [mscorlib]System.TypeInitializationException + { + IL_0059: pop + IL_005a: nop + IL_005b: ldstr "Caught expected exception 2nd time\n" + IL_0060: call void [System.Console]System.Console::WriteLine(string) + IL_0065: nop + IL_0066: nop + IL_0067: leave.s IL_0081 + + } // end handler + catch [mscorlib]System.Exception + { + IL_0069: stloc.1 + IL_006a: nop + IL_006b: ldstr "Caught unexpected exception 2nd time: " + IL_0070: ldloc.1 + IL_0071: call string [mscorlib]System.String::Concat(object, + object) + IL_0076: call void [System.Console]System.Console::WriteLine(string) + IL_007b: nop + IL_007c: ldc.i4.0 + IL_007d: stloc.0 + IL_007e: nop + IL_007f: leave.s IL_0081 + + } // end handler + IL_0081: nop + .try + { + IL_0082: nop + IL_0083: ldstr "LDFTN static method of a struct" + IL_0088: call void [System.Console]System.Console::WriteLine(string) + IL_008d: nop + + // LDFTN static method of a struct + ldftn void B::StaticMethod() + calli void () + + IL_008e: ldstr "Did not catch expected TypeInitializationException" + + " exception" + IL_0093: call void [System.Console]System.Console::WriteLine(string) + IL_0098: nop + IL_0099: ldc.i4.0 + IL_009a: stloc.0 + IL_009b: nop + IL_009c: leave.s IL_00c6 + + } // end .try + catch [mscorlib]System.TypeInitializationException + { + IL_009e: pop + IL_009f: nop + IL_00a0: ldstr "Caught expected exception 1st time" + IL_00a5: call void [System.Console]System.Console::WriteLine(string) + IL_00aa: nop + IL_00ab: nop + IL_00ac: leave.s IL_00c6 + + } // end handler + catch [mscorlib]System.Exception + { + IL_00ae: stloc.1 + IL_00af: nop + IL_00b0: ldstr "Caught unexpected exception 1st time: " + IL_00b5: ldloc.1 + IL_00b6: call string [mscorlib]System.String::Concat(object, + object) + IL_00bb: call void [System.Console]System.Console::WriteLine(string) + IL_00c0: nop + IL_00c1: ldc.i4.0 + IL_00c2: stloc.0 + IL_00c3: nop + IL_00c4: leave.s IL_00c6 + + } // end handler + IL_00c6: nop + .try + { + IL_00c7: nop + + // LDFTN static method of a struct + ldftn void B::StaticMethod() + calli void () + + IL_00c8: ldstr "Did not catch expected TypeInitializationException" + + " exception\n" + IL_00cd: call void [System.Console]System.Console::WriteLine(string) + IL_00d2: nop + IL_00d3: ldc.i4.0 + IL_00d4: stloc.0 + IL_00d5: nop + IL_00d6: leave.s IL_0100 + + } // end .try + catch [mscorlib]System.TypeInitializationException + { + IL_00d8: pop + IL_00d9: nop + IL_00da: ldstr "Caught expected exception 2nd time\n" + IL_00df: call void [System.Console]System.Console::WriteLine(string) + IL_00e4: nop + IL_00e5: nop + IL_00e6: leave.s IL_0100 + + } // end handler + catch [mscorlib]System.Exception + { + IL_00e8: stloc.1 + IL_00e9: nop + IL_00ea: ldstr "Caught unexpected exception 2nd time: " + IL_00ef: ldloc.1 + IL_00f0: call string [mscorlib]System.String::Concat(object, + object) + IL_00f5: call void [System.Console]System.Console::WriteLine(string) + IL_00fa: nop + IL_00fb: ldc.i4.0 + IL_00fc: stloc.0 + IL_00fd: nop + IL_00fe: leave.s IL_0100 + + } // end handler + IL_0100: nop + IL_0101: ldloc.0 + IL_0102: ldc.i4.0 + IL_0103: ceq + IL_0105: stloc.3 + IL_0106: ldloc.3 + IL_0107: brtrue.s IL_010f + + IL_0109: nop + IL_010a: ldc.i4.s 100 + IL_010c: stloc.2 + IL_010d: br.s IL_0115 + + IL_010f: nop + IL_0110: ldc.i4.s 101 + IL_0112: stloc.2 + IL_0113: br.s IL_0115 + + IL_0115: ldloc.2 + IL_0116: ret + } // end of method Test::Main + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method Test::.ctor + +} // end of class Test + + +// ============================================================= + +// *********** DISASSEMBLY COMPLETE *********************** +// WARNING: Created Win32 resource file CctorThrowLDFTNStaticMethod.res diff --git a/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowLDFTNStaticMethod.ilproj b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowLDFTNStaticMethod.ilproj new file mode 100644 index 0000000000..280674411f --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowLDFTNStaticMethod.ilproj @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> + <PropertyGroup> + <AssemblyName>CctorThrowLDFTNStaticMethod</AssemblyName> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid> + <FileAlignment>512</FileAlignment> + <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> + <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp> + <AllowUnsafeBlocks>true</AllowUnsafeBlocks> + <ReferenceLocalMscorlib>true</ReferenceLocalMscorlib> + <OutputType>Exe</OutputType> + <CLRTestKind>BuildAndRun</CLRTestKind> + <CLRTestPriority>0</CLRTestPriority> + </PropertyGroup> + + <ItemGroup> + <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies"> + <Visible>False</Visible> + </CodeAnalysisDependentAssemblyPaths> + </ItemGroup> + + <ItemGroup> + <Compile Include="CctorThrowLDFTNStaticMethod.il" /> + </ItemGroup> + + <ItemGroup> + <None Include="app.config" /> + </ItemGroup> + + <ItemGroup> + <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" /> + </ItemGroup> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> +</Project> diff --git a/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowMethodAccess.cs b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowMethodAccess.cs new file mode 100644 index 0000000000..f7e38a6770 --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowMethodAccess.cs @@ -0,0 +1,429 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/* + +A .cctor has only one chance to run in any appdomain. +If it fails, the 2nd time we try to access a static field we check if .cctor has been run. And it has, but failed so we fail again. + +Test throws an exception inside .cctor. +Try to access a static method twice. +Expected: Should return the same exception. + +*/ + +using System; + +// TEST1 +// static method access +public class A +{ + static A() + { + Console.WriteLine("In A.cctor"); + + throw new Exception(); + } + + public static void methA() + {} +} + +// TEST2 +// static method access +public struct B +{ + static B() + { + Console.WriteLine("In B.cctor"); + + throw new Exception(); + } + + public static void methB() + {} +} + +// TEST3 +// instance constructor trigger +public class C +{ + static C() + { + Console.WriteLine("In C.cctor"); + + throw new Exception(); + } +} + +// TEST4 +// instance constructor trigger +public struct D +{ + static D() + { + Console.WriteLine("In D.cctor"); + + throw new Exception(); + } + + public D(int i){} +} + +/* +// this will fail due to current postponed bug so I've disabled it for now +// TEST5 +// instance method trigger (for this null pointer) +public class E +{ + static E() + { + Console.WriteLine("In E.cctor"); + + throw new Exception(); + } + + public void methE() + {} +} +*/ + +// TEST6 +// instance method trigger (for zero initialized valuetype) +public struct F +{ + static F() + { + Console.WriteLine("In F.cctor"); + + throw new Exception(); + } + + public void methF() + {} +} + +public interface IG +{ + void methG(); +} + +// TEST7 +// virtual instance method trigger (for zero initialized valuetype) +public struct G : IG +{ + static G() + { + Console.WriteLine("In G.cctor"); + + throw new Exception(); + } + + public void methG() + {} +} + + + +public class Test +{ + public static bool RunTest(string s) + { + bool result = true; + + switch (s) + { + case "A": + { + try + { + Console.WriteLine("Accessing class's static method"); + A.methA(); + Console.WriteLine("Did not catch expected TypeInitializationException exception"); + result = false; + } + catch (TypeInitializationException) + { + Console.WriteLine("Caught expected exception 1st time"); + } + catch (Exception e) + { + Console.WriteLine("Caught unexpected exception 1st time: " + e); + result = false; + } + + try + { + A.methA(); + Console.WriteLine("Did not catch expected TypeInitializationException exception\n"); + result = false; + } + catch (TypeInitializationException) + { + Console.WriteLine("Caught expected exception 2nd time\n"); + } + catch (Exception e) + { + Console.WriteLine("Caught unexpected exception 2nd time: " + e); + result = false; + } + + return result; + } + case "B": + { + try + { + Console.WriteLine("Accessing struct's static method"); + B.methB(); + Console.WriteLine("Did not catch expected TypeInitializationException exception"); + result = false; + } + catch (TypeInitializationException) + { + Console.WriteLine("Caught expected exception 1st time"); + } + catch (Exception e) + { + Console.WriteLine("Caught unexpected exception 1st time: " + e); + result = false; + } + + try + { + B.methB(); + Console.WriteLine("Did not catch expected TypeInitializationException exception"); + result = false; + } + catch (TypeInitializationException) + { + Console.WriteLine("Caught expected exception 2nd time\n"); + } + catch (Exception e) + { + Console.WriteLine("Caught unexpected exception 2nd time: " + e); + result = false; + } + + return result; + } + case "C": + { + try + { + Console.WriteLine("Instantiating class"); + + C c = new C(); + + Console.WriteLine("Did not catch expected TypeInitializationException exception"); + result = false; + } + catch (TypeInitializationException) + { + Console.WriteLine("Caught expected exception 1st time"); + } + catch (Exception e) + { + Console.WriteLine("Caught unexpected exception 1st time: " + e); + result = false; + } + + try + { + C c = new C(); + + Console.WriteLine("Did not catch expected TypeInitializationException exception"); + result = false; + } + catch (TypeInitializationException) + { + Console.WriteLine("Caught expected exception 2nd time\n"); + } + catch (Exception e) + { + Console.WriteLine("Caught unexpected exception 2nd time: " + e); + result = false; + } + + return result; + } + case "D": + { + try + { + Console.WriteLine("Instantiating struct"); + D d = new D(6); + + // to get rid of compiler warning that var d is never used + string str = d.ToString(); + + Console.WriteLine("Did not catch expected TypeInitializationException exception"); + result = false; + } + catch (TypeInitializationException) + { + Console.WriteLine("Caught expected exception 1st time"); + } + catch (Exception e) + { + Console.WriteLine("Caught unexpected exception 1st time: " + e); + result = false; + } + + try + { + D d = new D(6); + + // to get rid of compiler warning that var d is never used + string str = d.ToString(); + + Console.WriteLine("Did not catch expected TypeInitializationException exception\n"); + result = false; + } + catch (TypeInitializationException) + { + Console.WriteLine("Caught expected exception 2nd time\n"); + } + catch (Exception e) + { + Console.WriteLine("Caught unexpected exception 2nd time: " + e); + result = false; + } + + return result; + } + case "F": + { + try + { + Console.WriteLine("Accessing struct's instance method (zero initialized struct)"); + F f = new F(); + + f.methF(); + Console.WriteLine("Did not catch expected TypeInitializationException exception"); + result = false; + } + catch (TypeInitializationException) + { + Console.WriteLine("Caught expected exception 1st time"); + } + catch (Exception e) + { + Console.WriteLine("Caught unexpected exception 1st time: " + e); + result = false; + } + + try + { + F f = new F(); + + f.methF(); + + Console.WriteLine("Did not catch expected TypeInitializationException exception"); + result = false; + } + catch (TypeInitializationException) + { + Console.WriteLine("Caught expected exception 2nd time\n"); + } + catch (Exception e) + { + Console.WriteLine("Caught unexpected exception 2nd time: " + e); + result = false; + } + + return result; + } + case "G": + { + try + { + Console.WriteLine("Accessing struct's virtual instance method (zero initialized struct)"); + IG g = new G(); + + g.methG(); + Console.WriteLine("Did not catch expected TypeInitializationException exception"); + result = false; + } + catch (TypeInitializationException) + { + Console.WriteLine("Caught expected exception 1st time"); + } + catch (Exception e) + { + Console.WriteLine("Caught unexpected exception 1st time: " + e); + result = false; + } + + try + { + IG g = new G(); + + g.methG(); + + Console.WriteLine("Did not catch expected TypeInitializationException exception"); + result = false; + } + catch (TypeInitializationException) + { + Console.WriteLine("Caught expected exception 2nd time\n"); + } + catch (Exception e) + { + Console.WriteLine("Caught unexpected exception 2nd time: " + e); + result = false; + } + + return result; + } + default : + return false; + } + } + + + public static int Main() + { + bool pass = true; + + + Console.WriteLine("\n============================================================"); + Console.WriteLine("NOTE: This test will fail with NGEN"); + Console.WriteLine("We do not guarantee to execute static .cctor for structs"); + Console.WriteLine("unless the instance .ctor is explicitly called\n"); + Console.WriteLine("============================================================"); + + + // run tests + if (!RunTest(typeof(A).ToString())) + pass = false; + + if (!RunTest(typeof(B).ToString())) + pass = false; + + if (!RunTest(typeof(C).ToString())) + pass = false; + + if (!RunTest(typeof(D).ToString())) + pass = false; + + if (!RunTest(typeof(F).ToString())) + pass = false; + + if (!RunTest(typeof(G).ToString())) + pass = false; + + if (pass) + { + Console.WriteLine("PASS"); + return 100; + } + else + { + Console.WriteLine("FAIL"); + return 101; + } + + } +} diff --git a/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowMethodAccess.csproj b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowMethodAccess.csproj new file mode 100644 index 0000000000..dd875e20b8 --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowMethodAccess.csproj @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> + <PropertyGroup> + <AssemblyName>CctorThrowMethodAccess</AssemblyName> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid> + <FileAlignment>512</FileAlignment> + <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> + <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp> + <AllowUnsafeBlocks>true</AllowUnsafeBlocks> + <ReferenceLocalMscorlib>false</ReferenceLocalMscorlib> + <OutputType>Exe</OutputType> + <CLRTestKind>BuildAndRun</CLRTestKind> + <CLRTestPriority>0</CLRTestPriority> + </PropertyGroup> + + <ItemGroup> + <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies"> + <Visible>False</Visible> + </CodeAnalysisDependentAssemblyPaths> + </ItemGroup> + + <ItemGroup> + <Compile Include="CctorThrowMethodAccess.cs" /> + </ItemGroup> + + <ItemGroup> + <None Include="app.config" /> + <None Include="project.json" /> + </ItemGroup> + + <ItemGroup> + <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" /> + </ItemGroup> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> +</Project> diff --git a/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowStaticField.cs b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowStaticField.cs new file mode 100644 index 0000000000..859318e598 --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowStaticField.cs @@ -0,0 +1,136 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/* + +A .cctor has only one chance to run in any appdomain. +If it fails, the 2nd time we try to access a static field we check if .cctor has been run. And it has, but failed so we fail again. + +Test throws an exception inside .cctor. +Try to access a static field twice. +Expected: Should return the same exception. + +*/ + +using System; + + +public class A +{ + public static int i; + + static A() + { + Console.WriteLine("In A.cctor"); + + A.i = 5; + + throw new Exception(); + } +} + + +public struct B +{ + public static int i; + + static B() + { + Console.WriteLine("In B.cctor"); + + B.i = 5; + + throw new Exception(); + } +} + + +public class Test +{ + public static int Main() + { + bool result = true; + + try + { + Console.WriteLine("Accessing class's static field"); + Console.WriteLine("A.i: " +A.i); + Console.WriteLine("Did not catch expected TypeInitializationException exception"); + result = false; + } + catch (TypeInitializationException) + { + Console.WriteLine("Caught expected exception 1st time"); + } + catch (Exception e) + { + Console.WriteLine("Caught unexpected exception 1st time: " + e); + result = false; + } + + + try + { + Console.WriteLine("A.i: " +A.i); + Console.WriteLine("Did not catch expected TypeInitializationException exception"); + result = false; + } + catch (TypeInitializationException) + { + Console.WriteLine("Caught expected exception 2nd time\n"); + } + catch (Exception e) + { + Console.WriteLine("Caught unexpected exception 2nd time: " + e); + result = false; + } + + + Console.WriteLine("Accessing struct's static field"); + try + { + Console.WriteLine("B.i: " +B.i); + Console.WriteLine("Did not catch expected TypeInitializationException exception"); + result = false; + } + catch (TypeInitializationException) + { + Console.WriteLine("Caught expected exception 1st time"); + } + catch (Exception e) + { + Console.WriteLine("Caught unexpected exception 1st time: " + e); + result = false; + } + + + try + { + Console.WriteLine("B.i: " +B.i); + Console.WriteLine("Did not catch expected TypeInitializationException exception"); + result = false; + } + catch (TypeInitializationException) + { + Console.WriteLine("Caught expected exception 2nd time\n"); + } + catch (Exception e) + { + Console.WriteLine("Caught unexpected exception 2nd time: " + e); + result = false; + } + + if (result) + { + Console.WriteLine("PASS"); + return 100; + } + else + { + Console.WriteLine("FAIL"); + return 101; + } + + } +} diff --git a/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowStaticField.csproj b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowStaticField.csproj new file mode 100644 index 0000000000..e38b2384f1 --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowStaticField.csproj @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> + <PropertyGroup> + <AssemblyName>CctorThrowStaticField</AssemblyName> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid> + <FileAlignment>512</FileAlignment> + <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> + <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp> + <AllowUnsafeBlocks>true</AllowUnsafeBlocks> + <ReferenceLocalMscorlib>false</ReferenceLocalMscorlib> + <OutputType>Exe</OutputType> + <CLRTestKind>BuildAndRun</CLRTestKind> + <CLRTestPriority>0</CLRTestPriority> + </PropertyGroup> + + <ItemGroup> + <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies"> + <Visible>False</Visible> + </CodeAnalysisDependentAssemblyPaths> + </ItemGroup> + + <ItemGroup> + <Compile Include="CctorThrowStaticField.cs" /> + </ItemGroup> + + <ItemGroup> + <None Include="app.config" /> + <None Include="project.json" /> + </ItemGroup> + + <ItemGroup> + <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" /> + </ItemGroup> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> +</Project> diff --git a/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowStaticFieldBFI.il b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowStaticFieldBFI.il new file mode 100644 index 0000000000..255282576c --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowStaticFieldBFI.il @@ -0,0 +1,346 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +.assembly extern System.Console { } + +// Microsoft (R) .NET Framework IL Disassembler. Version 2.0.50103.00 +// Copyright (C) Microsoft Corporation. All rights reserved. + + + +// Metadata version: v2.0.50103 +.assembly extern mscorlib +{ + .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. + .ver 2:0:0:0 +} +.assembly CctorThrowStaticFieldBFI +{ + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module CctorThrowStaticFieldBFI.exe +// MVID: {A7BE6B3C-FF8D-43DB-B091-60CBA24AD082} +.imagebase 0x00400000 +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 // WINDOWS_CUI +.corflags 0x00000001 // ILONLY +// Image base: 0x03090000 + + +// =============== CLASS MEMBERS DECLARATION =================== + +.class public auto ansi beforefieldinit A + extends [mscorlib]System.Object +{ + .field public static int32 i + .method private hidebysig specialname rtspecialname static + void .cctor() cil managed + { + // Code size 24 (0x18) + .maxstack 8 + IL_0000: nop + IL_0001: ldstr "In A.cctor" + IL_0006: call void [System.Console]System.Console::WriteLine(string) + IL_000b: nop + IL_000c: ldc.i4.5 + IL_000d: stsfld int32 A::i + IL_0012: newobj instance void [mscorlib]System.Exception::.ctor() + IL_0017: throw + } // end of method A::.cctor + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method A::.ctor + +} // end of class A + +.class public sequential ansi sealed B + extends [mscorlib]System.ValueType +{ + .pack 0 + .size 1 + .field public static int32 i + .method private hidebysig specialname rtspecialname static + void .cctor() cil managed + { + // Code size 24 (0x18) + .maxstack 8 + IL_0000: nop + IL_0001: ldstr "In B.cctor" + IL_0006: call void [System.Console]System.Console::WriteLine(string) + IL_000b: nop + IL_000c: ldc.i4.5 + IL_000d: stsfld int32 B::i + IL_0012: newobj instance void [mscorlib]System.Exception::.ctor() + IL_0017: throw + } // end of method B::.cctor + +} // end of class B + +.class public auto ansi beforefieldinit Test + extends [mscorlib]System.Object +{ + .method public hidebysig static int32 Main() cil managed + { + .entrypoint + // Code size 405 (0x195) + .maxstack 2 + .locals init (bool V_0, + class [mscorlib]System.Exception V_1, + int32 V_2, + bool V_3) + IL_0000: nop + IL_0001: ldc.i4.1 + IL_0002: stloc.0 + .try + { + IL_0003: nop + IL_0004: ldstr "Accessing class's static field" + IL_0009: call void [System.Console]System.Console::WriteLine(string) + IL_000e: nop + IL_000f: ldstr "A.i: " + IL_0014: ldsfld int32 A::i + IL_0019: box [mscorlib]System.Int32 + IL_001e: call string [mscorlib]System.String::Concat(object, + object) + IL_0023: call void [System.Console]System.Console::WriteLine(string) + IL_0028: nop + IL_0029: ldstr "Did not catch expected TypeInitializationException" + + " exception" + IL_002e: call void [System.Console]System.Console::WriteLine(string) + IL_0033: nop + IL_0034: ldc.i4.0 + IL_0035: stloc.0 + IL_0036: nop + IL_0037: leave.s IL_0061 + + } // end .try + catch [mscorlib]System.TypeInitializationException + { + IL_0039: pop + IL_003a: nop + IL_003b: ldstr "Caught expected exception 1st time" + IL_0040: call void [System.Console]System.Console::WriteLine(string) + IL_0045: nop + IL_0046: nop + IL_0047: leave.s IL_0061 + + } // end handler + catch [mscorlib]System.Exception + { + IL_0049: stloc.1 + IL_004a: nop + IL_004b: ldstr "Caught unexpected exception: " + IL_0050: ldloc.1 + IL_0051: call string [mscorlib]System.String::Concat(object, + object) + IL_0056: call void [System.Console]System.Console::WriteLine(string) + IL_005b: nop + IL_005c: ldc.i4.0 + IL_005d: stloc.0 + IL_005e: nop + IL_005f: leave.s IL_0061 + + } // end handler + IL_0061: nop + .try + { + IL_0062: nop + IL_0063: ldstr "A.i: " + IL_0068: ldsfld int32 A::i + IL_006d: box [mscorlib]System.Int32 + IL_0072: call string [mscorlib]System.String::Concat(object, + object) + IL_0077: call void [System.Console]System.Console::WriteLine(string) + IL_007c: nop + IL_007d: ldstr "Did not catch expected TypeInitializationException" + + " exception" + IL_0082: call void [System.Console]System.Console::WriteLine(string) + IL_0087: nop + IL_0088: ldc.i4.0 + IL_0089: stloc.0 + IL_008a: nop + IL_008b: leave.s IL_00b5 + + } // end .try + catch [mscorlib]System.TypeInitializationException + { + IL_008d: pop + IL_008e: nop + IL_008f: ldstr "Caught expected exception 2nd time\n" + IL_0094: call void [System.Console]System.Console::WriteLine(string) + IL_0099: nop + IL_009a: nop + IL_009b: leave.s IL_00b5 + + } // end handler + catch [mscorlib]System.Exception + { + IL_009d: stloc.1 + IL_009e: nop + IL_009f: ldstr "Caught unexpected exception: " + IL_00a4: ldloc.1 + IL_00a5: call string [mscorlib]System.String::Concat(object, + object) + IL_00aa: call void [System.Console]System.Console::WriteLine(string) + IL_00af: nop + IL_00b0: ldc.i4.0 + IL_00b1: stloc.0 + IL_00b2: nop + IL_00b3: leave.s IL_00b5 + + } // end handler + IL_00b5: nop + IL_00b6: ldstr "Accessing struct's static field" + IL_00bb: call void [System.Console]System.Console::WriteLine(string) + IL_00c0: nop + .try + { + IL_00c1: nop + IL_00c2: ldstr "B.i: " + IL_00c7: ldsfld int32 B::i + IL_00cc: box [mscorlib]System.Int32 + IL_00d1: call string [mscorlib]System.String::Concat(object, + object) + IL_00d6: call void [System.Console]System.Console::WriteLine(string) + IL_00db: nop + IL_00dc: ldstr "Did not catch expected TypeInitializationException" + + " exception" + IL_00e1: call void [System.Console]System.Console::WriteLine(string) + IL_00e6: nop + IL_00e7: ldc.i4.0 + IL_00e8: stloc.0 + IL_00e9: nop + IL_00ea: leave.s IL_0114 + + } // end .try + catch [mscorlib]System.TypeInitializationException + { + IL_00ec: pop + IL_00ed: nop + IL_00ee: ldstr "Caught expected exception 1st time" + IL_00f3: call void [System.Console]System.Console::WriteLine(string) + IL_00f8: nop + IL_00f9: nop + IL_00fa: leave.s IL_0114 + + } // end handler + catch [mscorlib]System.Exception + { + IL_00fc: stloc.1 + IL_00fd: nop + IL_00fe: ldstr "Caught unexpected exception: " + IL_0103: ldloc.1 + IL_0104: call string [mscorlib]System.String::Concat(object, + object) + IL_0109: call void [System.Console]System.Console::WriteLine(string) + IL_010e: nop + IL_010f: ldc.i4.0 + IL_0110: stloc.0 + IL_0111: nop + IL_0112: leave.s IL_0114 + + } // end handler + IL_0114: nop + .try + { + IL_0115: nop + IL_0116: ldstr "B.i: " + IL_011b: ldsfld int32 B::i + IL_0120: box [mscorlib]System.Int32 + IL_0125: call string [mscorlib]System.String::Concat(object, + object) + IL_012a: call void [System.Console]System.Console::WriteLine(string) + IL_012f: nop + IL_0130: ldstr "Did not catch expected TypeInitializationException" + + " exception" + IL_0135: call void [System.Console]System.Console::WriteLine(string) + IL_013a: nop + IL_013b: ldc.i4.0 + IL_013c: stloc.0 + IL_013d: nop + IL_013e: leave.s IL_0168 + + } // end .try + catch [mscorlib]System.TypeInitializationException + { + IL_0140: pop + IL_0141: nop + IL_0142: ldstr "Caught expected exception 2nd time\n" + IL_0147: call void [System.Console]System.Console::WriteLine(string) + IL_014c: nop + IL_014d: nop + IL_014e: leave.s IL_0168 + + } // end handler + catch [mscorlib]System.Exception + { + IL_0150: stloc.1 + IL_0151: nop + IL_0152: ldstr "Caught unexpected exception: " + IL_0157: ldloc.1 + IL_0158: call string [mscorlib]System.String::Concat(object, + object) + IL_015d: call void [System.Console]System.Console::WriteLine(string) + IL_0162: nop + IL_0163: ldc.i4.0 + IL_0164: stloc.0 + IL_0165: nop + IL_0166: leave.s IL_0168 + + } // end handler + IL_0168: nop + IL_0169: ldloc.0 + IL_016a: ldc.i4.0 + IL_016b: ceq + IL_016d: stloc.3 + IL_016e: ldloc.3 + IL_016f: brtrue.s IL_0182 + + IL_0171: nop + IL_0172: ldstr "PASS" + IL_0177: call void [System.Console]System.Console::WriteLine(string) + IL_017c: nop + IL_017d: ldc.i4.s 100 + IL_017f: stloc.2 + IL_0180: br.s IL_0193 + + IL_0182: nop + IL_0183: ldstr "FAIL" + IL_0188: call void [System.Console]System.Console::WriteLine(string) + IL_018d: nop + IL_018e: ldc.i4.s 101 + IL_0190: stloc.2 + IL_0191: br.s IL_0193 + + IL_0193: ldloc.2 + IL_0194: ret + } // end of method Test::Main + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method Test::.ctor + +} // end of class Test + + +// ============================================================= + +// *********** DISASSEMBLY COMPLETE *********************** +// WARNING: Created Win32 resource file TypeLoadInitExcepBFI.res diff --git a/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowStaticFieldBFI.ilproj b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowStaticFieldBFI.ilproj new file mode 100644 index 0000000000..a4da803e17 --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowStaticFieldBFI.ilproj @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> + <PropertyGroup> + <AssemblyName>CctorThrowStaticFieldBFI</AssemblyName> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid> + <FileAlignment>512</FileAlignment> + <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> + <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp> + <AllowUnsafeBlocks>true</AllowUnsafeBlocks> + <ReferenceLocalMscorlib>true</ReferenceLocalMscorlib> + <OutputType>Exe</OutputType> + <CLRTestKind>BuildAndRun</CLRTestKind> + <CLRTestPriority>0</CLRTestPriority> + </PropertyGroup> + + <ItemGroup> + <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies"> + <Visible>False</Visible> + </CodeAnalysisDependentAssemblyPaths> + </ItemGroup> + + <ItemGroup> + <Compile Include="CctorThrowStaticFieldBFI.il" /> + </ItemGroup> + + <ItemGroup> + <None Include="app.config" /> + </ItemGroup> + + <ItemGroup> + <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" /> + </ItemGroup> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> +</Project> diff --git a/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/ResetGlobalFields.il b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/ResetGlobalFields.il new file mode 100644 index 0000000000..600fd14e9c --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/ResetGlobalFields.il @@ -0,0 +1,127 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +.assembly extern System.Console { } + +// Microsoft (R) .NET Framework IL Disassembler. Version 2.0.50110.00 +// Copyright (C) Microsoft Corporation. All rights reserved. + + + +// Metadata version: v2.0.50110 +.assembly extern mscorlib +{ + .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. + .ver 2:0:0:0 +} +.assembly ResetGlobalFields +{ + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module ResetGlobalFields.exe +// MVID: {7BF531CB-7206-4C53-A779-930294C1158F} +.imagebase 0x00400000 +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 // WINDOWS_CUI +.corflags 0x00000001 // ILONLY +// Image base: 0x03090000 + + +// =============== CLASS MEMBERS DECLARATION =================== + +.class public auto ansi A + extends [mscorlib]System.Object +{ + .field public static int32 s + .method public hidebysig specialname rtspecialname static + void .cctor() cil managed + { + // Code size 8 (0x8) + .maxstack 8 + IL_0000: nop + IL_0001: ldc.i4.5 + IL_0002: stsfld int32 A::s + IL_0007: ret + } // end of method A::.cctor + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method A::.ctor + +} // end of class A + +.class public auto ansi beforefieldinit Test + extends [mscorlib]System.Object +{ + .method public hidebysig static int32 Main() cil managed + { + .entrypoint + // Code size 61 (0x3d) + .maxstack 2 + .locals init (class A V_0, + int32 V_1, + bool V_2) + IL_0000: nop + IL_0001: newobj instance void A::.ctor() + IL_0006: stloc.0 + IL_0007: ldc.i4.0 + IL_0008: stsfld int32 A::s + + // call .cctor explicitly + // global static field should be reset + call void A::.cctor() + + IL_000d: ldsfld int32 A::s + IL_0012: ldc.i4.5 + IL_0013: ceq + IL_0015: stloc.2 + IL_0016: ldloc.2 + IL_0017: brtrue.s IL_002a + + IL_0019: nop + IL_001a: ldstr "FAIL: Global field wasn't reset" + IL_001f: call void [System.Console]System.Console::WriteLine(string) + IL_0024: nop + IL_0025: ldc.i4.s 101 + IL_0027: stloc.1 + IL_0028: br.s IL_003b + + IL_002a: nop + IL_002b: ldstr "PASS: Global field was reset" + IL_0030: call void [System.Console]System.Console::WriteLine(string) + IL_0035: nop + IL_0036: ldc.i4.s 100 + IL_0038: stloc.1 + IL_0039: br.s IL_003b + + IL_003b: ldloc.1 + IL_003c: ret + } // end of method Test::Main + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method Test::.ctor + +} // end of class Test + + +// ============================================================= + +// *********** DISASSEMBLY COMPLETE *********************** +// WARNING: Created Win32 resource file ResetGlobalFields.res diff --git a/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/ResetGlobalFields.ilproj b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/ResetGlobalFields.ilproj new file mode 100644 index 0000000000..31e9c8550c --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/ResetGlobalFields.ilproj @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> + <PropertyGroup> + <AssemblyName>ResetGlobalFields</AssemblyName> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid> + <FileAlignment>512</FileAlignment> + <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> + <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp> + <AllowUnsafeBlocks>true</AllowUnsafeBlocks> + <ReferenceLocalMscorlib>true</ReferenceLocalMscorlib> + <OutputType>Exe</OutputType> + <CLRTestKind>BuildAndRun</CLRTestKind> + <CLRTestPriority>0</CLRTestPriority> + </PropertyGroup> + + <ItemGroup> + <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies"> + <Visible>False</Visible> + </CodeAnalysisDependentAssemblyPaths> + </ItemGroup> + + <ItemGroup> + <Compile Include="ResetGlobalFields.il" /> + </ItemGroup> + + <ItemGroup> + <None Include="app.config" /> + </ItemGroup> + + <ItemGroup> + <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" /> + </ItemGroup> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> +</Project> diff --git a/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/TypeLoadInitExcep.cs b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/TypeLoadInitExcep.cs new file mode 100644 index 0000000000..859318e598 --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/TypeLoadInitExcep.cs @@ -0,0 +1,136 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/* + +A .cctor has only one chance to run in any appdomain. +If it fails, the 2nd time we try to access a static field we check if .cctor has been run. And it has, but failed so we fail again. + +Test throws an exception inside .cctor. +Try to access a static field twice. +Expected: Should return the same exception. + +*/ + +using System; + + +public class A +{ + public static int i; + + static A() + { + Console.WriteLine("In A.cctor"); + + A.i = 5; + + throw new Exception(); + } +} + + +public struct B +{ + public static int i; + + static B() + { + Console.WriteLine("In B.cctor"); + + B.i = 5; + + throw new Exception(); + } +} + + +public class Test +{ + public static int Main() + { + bool result = true; + + try + { + Console.WriteLine("Accessing class's static field"); + Console.WriteLine("A.i: " +A.i); + Console.WriteLine("Did not catch expected TypeInitializationException exception"); + result = false; + } + catch (TypeInitializationException) + { + Console.WriteLine("Caught expected exception 1st time"); + } + catch (Exception e) + { + Console.WriteLine("Caught unexpected exception 1st time: " + e); + result = false; + } + + + try + { + Console.WriteLine("A.i: " +A.i); + Console.WriteLine("Did not catch expected TypeInitializationException exception"); + result = false; + } + catch (TypeInitializationException) + { + Console.WriteLine("Caught expected exception 2nd time\n"); + } + catch (Exception e) + { + Console.WriteLine("Caught unexpected exception 2nd time: " + e); + result = false; + } + + + Console.WriteLine("Accessing struct's static field"); + try + { + Console.WriteLine("B.i: " +B.i); + Console.WriteLine("Did not catch expected TypeInitializationException exception"); + result = false; + } + catch (TypeInitializationException) + { + Console.WriteLine("Caught expected exception 1st time"); + } + catch (Exception e) + { + Console.WriteLine("Caught unexpected exception 1st time: " + e); + result = false; + } + + + try + { + Console.WriteLine("B.i: " +B.i); + Console.WriteLine("Did not catch expected TypeInitializationException exception"); + result = false; + } + catch (TypeInitializationException) + { + Console.WriteLine("Caught expected exception 2nd time\n"); + } + catch (Exception e) + { + Console.WriteLine("Caught unexpected exception 2nd time: " + e); + result = false; + } + + if (result) + { + Console.WriteLine("PASS"); + return 100; + } + else + { + Console.WriteLine("FAIL"); + return 101; + } + + } +} diff --git a/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/TypeLoadInitExcep.csproj b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/TypeLoadInitExcep.csproj new file mode 100644 index 0000000000..4063ef5e3c --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/TypeLoadInitExcep.csproj @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> + <PropertyGroup> + <AssemblyName>TypeLoadInitExcep</AssemblyName> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid> + <FileAlignment>512</FileAlignment> + <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> + <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp> + <AllowUnsafeBlocks>true</AllowUnsafeBlocks> + <ReferenceLocalMscorlib>false</ReferenceLocalMscorlib> + <OutputType>Exe</OutputType> + <CLRTestKind>BuildAndRun</CLRTestKind> + <CLRTestPriority>0</CLRTestPriority> + </PropertyGroup> + + <ItemGroup> + <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies"> + <Visible>False</Visible> + </CodeAnalysisDependentAssemblyPaths> + </ItemGroup> + + <ItemGroup> + <Compile Include="TypeLoadInitExcep.cs" /> + </ItemGroup> + + <ItemGroup> + <None Include="app.config" /> + <None Include="project.json" /> + </ItemGroup> + + <ItemGroup> + <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" /> + </ItemGroup> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> +</Project> diff --git a/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/TypeLoadInitExcepBFI.il b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/TypeLoadInitExcepBFI.il new file mode 100644 index 0000000000..c0e0b14647 --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/TypeLoadInitExcepBFI.il @@ -0,0 +1,346 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +.assembly extern System.Console { } + +// Microsoft (R) .NET Framework IL Disassembler. Version 2.0.50103.00 +// Copyright (C) Microsoft Corporation. All rights reserved. + + + +// Metadata version: v2.0.50103 +.assembly extern mscorlib +{ + .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. + .ver 2:0:0:0 +} +.assembly TypeLoadInitExcep +{ + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module TypeLoadInitExcep.exe +// MVID: {A7BE6B3C-FF8D-43DB-B091-60CBA24AD082} +.imagebase 0x00400000 +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 // WINDOWS_CUI +.corflags 0x00000001 // ILONLY +// Image base: 0x03090000 + + +// =============== CLASS MEMBERS DECLARATION =================== + +.class public auto ansi beforefieldinit A + extends [mscorlib]System.Object +{ + .field public static int32 i + .method private hidebysig specialname rtspecialname static + void .cctor() cil managed + { + // Code size 24 (0x18) + .maxstack 8 + IL_0000: nop + IL_0001: ldstr "In A.cctor" + IL_0006: call void [System.Console]System.Console::WriteLine(string) + IL_000b: nop + IL_000c: ldc.i4.5 + IL_000d: stsfld int32 A::i + IL_0012: newobj instance void [mscorlib]System.Exception::.ctor() + IL_0017: throw + } // end of method A::.cctor + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method A::.ctor + +} // end of class A + +.class public sequential ansi sealed B + extends [mscorlib]System.ValueType +{ + .pack 0 + .size 1 + .field public static int32 i + .method private hidebysig specialname rtspecialname static + void .cctor() cil managed + { + // Code size 24 (0x18) + .maxstack 8 + IL_0000: nop + IL_0001: ldstr "In B.cctor" + IL_0006: call void [System.Console]System.Console::WriteLine(string) + IL_000b: nop + IL_000c: ldc.i4.5 + IL_000d: stsfld int32 B::i + IL_0012: newobj instance void [mscorlib]System.Exception::.ctor() + IL_0017: throw + } // end of method B::.cctor + +} // end of class B + +.class public auto ansi beforefieldinit Test + extends [mscorlib]System.Object +{ + .method public hidebysig static int32 Main() cil managed + { + .entrypoint + // Code size 405 (0x195) + .maxstack 2 + .locals init (bool V_0, + class [mscorlib]System.Exception V_1, + int32 V_2, + bool V_3) + IL_0000: nop + IL_0001: ldc.i4.1 + IL_0002: stloc.0 + .try + { + IL_0003: nop + IL_0004: ldstr "Accessing class's static field" + IL_0009: call void [System.Console]System.Console::WriteLine(string) + IL_000e: nop + IL_000f: ldstr "A.i: " + IL_0014: ldsfld int32 A::i + IL_0019: box [mscorlib]System.Int32 + IL_001e: call string [mscorlib]System.String::Concat(object, + object) + IL_0023: call void [System.Console]System.Console::WriteLine(string) + IL_0028: nop + IL_0029: ldstr "Did not catch expected TypeInitializationException" + + " exception" + IL_002e: call void [System.Console]System.Console::WriteLine(string) + IL_0033: nop + IL_0034: ldc.i4.0 + IL_0035: stloc.0 + IL_0036: nop + IL_0037: leave.s IL_0061 + + } // end .try + catch [mscorlib]System.TypeInitializationException + { + IL_0039: pop + IL_003a: nop + IL_003b: ldstr "Caught expected exception 1st time" + IL_0040: call void [System.Console]System.Console::WriteLine(string) + IL_0045: nop + IL_0046: nop + IL_0047: leave.s IL_0061 + + } // end handler + catch [mscorlib]System.Exception + { + IL_0049: stloc.1 + IL_004a: nop + IL_004b: ldstr "Caught unexpected exception: " + IL_0050: ldloc.1 + IL_0051: call string [mscorlib]System.String::Concat(object, + object) + IL_0056: call void [System.Console]System.Console::WriteLine(string) + IL_005b: nop + IL_005c: ldc.i4.0 + IL_005d: stloc.0 + IL_005e: nop + IL_005f: leave.s IL_0061 + + } // end handler + IL_0061: nop + .try + { + IL_0062: nop + IL_0063: ldstr "A.i: " + IL_0068: ldsfld int32 A::i + IL_006d: box [mscorlib]System.Int32 + IL_0072: call string [mscorlib]System.String::Concat(object, + object) + IL_0077: call void [System.Console]System.Console::WriteLine(string) + IL_007c: nop + IL_007d: ldstr "Did not catch expected TypeInitializationException" + + " exception" + IL_0082: call void [System.Console]System.Console::WriteLine(string) + IL_0087: nop + IL_0088: ldc.i4.0 + IL_0089: stloc.0 + IL_008a: nop + IL_008b: leave.s IL_00b5 + + } // end .try + catch [mscorlib]System.TypeInitializationException + { + IL_008d: pop + IL_008e: nop + IL_008f: ldstr "Caught expected exception 2nd time\n" + IL_0094: call void [System.Console]System.Console::WriteLine(string) + IL_0099: nop + IL_009a: nop + IL_009b: leave.s IL_00b5 + + } // end handler + catch [mscorlib]System.Exception + { + IL_009d: stloc.1 + IL_009e: nop + IL_009f: ldstr "Caught unexpected exception: " + IL_00a4: ldloc.1 + IL_00a5: call string [mscorlib]System.String::Concat(object, + object) + IL_00aa: call void [System.Console]System.Console::WriteLine(string) + IL_00af: nop + IL_00b0: ldc.i4.0 + IL_00b1: stloc.0 + IL_00b2: nop + IL_00b3: leave.s IL_00b5 + + } // end handler + IL_00b5: nop + IL_00b6: ldstr "Accessing struct's static field" + IL_00bb: call void [System.Console]System.Console::WriteLine(string) + IL_00c0: nop + .try + { + IL_00c1: nop + IL_00c2: ldstr "B.i: " + IL_00c7: ldsfld int32 B::i + IL_00cc: box [mscorlib]System.Int32 + IL_00d1: call string [mscorlib]System.String::Concat(object, + object) + IL_00d6: call void [System.Console]System.Console::WriteLine(string) + IL_00db: nop + IL_00dc: ldstr "Did not catch expected TypeInitializationException" + + " exception" + IL_00e1: call void [System.Console]System.Console::WriteLine(string) + IL_00e6: nop + IL_00e7: ldc.i4.0 + IL_00e8: stloc.0 + IL_00e9: nop + IL_00ea: leave.s IL_0114 + + } // end .try + catch [mscorlib]System.TypeInitializationException + { + IL_00ec: pop + IL_00ed: nop + IL_00ee: ldstr "Caught expected exception 1st time" + IL_00f3: call void [System.Console]System.Console::WriteLine(string) + IL_00f8: nop + IL_00f9: nop + IL_00fa: leave.s IL_0114 + + } // end handler + catch [mscorlib]System.Exception + { + IL_00fc: stloc.1 + IL_00fd: nop + IL_00fe: ldstr "Caught unexpected exception: " + IL_0103: ldloc.1 + IL_0104: call string [mscorlib]System.String::Concat(object, + object) + IL_0109: call void [System.Console]System.Console::WriteLine(string) + IL_010e: nop + IL_010f: ldc.i4.0 + IL_0110: stloc.0 + IL_0111: nop + IL_0112: leave.s IL_0114 + + } // end handler + IL_0114: nop + .try + { + IL_0115: nop + IL_0116: ldstr "B.i: " + IL_011b: ldsfld int32 B::i + IL_0120: box [mscorlib]System.Int32 + IL_0125: call string [mscorlib]System.String::Concat(object, + object) + IL_012a: call void [System.Console]System.Console::WriteLine(string) + IL_012f: nop + IL_0130: ldstr "Did not catch expected TypeInitializationException" + + " exception" + IL_0135: call void [System.Console]System.Console::WriteLine(string) + IL_013a: nop + IL_013b: ldc.i4.0 + IL_013c: stloc.0 + IL_013d: nop + IL_013e: leave.s IL_0168 + + } // end .try + catch [mscorlib]System.TypeInitializationException + { + IL_0140: pop + IL_0141: nop + IL_0142: ldstr "Caught expected exception 2nd time\n" + IL_0147: call void [System.Console]System.Console::WriteLine(string) + IL_014c: nop + IL_014d: nop + IL_014e: leave.s IL_0168 + + } // end handler + catch [mscorlib]System.Exception + { + IL_0150: stloc.1 + IL_0151: nop + IL_0152: ldstr "Caught unexpected exception: " + IL_0157: ldloc.1 + IL_0158: call string [mscorlib]System.String::Concat(object, + object) + IL_015d: call void [System.Console]System.Console::WriteLine(string) + IL_0162: nop + IL_0163: ldc.i4.0 + IL_0164: stloc.0 + IL_0165: nop + IL_0166: leave.s IL_0168 + + } // end handler + IL_0168: nop + IL_0169: ldloc.0 + IL_016a: ldc.i4.0 + IL_016b: ceq + IL_016d: stloc.3 + IL_016e: ldloc.3 + IL_016f: brtrue.s IL_0182 + + IL_0171: nop + IL_0172: ldstr "PASS" + IL_0177: call void [System.Console]System.Console::WriteLine(string) + IL_017c: nop + IL_017d: ldc.i4.s 100 + IL_017f: stloc.2 + IL_0180: br.s IL_0193 + + IL_0182: nop + IL_0183: ldstr "FAIL" + IL_0188: call void [System.Console]System.Console::WriteLine(string) + IL_018d: nop + IL_018e: ldc.i4.s 101 + IL_0190: stloc.2 + IL_0191: br.s IL_0193 + + IL_0193: ldloc.2 + IL_0194: ret + } // end of method Test::Main + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method Test::.ctor + +} // end of class Test + + +// ============================================================= + +// *********** DISASSEMBLY COMPLETE *********************** +// WARNING: Created Win32 resource file TypeLoadInitExcepBFI.res diff --git a/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/TypeLoadInitExcepBFI.ilproj b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/TypeLoadInitExcepBFI.ilproj new file mode 100644 index 0000000000..0f595c65c8 --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/TypeLoadInitExcepBFI.ilproj @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> + <PropertyGroup> + <AssemblyName>TypeLoadInitExcepBFI</AssemblyName> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid> + <FileAlignment>512</FileAlignment> + <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> + <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp> + <AllowUnsafeBlocks>true</AllowUnsafeBlocks> + <ReferenceLocalMscorlib>true</ReferenceLocalMscorlib> + <OutputType>Exe</OutputType> + <CLRTestKind>BuildAndRun</CLRTestKind> + <CLRTestPriority>0</CLRTestPriority> + </PropertyGroup> + + <ItemGroup> + <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies"> + <Visible>False</Visible> + </CodeAnalysisDependentAssemblyPaths> + </ItemGroup> + + <ItemGroup> + <Compile Include="TypeLoadInitExcepBFI.il" /> + </ItemGroup> + + <ItemGroup> + <None Include="app.config" /> + </ItemGroup> + + <ItemGroup> + <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" /> + </ItemGroup> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> +</Project> diff --git a/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/UntrustedCodeBFI.il b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/UntrustedCodeBFI.il new file mode 100644 index 0000000000..217be15789 --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/UntrustedCodeBFI.il @@ -0,0 +1,200 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +.assembly extern System.Console { } + + +.assembly extern mscorlib {} + +.assembly UntrustedCodeBFI {} + + +.class public auto ansi beforefieldinit B + extends [mscorlib]System.Object +{ + .field public static class C c_field + .method private hidebysig specialname rtspecialname static + void .cctor() cil managed + { + // Code size 50 (0x32) + .maxstack 2 + .locals init (class [mscorlib]System.Exception V_0) + IL_0000: nop + .try + { + IL_0001: nop + IL_0002: ldstr "In B.cctor" + IL_0007: call void [System.Console]System.Console::WriteLine(string) + IL_000c: nop + IL_000d: newobj instance void C::.ctor() + IL_0012: stsfld class C B::c_field + IL_0017: nop + IL_0018: leave.s IL_0030 + + } // end .try + catch [mscorlib]System.Exception + { + IL_001a: stloc.0 + IL_001b: nop + IL_001c: ldstr "PASS: Caught exception : " + IL_0021: ldloc.0 + IL_0022: call string [mscorlib]System.String::Concat(object, + object) + IL_0027: call void [System.Console]System.Console::WriteLine(string) + IL_002c: nop + IL_002d: nop + IL_002e: leave.s IL_0030 + + } // end handler + IL_0030: nop + IL_0031: ret + } // end of method B::.cctor + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method B::.ctor + +} // end of class B + +.class public auto ansi beforefieldinit C + extends [mscorlib]System.Object +{ + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 22 (0x16) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: nop + IL_0007: nop + IL_0008: ldc.i4.1 + IL_0009: newobj instance void [mscorlib]System.Security.Permissions.FileIOPermission::.ctor(valuetype [mscorlib]System.Security.Permissions.PermissionState) + IL_000e: call instance void [mscorlib]System.Security.CodeAccessPermission::Demand() + IL_0013: nop + IL_0014: nop + IL_0015: ret + } // end of method C::.ctor + +} // end of class C + +.class public auto ansi beforefieldinit Test + extends [mscorlib]System.Object +{ + .method public hidebysig static int32 Main() cil managed + { + .entrypoint + // Code size 98 (0x62) + .maxstack 2 + .locals init (class B V_0, + class A V_1, + class [mscorlib]System.Exception V_2, + int32 V_3) + IL_0000: nop + .try + { + IL_0001: nop + IL_0002: newobj instance void B::.ctor() + IL_0007: stloc.0 + IL_0008: newobj instance void A::.ctor() + IL_000d: stloc.1 + IL_000e: ldloc.1 + IL_000f: callvirt instance void A::methodA() + IL_0014: nop + IL_0015: ldsfld class C B::c_field + IL_001a: callvirt instance string [mscorlib]System.Object::ToString() + IL_001f: call void [System.Console]System.Console::WriteLine(string) + IL_0024: nop + IL_0025: ldstr "FAIL: Did not catch NullReferenceException expecte" + + "d exception" + IL_002a: call void [System.Console]System.Console::WriteLine(string) + IL_002f: nop + IL_0030: ldc.i4.s 101 + IL_0032: stloc.3 + IL_0033: leave.s IL_005f + + } // end .try + catch [mscorlib]System.NullReferenceException + { + IL_0035: pop + IL_0036: nop + IL_0037: ldstr "PASS: Caught expected NullReferenceException" + IL_003c: call void [System.Console]System.Console::WriteLine(string) + IL_0041: nop + IL_0042: ldc.i4.s 100 + IL_0044: stloc.3 + IL_0045: leave.s IL_005f + + } // end handler + catch [mscorlib]System.Exception + { + IL_0047: stloc.2 + IL_0048: nop + IL_0049: ldstr "PASS: Caught exception : " + IL_004e: ldloc.2 + IL_004f: call string [mscorlib]System.String::Concat(object, + object) + IL_0054: call void [System.Console]System.Console::WriteLine(string) + IL_0059: nop + IL_005a: ldc.i4.s 100 + IL_005c: stloc.3 + IL_005d: leave.s IL_005f + + } // end handler + IL_005f: nop + IL_0060: ldloc.3 + IL_0061: ret + } // end of method Test::Main + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method Test::.ctor + +} // end of class Test + +.class public auto ansi beforefieldinit A + extends [mscorlib]System.Object +{ + .permissionset deny + = {[mscorlib]System.Security.Permissions.FileIOPermissionAttribute = {property bool 'Unrestricted' = bool(true)}} + .method public hidebysig instance void + methodA() cil managed + { + // Code size 8 (0x8) + .maxstack 8 + IL_0000: nop + IL_0001: ldnull + IL_0002: stsfld class C B::c_field + IL_0007: ret + } // end of method A::methodA + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method A::.ctor + +} // end of class A + + +// ============================================================= + +// *********** DISASSEMBLY COMPLETE *********************** +// WARNING: Created Win32 resource file UntrustedCodeBFI.res diff --git a/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/UntrustedCodeBFI.ilproj b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/UntrustedCodeBFI.ilproj new file mode 100644 index 0000000000..53327a9555 --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/UntrustedCodeBFI.ilproj @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> + <PropertyGroup> + <AssemblyName>UntrustedCodeBFI</AssemblyName> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid> + <FileAlignment>512</FileAlignment> + <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> + <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp> + <AllowUnsafeBlocks>true</AllowUnsafeBlocks> + <ReferenceLocalMscorlib>true</ReferenceLocalMscorlib> + <OutputType>Exe</OutputType> + <CLRTestKind>BuildAndRun</CLRTestKind> + <CLRTestPriority>0</CLRTestPriority> + </PropertyGroup> + + <ItemGroup> + <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies"> + <Visible>False</Visible> + </CodeAnalysisDependentAssemblyPaths> + </ItemGroup> + + <ItemGroup> + <Compile Include="UntrustedCodeBFI.il" /> + </ItemGroup> + + <ItemGroup> + <None Include="app.config" /> + </ItemGroup> + + <ItemGroup> + <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" /> + </ItemGroup> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> +</Project> diff --git a/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/app.config b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/app.config new file mode 100644 index 0000000000..e5622f77ad --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/app.config @@ -0,0 +1,27 @@ +<?xml version = "1.0" encoding="utf-8"?> +<configuration> + <runtime> + <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> + <dependentAssembly> + <assemblyIdentity name="System.Runtime" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.20.0" newVersion="4.0.20.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.Text.Encoding" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.10.0" newVersion="4.0.10.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.Threading.Tasks" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.10.0" newVersion="4.0.10.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.IO" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.10.0" newVersion="4.0.10.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.Reflection" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.10.0" newVersion="4.0.10.0" /> + </dependentAssembly> + </assemblyBinding> + </runtime> +</configuration> diff --git a/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/project.json b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/project.json new file mode 100644 index 0000000000..a2e84dc340 --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/project.json @@ -0,0 +1,35 @@ +{ + "dependencies": { + "Microsoft.NETCore.Platforms": "1.0.1-rc2-23816", + "System.Collections": "4.0.10", + "System.Collections.NonGeneric": "4.0.1-rc2-23816", + "System.Collections.Specialized": "4.0.1-rc2-23816", + "System.ComponentModel": "4.0.1-rc2-23816", + "System.Console": "4.0.0-rc2-23816", + "System.Diagnostics.Process": "4.1.0-rc2-23816", + "System.Globalization": "4.0.10", + "System.Globalization.Calendars": "4.0.0", + "System.IO": "4.0.10", + "System.IO.FileSystem": "4.0.0", + "System.IO.FileSystem.Primitives": "4.0.0", + "System.Linq": "4.0.1-rc2-23816", + "System.Linq.Queryable": "4.0.1-rc2-23816", + "System.Reflection": "4.0.10", + "System.Reflection.Primitives": "4.0.0", + "System.Runtime": "4.1.0-rc2-23816", + "System.Runtime.Extensions": "4.0.10", + "System.Runtime.Handles": "4.0.0", + "System.Runtime.InteropServices": "4.1.0-rc2-23816", + "System.Runtime.Loader": "4.0.0-rc2-23816", + "System.Text.Encoding": "4.0.10", + "System.Threading": "4.0.10", + "System.Threading.Thread": "4.0.0-rc2-23816", + "System.Xml.ReaderWriter": "4.0.11-rc2-23816", + "System.Xml.XDocument": "4.0.11-rc2-23816", + "System.Xml.XmlDocument": "4.0.1-rc2-23816", + "System.Xml.XmlSerializer": "4.0.11-rc2-23816" + }, + "frameworks": { + "dnxcore50": {} + } +} diff --git a/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorFourThreads.cs b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorFourThreads.cs new file mode 100644 index 0000000000..6e0da6a922 --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorFourThreads.cs @@ -0,0 +1,192 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// A --> B --> C --> D --> E --> A +// We should detect the deadlock and allow one thread to proceed (and see unitialized state). +/* +A --> B --> C --> D --> E --> A +4 threads: +Thread T1 starts initialization at A +Thread T2 starts initialization at C +Thread T3 starts initialization at D +Thread T4 starts initialization at E + +A::.cctor sleeps for a few seconds so Thread T1 is blocked. +C::.cctor sleeps for a few seconds so Thread T2 is blocked. +D::.cctor sleeps for a few seconds so Thread T3 is blocked. + +In D.cctor: thread T3: E.i 0 +In C.cctor: thread T2: D.i 8 +In B.cctor: thread T1: C.i 7 +In A.cctor: thread T1: B.i 6 +In E.cctor: thread T4: A.i 5 +*/ + +using System; +using System.Threading; +using System.Runtime.CompilerServices; +public struct A +{ + public static int i; + + static A() + { + Thread.Sleep(1000*2); // 1 second + Console.WriteLine("In A.cctor: thread {0}: B.i {1}",Thread.CurrentThread.Name,B.i); + A.i = 5; + } + + // invoking this should trigger the cctor + [MethodImpl(MethodImplOptions.NoInlining)] + public static void SomeMethod() + { + Console.WriteLine("In MyClass.SomeMethod(): thread {0}",Thread.CurrentThread.Name); + } + +} + +public class B +{ + public static int i; + + static B() + { + Console.WriteLine("In B.cctor: thread {0}: C.i {1}",Thread.CurrentThread.Name,C.i); + + B.i = 6; + } + + // invoking this should trigger the cctor + [MethodImpl(MethodImplOptions.NoInlining)] + public static void SomeMethod() + { + Console.WriteLine("In MyClass.SomeMethod(): thread {0}",Thread.CurrentThread.Name); + } + +} + +public struct C +{ + public static int i; + + static C() + { + Thread.Sleep(1000*2); // 1 second + Console.WriteLine("In C.cctor: thread {0}: D.i {1}",Thread.CurrentThread.Name,D.i); + C.i = 7; + } + + // invoking this should trigger the cctor + [MethodImpl(MethodImplOptions.NoInlining)] + public static void SomeMethod() + { + Console.WriteLine("In MyClass.SomeMethod(): thread {0}",Thread.CurrentThread.Name); + } + +} + +public class D +{ + public static int i; + + static D() + { + Thread.Sleep(1000*5); // 1 second + Console.WriteLine("In D.cctor: thread {0}: E.i {1}",Thread.CurrentThread.Name,E.i); + D.i = 8; + } + + // invoking this should trigger the cctor + [MethodImpl(MethodImplOptions.NoInlining)] + public static void SomeMethod() + { + Console.WriteLine("In MyClass.SomeMethod(): thread {0}",Thread.CurrentThread.Name); + } + +} + +public struct E +{ + public static int i; + + static E() + { + + Console.WriteLine("In E.cctor: thread {0}: A.i {1}",Thread.CurrentThread.Name,A.i); + E.i = 9; + } + + // invoking this should trigger the cctor + [MethodImpl(MethodImplOptions.NoInlining)] + public static void SomeMethod() + { + Console.WriteLine("In MyClass.SomeMethod(): thread {0}",Thread.CurrentThread.Name); + } + +} + +public class Test +{ + + public static void RunGetA() + { + A.SomeMethod(); + } + + public static void RunGetC() + { + C.SomeMethod(); + } + + public static void RunGetD() + { + D.SomeMethod(); + } + + public static void RunGetE() + { + E.SomeMethod(); + } + + + public static int Main() + { + + Thread t1 = new Thread(RunGetA); + t1.Name = "T1"; + Thread t2 = new Thread(RunGetC); + t2.Name = "T2"; + Thread t3 = new Thread(RunGetD); + t3.Name = "T3"; + Thread t4 = new Thread(RunGetE); + t4.Name = "T4"; + + + + t1.Start(); + Thread.Sleep(1000*1); // 1 second + t2.Start(); + Thread.Sleep(1000*1); // 1 second + t3.Start(); + Thread.Sleep(1000*1); // 1 second + t4.Start(); + + t4.Join(); + t3.Join(); + t2.Join(); + t1.Join(); + + // make sure that statics were set correctly. + if ( A.i == 5 && B.i == 6 && C.i == 7 && D.i == 8 && E.i == 9 ) + { + Console.WriteLine("PASS"); + return 100; + } + else + { + Console.WriteLine("FAIL"); + return 101; + } + } +} diff --git a/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorFourThreads.csproj b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorFourThreads.csproj new file mode 100644 index 0000000000..4bf998c50a --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorFourThreads.csproj @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> + <PropertyGroup> + <AssemblyName>CircularCctorFourThreads</AssemblyName> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid> + <FileAlignment>512</FileAlignment> + <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> + <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp> + <AllowUnsafeBlocks>true</AllowUnsafeBlocks> + <ReferenceLocalMscorlib>false</ReferenceLocalMscorlib> + <OutputType>Exe</OutputType> + <CLRTestKind>BuildAndRun</CLRTestKind> + <CLRTestPriority>0</CLRTestPriority> + </PropertyGroup> + + <ItemGroup> + <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies"> + <Visible>False</Visible> + </CodeAnalysisDependentAssemblyPaths> + </ItemGroup> + + <ItemGroup> + <Compile Include="CircularCctorFourThreads.cs" /> + </ItemGroup> + + <ItemGroup> + <None Include="app.config" /> + <None Include="project.json" /> + </ItemGroup> + + <ItemGroup> + <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" /> + </ItemGroup> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> +</Project> diff --git a/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorFourThreadsBFI.il b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorFourThreadsBFI.il new file mode 100644 index 0000000000..f567de543f --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorFourThreadsBFI.il @@ -0,0 +1,463 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +.assembly extern System.Console { } + +// Microsoft (R) .NET Framework IL Disassembler. Version 2.0.50103.00 +// Copyright (C) Microsoft Corporation. All rights reserved. + + + +// Metadata version: v2.0.50103 +.assembly extern mscorlib +{ + .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. + .ver 2:0:0:0 +} +.assembly CircularCctorFourThreads +{ + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module CircularCctorFourThreads.exe +// MVID: {DCC29B4C-2098-4C6E-A788-8284AF4F4942} +.imagebase 0x00400000 +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 // WINDOWS_CUI +.corflags 0x00000001 // ILONLY +// Image base: 0x03090000 + + +// =============== CLASS MEMBERS DECLARATION =================== + +.class public sequential ansi sealed beforefieldinit A + extends [mscorlib]System.ValueType +{ + .pack 0 + .size 1 + .field public static int32 i + .method private hidebysig specialname rtspecialname static + void .cctor() cil managed + { + // Code size 50 (0x32) + .maxstack 8 + IL_0000: nop + IL_0001: ldc.i4 0x7d0 + IL_0006: call void [mscorlib]System.Threading.Thread::Sleep(int32) + IL_000b: nop + IL_000c: ldstr "In A.cctor: thread {0}: B.i {1}" + IL_0011: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread() + IL_0016: callvirt instance string [mscorlib]System.Threading.Thread::get_Name() + IL_001b: ldsfld int32 B::i + IL_0020: box [mscorlib]System.Int32 + IL_0025: call void [System.Console]System.Console::WriteLine(string, + object, + object) + IL_002a: nop + IL_002b: ldc.i4.5 + IL_002c: stsfld int32 A::i + IL_0031: ret + } // end of method A::.cctor + + .method public hidebysig static void SomeMethod() cil managed noinlining + { + // Code size 23 (0x17) + .maxstack 8 + IL_0000: nop + IL_0001: ldstr "In MyClass.SomeMethod(): thread {0}" + IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread() + IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name() + IL_0010: call void [System.Console]System.Console::WriteLine(string, + object) + IL_0015: nop + IL_0016: ret + } // end of method A::SomeMethod + +} // end of class A + +.class public auto ansi beforefieldinit B + extends [mscorlib]System.Object +{ + .field public static int32 i + .method private hidebysig specialname rtspecialname static + void .cctor() cil managed + { + // Code size 39 (0x27) + .maxstack 8 + IL_0000: nop + IL_0001: ldstr "In B.cctor: thread {0}: C.i {1}" + IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread() + IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name() + IL_0010: ldsfld int32 C::i + IL_0015: box [mscorlib]System.Int32 + IL_001a: call void [System.Console]System.Console::WriteLine(string, + object, + object) + IL_001f: nop + IL_0020: ldc.i4.6 + IL_0021: stsfld int32 B::i + IL_0026: ret + } // end of method B::.cctor + + .method public hidebysig static void SomeMethod() cil managed noinlining + { + // Code size 23 (0x17) + .maxstack 8 + IL_0000: nop + IL_0001: ldstr "In MyClass.SomeMethod(): thread {0}" + IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread() + IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name() + IL_0010: call void [System.Console]System.Console::WriteLine(string, + object) + IL_0015: nop + IL_0016: ret + } // end of method B::SomeMethod + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method B::.ctor + +} // end of class B + +.class public sequential ansi sealed beforefieldinit C + extends [mscorlib]System.ValueType +{ + .pack 0 + .size 1 + .field public static int32 i + .method private hidebysig specialname rtspecialname static + void .cctor() cil managed + { + // Code size 50 (0x32) + .maxstack 8 + IL_0000: nop + IL_0001: ldc.i4 0x7d0 + IL_0006: call void [mscorlib]System.Threading.Thread::Sleep(int32) + IL_000b: nop + IL_000c: ldstr "In C.cctor: thread {0}: D.i {1}" + IL_0011: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread() + IL_0016: callvirt instance string [mscorlib]System.Threading.Thread::get_Name() + IL_001b: ldsfld int32 D::i + IL_0020: box [mscorlib]System.Int32 + IL_0025: call void [System.Console]System.Console::WriteLine(string, + object, + object) + IL_002a: nop + IL_002b: ldc.i4.7 + IL_002c: stsfld int32 C::i + IL_0031: ret + } // end of method C::.cctor + + .method public hidebysig static void SomeMethod() cil managed noinlining + { + // Code size 23 (0x17) + .maxstack 8 + IL_0000: nop + IL_0001: ldstr "In MyClass.SomeMethod(): thread {0}" + IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread() + IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name() + IL_0010: call void [System.Console]System.Console::WriteLine(string, + object) + IL_0015: nop + IL_0016: ret + } // end of method C::SomeMethod + +} // end of class C + +.class public auto ansi beforefieldinit D + extends [mscorlib]System.Object +{ + .field public static int32 i + .method private hidebysig specialname rtspecialname static + void .cctor() cil managed + { + // Code size 50 (0x32) + .maxstack 8 + IL_0000: nop + IL_0001: ldc.i4 0x1388 + IL_0006: call void [mscorlib]System.Threading.Thread::Sleep(int32) + IL_000b: nop + IL_000c: ldstr "In D.cctor: thread {0}: E.i {1}" + IL_0011: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread() + IL_0016: callvirt instance string [mscorlib]System.Threading.Thread::get_Name() + IL_001b: ldsfld int32 E::i + IL_0020: box [mscorlib]System.Int32 + IL_0025: call void [System.Console]System.Console::WriteLine(string, + object, + object) + IL_002a: nop + IL_002b: ldc.i4.8 + IL_002c: stsfld int32 D::i + IL_0031: ret + } // end of method D::.cctor + + .method public hidebysig static void SomeMethod() cil managed noinlining + { + // Code size 23 (0x17) + .maxstack 8 + IL_0000: nop + IL_0001: ldstr "In MyClass.SomeMethod(): thread {0}" + IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread() + IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name() + IL_0010: call void [System.Console]System.Console::WriteLine(string, + object) + IL_0015: nop + IL_0016: ret + } // end of method D::SomeMethod + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method D::.ctor + +} // end of class D + +.class public sequential ansi sealed beforefieldinit E + extends [mscorlib]System.ValueType +{ + .pack 0 + .size 1 + .field public static int32 i + .method private hidebysig specialname rtspecialname static + void .cctor() cil managed + { + // Code size 40 (0x28) + .maxstack 8 + IL_0000: nop + IL_0001: ldstr "In E.cctor: thread {0}: A.i {1}" + IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread() + IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name() + IL_0010: ldsfld int32 A::i + IL_0015: box [mscorlib]System.Int32 + IL_001a: call void [System.Console]System.Console::WriteLine(string, + object, + object) + IL_001f: nop + IL_0020: ldc.i4.s 9 + IL_0022: stsfld int32 E::i + IL_0027: ret + } // end of method E::.cctor + + .method public hidebysig static void SomeMethod() cil managed noinlining + { + // Code size 23 (0x17) + .maxstack 8 + IL_0000: nop + IL_0001: ldstr "In MyClass.SomeMethod(): thread {0}" + IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread() + IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name() + IL_0010: call void [System.Console]System.Console::WriteLine(string, + object) + IL_0015: nop + IL_0016: ret + } // end of method E::SomeMethod + +} // end of class E + +.class public auto ansi beforefieldinit Test + extends [mscorlib]System.Object +{ + .method public hidebysig static void RunGetA() cil managed + { + // Code size 8 (0x8) + .maxstack 8 + IL_0000: nop + IL_0001: call void A::SomeMethod() + IL_0006: nop + IL_0007: ret + } // end of method Test::RunGetA + + .method public hidebysig static void RunGetC() cil managed + { + // Code size 8 (0x8) + .maxstack 8 + IL_0000: nop + IL_0001: call void C::SomeMethod() + IL_0006: nop + IL_0007: ret + } // end of method Test::RunGetC + + .method public hidebysig static void RunGetD() cil managed + { + // Code size 8 (0x8) + .maxstack 8 + IL_0000: nop + IL_0001: call void D::SomeMethod() + IL_0006: nop + IL_0007: ret + } // end of method Test::RunGetD + + .method public hidebysig static void RunGetE() cil managed + { + // Code size 8 (0x8) + .maxstack 8 + IL_0000: nop + IL_0001: call void E::SomeMethod() + IL_0006: nop + IL_0007: ret + } // end of method Test::RunGetE + + .method public hidebysig static int32 Main() cil managed + { + .entrypoint + // Code size 302 (0x12e) + .maxstack 3 + .locals init (class [mscorlib]System.Threading.Thread V_0, + class [mscorlib]System.Threading.Thread V_1, + class [mscorlib]System.Threading.Thread V_2, + class [mscorlib]System.Threading.Thread V_3, + int32 V_4, + bool V_5) + IL_0000: nop + IL_0001: ldnull + IL_0002: ldftn void Test::RunGetA() + IL_0008: newobj instance void [mscorlib]System.Threading.ThreadStart::.ctor(object, + native int) + IL_000d: newobj instance void [mscorlib]System.Threading.Thread::.ctor(class [mscorlib]System.Threading.ThreadStart) + IL_0012: stloc.0 + IL_0013: ldloc.0 + IL_0014: ldstr "T1" + IL_0019: callvirt instance void [mscorlib]System.Threading.Thread::set_Name(string) + IL_001e: nop + IL_001f: ldnull + IL_0020: ldftn void Test::RunGetC() + IL_0026: newobj instance void [mscorlib]System.Threading.ThreadStart::.ctor(object, + native int) + IL_002b: newobj instance void [mscorlib]System.Threading.Thread::.ctor(class [mscorlib]System.Threading.ThreadStart) + IL_0030: stloc.1 + IL_0031: ldloc.1 + IL_0032: ldstr "T2" + IL_0037: callvirt instance void [mscorlib]System.Threading.Thread::set_Name(string) + IL_003c: nop + IL_003d: ldnull + IL_003e: ldftn void Test::RunGetD() + IL_0044: newobj instance void [mscorlib]System.Threading.ThreadStart::.ctor(object, + native int) + IL_0049: newobj instance void [mscorlib]System.Threading.Thread::.ctor(class [mscorlib]System.Threading.ThreadStart) + IL_004e: stloc.2 + IL_004f: ldloc.2 + IL_0050: ldstr "T3" + IL_0055: callvirt instance void [mscorlib]System.Threading.Thread::set_Name(string) + IL_005a: nop + IL_005b: ldnull + IL_005c: ldftn void Test::RunGetE() + IL_0062: newobj instance void [mscorlib]System.Threading.ThreadStart::.ctor(object, + native int) + IL_0067: newobj instance void [mscorlib]System.Threading.Thread::.ctor(class [mscorlib]System.Threading.ThreadStart) + IL_006c: stloc.3 + IL_006d: ldloc.3 + IL_006e: ldstr "T4" + IL_0073: callvirt instance void [mscorlib]System.Threading.Thread::set_Name(string) + IL_0078: nop + IL_0079: ldloc.0 + IL_007a: callvirt instance void [mscorlib]System.Threading.Thread::Start() + IL_007f: nop + IL_0080: ldc.i4 0x3e8 + IL_0085: call void [mscorlib]System.Threading.Thread::Sleep(int32) + IL_008a: nop + IL_008b: ldloc.1 + IL_008c: callvirt instance void [mscorlib]System.Threading.Thread::Start() + IL_0091: nop + IL_0092: ldc.i4 0x3e8 + IL_0097: call void [mscorlib]System.Threading.Thread::Sleep(int32) + IL_009c: nop + IL_009d: ldloc.2 + IL_009e: callvirt instance void [mscorlib]System.Threading.Thread::Start() + IL_00a3: nop + IL_00a4: ldc.i4 0x3e8 + IL_00a9: call void [mscorlib]System.Threading.Thread::Sleep(int32) + IL_00ae: nop + IL_00af: ldloc.3 + IL_00b0: callvirt instance void [mscorlib]System.Threading.Thread::Start() + IL_00b5: nop + IL_00b6: ldloc.3 + IL_00b7: callvirt instance void [mscorlib]System.Threading.Thread::Join() + IL_00bc: nop + IL_00bd: ldloc.2 + IL_00be: callvirt instance void [mscorlib]System.Threading.Thread::Join() + IL_00c3: nop + IL_00c4: ldloc.1 + IL_00c5: callvirt instance void [mscorlib]System.Threading.Thread::Join() + IL_00ca: nop + IL_00cb: ldloc.0 + IL_00cc: callvirt instance void [mscorlib]System.Threading.Thread::Join() + IL_00d1: nop + IL_00d2: ldsfld int32 A::i + IL_00d7: ldc.i4.5 + IL_00d8: bne.un.s IL_0100 + + IL_00da: ldsfld int32 B::i + IL_00df: ldc.i4.6 + IL_00e0: bne.un.s IL_0100 + + IL_00e2: ldsfld int32 C::i + IL_00e7: ldc.i4.7 + IL_00e8: bne.un.s IL_0100 + + IL_00ea: ldsfld int32 D::i + IL_00ef: ldc.i4.8 + IL_00f0: bne.un.s IL_0100 + + IL_00f2: ldsfld int32 E::i + IL_00f7: ldc.i4.s 9 + IL_00f9: ceq + IL_00fb: ldc.i4.0 + IL_00fc: ceq + IL_00fe: br.s IL_0101 + + IL_0100: ldc.i4.1 + IL_0101: stloc.s V_5 + IL_0103: ldloc.s V_5 + IL_0105: brtrue.s IL_0119 + + IL_0107: nop + IL_0108: ldstr "PASS" + IL_010d: call void [System.Console]System.Console::WriteLine(string) + IL_0112: nop + IL_0113: ldc.i4.s 100 + IL_0115: stloc.s V_4 + IL_0117: br.s IL_012b + + IL_0119: nop + IL_011a: ldstr "FAIL" + IL_011f: call void [System.Console]System.Console::WriteLine(string) + IL_0124: nop + IL_0125: ldc.i4.s 101 + IL_0127: stloc.s V_4 + IL_0129: br.s IL_012b + + IL_012b: ldloc.s V_4 + IL_012d: ret + } // end of method Test::Main + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method Test::.ctor + +} // end of class Test + + +// ============================================================= + +// *********** DISASSEMBLY COMPLETE *********************** +// WARNING: Created Win32 resource file CircularCctorFourThreads.res diff --git a/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorFourThreadsBFI.ilproj b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorFourThreadsBFI.ilproj new file mode 100644 index 0000000000..7c1c2df15a --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorFourThreadsBFI.ilproj @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> + <PropertyGroup> + <AssemblyName>CircularCctorFourThreadsBFI</AssemblyName> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid> + <FileAlignment>512</FileAlignment> + <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> + <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp> + <AllowUnsafeBlocks>true</AllowUnsafeBlocks> + <ReferenceLocalMscorlib>true</ReferenceLocalMscorlib> + <OutputType>Exe</OutputType> + <CLRTestKind>BuildAndRun</CLRTestKind> + <CLRTestPriority>0</CLRTestPriority> + </PropertyGroup> + + <ItemGroup> + <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies"> + <Visible>False</Visible> + </CodeAnalysisDependentAssemblyPaths> + </ItemGroup> + + <ItemGroup> + <Compile Include="CircularCctorFourThreadsBFI.il" /> + </ItemGroup> + + <ItemGroup> + <None Include="app.config" /> + </ItemGroup> + + <ItemGroup> + <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" /> + </ItemGroup> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> +</Project> diff --git a/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads01.cs b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads01.cs new file mode 100644 index 0000000000..da06e4a15e --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads01.cs @@ -0,0 +1,163 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/* +A --> B --> C --> D --> E --> A +3 threads: Thread T1 starts initialization at A, thread T2 starts initialization at C, and thread T3 starts initialization at E. +This should form a three thread deadlock, which we will detect and allow one of the three threads to proceed, breaking the deadlock. +*/ + +using System; +using System.Threading; +using System.Runtime.CompilerServices; +public class A +{ + public static int i; + + static A() + { + + Console.WriteLine("In A.cctor: thread {0}: B.i {1}",Thread.CurrentThread.Name,B.i); + A.i = 5; + } + + // invoking this should trigger the cctor + [MethodImpl(MethodImplOptions.NoInlining)] + public static void SomeMethod() + { + Console.WriteLine("In MyClass.SomeMethod(): thread {0}",Thread.CurrentThread.Name); + } + +} + +public class B +{ + public static int i; + + static B() + { + + + Console.WriteLine("In B.cctor: thread {0}: C.i {1}",Thread.CurrentThread.Name,C.i); + B.i = 6; + } + + // invoking this should trigger the cctor + [MethodImpl(MethodImplOptions.NoInlining)] + public static void SomeMethod() + { + Console.WriteLine("In MyClass.SomeMethod(): thread {0}",Thread.CurrentThread.Name); + } + +} + +public class C +{ + public static int i; + + static C() + { + Console.WriteLine("In C.cctor: thread {0}: D.i {1}",Thread.CurrentThread.Name,D.i); + C.i = 7; + } + + // invoking this should trigger the cctor + [MethodImpl(MethodImplOptions.NoInlining)] + public static void SomeMethod() + { + Console.WriteLine("In MyClass.SomeMethod(): thread {0}",Thread.CurrentThread.Name); + } + +} + +public class D +{ + public static int i; + + static D() + { + Console.WriteLine("In D.cctor: thread {0}: E.i {1}",Thread.CurrentThread.Name,E.i); + D.i = 8; + } + + // invoking this should trigger the cctor + [MethodImpl(MethodImplOptions.NoInlining)] + public static void SomeMethod() + { + Console.WriteLine("In MyClass.SomeMethod(): thread {0}",Thread.CurrentThread.Name); + } + +} + +public class E +{ + public static int i; + + static E() + { + Console.WriteLine("In E.cctor: thread {0}: A.i {1}",Thread.CurrentThread.Name,A.i); + E.i = 9; + } + + // invoking this should trigger the cctor + [MethodImpl(MethodImplOptions.NoInlining)] + public static void SomeMethod() + { + Console.WriteLine("In MyClass.SomeMethod(): thread {0}",Thread.CurrentThread.Name); + } + +} + +public class Test +{ + + public static void RunGetA() + { + A.SomeMethod(); + } + + public static void RunGetC() + { + C.SomeMethod(); + } + + public static void RunGetE() + { + E.SomeMethod(); + } + + + public static int Main() + { + Thread t1 = new Thread(RunGetA); + t1.Name = "T1"; + Thread t2 = new Thread(RunGetC); + t2.Name = "T2"; + Thread t3 = new Thread(RunGetE); + t3.Name = "T3"; + + t1.Start(); + Thread.Sleep(1000*1); // 1 second + t2.Start(); + Thread.Sleep(1000*1); // 1 second + t3.Start(); + + t3.Join(); + t2.Join(); + t1.Join(); + + + // make sure that statics were set correctly + if ( A.i == 5 && B.i == 6 && C.i == 7 && D.i == 8 && E.i == 9 ) + { + Console.WriteLine("PASS"); + return 100; + } + else + { + Console.WriteLine("FAIL"); + return 101; + } + } +} diff --git a/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads01.csproj b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads01.csproj new file mode 100644 index 0000000000..1b61083bc9 --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads01.csproj @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> + <PropertyGroup> + <AssemblyName>CircularCctorThreeThreads01</AssemblyName> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid> + <FileAlignment>512</FileAlignment> + <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> + <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp> + <AllowUnsafeBlocks>true</AllowUnsafeBlocks> + <ReferenceLocalMscorlib>false</ReferenceLocalMscorlib> + <OutputType>Exe</OutputType> + <CLRTestKind>BuildAndRun</CLRTestKind> + <CLRTestPriority>0</CLRTestPriority> + </PropertyGroup> + + <ItemGroup> + <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies"> + <Visible>False</Visible> + </CodeAnalysisDependentAssemblyPaths> + </ItemGroup> + + <ItemGroup> + <Compile Include="CircularCctorThreeThreads01.cs" /> + </ItemGroup> + + <ItemGroup> + <None Include="app.config" /> + <None Include="project.json" /> + </ItemGroup> + + <ItemGroup> + <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" /> + </ItemGroup> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> +</Project> diff --git a/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads01BFI.il b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads01BFI.il new file mode 100644 index 0000000000..e3bf0905b1 --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads01BFI.il @@ -0,0 +1,448 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +.assembly extern System.Console { } + +// Microsoft (R) .NET Framework IL Disassembler. Version 2.0.50103.00 +// Copyright (C) Microsoft Corporation. All rights reserved. + + + +// Metadata version: v2.0.50103 +.assembly extern mscorlib +{ + .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. + .ver 2:0:0:0 +} +.assembly CircularCctorThreeThreads01 +{ + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module CircularCctorThreeThreads01.exe +// MVID: {391DADEC-FC20-4965-82DE-5A0027055F7B} +.imagebase 0x00400000 +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 // WINDOWS_CUI +.corflags 0x00000001 // ILONLY +// Image base: 0x03090000 + + +// =============== CLASS MEMBERS DECLARATION =================== + +.class public auto ansi beforefieldinit A + extends [mscorlib]System.Object +{ + .field public static int32 i + .method private hidebysig specialname rtspecialname static + void .cctor() cil managed + { + // Code size 39 (0x27) + .maxstack 8 + IL_0000: nop + IL_0001: ldstr "In A.cctor: thread {0}: B.i {1}" + IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread() + IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name() + IL_0010: ldsfld int32 B::i + IL_0015: box [mscorlib]System.Int32 + IL_001a: call void [System.Console]System.Console::WriteLine(string, + object, + object) + IL_001f: nop + IL_0020: ldc.i4.5 + IL_0021: stsfld int32 A::i + IL_0026: ret + } // end of method A::.cctor + + .method public hidebysig static void SomeMethod() cil managed noinlining + { + // Code size 23 (0x17) + .maxstack 8 + IL_0000: nop + IL_0001: ldstr "In MyClass.SomeMethod(): thread {0}" + IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread() + IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name() + IL_0010: call void [System.Console]System.Console::WriteLine(string, + object) + IL_0015: nop + IL_0016: ret + } // end of method A::SomeMethod + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method A::.ctor + +} // end of class A + +.class public auto ansi beforefieldinit B + extends [mscorlib]System.Object +{ + .field public static int32 i + .method private hidebysig specialname rtspecialname static + void .cctor() cil managed + { + // Code size 39 (0x27) + .maxstack 8 + IL_0000: nop + IL_0001: ldstr "In B.cctor: thread {0}: C.i {1}" + IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread() + IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name() + IL_0010: ldsfld int32 C::i + IL_0015: box [mscorlib]System.Int32 + IL_001a: call void [System.Console]System.Console::WriteLine(string, + object, + object) + IL_001f: nop + IL_0020: ldc.i4.6 + IL_0021: stsfld int32 B::i + IL_0026: ret + } // end of method B::.cctor + + .method public hidebysig static void SomeMethod() cil managed noinlining + { + // Code size 23 (0x17) + .maxstack 8 + IL_0000: nop + IL_0001: ldstr "In MyClass.SomeMethod(): thread {0}" + IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread() + IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name() + IL_0010: call void [System.Console]System.Console::WriteLine(string, + object) + IL_0015: nop + IL_0016: ret + } // end of method B::SomeMethod + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method B::.ctor + +} // end of class B + +.class public auto ansi beforefieldinit C + extends [mscorlib]System.Object +{ + .field public static int32 i + .method private hidebysig specialname rtspecialname static + void .cctor() cil managed + { + // Code size 39 (0x27) + .maxstack 8 + IL_0000: nop + IL_0001: ldstr "In C.cctor: thread {0}: D.i {1}" + IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread() + IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name() + IL_0010: ldsfld int32 D::i + IL_0015: box [mscorlib]System.Int32 + IL_001a: call void [System.Console]System.Console::WriteLine(string, + object, + object) + IL_001f: nop + IL_0020: ldc.i4.7 + IL_0021: stsfld int32 C::i + IL_0026: ret + } // end of method C::.cctor + + .method public hidebysig static void SomeMethod() cil managed noinlining + { + // Code size 23 (0x17) + .maxstack 8 + IL_0000: nop + IL_0001: ldstr "In MyClass.SomeMethod(): thread {0}" + IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread() + IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name() + IL_0010: call void [System.Console]System.Console::WriteLine(string, + object) + IL_0015: nop + IL_0016: ret + } // end of method C::SomeMethod + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method C::.ctor + +} // end of class C + +.class public auto ansi beforefieldinit D + extends [mscorlib]System.Object +{ + .field public static int32 i + .method private hidebysig specialname rtspecialname static + void .cctor() cil managed + { + // Code size 39 (0x27) + .maxstack 8 + IL_0000: nop + IL_0001: ldstr "In D.cctor: thread {0}: E.i {1}" + IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread() + IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name() + IL_0010: ldsfld int32 E::i + IL_0015: box [mscorlib]System.Int32 + IL_001a: call void [System.Console]System.Console::WriteLine(string, + object, + object) + IL_001f: nop + IL_0020: ldc.i4.8 + IL_0021: stsfld int32 D::i + IL_0026: ret + } // end of method D::.cctor + + .method public hidebysig static void SomeMethod() cil managed noinlining + { + // Code size 23 (0x17) + .maxstack 8 + IL_0000: nop + IL_0001: ldstr "In MyClass.SomeMethod(): thread {0}" + IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread() + IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name() + IL_0010: call void [System.Console]System.Console::WriteLine(string, + object) + IL_0015: nop + IL_0016: ret + } // end of method D::SomeMethod + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method D::.ctor + +} // end of class D + +.class public auto ansi beforefieldinit E + extends [mscorlib]System.Object +{ + .field public static int32 i + .method private hidebysig specialname rtspecialname static + void .cctor() cil managed + { + // Code size 40 (0x28) + .maxstack 8 + IL_0000: nop + IL_0001: ldstr "In E.cctor: thread {0}: A.i {1}" + IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread() + IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name() + IL_0010: ldsfld int32 A::i + IL_0015: box [mscorlib]System.Int32 + IL_001a: call void [System.Console]System.Console::WriteLine(string, + object, + object) + IL_001f: nop + IL_0020: ldc.i4.s 9 + IL_0022: stsfld int32 E::i + IL_0027: ret + } // end of method E::.cctor + + .method public hidebysig static void SomeMethod() cil managed noinlining + { + // Code size 23 (0x17) + .maxstack 8 + IL_0000: nop + IL_0001: ldstr "In MyClass.SomeMethod(): thread {0}" + IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread() + IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name() + IL_0010: call void [System.Console]System.Console::WriteLine(string, + object) + IL_0015: nop + IL_0016: ret + } // end of method E::SomeMethod + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method E::.ctor + +} // end of class E + +.class public auto ansi beforefieldinit Test + extends [mscorlib]System.Object +{ + .method public hidebysig static void RunGetA() cil managed + { + // Code size 8 (0x8) + .maxstack 8 + IL_0000: nop + IL_0001: call void A::SomeMethod() + IL_0006: nop + IL_0007: ret + } // end of method Test::RunGetA + + .method public hidebysig static void RunGetC() cil managed + { + // Code size 8 (0x8) + .maxstack 8 + IL_0000: nop + IL_0001: call void C::SomeMethod() + IL_0006: nop + IL_0007: ret + } // end of method Test::RunGetC + + .method public hidebysig static void RunGetE() cil managed + { + // Code size 8 (0x8) + .maxstack 8 + IL_0000: nop + IL_0001: call void E::SomeMethod() + IL_0006: nop + IL_0007: ret + } // end of method Test::RunGetE + + .method public hidebysig static int32 Main() cil managed + { + .entrypoint + // Code size 244 (0xf4) + .maxstack 3 + .locals init (class [mscorlib]System.Threading.Thread V_0, + class [mscorlib]System.Threading.Thread V_1, + class [mscorlib]System.Threading.Thread V_2, + int32 V_3, + bool V_4) + IL_0000: nop + IL_0001: ldnull + IL_0002: ldftn void Test::RunGetA() + IL_0008: newobj instance void [mscorlib]System.Threading.ThreadStart::.ctor(object, + native int) + IL_000d: newobj instance void [mscorlib]System.Threading.Thread::.ctor(class [mscorlib]System.Threading.ThreadStart) + IL_0012: stloc.0 + IL_0013: ldloc.0 + IL_0014: ldstr "T1" + IL_0019: callvirt instance void [mscorlib]System.Threading.Thread::set_Name(string) + IL_001e: nop + IL_001f: ldnull + IL_0020: ldftn void Test::RunGetC() + IL_0026: newobj instance void [mscorlib]System.Threading.ThreadStart::.ctor(object, + native int) + IL_002b: newobj instance void [mscorlib]System.Threading.Thread::.ctor(class [mscorlib]System.Threading.ThreadStart) + IL_0030: stloc.1 + IL_0031: ldloc.1 + IL_0032: ldstr "T2" + IL_0037: callvirt instance void [mscorlib]System.Threading.Thread::set_Name(string) + IL_003c: nop + IL_003d: ldnull + IL_003e: ldftn void Test::RunGetE() + IL_0044: newobj instance void [mscorlib]System.Threading.ThreadStart::.ctor(object, + native int) + IL_0049: newobj instance void [mscorlib]System.Threading.Thread::.ctor(class [mscorlib]System.Threading.ThreadStart) + IL_004e: stloc.2 + IL_004f: ldloc.2 + IL_0050: ldstr "T3" + IL_0055: callvirt instance void [mscorlib]System.Threading.Thread::set_Name(string) + IL_005a: nop + IL_005b: ldloc.0 + IL_005c: callvirt instance void [mscorlib]System.Threading.Thread::Start() + IL_0061: nop + IL_0062: ldc.i4 0x3e8 + IL_0067: call void [mscorlib]System.Threading.Thread::Sleep(int32) + IL_006c: nop + IL_006d: ldloc.1 + IL_006e: callvirt instance void [mscorlib]System.Threading.Thread::Start() + IL_0073: nop + IL_0074: ldc.i4 0x3e8 + IL_0079: call void [mscorlib]System.Threading.Thread::Sleep(int32) + IL_007e: nop + IL_007f: ldloc.2 + IL_0080: callvirt instance void [mscorlib]System.Threading.Thread::Start() + IL_0085: nop + IL_0086: ldloc.2 + IL_0087: callvirt instance void [mscorlib]System.Threading.Thread::Join() + IL_008c: nop + IL_008d: ldloc.1 + IL_008e: callvirt instance void [mscorlib]System.Threading.Thread::Join() + IL_0093: nop + IL_0094: ldloc.0 + IL_0095: callvirt instance void [mscorlib]System.Threading.Thread::Join() + IL_009a: nop + IL_009b: ldsfld int32 A::i + IL_00a0: ldc.i4.5 + IL_00a1: bne.un.s IL_00c9 + + IL_00a3: ldsfld int32 B::i + IL_00a8: ldc.i4.6 + IL_00a9: bne.un.s IL_00c9 + + IL_00ab: ldsfld int32 C::i + IL_00b0: ldc.i4.7 + IL_00b1: bne.un.s IL_00c9 + + IL_00b3: ldsfld int32 D::i + IL_00b8: ldc.i4.8 + IL_00b9: bne.un.s IL_00c9 + + IL_00bb: ldsfld int32 E::i + IL_00c0: ldc.i4.s 9 + IL_00c2: ceq + IL_00c4: ldc.i4.0 + IL_00c5: ceq + IL_00c7: br.s IL_00ca + + IL_00c9: ldc.i4.1 + IL_00ca: stloc.s V_4 + IL_00cc: ldloc.s V_4 + IL_00ce: brtrue.s IL_00e1 + + IL_00d0: nop + IL_00d1: ldstr "PASS" + IL_00d6: call void [System.Console]System.Console::WriteLine(string) + IL_00db: nop + IL_00dc: ldc.i4.s 100 + IL_00de: stloc.3 + IL_00df: br.s IL_00f2 + + IL_00e1: nop + IL_00e2: ldstr "FAIL" + IL_00e7: call void [System.Console]System.Console::WriteLine(string) + IL_00ec: nop + IL_00ed: ldc.i4.s 101 + IL_00ef: stloc.3 + IL_00f0: br.s IL_00f2 + + IL_00f2: ldloc.3 + IL_00f3: ret + } // end of method Test::Main + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method Test::.ctor + +} // end of class Test + + +// ============================================================= + +// *********** DISASSEMBLY COMPLETE *********************** +// WARNING: Created Win32 resource file CircularCctorThreeThreads01.res diff --git a/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads01BFI.ilproj b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads01BFI.ilproj new file mode 100644 index 0000000000..0cec84e064 --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads01BFI.ilproj @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> + <PropertyGroup> + <AssemblyName>CircularCctorThreeThreads01BFI</AssemblyName> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid> + <FileAlignment>512</FileAlignment> + <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> + <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp> + <AllowUnsafeBlocks>true</AllowUnsafeBlocks> + <ReferenceLocalMscorlib>true</ReferenceLocalMscorlib> + <OutputType>Exe</OutputType> + <CLRTestKind>BuildAndRun</CLRTestKind> + <CLRTestPriority>0</CLRTestPriority> + </PropertyGroup> + + <ItemGroup> + <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies"> + <Visible>False</Visible> + </CodeAnalysisDependentAssemblyPaths> + </ItemGroup> + + <ItemGroup> + <Compile Include="CircularCctorThreeThreads01BFI.il" /> + </ItemGroup> + + <ItemGroup> + <None Include="app.config" /> + </ItemGroup> + + <ItemGroup> + <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" /> + </ItemGroup> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> +</Project> diff --git a/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads02.cs b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads02.cs new file mode 100644 index 0000000000..e92a39bde7 --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads02.cs @@ -0,0 +1,177 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/* +A --> B --> C --> D --> E --> A +3 threads: Thread T1 starts initialization at A, thread T2 starts initialization at C, and thread T3 starts initialization at E. +A::.cctor sleeps for a few seconds so Thread T1 is blocked. +T2 invokes C::.cctor ' D::.cctor ' E::.cctor ' A::.cctor at which point T2 becomes blocked waiting for T1. +T3 is blocked because T2 is in E::.cctor. +T1 becomes unblocked, invokes B::.cctor, wants to invoke C::.cctor but, T2 is in C::.cctor so we get a 3 thread deadlock. +We detect the deadlock and allow T1 to see C.i uninitialized state. + +In B.cctor: thread T1: C.i 0 +In A.cctor: thread T1: B.i 6 +In E.cctor: thread T2: A.i 5 +In D.cctor: thread T2: E.i 9 +In C.cctor: thread T2: D.i 8 +*/ + +using System; +using System.Threading; +using System.Runtime.CompilerServices; +public class A +{ + public static int i; + + static A() + { + + Thread.Sleep(1000*2); // 1 second + Console.WriteLine("In A.cctor: thread {0}: B.i {1}",Thread.CurrentThread.Name,B.i); + A.i = 5; + } + + // invoking this should trigger the cctor + [MethodImpl(MethodImplOptions.NoInlining)] + public static void SomeMethod() + { + Console.WriteLine("In MyClass.SomeMethod(): thread {0}",Thread.CurrentThread.Name); + } + +} + +public class B +{ + public static int i; + + static B() + { + + + Console.WriteLine("In B.cctor: thread {0}: C.i {1}",Thread.CurrentThread.Name,C.i); + B.i = 6; + } + + // invoking this should trigger the cctor + [MethodImpl(MethodImplOptions.NoInlining)] + public static void SomeMethod() + { + Console.WriteLine("In MyClass.SomeMethod(): thread {0}",Thread.CurrentThread.Name); + } + +} + +public class C +{ + public static int i; + + static C() + { + Console.WriteLine("In C.cctor: thread {0}: D.i {1}",Thread.CurrentThread.Name,D.i); + C.i = 7; + } + + // invoking this should trigger the cctor + [MethodImpl(MethodImplOptions.NoInlining)] + public static void SomeMethod() + { + Console.WriteLine("In MyClass.SomeMethod(): thread {0}",Thread.CurrentThread.Name); + } + +} + +public class D +{ + public static int i; + + + static D() + { + Console.WriteLine("In D.cctor: thread {0}: E.i {1}",Thread.CurrentThread.Name,E.i); + D.i = 8; + } + + // invoking this should trigger the cctor + [MethodImpl(MethodImplOptions.NoInlining)] + public static void SomeMethod() + { + Console.WriteLine("In MyClass.SomeMethod(): thread {0}",Thread.CurrentThread.Name); + } + +} + +public class E +{ + public static int i; + + static E() + { + Console.WriteLine("In E.cctor: thread {0}: A.i {1}",Thread.CurrentThread.Name,A.i); + E.i = 9; + } + + // invoking this should trigger the cctor + [MethodImpl(MethodImplOptions.NoInlining)] + public static void SomeMethod() + { + Console.WriteLine("In MyClass.SomeMethod(): thread {0}",Thread.CurrentThread.Name); + } + +} + +public class Test +{ + + public static void RunGetA() + { + A.SomeMethod(); + } + + public static void RunGetC() + { + C.SomeMethod(); + } + + public static void RunGetE() + { + E.SomeMethod(); + } + + + public static int Main() + { + + Thread t1 = new Thread(RunGetA); + t1.Name = "T1"; + Thread t2 = new Thread(RunGetC); + t2.Name = "T2"; + Thread t3 = new Thread(RunGetE); + t3.Name = "T3"; + + + + t1.Start(); + Thread.Sleep(1000*1); // 1 second + t2.Start(); + Thread.Sleep(1000*1); // 1 second + t3.Start(); + + t3.Join(); + t2.Join(); + t1.Join(); + + // make sure that statics were set correctly. + if ( A.i == 5 && B.i == 6 && C.i == 7 && D.i == 8 && E.i == 9 ) + { + Console.WriteLine("PASS"); + return 100; + } + else + { + Console.WriteLine("FAIL"); + return 101; + } + } +} diff --git a/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads02.csproj b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads02.csproj new file mode 100644 index 0000000000..dbc05d5d3a --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads02.csproj @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> + <PropertyGroup> + <AssemblyName>CircularCctorThreeThreads02</AssemblyName> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid> + <FileAlignment>512</FileAlignment> + <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> + <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp> + <AllowUnsafeBlocks>true</AllowUnsafeBlocks> + <ReferenceLocalMscorlib>false</ReferenceLocalMscorlib> + <OutputType>Exe</OutputType> + <CLRTestKind>BuildAndRun</CLRTestKind> + <CLRTestPriority>0</CLRTestPriority> + </PropertyGroup> + + <ItemGroup> + <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies"> + <Visible>False</Visible> + </CodeAnalysisDependentAssemblyPaths> + </ItemGroup> + + <ItemGroup> + <Compile Include="CircularCctorThreeThreads02.cs" /> + </ItemGroup> + + <ItemGroup> + <None Include="app.config" /> + <None Include="project.json" /> + </ItemGroup> + + <ItemGroup> + <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" /> + </ItemGroup> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> +</Project> diff --git a/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads02BFI.il b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads02BFI.il new file mode 100644 index 0000000000..5c75d8ff5c --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads02BFI.il @@ -0,0 +1,451 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +.assembly extern System.Console { } + +// Microsoft (R) .NET Framework IL Disassembler. Version 2.0.50103.00 +// Copyright (C) Microsoft Corporation. All rights reserved. + + + +// Metadata version: v2.0.50103 +.assembly extern mscorlib +{ + .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. + .ver 2:0:0:0 +} +.assembly CircularCctorThreeThreads02 +{ + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module CircularCctorThreeThreads02.exe +// MVID: {D90A3A61-FEDA-4DC1-A90B-0FEBC5C34B33} +.imagebase 0x00400000 +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 // WINDOWS_CUI +.corflags 0x00000001 // ILONLY +// Image base: 0x03090000 + + +// =============== CLASS MEMBERS DECLARATION =================== + +.class public auto ansi beforefieldinit A + extends [mscorlib]System.Object +{ + .field public static int32 i + .method private hidebysig specialname rtspecialname static + void .cctor() cil managed + { + // Code size 50 (0x32) + .maxstack 8 + IL_0000: nop + IL_0001: ldc.i4 0x7d0 + IL_0006: call void [mscorlib]System.Threading.Thread::Sleep(int32) + IL_000b: nop + IL_000c: ldstr "In A.cctor: thread {0}: B.i {1}" + IL_0011: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread() + IL_0016: callvirt instance string [mscorlib]System.Threading.Thread::get_Name() + IL_001b: ldsfld int32 B::i + IL_0020: box [mscorlib]System.Int32 + IL_0025: call void [System.Console]System.Console::WriteLine(string, + object, + object) + IL_002a: nop + IL_002b: ldc.i4.5 + IL_002c: stsfld int32 A::i + IL_0031: ret + } // end of method A::.cctor + + .method public hidebysig static void SomeMethod() cil managed noinlining + { + // Code size 23 (0x17) + .maxstack 8 + IL_0000: nop + IL_0001: ldstr "In MyClass.SomeMethod(): thread {0}" + IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread() + IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name() + IL_0010: call void [System.Console]System.Console::WriteLine(string, + object) + IL_0015: nop + IL_0016: ret + } // end of method A::SomeMethod + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method A::.ctor + +} // end of class A + +.class public auto ansi beforefieldinit B + extends [mscorlib]System.Object +{ + .field public static int32 i + .method private hidebysig specialname rtspecialname static + void .cctor() cil managed + { + // Code size 39 (0x27) + .maxstack 8 + IL_0000: nop + IL_0001: ldstr "In B.cctor: thread {0}: C.i {1}" + IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread() + IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name() + IL_0010: ldsfld int32 C::i + IL_0015: box [mscorlib]System.Int32 + IL_001a: call void [System.Console]System.Console::WriteLine(string, + object, + object) + IL_001f: nop + IL_0020: ldc.i4.6 + IL_0021: stsfld int32 B::i + IL_0026: ret + } // end of method B::.cctor + + .method public hidebysig static void SomeMethod() cil managed noinlining + { + // Code size 23 (0x17) + .maxstack 8 + IL_0000: nop + IL_0001: ldstr "In MyClass.SomeMethod(): thread {0}" + IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread() + IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name() + IL_0010: call void [System.Console]System.Console::WriteLine(string, + object) + IL_0015: nop + IL_0016: ret + } // end of method B::SomeMethod + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method B::.ctor + +} // end of class B + +.class public auto ansi beforefieldinit C + extends [mscorlib]System.Object +{ + .field public static int32 i + .method private hidebysig specialname rtspecialname static + void .cctor() cil managed + { + // Code size 39 (0x27) + .maxstack 8 + IL_0000: nop + IL_0001: ldstr "In C.cctor: thread {0}: D.i {1}" + IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread() + IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name() + IL_0010: ldsfld int32 D::i + IL_0015: box [mscorlib]System.Int32 + IL_001a: call void [System.Console]System.Console::WriteLine(string, + object, + object) + IL_001f: nop + IL_0020: ldc.i4.7 + IL_0021: stsfld int32 C::i + IL_0026: ret + } // end of method C::.cctor + + .method public hidebysig static void SomeMethod() cil managed noinlining + { + // Code size 23 (0x17) + .maxstack 8 + IL_0000: nop + IL_0001: ldstr "In MyClass.SomeMethod(): thread {0}" + IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread() + IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name() + IL_0010: call void [System.Console]System.Console::WriteLine(string, + object) + IL_0015: nop + IL_0016: ret + } // end of method C::SomeMethod + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method C::.ctor + +} // end of class C + +.class public auto ansi beforefieldinit D + extends [mscorlib]System.Object +{ + .field public static int32 i + .method private hidebysig specialname rtspecialname static + void .cctor() cil managed + { + // Code size 39 (0x27) + .maxstack 8 + IL_0000: nop + IL_0001: ldstr "In D.cctor: thread {0}: E.i {1}" + IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread() + IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name() + IL_0010: ldsfld int32 E::i + IL_0015: box [mscorlib]System.Int32 + IL_001a: call void [System.Console]System.Console::WriteLine(string, + object, + object) + IL_001f: nop + IL_0020: ldc.i4.8 + IL_0021: stsfld int32 D::i + IL_0026: ret + } // end of method D::.cctor + + .method public hidebysig static void SomeMethod() cil managed noinlining + { + // Code size 23 (0x17) + .maxstack 8 + IL_0000: nop + IL_0001: ldstr "In MyClass.SomeMethod(): thread {0}" + IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread() + IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name() + IL_0010: call void [System.Console]System.Console::WriteLine(string, + object) + IL_0015: nop + IL_0016: ret + } // end of method D::SomeMethod + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method D::.ctor + +} // end of class D + +.class public auto ansi beforefieldinit E + extends [mscorlib]System.Object +{ + .field public static int32 i + .method private hidebysig specialname rtspecialname static + void .cctor() cil managed + { + // Code size 40 (0x28) + .maxstack 8 + IL_0000: nop + IL_0001: ldstr "In E.cctor: thread {0}: A.i {1}" + IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread() + IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name() + IL_0010: ldsfld int32 A::i + IL_0015: box [mscorlib]System.Int32 + IL_001a: call void [System.Console]System.Console::WriteLine(string, + object, + object) + IL_001f: nop + IL_0020: ldc.i4.s 9 + IL_0022: stsfld int32 E::i + IL_0027: ret + } // end of method E::.cctor + + .method public hidebysig static void SomeMethod() cil managed noinlining + { + // Code size 23 (0x17) + .maxstack 8 + IL_0000: nop + IL_0001: ldstr "In MyClass.SomeMethod(): thread {0}" + IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread() + IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name() + IL_0010: call void [System.Console]System.Console::WriteLine(string, + object) + IL_0015: nop + IL_0016: ret + } // end of method E::SomeMethod + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method E::.ctor + +} // end of class E + +.class public auto ansi beforefieldinit Test + extends [mscorlib]System.Object +{ + .method public hidebysig static void RunGetA() cil managed + { + // Code size 8 (0x8) + .maxstack 8 + IL_0000: nop + IL_0001: call void A::SomeMethod() + IL_0006: nop + IL_0007: ret + } // end of method Test::RunGetA + + .method public hidebysig static void RunGetC() cil managed + { + // Code size 8 (0x8) + .maxstack 8 + IL_0000: nop + IL_0001: call void C::SomeMethod() + IL_0006: nop + IL_0007: ret + } // end of method Test::RunGetC + + .method public hidebysig static void RunGetE() cil managed + { + // Code size 8 (0x8) + .maxstack 8 + IL_0000: nop + IL_0001: call void E::SomeMethod() + IL_0006: nop + IL_0007: ret + } // end of method Test::RunGetE + + .method public hidebysig static int32 Main() cil managed + { + .entrypoint + // Code size 244 (0xf4) + .maxstack 3 + .locals init (class [mscorlib]System.Threading.Thread V_0, + class [mscorlib]System.Threading.Thread V_1, + class [mscorlib]System.Threading.Thread V_2, + int32 V_3, + bool V_4) + IL_0000: nop + IL_0001: ldnull + IL_0002: ldftn void Test::RunGetA() + IL_0008: newobj instance void [mscorlib]System.Threading.ThreadStart::.ctor(object, + native int) + IL_000d: newobj instance void [mscorlib]System.Threading.Thread::.ctor(class [mscorlib]System.Threading.ThreadStart) + IL_0012: stloc.0 + IL_0013: ldloc.0 + IL_0014: ldstr "T1" + IL_0019: callvirt instance void [mscorlib]System.Threading.Thread::set_Name(string) + IL_001e: nop + IL_001f: ldnull + IL_0020: ldftn void Test::RunGetC() + IL_0026: newobj instance void [mscorlib]System.Threading.ThreadStart::.ctor(object, + native int) + IL_002b: newobj instance void [mscorlib]System.Threading.Thread::.ctor(class [mscorlib]System.Threading.ThreadStart) + IL_0030: stloc.1 + IL_0031: ldloc.1 + IL_0032: ldstr "T2" + IL_0037: callvirt instance void [mscorlib]System.Threading.Thread::set_Name(string) + IL_003c: nop + IL_003d: ldnull + IL_003e: ldftn void Test::RunGetE() + IL_0044: newobj instance void [mscorlib]System.Threading.ThreadStart::.ctor(object, + native int) + IL_0049: newobj instance void [mscorlib]System.Threading.Thread::.ctor(class [mscorlib]System.Threading.ThreadStart) + IL_004e: stloc.2 + IL_004f: ldloc.2 + IL_0050: ldstr "T3" + IL_0055: callvirt instance void [mscorlib]System.Threading.Thread::set_Name(string) + IL_005a: nop + IL_005b: ldloc.0 + IL_005c: callvirt instance void [mscorlib]System.Threading.Thread::Start() + IL_0061: nop + IL_0062: ldc.i4 0x3e8 + IL_0067: call void [mscorlib]System.Threading.Thread::Sleep(int32) + IL_006c: nop + IL_006d: ldloc.1 + IL_006e: callvirt instance void [mscorlib]System.Threading.Thread::Start() + IL_0073: nop + IL_0074: ldc.i4 0x3e8 + IL_0079: call void [mscorlib]System.Threading.Thread::Sleep(int32) + IL_007e: nop + IL_007f: ldloc.2 + IL_0080: callvirt instance void [mscorlib]System.Threading.Thread::Start() + IL_0085: nop + IL_0086: ldloc.2 + IL_0087: callvirt instance void [mscorlib]System.Threading.Thread::Join() + IL_008c: nop + IL_008d: ldloc.1 + IL_008e: callvirt instance void [mscorlib]System.Threading.Thread::Join() + IL_0093: nop + IL_0094: ldloc.0 + IL_0095: callvirt instance void [mscorlib]System.Threading.Thread::Join() + IL_009a: nop + IL_009b: ldsfld int32 A::i + IL_00a0: ldc.i4.5 + IL_00a1: bne.un.s IL_00c9 + + IL_00a3: ldsfld int32 B::i + IL_00a8: ldc.i4.6 + IL_00a9: bne.un.s IL_00c9 + + IL_00ab: ldsfld int32 C::i + IL_00b0: ldc.i4.7 + IL_00b1: bne.un.s IL_00c9 + + IL_00b3: ldsfld int32 D::i + IL_00b8: ldc.i4.8 + IL_00b9: bne.un.s IL_00c9 + + IL_00bb: ldsfld int32 E::i + IL_00c0: ldc.i4.s 9 + IL_00c2: ceq + IL_00c4: ldc.i4.0 + IL_00c5: ceq + IL_00c7: br.s IL_00ca + + IL_00c9: ldc.i4.1 + IL_00ca: stloc.s V_4 + IL_00cc: ldloc.s V_4 + IL_00ce: brtrue.s IL_00e1 + + IL_00d0: nop + IL_00d1: ldstr "PASS" + IL_00d6: call void [System.Console]System.Console::WriteLine(string) + IL_00db: nop + IL_00dc: ldc.i4.s 100 + IL_00de: stloc.3 + IL_00df: br.s IL_00f2 + + IL_00e1: nop + IL_00e2: ldstr "FAIL" + IL_00e7: call void [System.Console]System.Console::WriteLine(string) + IL_00ec: nop + IL_00ed: ldc.i4.s 101 + IL_00ef: stloc.3 + IL_00f0: br.s IL_00f2 + + IL_00f2: ldloc.3 + IL_00f3: ret + } // end of method Test::Main + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method Test::.ctor + +} // end of class Test + + +// ============================================================= + +// *********** DISASSEMBLY COMPLETE *********************** +// WARNING: Created Win32 resource file CircularCctorThreeThreads02BFI.res diff --git a/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads02BFI.ilproj b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads02BFI.ilproj new file mode 100644 index 0000000000..4607cad8b0 --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads02BFI.ilproj @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> + <PropertyGroup> + <AssemblyName>CircularCctorThreeThreads02BFI</AssemblyName> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid> + <FileAlignment>512</FileAlignment> + <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> + <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp> + <AllowUnsafeBlocks>true</AllowUnsafeBlocks> + <ReferenceLocalMscorlib>true</ReferenceLocalMscorlib> + <OutputType>Exe</OutputType> + <CLRTestKind>BuildAndRun</CLRTestKind> + <CLRTestPriority>0</CLRTestPriority> + </PropertyGroup> + + <ItemGroup> + <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies"> + <Visible>False</Visible> + </CodeAnalysisDependentAssemblyPaths> + </ItemGroup> + + <ItemGroup> + <Compile Include="CircularCctorThreeThreads02BFI.il" /> + </ItemGroup> + + <ItemGroup> + <None Include="app.config" /> + </ItemGroup> + + <ItemGroup> + <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" /> + </ItemGroup> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> +</Project> diff --git a/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads03.cs b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads03.cs new file mode 100644 index 0000000000..5b6b090709 --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads03.cs @@ -0,0 +1,180 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/* +A --> B --> C --> D --> E --> A +3 threads: Thread T1 starts initialization at A, thread T2 starts initialization at C, and thread T3 starts initialization at E. +A::.cctor sleeps for a few seconds so Thread T1 is blocked. +C::.cctor sleeps for a few seconds so Thread T2 is blocked. + +T3 invokes E::.cctor and blocks because T1 is in A::.cctor. +T1 becomes unblocked, invokes B::.cctor, tries to invoke C::.cctor and becomes blocked (because C::.cctor is used by T2). +T2 becomes unblocked , invokes D.::cctor, tries to invokes E::.cctor at which point we get 3 thread deadlock since T3 is waiting for T1 and T1 is waiting for T2 and T2 is waiting for T3. +We detect the deadlock and allow T2 to see E.i uninitialized state. + +In D.cctor: thread T2: E.i 0 +In C.cctor: thread T2: D.i 8 +In B.cctor: thread T1: C.i 7 +In A.cctor: thread T1: B.i 6 +In E.cctor: thread T3: A.i 5 +*/ + +using System; +using System.Threading; +using System.Runtime.CompilerServices; +public class A +{ + public static int i; + + static A() + { + + Thread.Sleep(1000*2); // 1 second + Console.WriteLine("In A.cctor: thread {0}: B.i {1}",Thread.CurrentThread.Name,B.i); + A.i = 5; + } + + // invoking this should trigger the cctor + [MethodImpl(MethodImplOptions.NoInlining)] + public static void SomeMethod() + { + Console.WriteLine("In MyClass.SomeMethod(): thread {0}",Thread.CurrentThread.Name); + } + +} + +public class B +{ + public static int i; + + static B() + { + + + Console.WriteLine("In B.cctor: thread {0}: C.i {1}",Thread.CurrentThread.Name,C.i); + B.i = 6; + } + + // invoking this should trigger the cctor + [MethodImpl(MethodImplOptions.NoInlining)] + public static void SomeMethod() + { + Console.WriteLine("In MyClass.SomeMethod(): thread {0}",Thread.CurrentThread.Name); + } + +} + +public class C +{ + public static int i; + + static C() + { + + Thread.Sleep(1000*2); // 1 second + Console.WriteLine("In C.cctor: thread {0}: D.i {1}",Thread.CurrentThread.Name,D.i); + C.i = 7; + } + + // invoking this should trigger the cctor + [MethodImpl(MethodImplOptions.NoInlining)] + public static void SomeMethod() + { + Console.WriteLine("In MyClass.SomeMethod(): thread {0}",Thread.CurrentThread.Name); + } + +} + +public class D +{ + public static int i; + + static D() + { + Console.WriteLine("In D.cctor: thread {0}: E.i {1}",Thread.CurrentThread.Name,E.i); + D.i = 8; + } + + // invoking this should trigger the cctor + [MethodImpl(MethodImplOptions.NoInlining)] + public static void SomeMethod() + { + Console.WriteLine("In MyClass.SomeMethod(): thread {0}",Thread.CurrentThread.Name); + } + +} + +public class E +{ + public static int i; + + static E() + { + Console.WriteLine("In E.cctor: thread {0}: A.i {1}",Thread.CurrentThread.Name,A.i); + E.i = 9; + } + + // invoking this should trigger the cctor + [MethodImpl(MethodImplOptions.NoInlining)] + public static void SomeMethod() + { + Console.WriteLine("In MyClass.SomeMethod(): thread {0}",Thread.CurrentThread.Name); + } + +} + +public class Test +{ + + public static void RunGetA() + { + A.SomeMethod(); + } + + public static void RunGetC() + { + C.SomeMethod(); + } + + public static void RunGetE() + { + E.SomeMethod(); + } + + + public static int Main() + { + + Thread t1 = new Thread(RunGetA); + t1.Name = "T1"; + Thread t2 = new Thread(RunGetC); + t2.Name = "T2"; + Thread t3 = new Thread(RunGetE); + t3.Name = "T3"; + + + + t1.Start(); + Thread.Sleep(1000*1); // 1 second + t2.Start(); + Thread.Sleep(1000*1); // 1 second + t3.Start(); + + t3.Join(); + t2.Join(); + t1.Join(); + + // make sure that statics were set correctly. + if ( A.i == 5 && B.i == 6 && C.i == 7 && D.i == 8 && E.i == 9 ) + { + Console.WriteLine("PASS"); + return 100; + } + else + { + Console.WriteLine("FAIL"); + return 101; + } + } +} diff --git a/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads03.csproj b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads03.csproj new file mode 100644 index 0000000000..d6d7447389 --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads03.csproj @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> + <PropertyGroup> + <AssemblyName>CircularCctorThreeThreads03</AssemblyName> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid> + <FileAlignment>512</FileAlignment> + <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> + <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp> + <AllowUnsafeBlocks>true</AllowUnsafeBlocks> + <ReferenceLocalMscorlib>false</ReferenceLocalMscorlib> + <OutputType>Exe</OutputType> + <CLRTestKind>BuildAndRun</CLRTestKind> + <CLRTestPriority>0</CLRTestPriority> + </PropertyGroup> + + <ItemGroup> + <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies"> + <Visible>False</Visible> + </CodeAnalysisDependentAssemblyPaths> + </ItemGroup> + + <ItemGroup> + <Compile Include="CircularCctorThreeThreads03.cs" /> + </ItemGroup> + + <ItemGroup> + <None Include="app.config" /> + <None Include="project.json" /> + </ItemGroup> + + <ItemGroup> + <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" /> + </ItemGroup> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> +</Project> diff --git a/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads03BFI.il b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads03BFI.il new file mode 100644 index 0000000000..51d9a3bbe7 --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads03BFI.il @@ -0,0 +1,454 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +.assembly extern System.Console { } + +// Microsoft (R) .NET Framework IL Disassembler. Version 2.0.50103.00 +// Copyright (C) Microsoft Corporation. All rights reserved. + + + +// Metadata version: v2.0.50103 +.assembly extern mscorlib +{ + .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. + .ver 2:0:0:0 +} +.assembly CircularCctorThreeThreads03 +{ + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module CircularCctorThreeThreads03.exe +// MVID: {11FF80B2-E180-44EE-815F-912DD3D6227D} +.imagebase 0x00400000 +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 // WINDOWS_CUI +.corflags 0x00000001 // ILONLY +// Image base: 0x03090000 + + +// =============== CLASS MEMBERS DECLARATION =================== + +.class public auto ansi beforefieldinit A + extends [mscorlib]System.Object +{ + .field public static int32 i + .method private hidebysig specialname rtspecialname static + void .cctor() cil managed + { + // Code size 50 (0x32) + .maxstack 8 + IL_0000: nop + IL_0001: ldc.i4 0x7d0 + IL_0006: call void [mscorlib]System.Threading.Thread::Sleep(int32) + IL_000b: nop + IL_000c: ldstr "In A.cctor: thread {0}: B.i {1}" + IL_0011: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread() + IL_0016: callvirt instance string [mscorlib]System.Threading.Thread::get_Name() + IL_001b: ldsfld int32 B::i + IL_0020: box [mscorlib]System.Int32 + IL_0025: call void [System.Console]System.Console::WriteLine(string, + object, + object) + IL_002a: nop + IL_002b: ldc.i4.5 + IL_002c: stsfld int32 A::i + IL_0031: ret + } // end of method A::.cctor + + .method public hidebysig static void SomeMethod() cil managed noinlining + { + // Code size 23 (0x17) + .maxstack 8 + IL_0000: nop + IL_0001: ldstr "In MyClass.SomeMethod(): thread {0}" + IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread() + IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name() + IL_0010: call void [System.Console]System.Console::WriteLine(string, + object) + IL_0015: nop + IL_0016: ret + } // end of method A::SomeMethod + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method A::.ctor + +} // end of class A + +.class public auto ansi beforefieldinit B + extends [mscorlib]System.Object +{ + .field public static int32 i + .method private hidebysig specialname rtspecialname static + void .cctor() cil managed + { + // Code size 39 (0x27) + .maxstack 8 + IL_0000: nop + IL_0001: ldstr "In B.cctor: thread {0}: C.i {1}" + IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread() + IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name() + IL_0010: ldsfld int32 C::i + IL_0015: box [mscorlib]System.Int32 + IL_001a: call void [System.Console]System.Console::WriteLine(string, + object, + object) + IL_001f: nop + IL_0020: ldc.i4.6 + IL_0021: stsfld int32 B::i + IL_0026: ret + } // end of method B::.cctor + + .method public hidebysig static void SomeMethod() cil managed noinlining + { + // Code size 23 (0x17) + .maxstack 8 + IL_0000: nop + IL_0001: ldstr "In MyClass.SomeMethod(): thread {0}" + IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread() + IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name() + IL_0010: call void [System.Console]System.Console::WriteLine(string, + object) + IL_0015: nop + IL_0016: ret + } // end of method B::SomeMethod + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method B::.ctor + +} // end of class B + +.class public auto ansi beforefieldinit C + extends [mscorlib]System.Object +{ + .field public static int32 i + .method private hidebysig specialname rtspecialname static + void .cctor() cil managed + { + // Code size 50 (0x32) + .maxstack 8 + IL_0000: nop + IL_0001: ldc.i4 0x7d0 + IL_0006: call void [mscorlib]System.Threading.Thread::Sleep(int32) + IL_000b: nop + IL_000c: ldstr "In C.cctor: thread {0}: D.i {1}" + IL_0011: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread() + IL_0016: callvirt instance string [mscorlib]System.Threading.Thread::get_Name() + IL_001b: ldsfld int32 D::i + IL_0020: box [mscorlib]System.Int32 + IL_0025: call void [System.Console]System.Console::WriteLine(string, + object, + object) + IL_002a: nop + IL_002b: ldc.i4.7 + IL_002c: stsfld int32 C::i + IL_0031: ret + } // end of method C::.cctor + + .method public hidebysig static void SomeMethod() cil managed noinlining + { + // Code size 23 (0x17) + .maxstack 8 + IL_0000: nop + IL_0001: ldstr "In MyClass.SomeMethod(): thread {0}" + IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread() + IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name() + IL_0010: call void [System.Console]System.Console::WriteLine(string, + object) + IL_0015: nop + IL_0016: ret + } // end of method C::SomeMethod + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method C::.ctor + +} // end of class C + +.class public auto ansi beforefieldinit D + extends [mscorlib]System.Object +{ + .field public static int32 i + .method private hidebysig specialname rtspecialname static + void .cctor() cil managed + { + // Code size 39 (0x27) + .maxstack 8 + IL_0000: nop + IL_0001: ldstr "In D.cctor: thread {0}: E.i {1}" + IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread() + IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name() + IL_0010: ldsfld int32 E::i + IL_0015: box [mscorlib]System.Int32 + IL_001a: call void [System.Console]System.Console::WriteLine(string, + object, + object) + IL_001f: nop + IL_0020: ldc.i4.8 + IL_0021: stsfld int32 D::i + IL_0026: ret + } // end of method D::.cctor + + .method public hidebysig static void SomeMethod() cil managed noinlining + { + // Code size 23 (0x17) + .maxstack 8 + IL_0000: nop + IL_0001: ldstr "In MyClass.SomeMethod(): thread {0}" + IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread() + IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name() + IL_0010: call void [System.Console]System.Console::WriteLine(string, + object) + IL_0015: nop + IL_0016: ret + } // end of method D::SomeMethod + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method D::.ctor + +} // end of class D + +.class public auto ansi beforefieldinit E + extends [mscorlib]System.Object +{ + .field public static int32 i + .method private hidebysig specialname rtspecialname static + void .cctor() cil managed + { + // Code size 40 (0x28) + .maxstack 8 + IL_0000: nop + IL_0001: ldstr "In E.cctor: thread {0}: A.i {1}" + IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread() + IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name() + IL_0010: ldsfld int32 A::i + IL_0015: box [mscorlib]System.Int32 + IL_001a: call void [System.Console]System.Console::WriteLine(string, + object, + object) + IL_001f: nop + IL_0020: ldc.i4.s 9 + IL_0022: stsfld int32 E::i + IL_0027: ret + } // end of method E::.cctor + + .method public hidebysig static void SomeMethod() cil managed noinlining + { + // Code size 23 (0x17) + .maxstack 8 + IL_0000: nop + IL_0001: ldstr "In MyClass.SomeMethod(): thread {0}" + IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread() + IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name() + IL_0010: call void [System.Console]System.Console::WriteLine(string, + object) + IL_0015: nop + IL_0016: ret + } // end of method E::SomeMethod + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method E::.ctor + +} // end of class E + +.class public auto ansi beforefieldinit Test + extends [mscorlib]System.Object +{ + .method public hidebysig static void RunGetA() cil managed + { + // Code size 8 (0x8) + .maxstack 8 + IL_0000: nop + IL_0001: call void A::SomeMethod() + IL_0006: nop + IL_0007: ret + } // end of method Test::RunGetA + + .method public hidebysig static void RunGetC() cil managed + { + // Code size 8 (0x8) + .maxstack 8 + IL_0000: nop + IL_0001: call void C::SomeMethod() + IL_0006: nop + IL_0007: ret + } // end of method Test::RunGetC + + .method public hidebysig static void RunGetE() cil managed + { + // Code size 8 (0x8) + .maxstack 8 + IL_0000: nop + IL_0001: call void E::SomeMethod() + IL_0006: nop + IL_0007: ret + } // end of method Test::RunGetE + + .method public hidebysig static int32 Main() cil managed + { + .entrypoint + // Code size 244 (0xf4) + .maxstack 3 + .locals init (class [mscorlib]System.Threading.Thread V_0, + class [mscorlib]System.Threading.Thread V_1, + class [mscorlib]System.Threading.Thread V_2, + int32 V_3, + bool V_4) + IL_0000: nop + IL_0001: ldnull + IL_0002: ldftn void Test::RunGetA() + IL_0008: newobj instance void [mscorlib]System.Threading.ThreadStart::.ctor(object, + native int) + IL_000d: newobj instance void [mscorlib]System.Threading.Thread::.ctor(class [mscorlib]System.Threading.ThreadStart) + IL_0012: stloc.0 + IL_0013: ldloc.0 + IL_0014: ldstr "T1" + IL_0019: callvirt instance void [mscorlib]System.Threading.Thread::set_Name(string) + IL_001e: nop + IL_001f: ldnull + IL_0020: ldftn void Test::RunGetC() + IL_0026: newobj instance void [mscorlib]System.Threading.ThreadStart::.ctor(object, + native int) + IL_002b: newobj instance void [mscorlib]System.Threading.Thread::.ctor(class [mscorlib]System.Threading.ThreadStart) + IL_0030: stloc.1 + IL_0031: ldloc.1 + IL_0032: ldstr "T2" + IL_0037: callvirt instance void [mscorlib]System.Threading.Thread::set_Name(string) + IL_003c: nop + IL_003d: ldnull + IL_003e: ldftn void Test::RunGetE() + IL_0044: newobj instance void [mscorlib]System.Threading.ThreadStart::.ctor(object, + native int) + IL_0049: newobj instance void [mscorlib]System.Threading.Thread::.ctor(class [mscorlib]System.Threading.ThreadStart) + IL_004e: stloc.2 + IL_004f: ldloc.2 + IL_0050: ldstr "T3" + IL_0055: callvirt instance void [mscorlib]System.Threading.Thread::set_Name(string) + IL_005a: nop + IL_005b: ldloc.0 + IL_005c: callvirt instance void [mscorlib]System.Threading.Thread::Start() + IL_0061: nop + IL_0062: ldc.i4 0x3e8 + IL_0067: call void [mscorlib]System.Threading.Thread::Sleep(int32) + IL_006c: nop + IL_006d: ldloc.1 + IL_006e: callvirt instance void [mscorlib]System.Threading.Thread::Start() + IL_0073: nop + IL_0074: ldc.i4 0x3e8 + IL_0079: call void [mscorlib]System.Threading.Thread::Sleep(int32) + IL_007e: nop + IL_007f: ldloc.2 + IL_0080: callvirt instance void [mscorlib]System.Threading.Thread::Start() + IL_0085: nop + IL_0086: ldloc.2 + IL_0087: callvirt instance void [mscorlib]System.Threading.Thread::Join() + IL_008c: nop + IL_008d: ldloc.1 + IL_008e: callvirt instance void [mscorlib]System.Threading.Thread::Join() + IL_0093: nop + IL_0094: ldloc.0 + IL_0095: callvirt instance void [mscorlib]System.Threading.Thread::Join() + IL_009a: nop + IL_009b: ldsfld int32 A::i + IL_00a0: ldc.i4.5 + IL_00a1: bne.un.s IL_00c9 + + IL_00a3: ldsfld int32 B::i + IL_00a8: ldc.i4.6 + IL_00a9: bne.un.s IL_00c9 + + IL_00ab: ldsfld int32 C::i + IL_00b0: ldc.i4.7 + IL_00b1: bne.un.s IL_00c9 + + IL_00b3: ldsfld int32 D::i + IL_00b8: ldc.i4.8 + IL_00b9: bne.un.s IL_00c9 + + IL_00bb: ldsfld int32 E::i + IL_00c0: ldc.i4.s 9 + IL_00c2: ceq + IL_00c4: ldc.i4.0 + IL_00c5: ceq + IL_00c7: br.s IL_00ca + + IL_00c9: ldc.i4.1 + IL_00ca: stloc.s V_4 + IL_00cc: ldloc.s V_4 + IL_00ce: brtrue.s IL_00e1 + + IL_00d0: nop + IL_00d1: ldstr "PASS" + IL_00d6: call void [System.Console]System.Console::WriteLine(string) + IL_00db: nop + IL_00dc: ldc.i4.s 100 + IL_00de: stloc.3 + IL_00df: br.s IL_00f2 + + IL_00e1: nop + IL_00e2: ldstr "FAIL" + IL_00e7: call void [System.Console]System.Console::WriteLine(string) + IL_00ec: nop + IL_00ed: ldc.i4.s 101 + IL_00ef: stloc.3 + IL_00f0: br.s IL_00f2 + + IL_00f2: ldloc.3 + IL_00f3: ret + } // end of method Test::Main + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method Test::.ctor + +} // end of class Test + + +// ============================================================= + +// *********** DISASSEMBLY COMPLETE *********************** +// WARNING: Created Win32 resource file CircularCctorThreeThreads03BFI.res diff --git a/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads03BFI.ilproj b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads03BFI.ilproj new file mode 100644 index 0000000000..53f3c3e5ef --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads03BFI.ilproj @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> + <PropertyGroup> + <AssemblyName>CircularCctorThreeThreads03BFI</AssemblyName> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid> + <FileAlignment>512</FileAlignment> + <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> + <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp> + <AllowUnsafeBlocks>true</AllowUnsafeBlocks> + <ReferenceLocalMscorlib>true</ReferenceLocalMscorlib> + <OutputType>Exe</OutputType> + <CLRTestKind>BuildAndRun</CLRTestKind> + <CLRTestPriority>0</CLRTestPriority> + </PropertyGroup> + + <ItemGroup> + <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies"> + <Visible>False</Visible> + </CodeAnalysisDependentAssemblyPaths> + </ItemGroup> + + <ItemGroup> + <Compile Include="CircularCctorThreeThreads03BFI.il" /> + </ItemGroup> + + <ItemGroup> + <None Include="app.config" /> + </ItemGroup> + + <ItemGroup> + <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" /> + </ItemGroup> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> +</Project> diff --git a/tests/src/Loader/classloader/TypeInitialization/CircularCctors/app.config b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/app.config new file mode 100644 index 0000000000..e5622f77ad --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/app.config @@ -0,0 +1,27 @@ +<?xml version = "1.0" encoding="utf-8"?> +<configuration> + <runtime> + <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> + <dependentAssembly> + <assemblyIdentity name="System.Runtime" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.20.0" newVersion="4.0.20.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.Text.Encoding" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.10.0" newVersion="4.0.10.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.Threading.Tasks" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.10.0" newVersion="4.0.10.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.IO" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.10.0" newVersion="4.0.10.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.Reflection" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.10.0" newVersion="4.0.10.0" /> + </dependentAssembly> + </assemblyBinding> + </runtime> +</configuration> diff --git a/tests/src/Loader/classloader/TypeInitialization/CircularCctors/project.json b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/project.json new file mode 100644 index 0000000000..a2e84dc340 --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/project.json @@ -0,0 +1,35 @@ +{ + "dependencies": { + "Microsoft.NETCore.Platforms": "1.0.1-rc2-23816", + "System.Collections": "4.0.10", + "System.Collections.NonGeneric": "4.0.1-rc2-23816", + "System.Collections.Specialized": "4.0.1-rc2-23816", + "System.ComponentModel": "4.0.1-rc2-23816", + "System.Console": "4.0.0-rc2-23816", + "System.Diagnostics.Process": "4.1.0-rc2-23816", + "System.Globalization": "4.0.10", + "System.Globalization.Calendars": "4.0.0", + "System.IO": "4.0.10", + "System.IO.FileSystem": "4.0.0", + "System.IO.FileSystem.Primitives": "4.0.0", + "System.Linq": "4.0.1-rc2-23816", + "System.Linq.Queryable": "4.0.1-rc2-23816", + "System.Reflection": "4.0.10", + "System.Reflection.Primitives": "4.0.0", + "System.Runtime": "4.1.0-rc2-23816", + "System.Runtime.Extensions": "4.0.10", + "System.Runtime.Handles": "4.0.0", + "System.Runtime.InteropServices": "4.1.0-rc2-23816", + "System.Runtime.Loader": "4.0.0-rc2-23816", + "System.Text.Encoding": "4.0.10", + "System.Threading": "4.0.10", + "System.Threading.Thread": "4.0.0-rc2-23816", + "System.Xml.ReaderWriter": "4.0.11-rc2-23816", + "System.Xml.XDocument": "4.0.11-rc2-23816", + "System.Xml.XmlDocument": "4.0.1-rc2-23816", + "System.Xml.XmlSerializer": "4.0.11-rc2-23816" + }, + "frameworks": { + "dnxcore50": {} + } +} diff --git a/tests/src/Loader/classloader/TypeInitialization/CoreCLR/CctorThrowStaticFieldBFI.il b/tests/src/Loader/classloader/TypeInitialization/CoreCLR/CctorThrowStaticFieldBFI.il new file mode 100644 index 0000000000..255282576c --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/CoreCLR/CctorThrowStaticFieldBFI.il @@ -0,0 +1,346 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +.assembly extern System.Console { } + +// Microsoft (R) .NET Framework IL Disassembler. Version 2.0.50103.00 +// Copyright (C) Microsoft Corporation. All rights reserved. + + + +// Metadata version: v2.0.50103 +.assembly extern mscorlib +{ + .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. + .ver 2:0:0:0 +} +.assembly CctorThrowStaticFieldBFI +{ + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module CctorThrowStaticFieldBFI.exe +// MVID: {A7BE6B3C-FF8D-43DB-B091-60CBA24AD082} +.imagebase 0x00400000 +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 // WINDOWS_CUI +.corflags 0x00000001 // ILONLY +// Image base: 0x03090000 + + +// =============== CLASS MEMBERS DECLARATION =================== + +.class public auto ansi beforefieldinit A + extends [mscorlib]System.Object +{ + .field public static int32 i + .method private hidebysig specialname rtspecialname static + void .cctor() cil managed + { + // Code size 24 (0x18) + .maxstack 8 + IL_0000: nop + IL_0001: ldstr "In A.cctor" + IL_0006: call void [System.Console]System.Console::WriteLine(string) + IL_000b: nop + IL_000c: ldc.i4.5 + IL_000d: stsfld int32 A::i + IL_0012: newobj instance void [mscorlib]System.Exception::.ctor() + IL_0017: throw + } // end of method A::.cctor + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method A::.ctor + +} // end of class A + +.class public sequential ansi sealed B + extends [mscorlib]System.ValueType +{ + .pack 0 + .size 1 + .field public static int32 i + .method private hidebysig specialname rtspecialname static + void .cctor() cil managed + { + // Code size 24 (0x18) + .maxstack 8 + IL_0000: nop + IL_0001: ldstr "In B.cctor" + IL_0006: call void [System.Console]System.Console::WriteLine(string) + IL_000b: nop + IL_000c: ldc.i4.5 + IL_000d: stsfld int32 B::i + IL_0012: newobj instance void [mscorlib]System.Exception::.ctor() + IL_0017: throw + } // end of method B::.cctor + +} // end of class B + +.class public auto ansi beforefieldinit Test + extends [mscorlib]System.Object +{ + .method public hidebysig static int32 Main() cil managed + { + .entrypoint + // Code size 405 (0x195) + .maxstack 2 + .locals init (bool V_0, + class [mscorlib]System.Exception V_1, + int32 V_2, + bool V_3) + IL_0000: nop + IL_0001: ldc.i4.1 + IL_0002: stloc.0 + .try + { + IL_0003: nop + IL_0004: ldstr "Accessing class's static field" + IL_0009: call void [System.Console]System.Console::WriteLine(string) + IL_000e: nop + IL_000f: ldstr "A.i: " + IL_0014: ldsfld int32 A::i + IL_0019: box [mscorlib]System.Int32 + IL_001e: call string [mscorlib]System.String::Concat(object, + object) + IL_0023: call void [System.Console]System.Console::WriteLine(string) + IL_0028: nop + IL_0029: ldstr "Did not catch expected TypeInitializationException" + + " exception" + IL_002e: call void [System.Console]System.Console::WriteLine(string) + IL_0033: nop + IL_0034: ldc.i4.0 + IL_0035: stloc.0 + IL_0036: nop + IL_0037: leave.s IL_0061 + + } // end .try + catch [mscorlib]System.TypeInitializationException + { + IL_0039: pop + IL_003a: nop + IL_003b: ldstr "Caught expected exception 1st time" + IL_0040: call void [System.Console]System.Console::WriteLine(string) + IL_0045: nop + IL_0046: nop + IL_0047: leave.s IL_0061 + + } // end handler + catch [mscorlib]System.Exception + { + IL_0049: stloc.1 + IL_004a: nop + IL_004b: ldstr "Caught unexpected exception: " + IL_0050: ldloc.1 + IL_0051: call string [mscorlib]System.String::Concat(object, + object) + IL_0056: call void [System.Console]System.Console::WriteLine(string) + IL_005b: nop + IL_005c: ldc.i4.0 + IL_005d: stloc.0 + IL_005e: nop + IL_005f: leave.s IL_0061 + + } // end handler + IL_0061: nop + .try + { + IL_0062: nop + IL_0063: ldstr "A.i: " + IL_0068: ldsfld int32 A::i + IL_006d: box [mscorlib]System.Int32 + IL_0072: call string [mscorlib]System.String::Concat(object, + object) + IL_0077: call void [System.Console]System.Console::WriteLine(string) + IL_007c: nop + IL_007d: ldstr "Did not catch expected TypeInitializationException" + + " exception" + IL_0082: call void [System.Console]System.Console::WriteLine(string) + IL_0087: nop + IL_0088: ldc.i4.0 + IL_0089: stloc.0 + IL_008a: nop + IL_008b: leave.s IL_00b5 + + } // end .try + catch [mscorlib]System.TypeInitializationException + { + IL_008d: pop + IL_008e: nop + IL_008f: ldstr "Caught expected exception 2nd time\n" + IL_0094: call void [System.Console]System.Console::WriteLine(string) + IL_0099: nop + IL_009a: nop + IL_009b: leave.s IL_00b5 + + } // end handler + catch [mscorlib]System.Exception + { + IL_009d: stloc.1 + IL_009e: nop + IL_009f: ldstr "Caught unexpected exception: " + IL_00a4: ldloc.1 + IL_00a5: call string [mscorlib]System.String::Concat(object, + object) + IL_00aa: call void [System.Console]System.Console::WriteLine(string) + IL_00af: nop + IL_00b0: ldc.i4.0 + IL_00b1: stloc.0 + IL_00b2: nop + IL_00b3: leave.s IL_00b5 + + } // end handler + IL_00b5: nop + IL_00b6: ldstr "Accessing struct's static field" + IL_00bb: call void [System.Console]System.Console::WriteLine(string) + IL_00c0: nop + .try + { + IL_00c1: nop + IL_00c2: ldstr "B.i: " + IL_00c7: ldsfld int32 B::i + IL_00cc: box [mscorlib]System.Int32 + IL_00d1: call string [mscorlib]System.String::Concat(object, + object) + IL_00d6: call void [System.Console]System.Console::WriteLine(string) + IL_00db: nop + IL_00dc: ldstr "Did not catch expected TypeInitializationException" + + " exception" + IL_00e1: call void [System.Console]System.Console::WriteLine(string) + IL_00e6: nop + IL_00e7: ldc.i4.0 + IL_00e8: stloc.0 + IL_00e9: nop + IL_00ea: leave.s IL_0114 + + } // end .try + catch [mscorlib]System.TypeInitializationException + { + IL_00ec: pop + IL_00ed: nop + IL_00ee: ldstr "Caught expected exception 1st time" + IL_00f3: call void [System.Console]System.Console::WriteLine(string) + IL_00f8: nop + IL_00f9: nop + IL_00fa: leave.s IL_0114 + + } // end handler + catch [mscorlib]System.Exception + { + IL_00fc: stloc.1 + IL_00fd: nop + IL_00fe: ldstr "Caught unexpected exception: " + IL_0103: ldloc.1 + IL_0104: call string [mscorlib]System.String::Concat(object, + object) + IL_0109: call void [System.Console]System.Console::WriteLine(string) + IL_010e: nop + IL_010f: ldc.i4.0 + IL_0110: stloc.0 + IL_0111: nop + IL_0112: leave.s IL_0114 + + } // end handler + IL_0114: nop + .try + { + IL_0115: nop + IL_0116: ldstr "B.i: " + IL_011b: ldsfld int32 B::i + IL_0120: box [mscorlib]System.Int32 + IL_0125: call string [mscorlib]System.String::Concat(object, + object) + IL_012a: call void [System.Console]System.Console::WriteLine(string) + IL_012f: nop + IL_0130: ldstr "Did not catch expected TypeInitializationException" + + " exception" + IL_0135: call void [System.Console]System.Console::WriteLine(string) + IL_013a: nop + IL_013b: ldc.i4.0 + IL_013c: stloc.0 + IL_013d: nop + IL_013e: leave.s IL_0168 + + } // end .try + catch [mscorlib]System.TypeInitializationException + { + IL_0140: pop + IL_0141: nop + IL_0142: ldstr "Caught expected exception 2nd time\n" + IL_0147: call void [System.Console]System.Console::WriteLine(string) + IL_014c: nop + IL_014d: nop + IL_014e: leave.s IL_0168 + + } // end handler + catch [mscorlib]System.Exception + { + IL_0150: stloc.1 + IL_0151: nop + IL_0152: ldstr "Caught unexpected exception: " + IL_0157: ldloc.1 + IL_0158: call string [mscorlib]System.String::Concat(object, + object) + IL_015d: call void [System.Console]System.Console::WriteLine(string) + IL_0162: nop + IL_0163: ldc.i4.0 + IL_0164: stloc.0 + IL_0165: nop + IL_0166: leave.s IL_0168 + + } // end handler + IL_0168: nop + IL_0169: ldloc.0 + IL_016a: ldc.i4.0 + IL_016b: ceq + IL_016d: stloc.3 + IL_016e: ldloc.3 + IL_016f: brtrue.s IL_0182 + + IL_0171: nop + IL_0172: ldstr "PASS" + IL_0177: call void [System.Console]System.Console::WriteLine(string) + IL_017c: nop + IL_017d: ldc.i4.s 100 + IL_017f: stloc.2 + IL_0180: br.s IL_0193 + + IL_0182: nop + IL_0183: ldstr "FAIL" + IL_0188: call void [System.Console]System.Console::WriteLine(string) + IL_018d: nop + IL_018e: ldc.i4.s 101 + IL_0190: stloc.2 + IL_0191: br.s IL_0193 + + IL_0193: ldloc.2 + IL_0194: ret + } // end of method Test::Main + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method Test::.ctor + +} // end of class Test + + +// ============================================================= + +// *********** DISASSEMBLY COMPLETE *********************** +// WARNING: Created Win32 resource file TypeLoadInitExcepBFI.res diff --git a/tests/src/Loader/classloader/TypeInitialization/CoreCLR/CctorThrowStaticFieldBFI.ilproj b/tests/src/Loader/classloader/TypeInitialization/CoreCLR/CctorThrowStaticFieldBFI.ilproj new file mode 100644 index 0000000000..a4da803e17 --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/CoreCLR/CctorThrowStaticFieldBFI.ilproj @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> + <PropertyGroup> + <AssemblyName>CctorThrowStaticFieldBFI</AssemblyName> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid> + <FileAlignment>512</FileAlignment> + <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> + <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp> + <AllowUnsafeBlocks>true</AllowUnsafeBlocks> + <ReferenceLocalMscorlib>true</ReferenceLocalMscorlib> + <OutputType>Exe</OutputType> + <CLRTestKind>BuildAndRun</CLRTestKind> + <CLRTestPriority>0</CLRTestPriority> + </PropertyGroup> + + <ItemGroup> + <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies"> + <Visible>False</Visible> + </CodeAnalysisDependentAssemblyPaths> + </ItemGroup> + + <ItemGroup> + <Compile Include="CctorThrowStaticFieldBFI.il" /> + </ItemGroup> + + <ItemGroup> + <None Include="app.config" /> + </ItemGroup> + + <ItemGroup> + <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" /> + </ItemGroup> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> +</Project> diff --git a/tests/src/Loader/classloader/TypeInitialization/CoreCLR/CircularCctorThreeThreads03.cs b/tests/src/Loader/classloader/TypeInitialization/CoreCLR/CircularCctorThreeThreads03.cs new file mode 100644 index 0000000000..5b6b090709 --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/CoreCLR/CircularCctorThreeThreads03.cs @@ -0,0 +1,180 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/* +A --> B --> C --> D --> E --> A +3 threads: Thread T1 starts initialization at A, thread T2 starts initialization at C, and thread T3 starts initialization at E. +A::.cctor sleeps for a few seconds so Thread T1 is blocked. +C::.cctor sleeps for a few seconds so Thread T2 is blocked. + +T3 invokes E::.cctor and blocks because T1 is in A::.cctor. +T1 becomes unblocked, invokes B::.cctor, tries to invoke C::.cctor and becomes blocked (because C::.cctor is used by T2). +T2 becomes unblocked , invokes D.::cctor, tries to invokes E::.cctor at which point we get 3 thread deadlock since T3 is waiting for T1 and T1 is waiting for T2 and T2 is waiting for T3. +We detect the deadlock and allow T2 to see E.i uninitialized state. + +In D.cctor: thread T2: E.i 0 +In C.cctor: thread T2: D.i 8 +In B.cctor: thread T1: C.i 7 +In A.cctor: thread T1: B.i 6 +In E.cctor: thread T3: A.i 5 +*/ + +using System; +using System.Threading; +using System.Runtime.CompilerServices; +public class A +{ + public static int i; + + static A() + { + + Thread.Sleep(1000*2); // 1 second + Console.WriteLine("In A.cctor: thread {0}: B.i {1}",Thread.CurrentThread.Name,B.i); + A.i = 5; + } + + // invoking this should trigger the cctor + [MethodImpl(MethodImplOptions.NoInlining)] + public static void SomeMethod() + { + Console.WriteLine("In MyClass.SomeMethod(): thread {0}",Thread.CurrentThread.Name); + } + +} + +public class B +{ + public static int i; + + static B() + { + + + Console.WriteLine("In B.cctor: thread {0}: C.i {1}",Thread.CurrentThread.Name,C.i); + B.i = 6; + } + + // invoking this should trigger the cctor + [MethodImpl(MethodImplOptions.NoInlining)] + public static void SomeMethod() + { + Console.WriteLine("In MyClass.SomeMethod(): thread {0}",Thread.CurrentThread.Name); + } + +} + +public class C +{ + public static int i; + + static C() + { + + Thread.Sleep(1000*2); // 1 second + Console.WriteLine("In C.cctor: thread {0}: D.i {1}",Thread.CurrentThread.Name,D.i); + C.i = 7; + } + + // invoking this should trigger the cctor + [MethodImpl(MethodImplOptions.NoInlining)] + public static void SomeMethod() + { + Console.WriteLine("In MyClass.SomeMethod(): thread {0}",Thread.CurrentThread.Name); + } + +} + +public class D +{ + public static int i; + + static D() + { + Console.WriteLine("In D.cctor: thread {0}: E.i {1}",Thread.CurrentThread.Name,E.i); + D.i = 8; + } + + // invoking this should trigger the cctor + [MethodImpl(MethodImplOptions.NoInlining)] + public static void SomeMethod() + { + Console.WriteLine("In MyClass.SomeMethod(): thread {0}",Thread.CurrentThread.Name); + } + +} + +public class E +{ + public static int i; + + static E() + { + Console.WriteLine("In E.cctor: thread {0}: A.i {1}",Thread.CurrentThread.Name,A.i); + E.i = 9; + } + + // invoking this should trigger the cctor + [MethodImpl(MethodImplOptions.NoInlining)] + public static void SomeMethod() + { + Console.WriteLine("In MyClass.SomeMethod(): thread {0}",Thread.CurrentThread.Name); + } + +} + +public class Test +{ + + public static void RunGetA() + { + A.SomeMethod(); + } + + public static void RunGetC() + { + C.SomeMethod(); + } + + public static void RunGetE() + { + E.SomeMethod(); + } + + + public static int Main() + { + + Thread t1 = new Thread(RunGetA); + t1.Name = "T1"; + Thread t2 = new Thread(RunGetC); + t2.Name = "T2"; + Thread t3 = new Thread(RunGetE); + t3.Name = "T3"; + + + + t1.Start(); + Thread.Sleep(1000*1); // 1 second + t2.Start(); + Thread.Sleep(1000*1); // 1 second + t3.Start(); + + t3.Join(); + t2.Join(); + t1.Join(); + + // make sure that statics were set correctly. + if ( A.i == 5 && B.i == 6 && C.i == 7 && D.i == 8 && E.i == 9 ) + { + Console.WriteLine("PASS"); + return 100; + } + else + { + Console.WriteLine("FAIL"); + return 101; + } + } +} diff --git a/tests/src/Loader/classloader/TypeInitialization/CoreCLR/CircularCctorThreeThreads03.csproj b/tests/src/Loader/classloader/TypeInitialization/CoreCLR/CircularCctorThreeThreads03.csproj new file mode 100644 index 0000000000..d6d7447389 --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/CoreCLR/CircularCctorThreeThreads03.csproj @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> + <PropertyGroup> + <AssemblyName>CircularCctorThreeThreads03</AssemblyName> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid> + <FileAlignment>512</FileAlignment> + <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> + <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp> + <AllowUnsafeBlocks>true</AllowUnsafeBlocks> + <ReferenceLocalMscorlib>false</ReferenceLocalMscorlib> + <OutputType>Exe</OutputType> + <CLRTestKind>BuildAndRun</CLRTestKind> + <CLRTestPriority>0</CLRTestPriority> + </PropertyGroup> + + <ItemGroup> + <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies"> + <Visible>False</Visible> + </CodeAnalysisDependentAssemblyPaths> + </ItemGroup> + + <ItemGroup> + <Compile Include="CircularCctorThreeThreads03.cs" /> + </ItemGroup> + + <ItemGroup> + <None Include="app.config" /> + <None Include="project.json" /> + </ItemGroup> + + <ItemGroup> + <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" /> + </ItemGroup> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> +</Project> diff --git a/tests/src/Loader/classloader/TypeInitialization/CoreCLR/app.config b/tests/src/Loader/classloader/TypeInitialization/CoreCLR/app.config new file mode 100644 index 0000000000..e5622f77ad --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/CoreCLR/app.config @@ -0,0 +1,27 @@ +<?xml version = "1.0" encoding="utf-8"?> +<configuration> + <runtime> + <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> + <dependentAssembly> + <assemblyIdentity name="System.Runtime" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.20.0" newVersion="4.0.20.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.Text.Encoding" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.10.0" newVersion="4.0.10.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.Threading.Tasks" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.10.0" newVersion="4.0.10.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.IO" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.10.0" newVersion="4.0.10.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.Reflection" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.10.0" newVersion="4.0.10.0" /> + </dependentAssembly> + </assemblyBinding> + </runtime> +</configuration> diff --git a/tests/src/Loader/classloader/TypeInitialization/CoreCLR/project.json b/tests/src/Loader/classloader/TypeInitialization/CoreCLR/project.json new file mode 100644 index 0000000000..a2e84dc340 --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/CoreCLR/project.json @@ -0,0 +1,35 @@ +{ + "dependencies": { + "Microsoft.NETCore.Platforms": "1.0.1-rc2-23816", + "System.Collections": "4.0.10", + "System.Collections.NonGeneric": "4.0.1-rc2-23816", + "System.Collections.Specialized": "4.0.1-rc2-23816", + "System.ComponentModel": "4.0.1-rc2-23816", + "System.Console": "4.0.0-rc2-23816", + "System.Diagnostics.Process": "4.1.0-rc2-23816", + "System.Globalization": "4.0.10", + "System.Globalization.Calendars": "4.0.0", + "System.IO": "4.0.10", + "System.IO.FileSystem": "4.0.0", + "System.IO.FileSystem.Primitives": "4.0.0", + "System.Linq": "4.0.1-rc2-23816", + "System.Linq.Queryable": "4.0.1-rc2-23816", + "System.Reflection": "4.0.10", + "System.Reflection.Primitives": "4.0.0", + "System.Runtime": "4.1.0-rc2-23816", + "System.Runtime.Extensions": "4.0.10", + "System.Runtime.Handles": "4.0.0", + "System.Runtime.InteropServices": "4.1.0-rc2-23816", + "System.Runtime.Loader": "4.0.0-rc2-23816", + "System.Text.Encoding": "4.0.10", + "System.Threading": "4.0.10", + "System.Threading.Thread": "4.0.0-rc2-23816", + "System.Xml.ReaderWriter": "4.0.11-rc2-23816", + "System.Xml.XDocument": "4.0.11-rc2-23816", + "System.Xml.XmlDocument": "4.0.1-rc2-23816", + "System.Xml.XmlSerializer": "4.0.11-rc2-23816" + }, + "frameworks": { + "dnxcore50": {} + } +} diff --git a/tests/src/Loader/classloader/TypeInitialization/Inlining/GenMethInlined.cs b/tests/src/Loader/classloader/TypeInitialization/Inlining/GenMethInlined.cs new file mode 100644 index 0000000000..77fa7ba329 --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/Inlining/GenMethInlined.cs @@ -0,0 +1,127 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// test that .cctor of NotInlined and Inlined (class/struct) is called when Foo.Meth_In and Foo_Meth_NotIn +// is invoked. + +using System; +using System.IO; +using System.Runtime.CompilerServices; + +public class Foo +{ + public static void Meth_In() + { + // NotInlined.NotInlinedMeth is not inlined + NotInlined.NotInlinedMeth<int>(); + } + + public static void Meth_NotIn() + { + // Inlined.InlinedMeth is inlined + Inlined.InlinedMeth<Foo>(); + } + + public static void ValMeth_In() + { + // NotInlinedVal.NotInlinedValMeth is not inlined + NotInlinedVal.NotInlinedValMeth<char>(); + } + + public static void ValMeth_NotIn() + { + // InlinedVal.InlinedValMeth is inlined + InlinedVal.InlinedValMeth<NotInlined>(); + } +} + +public class NotInlined +{ + + static NotInlined() + { + Console.WriteLine("Inside NotInlined::.cctor"); + File.WriteAllText("notinlined.txt", "inside .cctor"); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void NotInlinedMeth<T>() + { + } +} + + +public class Inlined +{ + + static Inlined() + { + Console.WriteLine("Inside Inlined::.cctor"); + File.WriteAllText("inlined.txt", "inside .cctor"); + } + + public static void InlinedMeth<T>() + { + } +} + + +public struct NotInlinedVal +{ + + static NotInlinedVal() + { + Console.WriteLine("Inside NotInlinedVal::.cctor"); + File.WriteAllText("notinlinedval.txt", "inside .cctor"); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void NotInlinedValMeth<T>() + { + } +} + + +public struct InlinedVal +{ + + static InlinedVal() + { + Console.WriteLine("Inside InlinedVal::.cctor"); + File.WriteAllText("inlinedval.txt", "inside .cctor"); + } + + public static void InlinedValMeth<T>() + { + } +} + + +public class Test +{ + public static int Main() + { + Foo.Meth_In(); + Foo.Meth_NotIn(); + + Foo.ValMeth_In(); + Foo.ValMeth_NotIn(); + + if (!File.Exists("inlined.txt") || !File.Exists("notinlined.txt") || !File.Exists("inlinedval.txt") || !File.Exists("notinlinedval.txt") ) + { + Console.WriteLine("FAIL: Cctor wasn't called"); + return 101; + } + else + { + Console.WriteLine("PASS: Cctor was called"); + File.Delete("inlined.txt"); + File.Delete("notinlined.txt"); + File.Delete("inlinedval.txt"); + File.Delete("notinlinedval.txt"); + return 100; + } + + } +} diff --git a/tests/src/Loader/classloader/TypeInitialization/Inlining/GenMethInlined.csproj b/tests/src/Loader/classloader/TypeInitialization/Inlining/GenMethInlined.csproj new file mode 100644 index 0000000000..5c46374fdd --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/Inlining/GenMethInlined.csproj @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> + <PropertyGroup> + <AssemblyName>GenMethInlined</AssemblyName> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid> + <FileAlignment>512</FileAlignment> + <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> + <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp> + <AllowUnsafeBlocks>true</AllowUnsafeBlocks> + <ReferenceLocalMscorlib>false</ReferenceLocalMscorlib> + <OutputType>Exe</OutputType> + <CLRTestKind>BuildAndRun</CLRTestKind> + <CLRTestPriority>0</CLRTestPriority> + </PropertyGroup> + + <ItemGroup> + <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies"> + <Visible>False</Visible> + </CodeAnalysisDependentAssemblyPaths> + </ItemGroup> + + <ItemGroup> + <Compile Include="GenMethInlined.cs" /> + </ItemGroup> + + <ItemGroup> + <None Include="app.config" /> + <None Include="project.json" /> + </ItemGroup> + + <ItemGroup> + <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" /> + </ItemGroup> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> +</Project> diff --git a/tests/src/Loader/classloader/TypeInitialization/Inlining/GenMethInlined_Multinested.cs b/tests/src/Loader/classloader/TypeInitialization/Inlining/GenMethInlined_Multinested.cs new file mode 100644 index 0000000000..0eab4443b1 --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/Inlining/GenMethInlined_Multinested.cs @@ -0,0 +1,155 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// test that .cctor of NotInlined and Inlined (class/struct) is called when Foo.Meth_In and Foo_Meth_NotIn +// is invoked in multinested scenario. + +using System; +using System.IO; +using System.Runtime.CompilerServices; + +public class Bar +{ + public static void BarMeth_In() + { + Foo.Meth_In(); + } + + public static void BarMeth_NotIn() + { + Foo.Meth_NotIn(); + } + + public static void BarValMeth_In() + { + Foo.ValMeth_In(); + } + + public static void BarValMeth_NotIn() + { + Foo.ValMeth_NotIn(); + } + +} + + + +public class Foo +{ + public static void Meth_In() + { + // NotInlined.NotInlinedMeth is not inlined + NotInlined.NotInlinedMeth<int>(); + } + + public static void Meth_NotIn() + { + // Inlined.InlinedMeth is inlined + Inlined.InlinedMeth<char>(); + } + + public static void ValMeth_In() + { + // NotInlinedVal.NotInlinedValMeth is not inlined + NotInlinedVal.NotInlinedValMeth<String>(); + } + + public static void ValMeth_NotIn() + { + // InlinedVal.InlinedValMeth is inlined + InlinedVal.InlinedValMeth<Bar>(); + } +} + + + +public class NotInlined +{ + + static NotInlined() + { + Console.WriteLine("Inside NotInlined::.cctor"); + File.WriteAllText("notinlined.txt", "inside .cctor"); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void NotInlinedMeth<T>() + { + } +} + + +public class Inlined +{ + + static Inlined() + { + Console.WriteLine("Inside Inlined::.cctor"); + File.WriteAllText("inlined.txt", "inside .cctor"); + } + + public static void InlinedMeth<T>() + { + } +} + + +public struct NotInlinedVal +{ + + static NotInlinedVal() + { + Console.WriteLine("Inside NotInlinedVal::.cctor"); + File.WriteAllText("notinlinedval.txt", "inside .cctor"); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void NotInlinedValMeth<T>() + { + } +} + + +public struct InlinedVal +{ + + static InlinedVal() + { + Console.WriteLine("Inside InlinedVal::.cctor"); + File.WriteAllText("inlinedval.txt", "inside .cctor"); + } + + public static void InlinedValMeth<T>() + { + } +} + + +public class Test +{ + public static int Main() + { + Bar.BarMeth_In(); + Bar.BarMeth_NotIn(); + + Bar.BarValMeth_In(); + Bar.BarValMeth_NotIn(); + + if (!File.Exists("inlined.txt") || !File.Exists("notinlined.txt") || !File.Exists("inlinedval.txt") || !File.Exists("notinlinedval.txt") ) + { + Console.WriteLine("FAIL: Cctor wasn't called"); + return 101; + } + else + { + Console.WriteLine("PASS: Cctor was called"); + File.Delete("inlined.txt"); + File.Delete("notinlined.txt"); + File.Delete("inlinedval.txt"); + File.Delete("notinlinedval.txt"); + return 100; + } + + } +} diff --git a/tests/src/Loader/classloader/TypeInitialization/Inlining/GenMethInlined_Multinested.csproj b/tests/src/Loader/classloader/TypeInitialization/Inlining/GenMethInlined_Multinested.csproj new file mode 100644 index 0000000000..c5415946b2 --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/Inlining/GenMethInlined_Multinested.csproj @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> + <PropertyGroup> + <AssemblyName>GenMethInlined_Multinested</AssemblyName> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid> + <FileAlignment>512</FileAlignment> + <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> + <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp> + <AllowUnsafeBlocks>true</AllowUnsafeBlocks> + <ReferenceLocalMscorlib>false</ReferenceLocalMscorlib> + <OutputType>Exe</OutputType> + <CLRTestKind>BuildAndRun</CLRTestKind> + <CLRTestPriority>0</CLRTestPriority> + </PropertyGroup> + + <ItemGroup> + <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies"> + <Visible>False</Visible> + </CodeAnalysisDependentAssemblyPaths> + </ItemGroup> + + <ItemGroup> + <Compile Include="GenMethInlined_Multinested.cs" /> + </ItemGroup> + + <ItemGroup> + <None Include="app.config" /> + <None Include="project.json" /> + </ItemGroup> + + <ItemGroup> + <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" /> + </ItemGroup> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> +</Project> diff --git a/tests/src/Loader/classloader/TypeInitialization/Inlining/GenTypeInlined.cs b/tests/src/Loader/classloader/TypeInitialization/Inlining/GenTypeInlined.cs new file mode 100644 index 0000000000..6709f344a6 --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/Inlining/GenTypeInlined.cs @@ -0,0 +1,126 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// test that .cctor of NotInlined and Inlined (class/struct) is called when Foo.Meth_In and Foo_Meth_NotIn is invoked. + +using System; +using System.IO; +using System.Runtime.CompilerServices; + +public class Foo<T> +{ + public static void Meth_In() + { + // NotInlined.NotInlinedMeth is not inlined + NotInlined<int>.NotInlinedMeth(); + } + + public static void Meth_NotIn() + { + // Inlined.InlinedMeth is inlined + Inlined<int>.InlinedMeth(); + } + + public static void ValMeth_In() + { + // NotInlinedVal.NotInlinedValMeth is not inlined + NotInlinedVal<int>.NotInlinedValMeth(); + } + + public static void ValMeth_NotIn() + { + // InlinedVal.InlinedValMeth is inlined + InlinedVal<int>.InlinedValMeth(); + } +} + +public class NotInlined<T> +{ + + static NotInlined() + { + Console.WriteLine("Inside NotInlined::.cctor"); + File.WriteAllText("notinlined.txt", "inside .cctor"); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void NotInlinedMeth() + { + } +} + + +public class Inlined<T> +{ + + static Inlined() + { + Console.WriteLine("Inside Inlined::.cctor"); + File.WriteAllText("inlined.txt", "inside .cctor"); + } + + public static void InlinedMeth() + { + } +} + + +public struct NotInlinedVal<T> +{ + + static NotInlinedVal() + { + Console.WriteLine("Inside NotInlinedVal::.cctor"); + File.WriteAllText("notinlinedval.txt", "inside .cctor"); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void NotInlinedValMeth() + { + } +} + + +public struct InlinedVal<T> +{ + + static InlinedVal() + { + Console.WriteLine("Inside InlinedVal::.cctor"); + File.WriteAllText("inlinedval.txt", "inside .cctor"); + } + + public static void InlinedValMeth() + { + } +} + + +public class Test +{ + public static int Main() + { + Foo<int>.Meth_In(); + Foo<char>.Meth_NotIn(); + + Foo<InlinedVal<int>>.ValMeth_In(); + Foo<NotInlined<bool>>.ValMeth_NotIn(); + + if (!File.Exists("inlined.txt") || !File.Exists("notinlined.txt") || !File.Exists("inlinedval.txt") || !File.Exists("notinlinedval.txt") ) + { + Console.WriteLine("FAIL: Cctor wasn't called"); + return 101; + } + else + { + Console.WriteLine("PASS: Cctor was called"); + File.Delete("inlined.txt"); + File.Delete("notinlined.txt"); + File.Delete("inlinedval.txt"); + File.Delete("notinlinedval.txt"); + return 100; + } + + } +} diff --git a/tests/src/Loader/classloader/TypeInitialization/Inlining/GenTypeInlined.csproj b/tests/src/Loader/classloader/TypeInitialization/Inlining/GenTypeInlined.csproj new file mode 100644 index 0000000000..0314a84eb3 --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/Inlining/GenTypeInlined.csproj @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> + <PropertyGroup> + <AssemblyName>GenTypeInlined</AssemblyName> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid> + <FileAlignment>512</FileAlignment> + <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> + <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp> + <AllowUnsafeBlocks>true</AllowUnsafeBlocks> + <ReferenceLocalMscorlib>false</ReferenceLocalMscorlib> + <OutputType>Exe</OutputType> + <CLRTestKind>BuildAndRun</CLRTestKind> + <CLRTestPriority>0</CLRTestPriority> + </PropertyGroup> + + <ItemGroup> + <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies"> + <Visible>False</Visible> + </CodeAnalysisDependentAssemblyPaths> + </ItemGroup> + + <ItemGroup> + <Compile Include="GenTypeInlined.cs" /> + </ItemGroup> + + <ItemGroup> + <None Include="app.config" /> + <None Include="project.json" /> + </ItemGroup> + + <ItemGroup> + <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" /> + </ItemGroup> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> +</Project> diff --git a/tests/src/Loader/classloader/TypeInitialization/Inlining/GenTypeInlined_Multinested.cs b/tests/src/Loader/classloader/TypeInitialization/Inlining/GenTypeInlined_Multinested.cs new file mode 100644 index 0000000000..6cbed4ca75 --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/Inlining/GenTypeInlined_Multinested.cs @@ -0,0 +1,154 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// test that .cctor of NotInlined and Inlined (class/struct) is called when Foo.Meth_In and Foo_Meth_NotIn +// is invoked in multinested scenario. + +using System; +using System.IO; +using System.Runtime.CompilerServices; + +public class Bar<T> +{ + public static void BarMeth_In() + { + Foo<int>.Meth_In(); + } + + public static void BarMeth_NotIn() + { + Foo<Foo<int>>.Meth_NotIn(); + } + + public static void BarValMeth_In() + { + Foo<char>.ValMeth_In(); + } + + public static void BarValMeth_NotIn() + { + Foo<Bar<String>>.ValMeth_NotIn(); + } +} + + + +public class Foo<U> +{ + public static void Meth_In() + { + // NotInlined.NotInlinedMeth is not inlined + NotInlined<int>.NotInlinedMeth(); + } + + public static void Meth_NotIn() + { + // Inlined.InlinedMeth is inlined + Inlined<int>.InlinedMeth(); + } + + public static void ValMeth_In() + { + // NotInlinedVal.NotInlinedValMeth is not inlined + NotInlinedVal<int>.NotInlinedValMeth(); + } + + public static void ValMeth_NotIn() + { + // InlinedVal.InlinedValMeth is inlined + InlinedVal<int>.InlinedValMeth(); + } +} + + + +public class NotInlined<T> +{ + + static NotInlined() + { + Console.WriteLine("Inside NotInlined::.cctor"); + File.WriteAllText("notinlined.txt", "inside .cctor"); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void NotInlinedMeth() + { + } +} + + +public class Inlined<T> +{ + + static Inlined() + { + Console.WriteLine("Inside Inlined::.cctor"); + File.WriteAllText("inlined.txt", "inside .cctor"); + } + + public static void InlinedMeth() + { + } +} + + +public struct NotInlinedVal<T> +{ + + static NotInlinedVal() + { + Console.WriteLine("Inside NotInlinedVal::.cctor"); + File.WriteAllText("notinlinedval.txt", "inside .cctor"); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void NotInlinedValMeth() + { + } +} + + +public struct InlinedVal<T> +{ + + static InlinedVal() + { + Console.WriteLine("Inside InlinedVal::.cctor"); + File.WriteAllText("inlinedval.txt", "inside .cctor"); + } + + public static void InlinedValMeth() + { + } +} + + +public class Test +{ + public static int Main() + { + Foo<int>.Meth_In(); + + Bar<int>.BarMeth_NotIn(); + + Bar<int>.BarValMeth_In(); + Bar<int>.BarValMeth_NotIn(); + + if (!File.Exists("inlined.txt") || !File.Exists("notinlined.txt") || !File.Exists("inlinedval.txt") || !File.Exists("notinlinedval.txt") ) + { + Console.WriteLine("FAIL: Cctor wasn't called"); + return 101; + } + else + { + Console.WriteLine("PASS: Cctor was called"); + File.Delete("inlined.txt"); + File.Delete("notinlined.txt"); + File.Delete("inlinedval.txt"); + File.Delete("notinlinedval.txt"); + return 100; + } + } +} diff --git a/tests/src/Loader/classloader/TypeInitialization/Inlining/GenTypeInlined_Multinested.csproj b/tests/src/Loader/classloader/TypeInitialization/Inlining/GenTypeInlined_Multinested.csproj new file mode 100644 index 0000000000..e776b199af --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/Inlining/GenTypeInlined_Multinested.csproj @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> + <PropertyGroup> + <AssemblyName>GenTypeInlined_Multinested</AssemblyName> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid> + <FileAlignment>512</FileAlignment> + <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> + <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp> + <AllowUnsafeBlocks>true</AllowUnsafeBlocks> + <ReferenceLocalMscorlib>false</ReferenceLocalMscorlib> + <OutputType>Exe</OutputType> + <CLRTestKind>BuildAndRun</CLRTestKind> + <CLRTestPriority>0</CLRTestPriority> + </PropertyGroup> + + <ItemGroup> + <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies"> + <Visible>False</Visible> + </CodeAnalysisDependentAssemblyPaths> + </ItemGroup> + + <ItemGroup> + <Compile Include="GenTypeInlined_Multinested.cs" /> + </ItemGroup> + + <ItemGroup> + <None Include="app.config" /> + <None Include="project.json" /> + </ItemGroup> + + <ItemGroup> + <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" /> + </ItemGroup> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> +</Project> diff --git a/tests/src/Loader/classloader/TypeInitialization/Inlining/Inlined.cs b/tests/src/Loader/classloader/TypeInitialization/Inlining/Inlined.cs new file mode 100644 index 0000000000..f73dd52fc7 --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/Inlining/Inlined.cs @@ -0,0 +1,126 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// test that .cctor of NotInlined and Inlined (class/struct) is called when Foo.Meth_In and Foo_Meth_NotIn is invoked. + +using System; +using System.IO; +using System.Runtime.CompilerServices; + +public class Foo +{ + public static void Meth_In() + { + // NotInlined.NotInlinedMeth is not inlined + NotInlined.NotInlinedMeth(); + } + + public static void Meth_NotIn() + { + // Inlined.InlinedMeth is inlined + Inlined.InlinedMeth(); + } + + public static void ValMeth_In() + { + // NotInlinedVal.NotInlinedValMeth is not inlined + NotInlinedVal.NotInlinedValMeth(); + } + + public static void ValMeth_NotIn() + { + // InlinedVal.InlinedValMeth is inlined + InlinedVal.InlinedValMeth(); + } +} + +public class NotInlined +{ + + static NotInlined() + { + Console.WriteLine("Inside NotInlined::.cctor"); + File.WriteAllText("notinlined.txt", "inside .cctor"); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void NotInlinedMeth() + { + } +} + + +public class Inlined +{ + + static Inlined() + { + Console.WriteLine("Inside Inlined::.cctor"); + File.WriteAllText("inlined.txt", "inside .cctor"); + } + + public static void InlinedMeth() + { + } +} + + +public struct NotInlinedVal +{ + + static NotInlinedVal() + { + Console.WriteLine("Inside NotInlinedVal::.cctor"); + File.WriteAllText("notinlinedval.txt", "inside .cctor"); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void NotInlinedValMeth() + { + } +} + + +public struct InlinedVal +{ + + static InlinedVal() + { + Console.WriteLine("Inside InlinedVal::.cctor"); + File.WriteAllText("inlinedval.txt", "inside .cctor"); + } + + public static void InlinedValMeth() + { + } +} + + +public class Test +{ + public static int Main() + { + Foo.Meth_In(); + Foo.Meth_NotIn(); + + Foo.ValMeth_In(); + Foo.ValMeth_NotIn(); + + if (!File.Exists("inlined.txt") || !File.Exists("notinlined.txt") || !File.Exists("inlinedval.txt") || !File.Exists("notinlinedval.txt") ) + { + Console.WriteLine("FAIL: Cctor wasn't called"); + return 101; + } + else + { + Console.WriteLine("PASS: Cctor was called"); + File.Delete("inlined.txt"); + File.Delete("notinlined.txt"); + File.Delete("inlinedval.txt"); + File.Delete("notinlinedval.txt"); + return 100; + } + + } +} diff --git a/tests/src/Loader/classloader/TypeInitialization/Inlining/Inlined.csproj b/tests/src/Loader/classloader/TypeInitialization/Inlining/Inlined.csproj new file mode 100644 index 0000000000..46d088b382 --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/Inlining/Inlined.csproj @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> + <PropertyGroup> + <AssemblyName>Inlined</AssemblyName> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid> + <FileAlignment>512</FileAlignment> + <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> + <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp> + <AllowUnsafeBlocks>true</AllowUnsafeBlocks> + <ReferenceLocalMscorlib>false</ReferenceLocalMscorlib> + <OutputType>Exe</OutputType> + <CLRTestKind>BuildAndRun</CLRTestKind> + <CLRTestPriority>0</CLRTestPriority> + </PropertyGroup> + + <ItemGroup> + <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies"> + <Visible>False</Visible> + </CodeAnalysisDependentAssemblyPaths> + </ItemGroup> + + <ItemGroup> + <Compile Include="Inlined.cs" /> + </ItemGroup> + + <ItemGroup> + <None Include="app.config" /> + <None Include="project.json" /> + </ItemGroup> + + <ItemGroup> + <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" /> + </ItemGroup> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> +</Project> diff --git a/tests/src/Loader/classloader/TypeInitialization/Inlining/Inlined_Multinested.cs b/tests/src/Loader/classloader/TypeInitialization/Inlining/Inlined_Multinested.cs new file mode 100644 index 0000000000..a09d865546 --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/Inlining/Inlined_Multinested.cs @@ -0,0 +1,154 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// test that .cctor of NotInlined and Inlined (class/struct) is called when Foo.Meth_In and Foo_Meth_NotIn is invoked. + +using System; +using System.IO; +using System.Runtime.CompilerServices; + +public class Bar +{ + public static void BarMeth_In() + { + Foo.Meth_In(); + } + + public static void BarMeth_NotIn() + { + Foo.Meth_NotIn(); + } + + public static void BarValMeth_In() + { + Foo.ValMeth_In(); + } + + public static void BarValMeth_NotIn() + { + Foo.ValMeth_NotIn(); + } + +} + + + +public class Foo +{ + public static void Meth_In() + { + // NotInlined.NotInlinedMeth is not inlined + NotInlined.NotInlinedMeth(); + } + + public static void Meth_NotIn() + { + // Inlined.InlinedMeth is inlined + Inlined.InlinedMeth(); + } + + public static void ValMeth_In() + { + // NotInlinedVal.NotInlinedValMeth is not inlined + NotInlinedVal.NotInlinedValMeth(); + } + + public static void ValMeth_NotIn() + { + // InlinedVal.InlinedValMeth is inlined + InlinedVal.InlinedValMeth(); + } +} + + + +public class NotInlined +{ + + static NotInlined() + { + Console.WriteLine("Inside NotInlined::.cctor"); + File.WriteAllText("notinlined.txt", "inside .cctor"); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void NotInlinedMeth() + { + } +} + + +public class Inlined +{ + + static Inlined() + { + Console.WriteLine("Inside Inlined::.cctor"); + File.WriteAllText("inlined.txt", "inside .cctor"); + } + + public static void InlinedMeth() + { + } +} + + +public struct NotInlinedVal +{ + + static NotInlinedVal() + { + Console.WriteLine("Inside NotInlinedVal::.cctor"); + File.WriteAllText("notinlinedval.txt", "inside .cctor"); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void NotInlinedValMeth() + { + } +} + + +public struct InlinedVal +{ + + static InlinedVal() + { + Console.WriteLine("Inside InlinedVal::.cctor"); + File.WriteAllText("inlinedval.txt", "inside .cctor"); + } + + public static void InlinedValMeth() + { + } +} + + +public class Test +{ + public static int Main() + { + Bar.BarMeth_In(); + Bar.BarMeth_NotIn(); + + Bar.BarValMeth_In(); + Bar.BarValMeth_NotIn(); + + if (!File.Exists("inlined.txt") || !File.Exists("notinlined.txt") || !File.Exists("inlinedval.txt") || !File.Exists("notinlinedval.txt") ) + { + Console.WriteLine("FAIL: Cctor wasn't called"); + return 101; + } + else + { + Console.WriteLine("PASS: Cctor was called"); + File.Delete("inlined.txt"); + File.Delete("notinlined.txt"); + File.Delete("inlinedval.txt"); + File.Delete("notinlinedval.txt"); + return 100; + } + + } +} diff --git a/tests/src/Loader/classloader/TypeInitialization/Inlining/Inlined_Multinested.csproj b/tests/src/Loader/classloader/TypeInitialization/Inlining/Inlined_Multinested.csproj new file mode 100644 index 0000000000..77bb024bff --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/Inlining/Inlined_Multinested.csproj @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> + <PropertyGroup> + <AssemblyName>Inlined_Multinested</AssemblyName> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid> + <FileAlignment>512</FileAlignment> + <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> + <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp> + <AllowUnsafeBlocks>true</AllowUnsafeBlocks> + <ReferenceLocalMscorlib>false</ReferenceLocalMscorlib> + <OutputType>Exe</OutputType> + <CLRTestKind>BuildAndRun</CLRTestKind> + <CLRTestPriority>0</CLRTestPriority> + </PropertyGroup> + + <ItemGroup> + <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies"> + <Visible>False</Visible> + </CodeAnalysisDependentAssemblyPaths> + </ItemGroup> + + <ItemGroup> + <Compile Include="Inlined_Multinested.cs" /> + </ItemGroup> + + <ItemGroup> + <None Include="app.config" /> + <None Include="project.json" /> + </ItemGroup> + + <ItemGroup> + <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" /> + </ItemGroup> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> +</Project> diff --git a/tests/src/Loader/classloader/TypeInitialization/Inlining/app.config b/tests/src/Loader/classloader/TypeInitialization/Inlining/app.config new file mode 100644 index 0000000000..e5622f77ad --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/Inlining/app.config @@ -0,0 +1,27 @@ +<?xml version = "1.0" encoding="utf-8"?> +<configuration> + <runtime> + <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> + <dependentAssembly> + <assemblyIdentity name="System.Runtime" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.20.0" newVersion="4.0.20.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.Text.Encoding" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.10.0" newVersion="4.0.10.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.Threading.Tasks" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.10.0" newVersion="4.0.10.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.IO" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.10.0" newVersion="4.0.10.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.Reflection" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.10.0" newVersion="4.0.10.0" /> + </dependentAssembly> + </assemblyBinding> + </runtime> +</configuration> diff --git a/tests/src/Loader/classloader/TypeInitialization/Inlining/project.json b/tests/src/Loader/classloader/TypeInitialization/Inlining/project.json new file mode 100644 index 0000000000..a2e84dc340 --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/Inlining/project.json @@ -0,0 +1,35 @@ +{ + "dependencies": { + "Microsoft.NETCore.Platforms": "1.0.1-rc2-23816", + "System.Collections": "4.0.10", + "System.Collections.NonGeneric": "4.0.1-rc2-23816", + "System.Collections.Specialized": "4.0.1-rc2-23816", + "System.ComponentModel": "4.0.1-rc2-23816", + "System.Console": "4.0.0-rc2-23816", + "System.Diagnostics.Process": "4.1.0-rc2-23816", + "System.Globalization": "4.0.10", + "System.Globalization.Calendars": "4.0.0", + "System.IO": "4.0.10", + "System.IO.FileSystem": "4.0.0", + "System.IO.FileSystem.Primitives": "4.0.0", + "System.Linq": "4.0.1-rc2-23816", + "System.Linq.Queryable": "4.0.1-rc2-23816", + "System.Reflection": "4.0.10", + "System.Reflection.Primitives": "4.0.0", + "System.Runtime": "4.1.0-rc2-23816", + "System.Runtime.Extensions": "4.0.10", + "System.Runtime.Handles": "4.0.0", + "System.Runtime.InteropServices": "4.1.0-rc2-23816", + "System.Runtime.Loader": "4.0.0-rc2-23816", + "System.Text.Encoding": "4.0.10", + "System.Threading": "4.0.10", + "System.Threading.Thread": "4.0.0-rc2-23816", + "System.Xml.ReaderWriter": "4.0.11-rc2-23816", + "System.Xml.XDocument": "4.0.11-rc2-23816", + "System.Xml.XmlDocument": "4.0.1-rc2-23816", + "System.Xml.XmlSerializer": "4.0.11-rc2-23816" + }, + "frameworks": { + "dnxcore50": {} + } +} diff --git a/tests/src/Loader/classloader/TypeInitialization/ThisNulllPointer/CctorZeroVal01.cs b/tests/src/Loader/classloader/TypeInitialization/ThisNulllPointer/CctorZeroVal01.cs new file mode 100644 index 0000000000..7279d6c274 --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/ThisNulllPointer/CctorZeroVal01.cs @@ -0,0 +1,70 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// Call a non-virtual instance method of a zero-constructed value type +// The method doesn't access type's static fields. + +using System; +using System.IO; + +public class FLAG +{ + public static bool success = false; +} + + +public struct A +{ + public static int i; + + static A() + { + + Console.WriteLine("In A.cctor"); + FLAG.success = true; + } + + public void methodA() + { + } +} + + +public class Test +{ + public static int Main() + { + + Console.WriteLine("\n============================================================"); + Console.WriteLine("NOTE: This test will fail with NGEN"); + Console.WriteLine("We do not guarantee to execute static .cctor for structs"); + Console.WriteLine("unless the instance .ctor is explicitly called\n"); + Console.WriteLine("============================================================"); + + try + { + // this will trigger A::.cctor + A a = new A(); + + a.methodA(); + + if(!FLAG.success) + { + Console.WriteLine("FAIL: Cctor wasn't called"); + return 101; + } + else + { + Console.WriteLine("PASS: Cctor was called"); + return 100; + } + } + catch (Exception e) + { + Console.WriteLine("FAIL: Caught unexpected exception: " + e); + return 102; + } + } +} + diff --git a/tests/src/Loader/classloader/TypeInitialization/ThisNulllPointer/CctorZeroVal01.csproj b/tests/src/Loader/classloader/TypeInitialization/ThisNulllPointer/CctorZeroVal01.csproj new file mode 100644 index 0000000000..0857ef3dfc --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/ThisNulllPointer/CctorZeroVal01.csproj @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> + <PropertyGroup> + <AssemblyName>CctorZeroVal01</AssemblyName> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid> + <FileAlignment>512</FileAlignment> + <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> + <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp> + <AllowUnsafeBlocks>true</AllowUnsafeBlocks> + <ReferenceLocalMscorlib>false</ReferenceLocalMscorlib> + <OutputType>Exe</OutputType> + <CLRTestKind>BuildAndRun</CLRTestKind> + <CLRTestPriority>0</CLRTestPriority> + </PropertyGroup> + + <ItemGroup> + <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies"> + <Visible>False</Visible> + </CodeAnalysisDependentAssemblyPaths> + </ItemGroup> + + <ItemGroup> + <Compile Include="CctorZeroVal01.cs" /> + </ItemGroup> + + <ItemGroup> + <None Include="app.config" /> + <None Include="project.json" /> + </ItemGroup> + + <ItemGroup> + <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" /> + </ItemGroup> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> +</Project> diff --git a/tests/src/Loader/classloader/TypeInitialization/ThisNulllPointer/CctorZeroVal02.cs b/tests/src/Loader/classloader/TypeInitialization/ThisNulllPointer/CctorZeroVal02.cs new file mode 100644 index 0000000000..8f3ded3cca --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/ThisNulllPointer/CctorZeroVal02.cs @@ -0,0 +1,64 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// Call a non-virtual instance method of a zero-constructed value type +// The method accesses type's static fields. + +using System; +using System.IO; + +public class FLAG +{ + public static bool success = false; +} + + +public struct A +{ + public static int i; + + static A() + { + + Console.WriteLine("In A.cctor"); + FLAG.success = true; + } + + public void methodA() + { + A.i = 5; + //Console.WriteLine("A.i : " + i); + } +} + + +public class Test +{ + public static int Main() + { + + try + { + A a = new A(); + + a.methodA(); + + if (!FLAG.success) + { + Console.WriteLine("FAIL: Cctor wasn't called"); + return 101; + } + else + { + Console.WriteLine("PASS: Cctor was called"); + return 100; + } + } + catch (Exception e) + { + Console.WriteLine("FAIL: Caught unexpected exception: " + e); + return 102; + } + } +} diff --git a/tests/src/Loader/classloader/TypeInitialization/ThisNulllPointer/CctorZeroVal02.csproj b/tests/src/Loader/classloader/TypeInitialization/ThisNulllPointer/CctorZeroVal02.csproj new file mode 100644 index 0000000000..3a7bf57366 --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/ThisNulllPointer/CctorZeroVal02.csproj @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> + <PropertyGroup> + <AssemblyName>CctorZeroVal02</AssemblyName> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid> + <FileAlignment>512</FileAlignment> + <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> + <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp> + <AllowUnsafeBlocks>true</AllowUnsafeBlocks> + <ReferenceLocalMscorlib>false</ReferenceLocalMscorlib> + <OutputType>Exe</OutputType> + <CLRTestKind>BuildAndRun</CLRTestKind> + <CLRTestPriority>0</CLRTestPriority> + </PropertyGroup> + + <ItemGroup> + <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies"> + <Visible>False</Visible> + </CodeAnalysisDependentAssemblyPaths> + </ItemGroup> + + <ItemGroup> + <Compile Include="CctorZeroVal02.cs" /> + </ItemGroup> + + <ItemGroup> + <None Include="app.config" /> + <None Include="project.json" /> + </ItemGroup> + + <ItemGroup> + <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" /> + </ItemGroup> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> +</Project> diff --git a/tests/src/Loader/classloader/TypeInitialization/ThisNulllPointer/CctorZeroVal03.cs b/tests/src/Loader/classloader/TypeInitialization/ThisNulllPointer/CctorZeroVal03.cs new file mode 100644 index 0000000000..ca7c80b0e9 --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/ThisNulllPointer/CctorZeroVal03.cs @@ -0,0 +1,65 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// Call a non-virtual instance method of a zero-constructed value type +// The method accesses type's instance fields. + +using System; +using System.IO; + +public class FLAG +{ + public static bool success = false; +} + + +public struct A +{ + public static int i; + + static A() + { + Console.WriteLine("In A.cctor"); + FLAG.success = true; + } + + public void methodA() + { + i = 5; + + } +} + + +public class Test +{ + public static int Main() + { + + try + { + A a = new A(); + + a.methodA(); + + if (!FLAG.success) + { + Console.WriteLine("FAIL: Cctor wasn't called"); + return 101; + } + else + { + Console.WriteLine("PASS: Cctor was called"); + return 100; + } + } + catch (Exception e) + { + Console.WriteLine("FAIL: Caught unexpected exception: " + e); + return 102; + } + + + } +} diff --git a/tests/src/Loader/classloader/TypeInitialization/ThisNulllPointer/CctorZeroVal03.csproj b/tests/src/Loader/classloader/TypeInitialization/ThisNulllPointer/CctorZeroVal03.csproj new file mode 100644 index 0000000000..0e3f6de18a --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/ThisNulllPointer/CctorZeroVal03.csproj @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> + <PropertyGroup> + <AssemblyName>CctorZeroVal03</AssemblyName> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid> + <FileAlignment>512</FileAlignment> + <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> + <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp> + <AllowUnsafeBlocks>true</AllowUnsafeBlocks> + <ReferenceLocalMscorlib>false</ReferenceLocalMscorlib> + <OutputType>Exe</OutputType> + <CLRTestKind>BuildAndRun</CLRTestKind> + <CLRTestPriority>0</CLRTestPriority> + </PropertyGroup> + + <ItemGroup> + <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies"> + <Visible>False</Visible> + </CodeAnalysisDependentAssemblyPaths> + </ItemGroup> + + <ItemGroup> + <Compile Include="CctorZeroVal03.cs" /> + </ItemGroup> + + <ItemGroup> + <None Include="app.config" /> + <None Include="project.json" /> + </ItemGroup> + + <ItemGroup> + <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" /> + </ItemGroup> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> +</Project> diff --git a/tests/src/Loader/classloader/TypeInitialization/ThisNulllPointer/app.config b/tests/src/Loader/classloader/TypeInitialization/ThisNulllPointer/app.config new file mode 100644 index 0000000000..e5622f77ad --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/ThisNulllPointer/app.config @@ -0,0 +1,27 @@ +<?xml version = "1.0" encoding="utf-8"?> +<configuration> + <runtime> + <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> + <dependentAssembly> + <assemblyIdentity name="System.Runtime" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.20.0" newVersion="4.0.20.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.Text.Encoding" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.10.0" newVersion="4.0.10.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.Threading.Tasks" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.10.0" newVersion="4.0.10.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.IO" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.10.0" newVersion="4.0.10.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.Reflection" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.10.0" newVersion="4.0.10.0" /> + </dependentAssembly> + </assemblyBinding> + </runtime> +</configuration> diff --git a/tests/src/Loader/classloader/TypeInitialization/ThisNulllPointer/project.json b/tests/src/Loader/classloader/TypeInitialization/ThisNulllPointer/project.json new file mode 100644 index 0000000000..a2e84dc340 --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/ThisNulllPointer/project.json @@ -0,0 +1,35 @@ +{ + "dependencies": { + "Microsoft.NETCore.Platforms": "1.0.1-rc2-23816", + "System.Collections": "4.0.10", + "System.Collections.NonGeneric": "4.0.1-rc2-23816", + "System.Collections.Specialized": "4.0.1-rc2-23816", + "System.ComponentModel": "4.0.1-rc2-23816", + "System.Console": "4.0.0-rc2-23816", + "System.Diagnostics.Process": "4.1.0-rc2-23816", + "System.Globalization": "4.0.10", + "System.Globalization.Calendars": "4.0.0", + "System.IO": "4.0.10", + "System.IO.FileSystem": "4.0.0", + "System.IO.FileSystem.Primitives": "4.0.0", + "System.Linq": "4.0.1-rc2-23816", + "System.Linq.Queryable": "4.0.1-rc2-23816", + "System.Reflection": "4.0.10", + "System.Reflection.Primitives": "4.0.0", + "System.Runtime": "4.1.0-rc2-23816", + "System.Runtime.Extensions": "4.0.10", + "System.Runtime.Handles": "4.0.0", + "System.Runtime.InteropServices": "4.1.0-rc2-23816", + "System.Runtime.Loader": "4.0.0-rc2-23816", + "System.Text.Encoding": "4.0.10", + "System.Threading": "4.0.10", + "System.Threading.Thread": "4.0.0-rc2-23816", + "System.Xml.ReaderWriter": "4.0.11-rc2-23816", + "System.Xml.XDocument": "4.0.11-rc2-23816", + "System.Xml.XmlDocument": "4.0.1-rc2-23816", + "System.Xml.XmlSerializer": "4.0.11-rc2-23816" + }, + "frameworks": { + "dnxcore50": {} + } +} diff --git a/tests/src/Loader/classloader/TypeInitialization/backpatching/app.config b/tests/src/Loader/classloader/TypeInitialization/backpatching/app.config new file mode 100644 index 0000000000..e5622f77ad --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/backpatching/app.config @@ -0,0 +1,27 @@ +<?xml version = "1.0" encoding="utf-8"?> +<configuration> + <runtime> + <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> + <dependentAssembly> + <assemblyIdentity name="System.Runtime" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.20.0" newVersion="4.0.20.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.Text.Encoding" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.10.0" newVersion="4.0.10.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.Threading.Tasks" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.10.0" newVersion="4.0.10.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.IO" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.10.0" newVersion="4.0.10.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.Reflection" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.10.0" newVersion="4.0.10.0" /> + </dependentAssembly> + </assemblyBinding> + </runtime> +</configuration> diff --git a/tests/src/Loader/classloader/TypeInitialization/backpatching/project.json b/tests/src/Loader/classloader/TypeInitialization/backpatching/project.json new file mode 100644 index 0000000000..a2e84dc340 --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/backpatching/project.json @@ -0,0 +1,35 @@ +{ + "dependencies": { + "Microsoft.NETCore.Platforms": "1.0.1-rc2-23816", + "System.Collections": "4.0.10", + "System.Collections.NonGeneric": "4.0.1-rc2-23816", + "System.Collections.Specialized": "4.0.1-rc2-23816", + "System.ComponentModel": "4.0.1-rc2-23816", + "System.Console": "4.0.0-rc2-23816", + "System.Diagnostics.Process": "4.1.0-rc2-23816", + "System.Globalization": "4.0.10", + "System.Globalization.Calendars": "4.0.0", + "System.IO": "4.0.10", + "System.IO.FileSystem": "4.0.0", + "System.IO.FileSystem.Primitives": "4.0.0", + "System.Linq": "4.0.1-rc2-23816", + "System.Linq.Queryable": "4.0.1-rc2-23816", + "System.Reflection": "4.0.10", + "System.Reflection.Primitives": "4.0.0", + "System.Runtime": "4.1.0-rc2-23816", + "System.Runtime.Extensions": "4.0.10", + "System.Runtime.Handles": "4.0.0", + "System.Runtime.InteropServices": "4.1.0-rc2-23816", + "System.Runtime.Loader": "4.0.0-rc2-23816", + "System.Text.Encoding": "4.0.10", + "System.Threading": "4.0.10", + "System.Threading.Thread": "4.0.0-rc2-23816", + "System.Xml.ReaderWriter": "4.0.11-rc2-23816", + "System.Xml.XDocument": "4.0.11-rc2-23816", + "System.Xml.XmlDocument": "4.0.1-rc2-23816", + "System.Xml.XmlSerializer": "4.0.11-rc2-23816" + }, + "frameworks": { + "dnxcore50": {} + } +} diff --git a/tests/src/Loader/classloader/TypeInitialization/backpatching/test1.cs b/tests/src/Loader/classloader/TypeInitialization/backpatching/test1.cs new file mode 100644 index 0000000000..54c199b039 --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/backpatching/test1.cs @@ -0,0 +1,81 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Threading; +using System.Runtime.CompilerServices; + +// This test case reproduces a race condition involving type initialization (aka, .cctor, aka static constructor). +// +// The idea is that Thread1 initiates a type load and type initialization on MyClass (running of the static constructor/.cctor). +// +// While Thread1 is doing this, Thread2 attempts to access a static member, MyClass.X +// by invoking static method MyClass.getX(). +// +// The failing behavior is that Thread2 is able to access MyClass.X before it is initialized--Thread1 is still busy +// with type initialization, but hasn't yet initialized MyClass.X. This is because the prestub for MyClass.getX(), the mechanism that +// would normally trigger the .cctor to be run, was already run by Thread1. By the time Thread2 hit getX(), there is +// no more prestub to trigger the .cctor--so Thread2 (effectively) assumes that MyClass is already initialized and +// proceeds to access the still uninitialized static member, MyClass.X. +// +// A likely fix for this would be to delay backpatching getX() until after the .cctor has fully completed. +// mwilk. 2/3/04. + + +public class MyClass{ + private static int X; + public static int X0; + static MyClass(){ + X0 = getX(); // expect this to return 0, since this forces a cctor loop. + Thread.Sleep(1000*5); // 5 seconds + X=12; + } + [MethodImpl(MethodImplOptions.NoInlining)] + public static int getX(){ + Console.WriteLine("In MyClass.getX(): thread {0}",Thread.CurrentThread.Name); + return X; + } + // invoking this should trigger the cctor + [MethodImpl(MethodImplOptions.NoInlining)] + public static void SomeMethod(){ + Console.WriteLine("In MyClass.SomeMethod(): thread {0}",Thread.CurrentThread.Name); + } +} + +public class CMain{ + public static int X_getX; + + public static void RunSomeMethod(){ + MyClass.SomeMethod(); + } + public static void RunGetX(){ + + X_getX = MyClass.getX(); + Console.WriteLine("X_getX: {0}: thread {1}",X_getX,Thread.CurrentThread.Name); + } + public static int Main(){ + Thread t1 = new Thread(RunSomeMethod); + t1.Name = "T1"; + Thread t2 = new Thread(RunGetX); + t2.Name = "T2"; + + t1.Start(); + Thread.Sleep(1000*1); // 1 second + t2.Start(); + + t2.Join(); + t1.Join(); + + + //Console.WriteLine("MyClass.X0: {0}",MyClass.X0); + if(12==X_getX){ + Console.WriteLine("PASS"); + return 100; + } + else{ + Console.WriteLine("FAIL"); + return 101; + } + } +} diff --git a/tests/src/Loader/classloader/TypeInitialization/backpatching/test1.csproj b/tests/src/Loader/classloader/TypeInitialization/backpatching/test1.csproj new file mode 100644 index 0000000000..2319faf07b --- /dev/null +++ b/tests/src/Loader/classloader/TypeInitialization/backpatching/test1.csproj @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> + <PropertyGroup> + <AssemblyName>test1</AssemblyName> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid> + <FileAlignment>512</FileAlignment> + <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> + <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp> + <AllowUnsafeBlocks>true</AllowUnsafeBlocks> + <ReferenceLocalMscorlib>false</ReferenceLocalMscorlib> + <OutputType>Exe</OutputType> + <CLRTestKind>BuildAndRun</CLRTestKind> + <CLRTestPriority>0</CLRTestPriority> + </PropertyGroup> + + <ItemGroup> + <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies"> + <Visible>False</Visible> + </CodeAnalysisDependentAssemblyPaths> + </ItemGroup> + + <ItemGroup> + <Compile Include="test1.cs" /> + </ItemGroup> + + <ItemGroup> + <None Include="app.config" /> + <None Include="project.json" /> + </ItemGroup> + + <ItemGroup> + <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" /> + </ItemGroup> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> +</Project> |