From 94b6b6f4f7985be7c006c3eb87691992d872142a Mon Sep 17 00:00:00 2001 From: Dongbo Wang Date: Tue, 18 Jun 2019 23:34:47 -0700 Subject: [PATCH] Clean up the use of 'SetProfileRoot' and 'StartProfile' in ConsoleHost (#9931) * Clean up the use of 'SetProfileRoot' and 'StartProfile' in ConsoleHost * Remove 'pwsh.pdb' from our component file list --- assets/files.wxs | 4 --- build.psm1 | 1 + .../host/msh/CommandLineParameterParser.cs | 17 +---------- .../host/msh/ConsoleHost.cs | 24 ++++++++-------- .../host/msh/ManagedEntrance.cs | 7 +++-- .../CoreCLR/CorePsAssemblyLoadContext.cs | 16 ----------- .../engine/InitialSessionState.cs | 6 ++-- .../utils/ClrFacade.cs | 18 ------------ tools/performance/GC.Regions.xml | 5 ++-- tools/performance/Invoke-PerfviewPS.ps1 | 28 ++++--------------- tools/performance/PowerShell.Regions.xml | 1 + tools/performance/PowerShell.stacktags | 9 +++--- 12 files changed, 36 insertions(+), 100 deletions(-) diff --git a/assets/files.wxs b/assets/files.wxs index d19c2b8bb9..d1651ac5a8 100644 --- a/assets/files.wxs +++ b/assets/files.wxs @@ -325,9 +325,6 @@ - - - @@ -2456,7 +2453,6 @@ - diff --git a/build.psm1 b/build.psm1 index 9f83cb3a4b..1b4559af3f 100644 --- a/build.psm1 +++ b/build.psm1 @@ -2154,6 +2154,7 @@ function Start-CrossGen { # Common PowerShell libraries to crossgen $psCoreAssemblyList = @( + "pwsh.dll", "Microsoft.PowerShell.Commands.Utility.dll", "Microsoft.PowerShell.Commands.Management.dll", "Microsoft.PowerShell.Security.dll", diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/CommandLineParameterParser.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/CommandLineParameterParser.cs index eb46b6a7e6..4791100c68 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/CommandLineParameterParser.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/CommandLineParameterParser.cs @@ -498,21 +498,6 @@ namespace Microsoft.PowerShell return true; } - /// - /// Processes the command line parameters to ConsoleHost which must be parsed before the Host is created. - /// Success to indicate that the program should continue running. - /// - /// - /// The command line parameters to be processed. - /// - internal static void EarlyParse(string[] args) - { - // indicates that we've called this method on this instance, and that when it's done, the state variables - // will reflect the parse. - - EarlyParseHelper(args); - } - private static string GetConfigurationNameFromGroupPolicy() { // Current user policy takes precedence. @@ -529,7 +514,7 @@ namespace Microsoft.PowerShell /// /// The command line parameters to be processed. /// - private static void EarlyParseHelper(string[] args) + internal static void EarlyParse(string[] args) { if (args == null) { diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHost.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHost.cs index a0689ba60a..9683270236 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHost.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHost.cs @@ -20,6 +20,7 @@ using System.Management.Automation.Runspaces; using System.Management.Automation.Remoting; using System.Management.Automation.Security; using System.Threading; +using System.Runtime; using System.Runtime.InteropServices; using System.Management.Automation.Language; @@ -133,7 +134,7 @@ namespace Microsoft.PowerShell Directory.CreateDirectory(profileDir); } #endif - ClrFacade.SetProfileOptimizationRoot(profileDir); + ProfileOptimization.SetProfileRoot(profileDir); } catch { @@ -143,7 +144,7 @@ namespace Microsoft.PowerShell uint exitCode = ExitCodeSuccess; - System.Threading.Thread.CurrentThread.Name = "ConsoleHost main thread"; + Thread.CurrentThread.Name = "ConsoleHost main thread"; try { @@ -205,26 +206,26 @@ namespace Microsoft.PowerShell // First check for and handle PowerShell running in a server mode. if (s_cpp.ServerMode) { - ClrFacade.StartProfileOptimization("StartupProfileData-ServerMode"); + ProfileOptimization.StartProfile("StartupProfileData-ServerMode"); System.Management.Automation.Remoting.Server.OutOfProcessMediator.Run(s_cpp.InitialCommand); exitCode = 0; } else if (s_cpp.NamedPipeServerMode) { - ClrFacade.StartProfileOptimization("StartupProfileData-NamedPipeServerMode"); + ProfileOptimization.StartProfile("StartupProfileData-NamedPipeServerMode"); System.Management.Automation.Remoting.RemoteSessionNamedPipeServer.RunServerMode( s_cpp.ConfigurationName); exitCode = 0; } else if (s_cpp.SSHServerMode) { - ClrFacade.StartProfileOptimization("StartupProfileData-SSHServerMode"); + ProfileOptimization.StartProfile("StartupProfileData-SSHServerMode"); System.Management.Automation.Remoting.Server.SSHProcessMediator.Run(s_cpp.InitialCommand); exitCode = 0; } else if (s_cpp.SocketServerMode) { - ClrFacade.StartProfileOptimization("StartupProfileData-SocketServerMode"); + ProfileOptimization.StartProfile("StartupProfileData-SocketServerMode"); System.Management.Automation.Remoting.Server.HyperVSocketMediator.Run(s_cpp.InitialCommand, s_cpp.ConfigurationName); exitCode = 0; @@ -238,16 +239,17 @@ namespace Microsoft.PowerShell throw hostException; } + ProfileOptimization.StartProfile( + s_theConsoleHost.LoadPSReadline() + ? "StartupProfileData-Interactive" + : "StartupProfileData-NonInteractive"); + s_theConsoleHost.BindBreakHandler(); PSHost.IsStdOutputRedirected = Console.IsOutputRedirected; // Send startup telemetry for ConsoleHost startup ApplicationInsightsTelemetry.SendPSCoreStartupTelemetry(); - ClrFacade.StartProfileOptimization( - s_theConsoleHost.LoadPSReadline() - ? "StartupProfileData-Interactive" - : "StartupProfileData-NonInteractive"); exitCode = s_theConsoleHost.Run(s_cpp, false); } } @@ -2833,7 +2835,7 @@ namespace Microsoft.PowerShell private ConsoleControl.ConsoleModes _savedConsoleMode = ConsoleControl.ConsoleModes.Unknown; private ConsoleControl.ConsoleModes _initialConsoleMode = ConsoleControl.ConsoleModes.Unknown; #endif - private System.Threading.Thread _breakHandlerThread; + private Thread _breakHandlerThread; private bool _isDisposed; internal ConsoleHostUserInterface ui; diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ManagedEntrance.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ManagedEntrance.cs index b400f7ed0f..eb9b588d41 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ManagedEntrance.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ManagedEntrance.cs @@ -27,13 +27,14 @@ namespace Microsoft.PowerShell /// /// Command line arguments to the managed MSH /// -#pragma warning disable 1573 + /// public static int Start(string consoleFilePath, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPWStr, SizeParamIndex = 2)]string[] args, int argc) -#pragma warning restore 1573 { + // Warm up some components concurrently on background threads. + System.Management.Automation.Runspaces.EarlyStartup.Init(); + // We need to read the settings file before we create the console host Microsoft.PowerShell.CommandLineParameterParser.EarlyParse(args); - System.Management.Automation.Runspaces.EarlyStartup.Init(); #if !UNIX // NOTE: On Unix, logging has to be deferred until after command-line parsing diff --git a/src/System.Management.Automation/CoreCLR/CorePsAssemblyLoadContext.cs b/src/System.Management.Automation/CoreCLR/CorePsAssemblyLoadContext.cs index d1687ff6ab..3d55ed1b67 100644 --- a/src/System.Management.Automation/CoreCLR/CorePsAssemblyLoadContext.cs +++ b/src/System.Management.Automation/CoreCLR/CorePsAssemblyLoadContext.cs @@ -194,22 +194,6 @@ namespace System.Management.Automation return null; } - /// - /// Set the profile optimization root on the appropriate load context. - /// - internal void SetProfileOptimizationRootImpl(string directoryPath) - { - AssemblyLoadContext.Default.SetProfileOptimizationRoot(directoryPath); - } - - /// - /// Start the profile optimization on the appropriate load context. - /// - internal void StartProfileOptimizationImpl(string profile) - { - AssemblyLoadContext.Default.StartProfileOptimization(profile); - } - #endregion Internal_Methods #region Private_Methods diff --git a/src/System.Management.Automation/engine/InitialSessionState.cs b/src/System.Management.Automation/engine/InitialSessionState.cs index 18bfdf3bd0..2ae6765489 100644 --- a/src/System.Management.Automation/engine/InitialSessionState.cs +++ b/src/System.Management.Automation/engine/InitialSessionState.cs @@ -56,13 +56,13 @@ namespace System.Management.Automation.Runspaces { // Loading the resources for System.Management.Automation can be expensive, so force that to // happen early on a background thread. - var unused0 = RunspaceInit.OutputEncodingDescription; + _ = RunspaceInit.OutputEncodingDescription; // This will init some tables and could load some assemblies. - var unused1 = TypeAccelerators.builtinTypeAccelerators; + _ = TypeAccelerators.builtinTypeAccelerators; // This will init some tables and could load some assemblies. - var unused2 = LanguagePrimitives.GetEnumerator(null); + LanguagePrimitives.GetEnumerator(null); }); } } diff --git a/src/System.Management.Automation/utils/ClrFacade.cs b/src/System.Management.Automation/utils/ClrFacade.cs index eea0ffb7d7..9feafe40d4 100644 --- a/src/System.Management.Automation/utils/ClrFacade.cs +++ b/src/System.Management.Automation/utils/ClrFacade.cs @@ -361,24 +361,6 @@ namespace System.Management.Automation #endif } - /// - /// Facade for ProfileOptimization.SetProfileRoot. - /// - /// The full path to the folder where profile files are stored for the current application domain. - internal static void SetProfileOptimizationRoot(string directoryPath) - { - PSAssemblyLoadContext.SetProfileOptimizationRootImpl(directoryPath); - } - - /// - /// Facade for ProfileOptimization.StartProfile. - /// - /// The file name of the profile to use. - internal static void StartProfileOptimization(string profile) - { - PSAssemblyLoadContext.StartProfileOptimizationImpl(profile); - } - #endregion Misc /// diff --git a/tools/performance/GC.Regions.xml b/tools/performance/GC.Regions.xml index b89be6ffd7..5b5de4c816 100644 --- a/tools/performance/GC.Regions.xml +++ b/tools/performance/GC.Regions.xml @@ -1,12 +1,13 @@ + diff --git a/tools/performance/Invoke-PerfviewPS.ps1 b/tools/performance/Invoke-PerfviewPS.ps1 index 77a33f3a75..99ff988da2 100644 --- a/tools/performance/Invoke-PerfviewPS.ps1 +++ b/tools/performance/Invoke-PerfviewPS.ps1 @@ -8,8 +8,9 @@ param( $ScriptBlock, $LogFileName = '.\perfview.log', - - $PowerShellPath = $(Get-Command pwsh.exe).Source) + $PowerShellPath = $(Get-Command -Name pwsh.exe).Source, + $PerfViewPath = $(Get-Command -Name PerfView.exe).Source +) $EncodedScriptBlock = [System.Convert]::ToBase64String([System.Text.Encoding]::UNICODE.GetBytes($ScriptBlock.ToString())) $perfViewArgs = @( @@ -30,26 +31,7 @@ $perfViewArgs = @( $EncodedScriptBlock ) -$process = Start-Process -FilePath (Get-Command PerfView.exe).Source -ArgumentList $perfViewArgs -PassThru - -$rs = [runspacefactory]::CreateRunspace($host) -$rs.Open() -$ps = [powershell]::Create() -$ps.Runspace = $rs - -$null = $ps.AddCommand("Get-Content"). - AddArgument($LogFileName). - AddParameter("Wait"). - AddParameter("Tail", 0) -$null = $ps.AddCommand("Out-Host") - -# If log file doesn't exist yet, wait a little bit so Get-Content doesn't fail -while (!(Test-Path $LogFileName)) -{ - Start-Sleep -Seconds 1 -} - -$null = $ps.BeginInvoke() +$process = Start-Process -FilePath $PerfViewPath -ArgumentList $perfViewArgs -PassThru $process.WaitForExit() -$ps.Stop() +Get-Content $LogFileName | Out-Host diff --git a/tools/performance/PowerShell.Regions.xml b/tools/performance/PowerShell.Regions.xml index 0a07024248..180374ecf5 100644 --- a/tools/performance/PowerShell.Regions.xml +++ b/tools/performance/PowerShell.Regions.xml @@ -1,5 +1,6 @@ + diff --git a/tools/performance/PowerShell.stacktags b/tools/performance/PowerShell.stacktags index a4bbecfc94..ed1b89e9a9 100644 --- a/tools/performance/PowerShell.stacktags +++ b/tools/performance/PowerShell.stacktags @@ -1,15 +1,16 @@ + - - + + - - + +