-
Notifications
You must be signed in to change notification settings - Fork 833
Enable graph-based type checking, parallel optimizations and ILX gen in deterministic build #19028
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 18 commits
f725638
9402d02
3cd1abf
1c73196
128da51
e1a4c93
da1e2b7
277a6dc
b3b9e2f
252dd09
43f0a78
7336f29
0c4e421
c032cc3
caebe81
48f0f63
45ffedc
15fbf8f
3e81e54
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -343,9 +343,12 @@ let scopeSorter (scope1: PdbMethodScope) (scope2: PdbMethodScope) = | |
| type PortablePdbGenerator | ||
| (embedAllSource: bool, embedSourceList: string list, sourceLink: string, checksumAlgorithm, info: PdbData, pathMap: PathMap) = | ||
|
|
||
| let docs = info.Documents | ||
| // Deterministic: build the Document table in a stable order by mapped file path, | ||
| // but preserve the original-document-index -> handle mapping by filename. | ||
| let originalDocFiles = info.Documents |> Array.map (fun d -> d.File) | ||
|
|
||
| // The metadata to wite to the PortablePDB (Roslyn = _debugMetadataOpt) | ||
| let docsSorted = | ||
| info.Documents |> Array.sortBy (fun d -> PathMap.apply pathMap d.File) | ||
|
|
||
| let metadata = MetadataBuilder() | ||
|
|
||
|
|
@@ -418,15 +421,16 @@ type PortablePdbGenerator | |
|
|
||
| Some(builder.ToImmutableArray()) | ||
|
|
||
| // Build Document table in deterministic order | ||
| let documentIndex = | ||
| let mutable index = Dictionary<string, DocumentHandle>(docs.Length) | ||
| let mutable index = Dictionary<string, DocumentHandle>(docsSorted.Length) | ||
|
|
||
| let docLength = docs.Length + if String.IsNullOrEmpty sourceLink then 1 else 0 | ||
| let docLength = | ||
| docsSorted.Length + (if String.IsNullOrWhiteSpace sourceLink then 0 else 1) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure why 1 and 0 are flipped in this diff? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Copilot did this. Apparently, the idea of this line was to reserve extra slot in case the
so this does not seem critical. Now Copilot says the line is not needed at all because sourceLink does not go into document table. |
||
|
|
||
| metadata.SetCapacity(TableIndex.Document, docLength) | ||
|
|
||
| for doc in docs do | ||
| // For F# Interactive, file name 'stdin' gets generated for interactive inputs | ||
| for doc in docsSorted do | ||
| let handle = | ||
| match checkSum doc.File checksumAlgorithm with | ||
| | Some(hashAlg, checkSum) -> | ||
|
|
@@ -476,11 +480,12 @@ type PortablePdbGenerator | |
|
|
||
| let mutable lastLocalVariableHandle = Unchecked.defaultof<LocalVariableHandle> | ||
|
|
||
| // IMPORTANT: map original document index -> filename -> handle | ||
| let getDocumentHandle d = | ||
| if docs.Length = 0 || d < 0 || d > docs.Length then | ||
| if info.Documents.Length = 0 || d < 0 || d >= info.Documents.Length then | ||
| Unchecked.defaultof<DocumentHandle> | ||
| else | ||
| match documentIndex.TryGetValue(docs[d].File) with | ||
| match documentIndex.TryGetValue(originalDocFiles[d]) with | ||
| | false, _ -> Unchecked.defaultof<DocumentHandle> | ||
| | true, h -> h | ||
|
|
||
|
|
@@ -563,7 +568,16 @@ type PortablePdbGenerator | |
| let serializeImportsBlob (imports: PdbImport[]) = | ||
| let writer = new BlobBuilder() | ||
|
|
||
| for import in imports do | ||
| let importsSorted = | ||
| imports | ||
| |> Array.sortWith (fun a b -> | ||
| match a, b with | ||
| | ImportType t1, ImportType t2 -> compare t1 t2 | ||
| | ImportNamespace n1, ImportNamespace n2 -> compare n1 n2 | ||
| | ImportType _, ImportNamespace _ -> -1 | ||
| | ImportNamespace _, ImportType _ -> 1) | ||
|
|
||
| for import in importsSorted do | ||
| serializeImport writer import | ||
|
|
||
| metadata.GetOrAddBlob(writer) | ||
|
|
@@ -640,7 +654,8 @@ type PortablePdbGenerator | |
| ) | ||
| |> ignore | ||
|
|
||
| for localVariable in scope.Locals do | ||
| // Deterministic: write locals by stable index | ||
| for localVariable in scope.Locals |> Array.sortBy (fun l -> l.Index) do | ||
| lastLocalVariableHandle <- | ||
| metadata.AddLocalVariable( | ||
| LocalVariableAttributes.None, | ||
|
|
@@ -653,7 +668,7 @@ type PortablePdbGenerator | |
| let sps = | ||
| match minfo.DebugRange with | ||
| | None -> Array.empty | ||
| | Some _ -> minfo.DebugPoints | ||
| | Some _ -> minfo.DebugPoints |> Array.sortWith SequencePoint.orderByOffset | ||
|
|
||
| let builder = BlobBuilder() | ||
| builder.WriteCompressedInteger(minfo.LocalSignatureToken) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
changes in this file are 100% copilot 😅 , so, caveat emptor