| Index: pkg/front_end/lib/src/incremental/file_state.dart
|
| diff --git a/pkg/front_end/lib/src/incremental/file_state.dart b/pkg/front_end/lib/src/incremental/file_state.dart
|
| index fd463b381f8a32aae8e7eafd93aedd44549acb58..34a92338822e7aa2eb441c0653b660f9e45fa9d3 100644
|
| --- a/pkg/front_end/lib/src/incremental/file_state.dart
|
| +++ b/pkg/front_end/lib/src/incremental/file_state.dart
|
| @@ -54,6 +54,10 @@ class FileState {
|
| Set<FileState> _directReferencedFiles = new Set<FileState>();
|
| List<FileState> _directReferencedLibraries = <FileState>[];
|
|
|
| + /// This flag is set to `true` during the mark phase of garbage collection
|
| + /// and set back to `false` for survived instances.
|
| + bool _gcMarked = false;
|
| +
|
| FileState._(this._fsState, this.uri, this.fileUri);
|
|
|
| /// The MD5 signature of the file API as a byte array.
|
| @@ -309,6 +313,35 @@ class FileSystemState {
|
| /// The `file:` URI of all files currently tracked by this instance.
|
| Iterable<Uri> get fileUris => _fileUriToFile.keys;
|
|
|
| + /// Perform mark and sweep garbage collection of [FileState]s.
|
| + void gc(Uri entryPoint) {
|
| + void mark(FileState file) {
|
| + if (!file._gcMarked) {
|
| + file._gcMarked = true;
|
| + file._directReferencedFiles.forEach(mark);
|
| + }
|
| + }
|
| +
|
| + var file = _uriToFile[entryPoint];
|
| + if (file == null) return;
|
| +
|
| + mark(file);
|
| +
|
| + var urisToRemove = new Set<Uri>();
|
| + var fileUrisToRemove = new Set<Uri>();
|
| + for (var file in _uriToFile.values) {
|
| + if (file._gcMarked) {
|
| + file._gcMarked = false;
|
| + } else {
|
| + urisToRemove.add(file.uri);
|
| + fileUrisToRemove.add(file.fileUri);
|
| + }
|
| + }
|
| +
|
| + urisToRemove.forEach(_uriToFile.remove);
|
| + fileUrisToRemove.forEach(_fileUriToFile.remove);
|
| + }
|
| +
|
| /// Return the [FileState] for the given [absoluteUri], or `null` if the
|
| /// [absoluteUri] cannot be resolved into a file URI.
|
| ///
|
|
|