This repository has been archived by the owner on Nov 1, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 509
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2488 from nattress/cctorrunner
Run ordered class constructors explicitly
- Loading branch information
Showing
23 changed files
with
312 additions
and
112 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
103 changes: 103 additions & 0 deletions
103
src/ILCompiler.Compiler/src/Compiler/LibraryInitializers.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
// 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.Collections.Generic; | ||
|
||
using Internal.TypeSystem; | ||
|
||
using AssemblyName = System.Reflection.AssemblyName; | ||
using Debug = System.Diagnostics.Debug; | ||
|
||
namespace ILCompiler | ||
{ | ||
/// <summary> | ||
/// Encapsulates a list of class constructors that must be run in a prescribed order during start-up | ||
/// </summary> | ||
public sealed class LibraryInitializers | ||
{ | ||
private const string ClassLibraryPlaceHolderString = "*ClassLibrary*"; | ||
private const string LibraryInitializerContainerNamespaceName = "Internal.Runtime.CompilerHelpers"; | ||
private const string LibraryInitializerContainerTypeName = "LibraryInitializer"; | ||
private const string LibraryInitializerMethodName = "InitializeLibrary"; | ||
|
||
private static readonly LibraryInitializerInfo[] s_assembliesWithLibraryInitializers = | ||
{ | ||
new LibraryInitializerInfo(ClassLibraryPlaceHolderString), | ||
new LibraryInitializerInfo("System.Private.TypeLoader", false), | ||
new LibraryInitializerInfo("System.Private.Reflection.Execution", false), | ||
new LibraryInitializerInfo("System.Private.DeveloperExperience.Console"), | ||
}; | ||
|
||
private List<MethodDesc> _libraryInitializerMethods; | ||
|
||
private readonly TypeSystemContext _context; | ||
private readonly bool _isCppCodeGen; | ||
|
||
public LibraryInitializers(TypeSystemContext context, bool isCppCodeGen) | ||
{ | ||
_context = context; | ||
// | ||
// We should not care which code-gen is being used, however currently CppCodeGen cannot | ||
// handle code pulled in by all explicit cctors. | ||
// | ||
// See https://github.com/dotnet/corert/issues/2486 | ||
// | ||
_isCppCodeGen = isCppCodeGen; | ||
} | ||
|
||
public IList<MethodDesc> LibraryInitializerMethods | ||
{ | ||
get | ||
{ | ||
if (_libraryInitializerMethods == null) | ||
InitLibraryInitializers(); | ||
|
||
return _libraryInitializerMethods; | ||
} | ||
} | ||
|
||
private void InitLibraryInitializers() | ||
{ | ||
Debug.Assert(_libraryInitializerMethods == null); | ||
|
||
_libraryInitializerMethods = new List<MethodDesc>(); | ||
|
||
foreach (var entry in s_assembliesWithLibraryInitializers) | ||
{ | ||
if (_isCppCodeGen && !entry.UseWithCppCodeGen) | ||
continue; | ||
|
||
ModuleDesc assembly = entry.Assembly == ClassLibraryPlaceHolderString | ||
? _context.SystemModule | ||
: _context.ResolveAssembly(new AssemblyName(entry.Assembly), false); | ||
|
||
if (assembly == null) | ||
continue; | ||
|
||
TypeDesc containingType = assembly.GetType(LibraryInitializerContainerNamespaceName, LibraryInitializerContainerTypeName, false); | ||
if (containingType == null) | ||
continue; | ||
|
||
MethodDesc initializerMethod = containingType.GetMethod(LibraryInitializerMethodName, null); | ||
if (initializerMethod == null) | ||
continue; | ||
|
||
_libraryInitializerMethods.Add(initializerMethod); | ||
} | ||
} | ||
|
||
private sealed class LibraryInitializerInfo | ||
{ | ||
public string Assembly { get; } | ||
public bool UseWithCppCodeGen { get; } | ||
|
||
public LibraryInitializerInfo(string assembly, bool useWithCppCodeGen = true) | ||
{ | ||
Assembly = assembly; | ||
UseWithCppCodeGen = useWithCppCodeGen; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
26 changes: 26 additions & 0 deletions
26
src/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/LibraryInitializer.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
// 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.Runtime; | ||
using System.Runtime.CompilerServices; | ||
|
||
using Debug = System.Diagnostics.Debug; | ||
|
||
namespace Internal.Runtime.CompilerHelpers | ||
{ | ||
/// <summary> | ||
/// Container class to run specific class constructors in a defined order. Since we can't | ||
/// directly invoke class constructors in C#, they're renamed Initialize. | ||
/// </summary> | ||
internal class LibraryInitializer | ||
{ | ||
public static void InitializeLibrary() | ||
{ | ||
PreallocatedOutOfMemoryException.Initialize(); | ||
ClassConstructorRunner.Initialize(); | ||
TypeLoaderExports.Initialize(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.