From db0f86f69266dfecf73d3f59e5c7cf6465d49285 Mon Sep 17 00:00:00 2001 From: majocha Date: Wed, 26 Apr 2023 19:25:12 +0200 Subject: [PATCH 1/2] fix block on synchronous state updates --- src/Compiler/Service/IncrementalBuild.fs | 26 +++++++++++++---------- src/Compiler/Service/IncrementalBuild.fsi | 7 ++++-- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/Compiler/Service/IncrementalBuild.fs b/src/Compiler/Service/IncrementalBuild.fs index 4d88e39c428..b57fe869f79 100644 --- a/src/Compiler/Service/IncrementalBuild.fs +++ b/src/Compiler/Service/IncrementalBuild.fs @@ -914,7 +914,7 @@ module IncrementalBuilderStateHelpers = return! prevBoundModel.Next(syntaxTree) }) - let rec createFinalizeBoundModelGraphNode (initialState: IncrementalBuilderInitialState) (boundModels: GraphNode seq) = + let createFinalizeBoundModelGraphNode (initialState: IncrementalBuilderInitialState) (boundModels: GraphNode seq) = GraphNode(node { use _ = Activity.start "GetCheckResultsAndImplementationsForProject" [|Activity.Tags.project, initialState.outfile|] let! result = @@ -928,15 +928,19 @@ module IncrementalBuilderStateHelpers = return result, DateTime.UtcNow }) - and computeStampedFileNames (initialState: IncrementalBuilderInitialState) (state: IncrementalBuilderState) (cache: TimeStampCache) = - let slots = + let updateStamps (state: IncrementalBuilderState) (cache: TimeStampCache) = + let slots = [ for slot in state.slots -> cache.GetFileTimeStamp slot.SyntaxTree.FileName |> slot.Notify ] + { state with slots = slots } + + let computeStampedFileNames (initialState: IncrementalBuilderInitialState) (state: IncrementalBuilderState) (cache: TimeStampCache) = + let state = if initialState.useChangeNotifications then - state.slots + state else - [ for slot in state.slots -> cache.GetFileTimeStamp slot.SyntaxTree.FileName |> slot.Notify ] + updateStamps state cache let slots = - [ for slot in slots do + [ for slot in state.slots do if slot.Notified then { slot with SyntaxTree = slot.SyntaxTree.Invalidate() } else slot ] let mapping (status, prevNode) slot = @@ -967,7 +971,7 @@ module IncrementalBuilderStateHelpers = else state - and computeStampedReferencedAssemblies (initialState: IncrementalBuilderInitialState) state canTriggerInvalidation (cache: TimeStampCache) = + let computeStampedReferencedAssemblies (initialState: IncrementalBuilderInitialState) state canTriggerInvalidation (cache: TimeStampCache) = let stampedReferencedAssemblies = state.stampedReferencedAssemblies.ToBuilder() let mutable referencesUpdated = false @@ -1277,12 +1281,12 @@ type IncrementalBuilder(initialState: IncrementalBuilderInitialState, state: Inc member _.GetLogicalTimeStampForFileInProject(slotOfFile: int) = let cache = TimeStampCache defaultTimeStamp - checkFileTimeStampsSynchronously cache - computeProjectTimeStamp currentState slotOfFile + let tempStateJustForCheckingTimeStamps = updateStamps currentState cache + computeProjectTimeStamp tempStateJustForCheckingTimeStamps slotOfFile member _.GetLogicalTimeStampForProject(cache) = - checkFileTimeStampsSynchronously cache - computeProjectTimeStamp currentState -1 + let tempStateJustForCheckingTimeStamps = updateStamps currentState cache + computeProjectTimeStamp tempStateJustForCheckingTimeStamps -1 member _.TryGetSlotOfFileName(fileName: string) = // Get the slot of the given file and force it to build. diff --git a/src/Compiler/Service/IncrementalBuild.fsi b/src/Compiler/Service/IncrementalBuild.fsi index 9ffc66a2fdb..ec8d0ed7461 100644 --- a/src/Compiler/Service/IncrementalBuild.fsi +++ b/src/Compiler/Service/IncrementalBuild.fsi @@ -185,6 +185,8 @@ type internal IncrementalBuilder = /// This is safe for use from non-compiler threads but the objects returned must in many cases be accessed only from the compiler thread. member GetCheckResultsForFileInProjectEvenIfStale: fileName: string -> PartialCheckResults option + // TODO: Looks like the following doc does not match the actual method or it's signature. + /// Get the preceding typecheck state of a slot, but only if it is up-to-date w.r.t. /// the timestamps on files and referenced DLLs prior to this one. Return None if the result is not available. /// This is a relatively quick operation. @@ -192,8 +194,9 @@ type internal IncrementalBuilder = /// This is safe for use from non-compiler threads member AreCheckResultsBeforeFileInProjectReady: fileName: string -> bool - /// Get the preceding typecheck state of a slot, WITH checking if it is up-to-date w.r.t. However, files will not be parsed or checked. - /// the timestamps on files and referenced DLLs prior to this one. Return None if the result is not available or if it is not up-to-date. + /// Get the preceding typecheck state of a slot, WITH checking if it is up-to-date w.r.t. the timestamps of files and referenced DLLs prior to this one. + /// However, files will not be parsed or checked. + /// Return None if the result is not available or if it is not up-to-date. /// /// This is safe for use from non-compiler threads but the objects returned must in many cases be accessed only from the compiler thread. member TryGetCheckResultsBeforeFileInProject: fileName: string -> PartialCheckResults option From abc3c21ea65f14c875c3afb1136c946c655aa56c Mon Sep 17 00:00:00 2001 From: majocha Date: Wed, 26 Apr 2023 22:51:41 +0200 Subject: [PATCH 2/2] revert it fully --- src/Compiler/Service/IncrementalBuild.fs | 29 ++++++++---------------- 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/src/Compiler/Service/IncrementalBuild.fs b/src/Compiler/Service/IncrementalBuild.fs index b57fe869f79..d010a518b80 100644 --- a/src/Compiler/Service/IncrementalBuild.fs +++ b/src/Compiler/Service/IncrementalBuild.fs @@ -928,19 +928,15 @@ module IncrementalBuilderStateHelpers = return result, DateTime.UtcNow }) - let updateStamps (state: IncrementalBuilderState) (cache: TimeStampCache) = - let slots = [ for slot in state.slots -> cache.GetFileTimeStamp slot.SyntaxTree.FileName |> slot.Notify ] - { state with slots = slots } - let computeStampedFileNames (initialState: IncrementalBuilderInitialState) (state: IncrementalBuilderState) (cache: TimeStampCache) = - let state = + let slots = if initialState.useChangeNotifications then - state + state.slots else - updateStamps state cache + [ for slot in state.slots -> cache.GetFileTimeStamp slot.SyntaxTree.FileName |> slot.Notify ] let slots = - [ for slot in state.slots do + [ for slot in slots do if slot.Notified then { slot with SyntaxTree = slot.SyntaxTree.Invalidate() } else slot ] let mapping (status, prevNode) slot = @@ -1136,11 +1132,6 @@ type IncrementalBuilder(initialState: IncrementalBuilderInitialState, state: Inc do! setCurrentState currentState cache ct } - let checkFileTimeStampsSynchronously cache = - checkFileTimeStamps cache - |> Async.AwaitNodeCode - |> Async.RunSynchronously - do IncrementalBuilderEventTesting.MRU.Add(IncrementalBuilderEventTesting.IBECreated) member _.TcConfig = tcConfig @@ -1196,10 +1187,10 @@ type IncrementalBuilder(initialState: IncrementalBuilderInitialState, state: Inc member builder.TryGetCheckResultsBeforeFileInProject fileName = let cache = TimeStampCache defaultTimeStamp - checkFileTimeStampsSynchronously cache + let tmpState = computeStampedFileNames initialState currentState cache let slotOfFile = builder.GetSlotOfFileName fileName - match tryGetBeforeSlot currentState slotOfFile with + match tryGetBeforeSlot tmpState slotOfFile with | Some(boundModel, timestamp) -> let projectTimeStamp = builder.GetLogicalTimeStampForFileInProject(fileName) Some (PartialCheckResults (boundModel, timestamp, projectTimeStamp)) @@ -1281,12 +1272,12 @@ type IncrementalBuilder(initialState: IncrementalBuilderInitialState, state: Inc member _.GetLogicalTimeStampForFileInProject(slotOfFile: int) = let cache = TimeStampCache defaultTimeStamp - let tempStateJustForCheckingTimeStamps = updateStamps currentState cache - computeProjectTimeStamp tempStateJustForCheckingTimeStamps slotOfFile + let tempState = computeStampedFileNames initialState currentState cache + computeProjectTimeStamp tempState slotOfFile member _.GetLogicalTimeStampForProject(cache) = - let tempStateJustForCheckingTimeStamps = updateStamps currentState cache - computeProjectTimeStamp tempStateJustForCheckingTimeStamps -1 + let tempState = computeStampedFileNames initialState currentState cache + computeProjectTimeStamp tempState -1 member _.TryGetSlotOfFileName(fileName: string) = // Get the slot of the given file and force it to build.