protected override TRoot Recover(CancellationToken cancellationToken) { Contract.ThrowIfNull(_storage); using var stream = _storage.ReadStream(cancellationToken); return(RecoverRoot(stream, cancellationToken)); }
protected override TRoot Recover(CancellationToken cancellationToken) { using (var stream = _storage.ReadStream(cancellationToken)) { return(RecoverRoot(stream, cancellationToken)); } }
protected override TRoot Recover(CancellationToken cancellationToken) { Contract.ThrowIfNull(_storage); var tickCount = Environment.TickCount; try { if (RoslynEventSource.Instance.IsEnabled(EventLevel.Informational, EventKeywords.None)) { RoslynEventSource.Instance.BlockStart(_containingTree.FilePath, FunctionId.Workspace_Recoverable_RecoverRoot, blockId: 0); } using var stream = _storage.ReadStream(cancellationToken); return(RecoverRoot(stream, cancellationToken)); } finally { if (RoslynEventSource.Instance.IsEnabled(EventLevel.Informational, EventKeywords.None)) { var tick = Environment.TickCount - tickCount; if (cancellationToken.IsCancellationRequested) { RoslynEventSource.Instance.BlockCanceled(FunctionId.Workspace_Recoverable_RecoverRoot, tick, blockId: 0); } else { RoslynEventSource.Instance.BlockStop(FunctionId.Workspace_Recoverable_RecoverRoot, tick, blockId: 0); } } } }
public void TestTemporaryStorageMemoryMappedFileManagement() { using var workspace = new AdhocWorkspace(); var textFactory = Assert.IsType <TextFactoryService>( workspace.Services.GetService <ITextFactoryService>() ); var service = new TemporaryStorageServiceFactory.TemporaryStorageService(textFactory); var buffer = new MemoryStream(257 * 1024 + 1); for (var i = 0; i < buffer.Length; i++) { buffer.WriteByte((byte)i); } // Do a relatively cheap concurrent stress test of the backing MemoryMappedFile management var tasks = Enumerable .Range(1, 257) .Select( async i => { for (var j = 1; j < 5; j++) { using ITemporaryStreamStorage storage1 = service.CreateTemporaryStreamStorage( CancellationToken.None ), storage2 = service.CreateTemporaryStreamStorage( CancellationToken.None ); var storage3 = service.CreateTemporaryStreamStorage( CancellationToken.None ); // let the finalizer run for this instance storage1.WriteStream( new MemoryStream(buffer.GetBuffer(), 0, 1024 * i - 1) ); storage2.WriteStream(new MemoryStream(buffer.GetBuffer(), 0, 1024 * i)); storage3.WriteStream( new MemoryStream(buffer.GetBuffer(), 0, 1024 * i + 1) ); await Task.Yield(); using Stream s1 = storage1.ReadStream(), s2 = storage2.ReadStream(), s3 = storage3.ReadStream(); Assert.Equal(1024 * i - 1, s1.Length); Assert.Equal(1024 * i, s2.Length); Assert.Equal(1024 * i + 1, s3.Length); } } ); Task.WaitAll(tasks.ToArray()); GC.Collect(2); GC.WaitForPendingFinalizers(); GC.Collect(2); }
private static IEnumerable <string> EnumerateLines(ITemporaryStreamStorage storage) { using var stream = storage.ReadStream(); using var reader = new StreamReader(stream); string line; while ((line = reader.ReadLine()) != null) { yield return(line); } }
protected override TRoot Recover(CancellationToken cancellationToken) { Contract.ThrowIfNull(_storage); var tickCount = Environment.TickCount; using (RoslynEventSource.LogInformationalBlock(FunctionId.Workspace_Recoverable_RecoverRoot, _containingTree.FilePath, cancellationToken)) { using var stream = _storage.ReadStream(cancellationToken); return(RecoverRoot(stream, cancellationToken)); } }
private ModuleMetadata GetModuleMetadata(ITemporaryStreamStorage storage) { var stream = storage.ReadStream(CancellationToken.None); // under VS host, direct access should be supported var directAccess = (ISupportDirectMemoryAccess)stream; var pImage = directAccess.GetPointer(); var metadata = ModuleMetadata.CreateFromMetadata(pImage, (int)stream.Length); // memory management. _lifetimeMap.Add(metadata, stream); return(metadata); }
public MetadataReference CreateReference(ImmutableArray <string> aliases, bool embedInteropTypes, DocumentationProvider documentationProvider) { if (this.IsEmpty) { return(null); } // first see whether we can use native memory directly. var stream = _storage.ReadStream(); var supportNativeMemory = stream as ISupportDirectMemoryAccess; if (supportNativeMemory != null) { // this is unfortunate that if we give stream, compiler will just re-copy whole content to // native memory again. this is a way to get around the issue by we getting native memory ourselves and then // give them pointer to the native memory. also we need to handle lifetime ourselves. var metadata = AssemblyMetadata.Create(ModuleMetadata.CreateFromImage(supportNativeMemory.GetPointer(), (int)stream.Length)); var referenceWithNativeMemory = metadata.GetReference( documentation: documentationProvider, aliases: aliases, embedInteropTypes: embedInteropTypes, display: _assemblyName); // tie lifetime of stream to metadata reference we created. native memory's lifetime is tied to // stream internally and stream is shared between same temporary storage. so here, we should be // sharing same native memory for all skeleton assemblies from same project snapshot. s_lifetime.GetValue(referenceWithNativeMemory, _ => stream); return(referenceWithNativeMemory); } // Otherwise, we just let it use stream. Unfortunately, if we give stream, compiler will // internally copy it to native memory again. since compiler owns lifetime of stream, // it would be great if compiler can be little bit smarter on how it deals with stream. // We don't deterministically release the resulting metadata since we don't know // when we should. So we leave it up to the GC to collect it and release all the associated resources. var metadataFromStream = AssemblyMetadata.CreateFromStream(stream); return(metadataFromStream.GetReference( documentation: documentationProvider, aliases: aliases, embedInteropTypes: embedInteropTypes, display: _assemblyName)); }
private void GetStorageInfoFromTemporaryStorage(FileKey moduleFileKey, out ITemporaryStreamStorage storage, out Stream stream, out IntPtr pImage) { int size; using (var copyStream = SerializableBytes.CreateWritableStream()) { // open a file and let it go as soon as possible using (var fileStream = FileUtilities.OpenRead(moduleFileKey.FullPath)) { var headers = new PEHeaders(fileStream); var offset = headers.MetadataStartOffset; size = headers.MetadataSize; // given metadata contains no metadata info. // throw bad image format exception so that we can show right diagnostic to user. if (size <= 0) { throw new BadImageFormatException(); } StreamCopy(fileStream, copyStream, offset, size); } // copy over the data to temp storage and let pooled stream go storage = _temporaryStorageService.CreateTemporaryStreamStorage(CancellationToken.None); copyStream.Position = 0; storage.WriteStream(copyStream); } // get stream that owns direct access memory stream = storage.ReadStream(CancellationToken.None); // stream size must be same as what metadata reader said the size should be. Contract.ThrowIfFalse(stream.Length == size); // under VS host, direct access should be supported var directAccess = (ISupportDirectMemoryAccess)stream; pImage = directAccess.GetPointer(); }
public MetadataReference CreateReference(ImmutableArray <string> aliases, bool embedInteropTypes, DocumentationProvider documentationProvider) { if (this.IsEmpty) { return(null); } // first see whether we can use native memory directly. var stream = _storage.ReadStream(); var supportNativeMemory = stream as ISupportDirectMemoryAccess; AssemblyMetadata metadata; if (supportNativeMemory != null) { // this is unfortunate that if we give stream, compiler will just re-copy whole content to // native memory again. this is a way to get around the issue by we getting native memory ourselves and then // give them pointer to the native memory. also we need to handle lifetime ourselves. metadata = AssemblyMetadata.Create(ModuleMetadata.CreateFromImage(supportNativeMemory.GetPointer(), (int)stream.Length)); // Tie lifetime of stream to metadata we created. It is important to tie this to the Metadata and not the // metadata reference, as PE symbols hold onto just the Metadata. We can use Add here since we created // a brand new object in AssemblyMetadata.Create above. s_lifetime.Add(metadata, supportNativeMemory); } else { // Otherwise, we just let it use stream. Unfortunately, if we give stream, compiler will // internally copy it to native memory again. since compiler owns lifetime of stream, // it would be great if compiler can be little bit smarter on how it deals with stream. // We don't deterministically release the resulting metadata since we don't know // when we should. So we leave it up to the GC to collect it and release all the associated resources. metadata = AssemblyMetadata.CreateFromStream(stream); } return(metadata.GetReference( documentation: documentationProvider, aliases: aliases, embedInteropTypes: embedInteropTypes, display: _assemblyName)); }
private void GetStorageInfoFromTemporaryStorage(FileKey moduleFileKey, out ITemporaryStreamStorage storage, out Stream stream, out IntPtr pImage) { int size; using (var copyStream = SerializableBytes.CreateWritableStream()) { // open a file and let it go as soon as possible using (var fileStream = FileUtilities.OpenRead(moduleFileKey.FullPath)) { var headers = new PEHeaders(fileStream); var offset = headers.MetadataStartOffset; size = headers.MetadataSize; // given metadata contains no metadata info. // throw bad image format exception so that we can show right diagnostic to user. if (size <= 0) { throw new BadImageFormatException(); } StreamCopy(fileStream, copyStream, offset, size); } // copy over the data to temp storage and let pooled stream go storage = _temporaryStorageService.CreateTemporaryStreamStorage(CancellationToken.None); copyStream.Position = 0; storage.WriteStream(copyStream); } // get stream that owns direct access memory stream = storage.ReadStream(CancellationToken.None); // stream size must be same as what metadata reader said the size should be. Contract.ThrowIfFalse(stream.Length == size); // under VS host, direct access should be supported var directAccess = (ISupportDirectMemoryAccess)stream; pImage = directAccess.GetPointer(); }
public static string ReadString(this ITemporaryStreamStorage storage) { using var stream = storage.ReadStream(); using var reader = new StreamReader(stream); return(reader.ReadToEnd()); }