@@ -19,6 +19,31 @@ open Microsoft.FSharp.Compiler.AbstractIL.Internal.Library
19
19
open Microsoft.FSharp .Compiler .ErrorLogger
20
20
open Microsoft.FSharp .Compiler .Range
21
21
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 = 0 L with get, set
46
+
22
47
// --------------------------------------------------------------------
23
48
// PDB types
24
49
// --------------------------------------------------------------------
@@ -227,7 +252,7 @@ let fixupOverlappingSequencePoints fixupSPs showTimes methods =
227
252
Array.sortInPlaceBy fst allSps
228
253
spCounts, allSps
229
254
230
- let generatePortablePdb fixupSPs showTimes ( info : PdbData ) =
255
+ let generatePortablePdb fixupSPs ( embedAllSource : bool ) ( embedSourceList : string list ) showTimes ( info : PdbData ) =
231
256
sortMethods showTimes info
232
257
let _spCounts , _allSps = fixupOverlappingSequencePoints fixupSPs showTimes info.Methods
233
258
let externalRowCounts = getRowCounts info.TableRowCounts
@@ -253,23 +278,69 @@ let generatePortablePdb fixupSPs showTimes (info:PdbData) =
253
278
metadata.GetOrAddBlob( writer)
254
279
255
280
let corSymLanguageTypeFSharp = System.Guid( 0xAB4F38C9 u, 0xB6E6 us, 0x43ba us, 0xBE uy, 0x3B uy, 0x58 uy, 0x08 uy, 0x0B uy, 0x2C uy, 0xCC uy, 0xE3 uy)
281
+ let embeddedSource = System.Guid( 0x0e8a571b u, 0x6926 us, 0x466e us, 0xb4 uy, 0xad uy, 0x8a uy, 0xb0 uy, 0x46 uy, 0x11 uy, 0xf5 uy, 0xfe uy)
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
+
256
294
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
+
257
319
let mutable index = new Dictionary< string, DocumentHandle>( docs.Length)
258
320
metadata.SetCapacity( TableIndex.Document, docs.Length)
259
321
for doc in docs do
260
322
let handle =
261
323
match checkSum doc.File with
262
324
| 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
267
337
| 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
273
344
index.Add( doc.File, handle)
274
345
index
275
346
@@ -291,7 +362,7 @@ let generatePortablePdb fixupSPs showTimes (info:PdbData) =
291
362
else
292
363
match documentIndex.TryGetValue( docs.[ d]. File) with
293
364
| false , _ -> Unchecked.defaultof< DocumentHandle>
294
- | true , f -> f
365
+ | true , h -> h
295
366
296
367
if sps.Length = 0 then
297
368
Unchecked.defaultof< DocumentHandle>, Unchecked.defaultof< BlobHandle>
@@ -306,7 +377,6 @@ let generatePortablePdb fixupSPs showTimes (info:PdbData) =
306
377
singleDocumentIndex
307
378
308
379
let builder = new BlobBuilder()
309
-
310
380
builder.WriteCompressedInteger( minfo.LocalSignatureToken)
311
381
312
382
// Initial document: When sp's spread over more than one document we put the initial document here.
0 commit comments