未验证 提交 f0143ef0 编写于 作者: J Janusz Wrobel 提交者: GitHub

Optionally record activities in the service (#13835)

Co-authored-by: NChet Husk <chusk3@gmail.com>
Co-authored-by: NTomas Grosup <tomasgrosup@microsoft.com>
上级 c6350ce3
......@@ -88,6 +88,7 @@
<SystemBuffersVersion>4.5.1</SystemBuffersVersion>
<SystemCollectionsImmutableVersion>6.0.0</SystemCollectionsImmutableVersion>
<MicrosoftDiaSymReaderPortablePdbVersion>1.6.0</MicrosoftDiaSymReaderPortablePdbVersion>
<SystemDiagnosticsDiagnosticSourceVersion>6.0.0</SystemDiagnosticsDiagnosticSourceVersion>
<SystemMemoryVersion>4.5.5</SystemMemoryVersion>
<SystemReflectionEmitVersion>4.7.0</SystemReflectionEmitVersion>
<SystemReflectionMetadataVersion>6.0.0</SystemReflectionMetadataVersion>
......
......@@ -5,6 +5,7 @@ module internal FSharp.Compiler.CheckDeclarations
open System
open System.Collections.Generic
open FSharp.Compiler.Diagnostics
open Internal.Utilities.Collections
open Internal.Utilities.Library
open Internal.Utilities.Library.Extras
......@@ -5289,11 +5290,17 @@ let CheckOneImplFile
env,
rootSigOpt: ModuleOrNamespaceType option,
synImplFile) =
let (ParsedImplFileInput (_, isScript, qualNameOfFile, scopedPragmas, _, implFileFrags, isLastCompiland, _)) = synImplFile
let (ParsedImplFileInput (fileName, isScript, qualNameOfFile, scopedPragmas, _, implFileFrags, isLastCompiland, _)) = synImplFile
let infoReader = InfoReader(g, amap)
cancellable {
use _ =
Activity.start "CheckDeclarations.CheckOneImplFile"
[|
"fileName", fileName
"qualifiedNameOfFile", qualNameOfFile.Text
|]
let cenv =
cenv.Create (g, isScript, amap, thisCcu, false, Option.isSome rootSigOpt,
conditionalDefines, tcSink, (LightweightTcValForUsingInBuildMethodCall g), isInternalTestSpanStackReferring,
......@@ -5421,6 +5428,12 @@ let CheckOneImplFile
/// Check an entire signature file
let CheckOneSigFile (g, amap, thisCcu, checkForErrors, conditionalDefines, tcSink, isInternalTestSpanStackReferring) tcEnv (sigFile: ParsedSigFileInput) =
cancellable {
use _ =
Activity.start "CheckDeclarations.CheckOneSigFile"
[|
"fileName", sigFile.FileName
"qualifiedNameOfFile", sigFile.QualifiedName.Text
|]
let cenv =
cenv.Create
(g, false, amap, thisCcu, true, false, conditionalDefines, tcSink,
......
......@@ -2331,13 +2331,14 @@ let PrintWholeAssemblyImplementation (tcConfig: TcConfig) outfile header expr =
//----------------------------------------------------------------------------
let mutable tPrev: (DateTime * DateTime * float * int[]) option = None
let mutable nPrev: string option = None
let mutable nPrev: (string * IDisposable) option = None
let ReportTime (tcConfig: TcConfig) descr =
match nPrev with
| None -> ()
| Some prevDescr ->
| Some (prevDescr, prevActivity) ->
use _ = prevActivity // Finish the previous diagnostics activity by .Dispose() at the end of this block
if tcConfig.pause then
dprintf "[done '%s', entering '%s'] press <enter> to continue... " prevDescr descr
Console.ReadLine() |> ignore
......@@ -2376,7 +2377,7 @@ let ReportTime (tcConfig: TcConfig) descr =
let tStart =
match tPrev, nPrev with
| Some (tStart, tPrev, utPrev, gcPrev), Some prevDescr ->
| Some (tStart, tPrev, utPrev, gcPrev), Some (prevDescr, _) ->
let spanGC = [| for i in 0..maxGen -> GC.CollectionCount i - gcPrev[i] |]
let t = tNow - tStart
let tDelta = tNow - tPrev
......@@ -2403,7 +2404,7 @@ let ReportTime (tcConfig: TcConfig) descr =
tPrev <- Some(tStart, tNow, utNow, gcNow)
nPrev <- Some descr
nPrev <- Some(descr, Activity.startNoTags descr)
let ignoreFailureOnMono1_1_16 f =
try
......
......@@ -4,6 +4,7 @@
module internal FSharp.Compiler.ParseAndCheckInputs
open System
open System.Diagnostics
open System.IO
open System.Collections.Generic
......@@ -1175,6 +1176,9 @@ let CheckOneInputAux
cancellable {
try
use _ =
Activity.start "ParseAndCheckInputs.CheckOneInput" [| "fileName", inp.FileName |]
CheckSimulateException tcConfig
let m = inp.Range
......@@ -1365,10 +1369,8 @@ let CheckMultipleInputsFinish (results, tcState: TcState) =
let CheckOneInputAndFinish (checkForErrors, tcConfig: TcConfig, tcImports, tcGlobals, prefixPathOpt, tcSink, tcState, input) =
cancellable {
Logger.LogBlockStart LogCompilerFunctionId.CompileOps_TypeCheckOneInputAndFinishEventually
let! result, tcState = CheckOneInput(checkForErrors, tcConfig, tcImports, tcGlobals, prefixPathOpt, tcSink, tcState, input, false)
let finishedResult = CheckMultipleInputsFinish([ result ], tcState)
Logger.LogBlockStop LogCompilerFunctionId.CompileOps_TypeCheckOneInputAndFinishEventually
return finishedResult
}
......
......@@ -532,7 +532,6 @@ let main1
// Process command line, flags and collect filenames
let sourceFiles =
// The ParseCompilerOptions function calls imperative function to process "real" args
// Rather than start processing, just collect names, then process them.
try
......@@ -710,7 +709,6 @@ let main2
exiter: Exiter,
ilSourceDocs))
=
if tcConfig.typeCheckOnly then
exiter.Exit 0
......@@ -818,7 +816,6 @@ let main3
exiter: Exiter,
ilSourceDocs))
=
// Encode the signature data
ReportTime tcConfig "Encode Interface Data"
let exportRemapping = MakeExportRemapping generatedCcu generatedCcu.Contents
......@@ -914,7 +911,6 @@ let main4
exiter: Exiter,
ilSourceDocs))
=
match tcImportsCapture with
| None -> ()
| Some f -> f tcImports
......@@ -1049,7 +1045,6 @@ let main6
exiter: Exiter,
ilSourceDocs))
=
ReportTime tcConfig "Write .NET Binary"
use _ = UseBuildPhase BuildPhase.Output
......
......@@ -29,7 +29,7 @@
<!-- The FSharp.Compiler.Service dll provides a referencable public interface for tool builders -->
<PropertyGroup Condition="'$(Configuration)' != 'Proto'">
<CompressMetadata Condition="'$(CompressAllMetadata)' != 'true'">false</CompressMetadata>
<CompressMetadata Condition="'$(CompressAllMetadata)' != 'true'">false</CompressMetadata>
</PropertyGroup>
<PropertyGroup>
......@@ -57,6 +57,7 @@
<NuspecProperty Include="SystemBuffersPackageVersion=$(SystemBuffersVersion)" />
<NuspecProperty Include="SystemCollectionsImmutablePackageVersion=$(SystemCollectionsImmutableVersion)" />
<NuspecProperty Include="SystemMemoryPackageVersion=$(SystemMemoryVersion)" />
<NuspecProperty Include="SystemDiagnosticsDiagnosticSourcePackageVersion=$(SystemDiagnosticsDiagnosticSourceVersion)" />
<NuspecProperty Include="SystemReflectionEmitPackageVersion=$(SystemReflectionEmitVersion)" />
<NuspecProperty Include="SystemReflectionMetadataPackageVersion=$(SystemReflectionMetadataVersion)" />
<NuspecProperty Include="SystemRuntimeCompilerServicesUnsafePackageVersion=$(SystemRuntimeCompilerServicesUnsafeVersion)" />
......@@ -91,6 +92,8 @@
<Link>FSStrings.resx</Link>
<LogicalName>FSStrings.resources</LogicalName>
</EmbeddedResource>
<Compile Include="Utilities\Activity.fsi" />
<Compile Include="Utilities\Activity.fs" />
<Compile Include="Utilities\sformat.fsi" />
<Compile Include="Utilities\sformat.fs" />
<Compile Include="Utilities\sr.fsi" />
......@@ -131,8 +134,6 @@
<Compile Include="Utilities\range.fsi" />
<Compile Include="Utilities\range.fs" />
<EmbeddedText Include="Facilities\UtilsStrings.txt" />
<Compile Include="Facilities\Logger.fsi" />
<Compile Include="Facilities\Logger.fs" />
<Compile Include="Facilities\LanguageFeatures.fsi" />
<Compile Include="Facilities\LanguageFeatures.fs" />
<Compile Include="Facilities\DiagnosticOptions.fsi" />
......@@ -488,6 +489,7 @@
<PackageReference Include="System.Reflection.Emit" Version="$(SystemReflectionEmitVersion)" />
<PackageReference Include="System.Reflection.Metadata" Version="$(SystemReflectionMetadataVersion)" />
<PackageReference Include="System.Buffers" Version="$(SystemBuffersVersion)" />
<PackageReference Include="System.Diagnostics.DiagnosticSource" Version="$(SystemDiagnosticsDiagnosticSourceVersion)" />
<PackageReference Include="System.Memory" Version="$(SystemMemoryVersion)" />
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="$(SystemRuntimeCompilerServicesUnsafeVersion)" />
</ItemGroup>
......
......@@ -8,6 +8,7 @@
<dependency id="FSharp.Core" version="$FSharpCorePackageVersion$" exclude="Build,Analyzers" />
<dependency id="System.Buffers" version="$SystemBuffersPackageVersion$" exclude="Build,Analyzers" />
<dependency id="System.Collections.Immutable" version="$SystemCollectionsImmutablePackageVersion$" exclude="Build,Analyzers" />
<dependency id="System.Diagnostics.DiagnosticSource" version="$SystemDiagnosticsDiagnosticSourcePackageVersion$" exclude="Build,Analyzers" />
<dependency id="System.Memory" version="$SystemMemoryPackageVersion$" exclude="Build,Analyzers" />
<dependency id="System.Reflection.Emit" version="$SystemReflectionEmitPackageVersion$" exclude="Build,Analyzers" />
<dependency id="System.Reflection.Metadata" version="$SystemReflectionMetadataPackageVersion$" exclude="Build,Analyzers" />
......
......@@ -105,6 +105,16 @@ type NodeCodeBuilder() =
(value :> IDisposable).Dispose()
}
)
[<DebuggerHidden; DebuggerStepThrough>]
member _.Using(value: IDisposable, binder: IDisposable -> NodeCode<'U>) =
Node(
async {
use _ = value
return! binder value |> Async.AwaitNodeCode
}
)
let node = NodeCodeBuilder()
......
......@@ -3,6 +3,7 @@
module internal FSharp.Compiler.BuildGraph
open System
open System.Diagnostics
open System.Threading
open System.Threading.Tasks
open FSharp.Compiler.DiagnosticsLogger
......@@ -43,10 +44,12 @@ type NodeCodeBuilder =
member Combine: x1: NodeCode<unit> * x2: NodeCode<'T> -> NodeCode<'T>
/// A limited form 'use' for establishing the compilation globals. (Note
/// that a proper generic 'use' could be implemented but has not currently been necessary)
/// A limited form 'use' for establishing the compilation globals.
member Using: CompilationGlobalsScope * (CompilationGlobalsScope -> NodeCode<'T>) -> NodeCode<'T>
/// A generic 'use' that disposes of the IDisposable at the end of the computation.
member Using: IDisposable * (IDisposable -> NodeCode<'T>) -> NodeCode<'T>
/// Specifies code that can be run as part of the build graph.
val node: NodeCodeBuilder
......
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
namespace FSharp.Compiler.Diagnostics
open System.Diagnostics.Tracing
open System
type LogCompilerFunctionId =
| Service_ParseAndCheckFileInProject = 1
| Service_CheckOneFile = 2
| Service_IncrementalBuildersCache_BuildingNewCache = 3
| Service_IncrementalBuildersCache_GettingCache = 4
| CompileOps_TypeCheckOneInputAndFinishEventually = 5
| IncrementalBuild_CreateItemKeyStoreAndSemanticClassification = 6
| IncrementalBuild_TypeCheck = 7
/// This is for ETW tracing across FSharp.Compiler.
[<Sealed; EventSource(Name = "FSharpCompiler")>]
type FSharpCompilerEventSource() =
inherit EventSource()
static let instance = new FSharpCompilerEventSource()
static member Instance = instance
[<Event(1)>]
member this.Log(functionId: LogCompilerFunctionId) =
if this.IsEnabled() then this.WriteEvent(1, int functionId)
[<Event(2)>]
member this.LogMessage(message: string, functionId: LogCompilerFunctionId) =
if this.IsEnabled() then
this.WriteEvent(2, message, int functionId)
[<Event(3)>]
member this.BlockStart(functionId: LogCompilerFunctionId) =
if this.IsEnabled() then this.WriteEvent(3, int functionId)
[<Event(4)>]
member this.BlockStop(functionId: LogCompilerFunctionId) =
if this.IsEnabled() then this.WriteEvent(4, int functionId)
[<Event(5)>]
member this.BlockMessageStart(message: string, functionId: LogCompilerFunctionId) =
if this.IsEnabled() then
this.WriteEvent(5, message, int functionId)
[<Event(6)>]
member this.BlockMessageStop(message: string, functionId: LogCompilerFunctionId) =
if this.IsEnabled() then
this.WriteEvent(6, message, int functionId)
[<RequireQualifiedAccess>]
module Logger =
let Log functionId =
FSharpCompilerEventSource.Instance.Log(functionId)
let LogMessage message functionId =
FSharpCompilerEventSource.Instance.LogMessage(message, functionId)
let LogBlockStart functionId =
FSharpCompilerEventSource.Instance.BlockStart(functionId)
let LogBlockStop functionId =
FSharpCompilerEventSource.Instance.BlockStop(functionId)
let LogBlockMessageStart message functionId =
FSharpCompilerEventSource.Instance.BlockMessageStart(message, functionId)
let LogBlockMessageStop message functionId =
FSharpCompilerEventSource.Instance.BlockMessageStop(message, functionId)
let LogBlock functionId =
FSharpCompilerEventSource.Instance.BlockStart(functionId)
{ new IDisposable with
member _.Dispose() =
FSharpCompilerEventSource.Instance.BlockStop(functionId)
}
let LogBlockMessage message functionId =
FSharpCompilerEventSource.Instance.BlockMessageStart(message, functionId)
{ new IDisposable with
member _.Dispose() =
FSharpCompilerEventSource.Instance.BlockMessageStop(message, functionId)
}
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
namespace FSharp.Compiler.Diagnostics
open System
type internal LogCompilerFunctionId =
| Service_ParseAndCheckFileInProject = 1
| Service_CheckOneFile = 2
| Service_IncrementalBuildersCache_BuildingNewCache = 3
| Service_IncrementalBuildersCache_GettingCache = 4
| CompileOps_TypeCheckOneInputAndFinishEventually = 5
| IncrementalBuild_CreateItemKeyStoreAndSemanticClassification = 6
| IncrementalBuild_TypeCheck = 7
[<RequireQualifiedAccess>]
module internal Logger =
val Log: LogCompilerFunctionId -> unit
val LogMessage: message: string -> LogCompilerFunctionId -> unit
val LogBlockStart: LogCompilerFunctionId -> unit
val LogBlockStop: LogCompilerFunctionId -> unit
val LogBlockMessageStart: message: string -> LogCompilerFunctionId -> unit
val LogBlockMessageStop: message: string -> LogCompilerFunctionId -> unit
val LogBlock: LogCompilerFunctionId -> IDisposable
val LogBlockMessage: message: string -> LogCompilerFunctionId -> IDisposable
......@@ -2347,6 +2347,7 @@ module internal ParseAndCheckFile =
let parseFile (sourceText: ISourceText, fileName, options: FSharpParsingOptions, userOpName: string, suggestNamesForErrors: bool) =
Trace.TraceInformation("FCS: {0}.{1} ({2})", userOpName, "parseFile", fileName)
use act = Activity.start "ParseAndCheckFile.parseFile" [| "fileName", fileName |]
let errHandler =
DiagnosticsHandler(true, fileName, options.DiagnosticOptions, sourceText, suggestNamesForErrors)
......@@ -2502,7 +2503,8 @@ module internal ParseAndCheckFile =
) =
cancellable {
use _logBlock = Logger.LogBlock LogCompilerFunctionId.Service_CheckOneFile
use _ =
Activity.start "ParseAndCheckFile.CheckOneFile" [| "fileName", mainInputFileName; "length", sourceText.Length.ToString() |]
let parsedMainInput = parseResults.ParseTree
......
......@@ -116,6 +116,7 @@ module IncrementalBuildSyntaxTree =
let mutable weakCache: WeakReference<_> option = None
let parse(sigNameOpt: QualifiedNameOfFile option) =
let diagnosticsLogger = CompilationDiagnosticLogger("Parse", tcConfig.diagnosticsOptions)
// Return the disposable object that cleans up
use _holder = new CompilationGlobalsScope(diagnosticsLogger, BuildPhase.Parse)
......@@ -123,6 +124,13 @@ module IncrementalBuildSyntaxTree =
try
IncrementalBuilderEventTesting.MRU.Add(IncrementalBuilderEventTesting.IBEParsed fileName)
let canSkip = sigNameOpt.IsSome && FSharpImplFileSuffixes |> List.exists (FileSystemUtils.checkSuffix fileName)
use act =
Activity.start "IncrementalBuildSyntaxTree.parse"
[|
"fileName", source.FilePath
"buildPhase", BuildPhase.Parse.ToString()
"canSkip", canSkip.ToString()
|]
let input =
if canSkip then
ParsedInput.ImplFile(
......@@ -465,6 +473,7 @@ type BoundModel private (tcConfig: TcConfig,
let! res = defaultTypeCheck ()
return res
| Some syntaxTree ->
use _ = Activity.start "BoundModel.TypeCheck" [|"fileName", syntaxTree.FileName|]
let sigNameOpt =
if partialCheck then
this.BackingSignature
......@@ -489,8 +498,6 @@ type BoundModel private (tcConfig: TcConfig,
let hadParseErrors = not (Array.isEmpty parseErrors)
let input, moduleNamesDict = DeduplicateParsedInputModuleName prevModuleNamesDict input
Logger.LogBlockMessageStart fileName LogCompilerFunctionId.IncrementalBuild_TypeCheck
let! (tcEnvAtEndOfFile, topAttribs, implFile, ccuSigForFile), tcState =
CheckOneInput
((fun () -> hadParseErrors || diagnosticsLogger.ErrorCount > 0),
......@@ -502,8 +509,6 @@ type BoundModel private (tcConfig: TcConfig,
partialCheck)
|> NodeCode.FromCancellable
Logger.LogBlockMessageStop fileName LogCompilerFunctionId.IncrementalBuild_TypeCheck
fileChecked.Trigger fileName
let newErrors = Array.append parseErrors (capturingDiagnosticsLogger.Diagnostics |> List.toArray)
let tcEnvAtEndOfFile = if keepAllBackgroundResolutions then tcEnvAtEndOfFile else tcState.TcEnvFromImpls
......@@ -531,7 +536,7 @@ type BoundModel private (tcConfig: TcConfig,
// Build symbol keys
let itemKeyStore, semanticClassification =
if enableBackgroundItemKeyStoreAndSemanticClassification then
Logger.LogBlockMessageStart fileName LogCompilerFunctionId.IncrementalBuild_CreateItemKeyStoreAndSemanticClassification
use _ = Activity.start "IncrementalBuild.CreateItemKeyStoreAndSemanticClassification" [|"fileName", fileName|]
let sResolutions = sink.GetResolutions()
let builder = ItemKeyStoreBuilder()
let preventDuplicates = HashSet({ new IEqualityComparer<struct(pos * pos)> with
......@@ -549,7 +554,6 @@ type BoundModel private (tcConfig: TcConfig,
sckBuilder.WriteAll semanticClassification
let res = builder.TryBuildAndReset(), sckBuilder.TryBuildAndReset()
Logger.LogBlockMessageStop fileName LogCompilerFunctionId.IncrementalBuild_CreateItemKeyStoreAndSemanticClassification
res
else
None, None
......@@ -1037,6 +1041,7 @@ module IncrementalBuilderStateHelpers =
let rec createFinalizeBoundModelGraphNode (initialState: IncrementalBuilderInitialState) (boundModels: ImmutableArray<GraphNode<BoundModel>>.Builder) =
GraphNode(node {
use _ = Activity.start "GetCheckResultsAndImplementationsForProject" [|"projectOutFile", initialState.outfile|]
// Compute last bound model then get all the evaluated models.
let! _ = boundModels[boundModels.Count - 1].GetOrComputeValue()
let boundModels =
......
......@@ -274,6 +274,9 @@ type BackgroundCompiler
/// creates an incremental builder used by the command line compiler.
let CreateOneIncrementalBuilder (options: FSharpProjectOptions, userOpName) =
node {
use _ =
Activity.start "BackgroundCompiler.CreateOneIncrementalBuilder" [| "project", options.ProjectFileName |]
Trace.TraceInformation("FCS: {0}.{1} ({2})", userOpName, "CreateOneIncrementalBuilder", options.ProjectFileName)
let projectReferences = getProjectReferences options userOpName
......@@ -402,9 +405,7 @@ type BackgroundCompiler
| Some getBuilder ->
node {
match! getBuilder with
| builderOpt, creationDiags when builderOpt.IsNone || not builderOpt.Value.IsReferencesInvalidated ->
Logger.Log LogCompilerFunctionId.Service_IncrementalBuildersCache_GettingCache
return builderOpt, creationDiags
| builderOpt, creationDiags when builderOpt.IsNone || not builderOpt.Value.IsReferencesInvalidated -> return builderOpt, creationDiags
| _ ->
// The builder could be re-created,
// clear the check file caches that are associated with it.
......@@ -434,9 +435,7 @@ type BackgroundCompiler
let getAnyBuilder (options, userOpName) =
match tryGetAnyBuilder options with
| Some getBuilder ->
Logger.Log LogCompilerFunctionId.Service_IncrementalBuildersCache_GettingCache
getBuilder
| Some getBuilder -> getBuilder
| _ -> getOrCreateBuilder (options, userOpName)
static let mutable actualParseFileCount = 0
......@@ -467,6 +466,9 @@ type BackgroundCompiler
member _.ParseFile(fileName: string, sourceText: ISourceText, options: FSharpParsingOptions, cache: bool, userOpName: string) =
async {
use _ =
Activity.start "BackgroundCompiler.ParseFile" [| "fileName", fileName; "userOpName", userOpName; "cache", cache.ToString() |]
if cache then
let hash = sourceText.GetHashCode() |> int64
......@@ -491,6 +493,9 @@ type BackgroundCompiler
/// Fetch the parse information from the background compiler (which checks w.r.t. the FileSystem API)
member _.GetBackgroundParseResultsForFileInProject(fileName, options, userOpName) =
node {
use _ =
Activity.start "BackgroundCompiler.GetBackgroundParseResultsForFileInProject" [| "fileName", fileName; "userOpName", userOpName |]
let! builderOpt, creationDiags = getOrCreateBuilder (options, userOpName)
match builderOpt with
......@@ -518,6 +523,7 @@ type BackgroundCompiler
member _.GetCachedCheckFileResult(builder: IncrementalBuilder, fileName, sourceText: ISourceText, options) =
node {
use _ = Activity.start "BackgroundCompiler.GetCachedCheckFileResult" [| "fileName", fileName |]
let hash = sourceText.GetHashCode() |> int64
let key = (fileName, hash, options)
let cachedResultsOpt = parseCacheLock.AcquireLock(fun ltok -> checkFileInProjectCache.TryGet(ltok, key))
......@@ -620,6 +626,15 @@ type BackgroundCompiler
userOpName
) =
node {
use _ =
Activity.start
"BackgroundCompiler.CheckFileInProjectAllowingStaleCachedResults"
[|
"project", options.ProjectFileName
"fileName", fileName
"userOpName", userOpName
|]
let! cachedResults =
node {
let! builderOpt, creationDiags = getAnyBuilder (options, userOpName)
......@@ -653,6 +668,15 @@ type BackgroundCompiler
/// Type-check the result obtained by parsing. Force the evaluation of the antecedent type checking context if needed.
member bc.CheckFileInProject(parseResults: FSharpParseFileResults, fileName, fileVersion, sourceText: ISourceText, options, userOpName) =
node {
use _ =
Activity.start
"BackgroundCompiler.CheckFileInProject"
[|
"project", options.ProjectFileName
"fileName", fileName
"userOpName", userOpName
|]
let! builderOpt, creationDiags = getOrCreateBuilder (options, userOpName)
match builderOpt with
......@@ -672,15 +696,19 @@ type BackgroundCompiler
/// Parses and checks the source file and returns untyped AST and check results.
member bc.ParseAndCheckFileInProject(fileName: string, fileVersion, sourceText: ISourceText, options: FSharpProjectOptions, userOpName) =
node {
let strGuid = "_ProjectId=" + (options.ProjectId |> Option.defaultValue "null")
Logger.LogBlockMessageStart (fileName + strGuid) LogCompilerFunctionId.Service_ParseAndCheckFileInProject
use _ =
Activity.start
"BackgroundCompiler.ParseAndCheckFileInProject"
[|
"project", options.ProjectFileName
"fileName", fileName
"userOpName", userOpName
|]
let! builderOpt, creationDiags = getOrCreateBuilder (options, userOpName)
match builderOpt with
| None ->
Logger.LogBlockMessageStop (fileName + strGuid + "-Failed_Aborted") LogCompilerFunctionId.Service_ParseAndCheckFileInProject
let parseTree = EmptyParsedInput(fileName, (false, false))
let parseResults = FSharpParseFileResults(creationDiags, parseTree, true, [||])
return (parseResults, FSharpCheckFileAnswer.Aborted)
......@@ -689,10 +717,7 @@ type BackgroundCompiler
let! cachedResults = bc.GetCachedCheckFileResult(builder, fileName, sourceText, options)
match cachedResults with
| Some (parseResults, checkResults) ->
Logger.LogBlockMessageStop (fileName + strGuid + "-Successful_Cached") LogCompilerFunctionId.Service_ParseAndCheckFileInProject
return (parseResults, FSharpCheckFileAnswer.Succeeded checkResults)
| Some (parseResults, checkResults) -> return (parseResults, FSharpCheckFileAnswer.Succeeded checkResults)
| _ ->
let! tcPrior = builder.GetCheckResultsBeforeFileInProject fileName
let! tcInfo = tcPrior.GetOrComputeTcInfo()
......@@ -711,14 +736,21 @@ type BackgroundCompiler
let! checkResults =
bc.CheckOneFileImpl(parseResults, sourceText, fileName, options, fileVersion, builder, tcPrior, tcInfo, creationDiags)
Logger.LogBlockMessageStop (fileName + strGuid + "-Successful") LogCompilerFunctionId.Service_ParseAndCheckFileInProject
return (parseResults, checkResults)
}
/// Fetch the check information from the background compiler (which checks w.r.t. the FileSystem API)
member _.GetBackgroundCheckResultsForFileInProject(fileName, options, userOpName) =
node {
use _ =
Activity.start
"BackgroundCompiler.ParseAndCheckFileInProject"
[|
"project", options.ProjectFileName
"fileName", fileName
"userOpName", userOpName
|]
let! builderOpt, creationDiags = getOrCreateBuilder (options, userOpName)
match builderOpt with
......@@ -802,6 +834,16 @@ type BackgroundCompiler
userOpName: string
) =
node {
use _ =
Activity.start
"BackgroundCompiler.FindReferencesInFile"
[|
"project", options.ProjectFileName
"fileName", fileName
"userOpName", userOpName
"symbol", symbol.FullName
|]
let! builderOpt, _ = getOrCreateBuilderWithInvalidationFlag (options, canInvalidateProject, userOpName)
match builderOpt with
......@@ -820,6 +862,15 @@ type BackgroundCompiler
member _.GetSemanticClassificationForFile(fileName: string, options: FSharpProjectOptions, userOpName: string) =
node {
use _ =
Activity.start
"BackgroundCompiler.GetSemanticClassificationForFile"
[|
"project", options.ProjectFileName
"fileName", fileName
"userOpName", userOpName
|]
let! builderOpt, _ = getOrCreateBuilder (options, userOpName)
match builderOpt with
......@@ -835,6 +886,15 @@ type BackgroundCompiler
/// Try to get recent approximate type check results for a file.
member _.TryGetRecentCheckResultsForFile(fileName: string, options: FSharpProjectOptions, sourceText: ISourceText option, _userOpName: string) =
use _ =
Activity.start
"BackgroundCompiler.GetSemanticClassificationForFile"
[|
"project", options.ProjectFileName
"fileName", fileName
"userOpName", _userOpName
|]
match sourceText with
| Some sourceText ->
let hash = sourceText.GetHashCode() |> int64
......@@ -907,6 +967,9 @@ type BackgroundCompiler
member _.GetAssemblyData(options, userOpName) =
node {
use _ =
Activity.start "BackgroundCompiler.GetAssemblyData" [| "project", options.ProjectFileName; "userOpName", userOpName |]
let! builderOpt, _ = getOrCreateBuilder (options, userOpName)
match builderOpt with
......@@ -927,6 +990,9 @@ type BackgroundCompiler
/// Parse and typecheck the whole project.
member bc.ParseAndCheckProject(options, userOpName) =
use _ =
Activity.start "BackgroundCompiler.ParseAndCheckProject" [| "project", options.ProjectFileName; "userOpName", userOpName |]
bc.ParseAndCheckProjectImpl(options, userOpName)
member _.GetProjectOptionsFromScript
......@@ -943,6 +1009,9 @@ type BackgroundCompiler
optionsStamp: int64 option,
_userOpName
) =
use _ =
Activity.start "BackgroundCompiler.GetProjectOptionsFromScript" [| "fileName", fileName; "userOpName", _userOpName |]
cancellable {
use diagnostics = new DiagnosticsScope()
......@@ -1027,6 +1096,9 @@ type BackgroundCompiler
|> Cancellable.toAsync
member bc.InvalidateConfiguration(options: FSharpProjectOptions, userOpName) =
use _ =
Activity.start "BackgroundCompiler.InvalidateConfiguration" [| "project", options.ProjectFileName; "userOpName", userOpName |]
if incrementalBuildersCache.ContainsSimilarKey(AnyCallerThread, options) then
parseCacheLock.AcquireLock(fun ltok ->
for sourceFile in options.SourceFiles do
......@@ -1036,11 +1108,16 @@ type BackgroundCompiler
()
member bc.ClearCache(options: seq<FSharpProjectOptions>, _userOpName) =
use _ = Activity.start "BackgroundCompiler.ClearCache" [| "userOpName", _userOpName |]
lock gate (fun () ->
options
|> Seq.iter (fun options -> incrementalBuildersCache.RemoveAnySimilar(AnyCallerThread, options)))
member _.NotifyProjectCleaned(options: FSharpProjectOptions, userOpName) =
use _ =
Activity.start "BackgroundCompiler.NotifyProjectCleaned" [| "project", options.ProjectFileName; "userOpName", userOpName |]
async {
let! ct = Async.CancellationToken
// If there was a similar entry (as there normally will have been) then re-establish an empty builder . This
......@@ -1060,6 +1137,8 @@ type BackgroundCompiler
member _.ProjectChecked = projectChecked.Publish
member _.ClearCaches() =
use _ = Activity.startNoTags "BackgroundCompiler.ClearCaches"
lock gate (fun () ->
parseCacheLock.AcquireLock(fun ltok ->
checkFileInProjectCache.Clear(ltok)
......@@ -1070,6 +1149,8 @@ type BackgroundCompiler
scriptClosureCache.Clear AnyCallerThread)
member _.DownsizeCaches() =
use _ = Activity.startNoTags "BackgroundCompiler.DownsizeCaches"
lock gate (fun () ->
parseCacheLock.AcquireLock(fun ltok ->
checkFileInProjectCache.Resize(ltok, newKeepStrongly = 1)
......@@ -1160,6 +1241,8 @@ type FSharpChecker
?parallelReferenceResolution
) =
use _ = Activity.startNoTags "FSharpChecker.Create"
let legacyReferenceResolver =
match legacyReferenceResolver with
| Some rr -> rr
......@@ -1201,6 +1284,7 @@ type FSharpChecker
member _.MatchBraces(fileName, sourceText: ISourceText, options: FSharpParsingOptions, ?userOpName: string) =
let userOpName = defaultArg userOpName "Unknown"
use _ = Activity.start "FSharpChecker.MatchBraces" [| "fileName", fileName; "userOpName", userOpName |]
let hash = sourceText.GetHashCode() |> int64
async {
......@@ -1252,6 +1336,7 @@ type FSharpChecker
member _.Compile(argv: string[], ?userOpName: string) =
let _userOpName = defaultArg userOpName "Unknown"
use _ = Activity.start "FSharpChecker.Compile" [| "userOpName", _userOpName |]
async {
let ctok = CompilationThreadToken()
......@@ -1270,6 +1355,9 @@ type FSharpChecker
// This is for unit testing only
member ic.ClearLanguageServiceRootCachesAndCollectAndFinalizeAllTransients() =
use _ =
Activity.startNoTags "FsharpChecker.ClearLanguageServiceRootCachesAndCollectAndFinalizeAllTransients"
ic.ClearCaches()
GC.Collect()
GC.WaitForPendingFinalizers()
......
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
namespace FSharp.Compiler.Diagnostics
open System
open System.Diagnostics
[<RequireQualifiedAccess>]
module Activity =
let private activitySourceName = "fsc"
let private activitySource = new ActivitySource(activitySourceName)
let start (name: string) (tags: (string * string) seq) : IDisposable =
let activity = activitySource.StartActivity(name)
match activity with
| null -> ()
| activity ->
for key, value in tags do
activity.AddTag(key, value) |> ignore
activity
let startNoTags (name: string) : IDisposable = activitySource.StartActivity(name)
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
namespace FSharp.Compiler.Diagnostics
open System
/// For activities following the dotnet distributed tracing concept
/// https://learn.microsoft.com/en-us/dotnet/core/diagnostics/distributed-tracing-concepts?source=recommendations
[<RequireQualifiedAccess>]
module internal Activity =
val startNoTags: name: string -> IDisposable
val start: name: string -> tags: (string * string) seq -> IDisposable
......@@ -997,7 +997,7 @@ type CancellableBuilder() =
match compRes with
| ValueOrCancelled.Value res ->
(resource :> IDisposable).Dispose()
Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicFunctions.Dispose resource
match res with
| Choice1Of2 r -> ValueOrCancelled.Value r
......
......@@ -48,6 +48,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="System.Diagnostics.DiagnosticSource" Version="$(SystemDiagnosticsDiagnosticSourceVersion)" />
<PackageReference Include="System.Memory" Version="$(SystemMemoryVersion)" />
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="$(SystemRuntimeCompilerServicesUnsafeVersion)" />
<PackageReference Include="System.Reflection.Metadata" Version="$(SystemReflectionMetadataVersion)" />
......
......@@ -15,6 +15,7 @@
<PackageReference Include="System.Memory" Version="$(SystemMemoryVersion)" PrivateAssets="all" ExcludeAssets="contentFiles;analyzers;native" />
<PackageReference Include="System.Reflection.Metadata" Version="$(SystemReflectionMetadataVersion)" PrivateAssets="all" ExcludeAssets="contentFiles;analyzers;native" />
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="$(SystemRuntimeCompilerServicesUnsafeVersion)" PrivateAssets="all" ExcludeAssets="contentFiles;analyzers;native" />
<PackageReference Include="System.Diagnostics.DiagnosticSource" Version="$(SystemDiagnosticsDiagnosticSourceVersion)" PrivateAssets="all" ExcludeAssets="contentFiles;analyzers;native" />
</ItemGroup>
<!-- New VS does not allow embedded interop assemblies ... this turns off the target that turns it on -->
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册