-
Notifications
You must be signed in to change notification settings - Fork 847
Embedded source #1591
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
Embedded source #1591
Changes from all commits
52fb016
022f5de
3a6dd4f
cfe36de
a162a6c
7c2d7fd
358cda2
fac749b
91a49e7
1020d62
210eddf
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 |
|---|---|---|
|
|
@@ -19,6 +19,31 @@ open Microsoft.FSharp.Compiler.AbstractIL.Internal.Library | |
| open Microsoft.FSharp.Compiler.ErrorLogger | ||
| open Microsoft.FSharp.Compiler.Range | ||
|
|
||
|
|
||
| type BlobBuildingStream () = | ||
| inherit Stream() | ||
|
|
||
| static let chunkSize = 32 * 1024 | ||
| let builder = new BlobBuilder(chunkSize) | ||
|
|
||
| override this.CanWrite with get() = true | ||
| override this.CanRead with get() = false | ||
| override this.CanSeek with get() = false | ||
| override this.Length with get() = int64(builder.Count) | ||
|
|
||
| override this.Write(buffer:byte array, offset:int, count:int) = builder.WriteBytes(buffer, offset, count) | ||
| override this.WriteByte(value:byte) = builder.WriteByte(value) | ||
| member this.WriteInt32(value:int) = builder.WriteInt32(value) | ||
| member this.ToImmutableArray() = builder.ToImmutableArray() | ||
| member this.TryWriteBytes(stream:Stream, length:int) = builder.TryWriteBytes(stream, length) | ||
|
|
||
| override this.Flush() = () | ||
| override this.Dispose(_disposing:bool) = () | ||
| override this.Seek(_offset:int64, _origin:SeekOrigin) = raise (new NotSupportedException()) | ||
| override this.Read(_buffer:byte array, _offset:int, _count:int) = raise (new NotSupportedException()) | ||
| override this.SetLength(_value:int64) = raise (new NotSupportedException()) | ||
| override val Position = 0L with get, set | ||
|
|
||
| // -------------------------------------------------------------------- | ||
| // PDB types | ||
| // -------------------------------------------------------------------- | ||
|
|
@@ -227,7 +252,7 @@ let fixupOverlappingSequencePoints fixupSPs showTimes methods = | |
| Array.sortInPlaceBy fst allSps | ||
| spCounts, allSps | ||
|
|
||
| let generatePortablePdb fixupSPs showTimes (info:PdbData) = | ||
| let generatePortablePdb fixupSPs (embedAllSource:bool) (embedSourceList:string list) showTimes (info:PdbData) = | ||
| sortMethods showTimes info | ||
| let _spCounts, _allSps = fixupOverlappingSequencePoints fixupSPs showTimes info.Methods | ||
| let externalRowCounts = getRowCounts info.TableRowCounts | ||
|
|
@@ -253,23 +278,71 @@ let generatePortablePdb fixupSPs showTimes (info:PdbData) = | |
| metadata.GetOrAddBlob(writer) | ||
|
|
||
| let corSymLanguageTypeFSharp = System.Guid(0xAB4F38C9u, 0xB6E6us, 0x43baus, 0xBEuy, 0x3Buy, 0x58uy, 0x08uy, 0x0Buy, 0x2Cuy, 0xCCuy, 0xE3uy) | ||
| let embeddedSource = System.Guid(0x0e8a571bu, 0x6926us, 0x466eus, 0xb4uy, 0xaduy, 0x8auy, 0xb0uy, 0x46uy, 0x11uy, 0xf5uy, 0xfeuy) | ||
|
|
||
| /// <summary> | ||
| /// The maximum number of bytes in to write out uncompressed. | ||
| /// | ||
| /// This prevents wasting resources on compressing tiny files with little to negative gain | ||
| /// in PDB file size. | ||
| /// | ||
| /// Chosen as the point at which we start to see > 10% blob size reduction using all | ||
| /// current source files in corefx and roslyn as sample data. | ||
| /// </summary> | ||
| let sourceCompressionThreshold = 200 | ||
|
|
||
| let documentIndex = | ||
| let includeSource file = | ||
| let isInList = | ||
| if embedSourceList |> List.length = 0 then false | ||
|
Contributor
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. You can just use
Contributor
Author
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. done
Contributor
Author
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. done |
||
| else | ||
| match embedSourceList |> List.tryFind(fun f -> String.Compare(file, f, StringComparison.OrdinalIgnoreCase ) = 0) with | ||
| | Some _ -> true | ||
|
Contributor
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. This match is the same as |
||
| | None -> false | ||
|
|
||
| if not embedAllSource && not isInList || not (File.Exists(file)) then | ||
| None | ||
| else | ||
| let stream = File.OpenRead(file) | ||
| let length64 = stream.Length | ||
| if length64 > int64(Int32.MaxValue) then raise (new IOException("File is too long")) | ||
|
|
||
| let builder = new BlobBuildingStream() | ||
| let length = int(length64) | ||
| if length < sourceCompressionThreshold then | ||
| builder.WriteInt32(0) | ||
| builder.TryWriteBytes(stream, length) |> ignore | ||
| else | ||
| builder.WriteInt32(length) |>ignore | ||
| use deflater = new DeflateStream(builder, CompressionMode.Compress, true) | ||
| stream.CopyTo(deflater) |> ignore | ||
| Some (builder.ToImmutableArray()) | ||
|
|
||
| let mutable index = new Dictionary<string, DocumentHandle>(docs.Length) | ||
| metadata.SetCapacity(TableIndex.Document, docs.Length) | ||
| for doc in docs do | ||
| let handle = | ||
| match checkSum doc.File with | ||
| | Some (hashAlg, checkSum) -> | ||
| serializeDocumentName doc.File, | ||
| metadata.GetOrAddGuid(hashAlg), | ||
| metadata.GetOrAddBlob(checkSum.ToImmutableArray()), | ||
| metadata.GetOrAddGuid(corSymLanguageTypeFSharp) | ||
| let h = | ||
|
Contributor
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. A better name than |
||
| (serializeDocumentName doc.File, | ||
| metadata.GetOrAddGuid(hashAlg), | ||
| metadata.GetOrAddBlob(checkSum.ToImmutableArray()), | ||
| metadata.GetOrAddGuid(corSymLanguageTypeFSharp)) |> metadata.AddDocument | ||
| match includeSource doc.File with | ||
| | None -> () | ||
| | Some blob -> | ||
| metadata.AddCustomDebugInformation(DocumentHandle.op_Implicit(h), | ||
| metadata.GetOrAddGuid(embeddedSource), | ||
| metadata.GetOrAddBlob(blob)) |> ignore | ||
| h | ||
| | None -> | ||
| serializeDocumentName doc.File, | ||
| metadata.GetOrAddGuid(System.Guid.Empty), | ||
| metadata.GetOrAddBlob(ImmutableArray<byte>.Empty), | ||
| metadata.GetOrAddGuid(corSymLanguageTypeFSharp) | ||
| |> metadata.AddDocument | ||
| let h = | ||
| (serializeDocumentName doc.File, | ||
| metadata.GetOrAddGuid(System.Guid.Empty), | ||
| metadata.GetOrAddBlob(ImmutableArray<byte>.Empty), | ||
| metadata.GetOrAddGuid(corSymLanguageTypeFSharp)) |> metadata.AddDocument | ||
| h | ||
| index.Add(doc.File, handle) | ||
| index | ||
|
|
||
|
|
@@ -291,7 +364,7 @@ let generatePortablePdb fixupSPs showTimes (info:PdbData) = | |
| else | ||
| match documentIndex.TryGetValue(docs.[d].File) with | ||
| | false, _ -> Unchecked.defaultof<DocumentHandle> | ||
| | true, f -> f | ||
| | true, h -> h | ||
|
|
||
| if sps.Length = 0 then | ||
| Unchecked.defaultof<DocumentHandle>, Unchecked.defaultof<BlobHandle> | ||
|
|
@@ -306,7 +379,6 @@ let generatePortablePdb fixupSPs showTimes (info:PdbData) = | |
| singleDocumentIndex | ||
|
|
||
| let builder = new BlobBuilder() | ||
|
|
||
| builder.WriteCompressedInteger(minfo.LocalSignatureToken) | ||
|
|
||
| // Initial document: When sp's spread over more than one document we put the initial document here. | ||
|
|
||
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.
"with get()" is not idiomatic - you can just remove it
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.
done