Skip to content

Commit 53d10d6

Browse files
authored
Merge pull request #651 from dsyme/integrate-780
Integrate all the latest from visualfsharp\master
2 parents 0929055 + 3328947 commit 53d10d6

16 files changed

+333
-267
lines changed

src/absil/il.fs

100755100644
File mode changed.

src/absil/ilwrite.fs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3536,7 +3536,7 @@ let writeDirectory os dict =
35363536

35373537
let writeBytes (os: BinaryWriter) (chunk:byte[]) = os.Write(chunk,0,chunk.Length)
35383538

3539-
let writeBinaryAndReportMappings (outfile, ilg, pdbfile: string option, signer: ILStrongNameSigner option, portablePDB, embeddedPDB,
3539+
let writeBinaryAndReportMappings (outfile, ilg, pdbfile: string option, signer: ILStrongNameSigner option, portablePDB, embeddedPDB, embedAllSource, embedSourceList,
35403540
fixupOverlappingSequencePoints, emitTailcalls, showTimes, dumpDebugInfo) modul noDebugData =
35413541
// Store the public key from the signer into the manifest. This means it will be written
35423542
// to the binary and also acts as an indicator to leave space for delay sign
@@ -3690,7 +3690,7 @@ let writeBinaryAndReportMappings (outfile, ilg, pdbfile: string option, signer:
36903690
let pdbOpt =
36913691
match portablePDB with
36923692
| true ->
3693-
let (uncompressedLength, contentId, stream) as pdbStream = generatePortablePdb fixupOverlappingSequencePoints showTimes pdbData
3693+
let (uncompressedLength, contentId, stream) as pdbStream = generatePortablePdb fixupOverlappingSequencePoints embedAllSource embedSourceList showTimes pdbData
36943694
if embeddedPDB then Some (compressPortablePdbStream uncompressedLength contentId stream)
36953695
else Some (pdbStream)
36963696
| _ -> None
@@ -4260,13 +4260,15 @@ type options =
42604260
pdbfile: string option
42614261
portablePDB: bool
42624262
embeddedPDB: bool
4263+
embedAllSource: bool
4264+
embedSourceList: string list
42634265
signer: ILStrongNameSigner option
42644266
fixupOverlappingSequencePoints: bool
42654267
emitTailcalls : bool
42664268
showTimes: bool
42674269
dumpDebugInfo:bool }
42684270

42694271
let WriteILBinary (outfile, (args: options), modul, noDebugData) =
4270-
ignore (writeBinaryAndReportMappings (outfile, args.ilg, args.pdbfile, args.signer, args.portablePDB, args.embeddedPDB,
4271-
args.fixupOverlappingSequencePoints, args.emitTailcalls, args.showTimes,
4272-
args.dumpDebugInfo) modul noDebugData)
4272+
ignore (writeBinaryAndReportMappings (outfile, args.ilg, args.pdbfile, args.signer, args.portablePDB, args.embeddedPDB,
4273+
args.embedAllSource, args.embedSourceList, args.fixupOverlappingSequencePoints,
4274+
args.emitTailcalls, args.showTimes, args.dumpDebugInfo) modul noDebugData)

src/absil/ilwrite.fsi

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ type options =
2020
pdbfile: string option
2121
portablePDB: bool
2222
embeddedPDB: bool
23+
embedAllSource: bool
24+
embedSourceList: string list
2325
signer : ILStrongNameSigner option
2426
fixupOverlappingSequencePoints : bool
2527
emitTailcalls: bool

src/absil/ilwritepdb.fs

Lines changed: 82 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,31 @@ open Microsoft.FSharp.Compiler.AbstractIL.Internal.Library
1919
open Microsoft.FSharp.Compiler.ErrorLogger
2020
open Microsoft.FSharp.Compiler.Range
2121

22+
23+
type BlobBuildingStream () =
24+
inherit Stream()
25+
26+
static let chunkSize = 32 * 1024
27+
let builder = new BlobBuilder(chunkSize)
28+
29+
override this.CanWrite = true
30+
override this.CanRead = false
31+
override this.CanSeek = false
32+
override this.Length = int64(builder.Count)
33+
34+
override this.Write(buffer:byte array, offset:int, count:int) = builder.WriteBytes(buffer, offset, count)
35+
override this.WriteByte(value:byte) = builder.WriteByte(value)
36+
member this.WriteInt32(value:int) = builder.WriteInt32(value)
37+
member this.ToImmutableArray() = builder.ToImmutableArray()
38+
member this.TryWriteBytes(stream:Stream, length:int) = builder.TryWriteBytes(stream, length)
39+
40+
override this.Flush() = ()
41+
override this.Dispose(_disposing:bool) = ()
42+
override this.Seek(_offset:int64, _origin:SeekOrigin) = raise (new NotSupportedException())
43+
override this.Read(_buffer:byte array, _offset:int, _count:int) = raise (new NotSupportedException())
44+
override this.SetLength(_value:int64) = raise (new NotSupportedException())
45+
override val Position = 0L with get, set
46+
2247
// --------------------------------------------------------------------
2348
// PDB types
2449
// --------------------------------------------------------------------
@@ -227,7 +252,7 @@ let fixupOverlappingSequencePoints fixupSPs showTimes methods =
227252
Array.sortInPlaceBy fst allSps
228253
spCounts, allSps
229254

230-
let generatePortablePdb fixupSPs showTimes (info:PdbData) =
255+
let generatePortablePdb fixupSPs (embedAllSource:bool) (embedSourceList:string list) showTimes (info:PdbData) =
231256
sortMethods showTimes info
232257
let _spCounts, _allSps = fixupOverlappingSequencePoints fixupSPs showTimes info.Methods
233258
let externalRowCounts = getRowCounts info.TableRowCounts
@@ -253,23 +278,69 @@ let generatePortablePdb fixupSPs showTimes (info:PdbData) =
253278
metadata.GetOrAddBlob(writer)
254279

255280
let corSymLanguageTypeFSharp = System.Guid(0xAB4F38C9u, 0xB6E6us, 0x43baus, 0xBEuy, 0x3Buy, 0x58uy, 0x08uy, 0x0Buy, 0x2Cuy, 0xCCuy, 0xE3uy)
281+
let embeddedSource = System.Guid(0x0e8a571bu, 0x6926us, 0x466eus, 0xb4uy, 0xaduy, 0x8auy, 0xb0uy, 0x46uy, 0x11uy, 0xf5uy, 0xfeuy)
282+
283+
/// <summary>
284+
/// The maximum number of bytes in to write out uncompressed.
285+
///
286+
/// This prevents wasting resources on compressing tiny files with little to negative gain
287+
/// in PDB file size.
288+
///
289+
/// Chosen as the point at which we start to see > 10% blob size reduction using all
290+
/// current source files in corefx and roslyn as sample data.
291+
/// </summary>
292+
let sourceCompressionThreshold = 200
293+
256294
let documentIndex =
295+
let includeSource file =
296+
let isInList =
297+
if embedSourceList.Length = 0 then false
298+
else
299+
embedSourceList |> List.tryFind(fun f -> String.Compare(file, f, StringComparison.OrdinalIgnoreCase ) = 0) |> Option.isSome
300+
301+
if not embedAllSource && not isInList || not (File.Exists(file)) then
302+
None
303+
else
304+
let stream = File.OpenRead(file)
305+
let length64 = stream.Length
306+
if length64 > int64(Int32.MaxValue) then raise (new IOException("File is too long"))
307+
308+
let builder = new BlobBuildingStream()
309+
let length = int(length64)
310+
if length < sourceCompressionThreshold then
311+
builder.WriteInt32(0)
312+
builder.TryWriteBytes(stream, length) |> ignore
313+
else
314+
builder.WriteInt32(length) |>ignore
315+
use deflater = new DeflateStream(builder, CompressionMode.Compress, true)
316+
stream.CopyTo(deflater) |> ignore
317+
Some (builder.ToImmutableArray())
318+
257319
let mutable index = new Dictionary<string, DocumentHandle>(docs.Length)
258320
metadata.SetCapacity(TableIndex.Document, docs.Length)
259321
for doc in docs do
260322
let handle =
261323
match checkSum doc.File with
262324
| Some (hashAlg, checkSum) ->
263-
serializeDocumentName doc.File,
264-
metadata.GetOrAddGuid(hashAlg),
265-
metadata.GetOrAddBlob(checkSum.ToImmutableArray()),
266-
metadata.GetOrAddGuid(corSymLanguageTypeFSharp)
325+
let dbgInfo =
326+
(serializeDocumentName doc.File,
327+
metadata.GetOrAddGuid(hashAlg),
328+
metadata.GetOrAddBlob(checkSum.ToImmutableArray()),
329+
metadata.GetOrAddGuid(corSymLanguageTypeFSharp)) |> metadata.AddDocument
330+
match includeSource doc.File with
331+
| None -> ()
332+
| Some blob ->
333+
metadata.AddCustomDebugInformation(DocumentHandle.op_Implicit(dbgInfo),
334+
metadata.GetOrAddGuid(embeddedSource),
335+
metadata.GetOrAddBlob(blob)) |> ignore
336+
dbgInfo
267337
| None ->
268-
serializeDocumentName doc.File,
269-
metadata.GetOrAddGuid(System.Guid.Empty),
270-
metadata.GetOrAddBlob(ImmutableArray<byte>.Empty),
271-
metadata.GetOrAddGuid(corSymLanguageTypeFSharp)
272-
|> metadata.AddDocument
338+
let dbgInfo =
339+
(serializeDocumentName doc.File,
340+
metadata.GetOrAddGuid(System.Guid.Empty),
341+
metadata.GetOrAddBlob(ImmutableArray<byte>.Empty),
342+
metadata.GetOrAddGuid(corSymLanguageTypeFSharp)) |> metadata.AddDocument
343+
dbgInfo
273344
index.Add(doc.File, handle)
274345
index
275346

@@ -291,7 +362,7 @@ let generatePortablePdb fixupSPs showTimes (info:PdbData) =
291362
else
292363
match documentIndex.TryGetValue(docs.[d].File) with
293364
| false, _ -> Unchecked.defaultof<DocumentHandle>
294-
| true, f -> f
365+
| true, h -> h
295366

296367
if sps.Length = 0 then
297368
Unchecked.defaultof<DocumentHandle>, Unchecked.defaultof<BlobHandle>
@@ -306,7 +377,6 @@ let generatePortablePdb fixupSPs showTimes (info:PdbData) =
306377
singleDocumentIndex
307378

308379
let builder = new BlobBuilder()
309-
310380
builder.WriteCompressedInteger(minfo.LocalSignatureToken)
311381

312382
// Initial document: When sp's spread over more than one document we put the initial document here.

src/absil/ilwritepdb.fsi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ type idd =
8282
iddData: byte[];
8383
iddChunk: BinaryChunk }
8484

85-
val generatePortablePdb : fixupSPs:bool -> showTimes:bool -> info:PdbData -> (int64 * BlobContentId * MemoryStream)
85+
val generatePortablePdb : fixupSPs:bool -> embedAllSource:bool -> embedSourceList:string list -> showTimes:bool -> info:PdbData -> (int64 * BlobContentId * MemoryStream)
8686
val compressPortablePdbStream : uncompressedLength:int64 -> contentId:BlobContentId -> stream:MemoryStream -> (int64 * BlobContentId * MemoryStream)
8787
val embedPortablePdbInfo : uncompressedLength:int64 -> contentId:BlobContentId -> stream:MemoryStream -> showTimes:bool -> fpdb:string -> cvChunk:BinaryChunk -> pdbChunk:BinaryChunk -> idd[]
8888
val writePortablePdbInfo : contentId:BlobContentId -> stream:MemoryStream -> showTimes:bool -> fpdb:string -> cvChunk:BinaryChunk -> idd[]

0 commit comments

Comments
 (0)