Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(722)

Side by Side Diff: pkg/analyzer/lib/src/context/cache.dart

Issue 1696193003: Fix cache corruption in incremental resolver (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library analyzer.src.context.cache; 5 library analyzer.src.context.cache;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 import 'dart:collection'; 8 import 'dart:collection';
9 9
10 import 'package:analyzer/src/dart/element/element.dart'
11 show ElementImpl, Modifier;
10 import 'package:analyzer/src/generated/engine.dart'; 12 import 'package:analyzer/src/generated/engine.dart';
11 import 'package:analyzer/src/generated/java_engine.dart'; 13 import 'package:analyzer/src/generated/java_engine.dart';
12 import 'package:analyzer/src/generated/source.dart'; 14 import 'package:analyzer/src/generated/source.dart';
13 import 'package:analyzer/src/generated/utilities_collection.dart'; 15 import 'package:analyzer/src/generated/utilities_collection.dart';
14 import 'package:analyzer/src/task/model.dart'; 16 import 'package:analyzer/src/task/model.dart';
15 import 'package:analyzer/task/model.dart'; 17 import 'package:analyzer/task/model.dart';
16 18
17 /** 19 /**
18 * Return `true` if the given [target] is a priority one. 20 * Return `true` if the given [target] is a priority one.
19 */ 21 */
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
232 */ 234 */
233 CacheEntry remove(AnalysisTarget target) { 235 CacheEntry remove(AnalysisTarget target) {
234 int count = _partitions.length; 236 int count = _partitions.length;
235 for (int i = 0; i < count; i++) { 237 for (int i = 0; i < count; i++) {
236 CachePartition partition = _partitions[i]; 238 CachePartition partition = _partitions[i];
237 if (partition.isResponsibleFor(target)) { 239 if (partition.isResponsibleFor(target)) {
238 if (_TRACE_CHANGES) { 240 if (_TRACE_CHANGES) {
239 AnalysisEngine.instance.logger 241 AnalysisEngine.instance.logger
240 .logInformation('Removed the cache entry for $target.'); 242 .logInformation('Removed the cache entry for $target.');
241 } 243 }
242 return partition.remove(target); 244 var entry = partition.remove(target);
Brian Wilkerson 2016/02/16 15:10:48 Missing type
skybrian 2016/02/17 01:23:41 Done.
245 if (entry != null) {
246 entry.dispose();
247 if (target is ElementImpl) {
248 target.setModifier(Modifier.CACHE_KEY, false);
Brian Wilkerson 2016/02/16 15:10:48 Won't `dispose` have already cleared the flag?
skybrian 2016/02/17 01:23:41 Fixed. (Yes, this was left over from debugging.)
249 }
250 }
251 return entry;
243 } 252 }
244 } 253 }
245 return null; 254 return null;
246 } 255 }
247 256
248 /** 257 /**
249 * Return the number of targets that are mapped to cache entries. 258 * Return the number of targets that are mapped to cache entries.
250 */ 259 */
251 int size() { 260 int size() {
252 int size = 0; 261 int size = 0;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
300 * A bit-encoding of boolean flags associated with this entry's target. 309 * A bit-encoding of boolean flags associated with this entry's target.
301 */ 310 */
302 int _flags = 0; 311 int _flags = 0;
303 312
304 /** 313 /**
305 * A table mapping result descriptors to the cached values of those results. 314 * A table mapping result descriptors to the cached values of those results.
306 */ 315 */
307 Map<ResultDescriptor, ResultData> _resultMap = 316 Map<ResultDescriptor, ResultData> _resultMap =
308 new HashMap<ResultDescriptor, ResultData>(); 317 new HashMap<ResultDescriptor, ResultData>();
309 318
310 CacheEntry(this.target); 319 CacheEntry(this.target) {
320 if (target is ElementImpl) {
321 (target as ElementImpl).setModifier(Modifier.CACHE_KEY, true);
skybrian 2016/02/16 07:11:06 Since target is a field, the extra cast is necessa
322 }
323 }
311 324
312 /** 325 /**
313 * The exception that caused one or more values to have a state of 326 * The exception that caused one or more values to have a state of
314 * [CacheState.ERROR]. 327 * [CacheState.ERROR].
315 */ 328 */
316 CaughtException get exception => _exception; 329 CaughtException get exception => _exception;
317 330
318 /** 331 /**
319 * Return `true` if the source was explicitly added to the context or `false` 332 * Return `true` if the source was explicitly added to the context or `false`
320 * if the source was implicitly added because it was referenced by another 333 * if the source was implicitly added because it was referenced by another
(...skipping 22 matching lines...) Expand all
343 _resultMap.forEach((descriptor, data) { 356 _resultMap.forEach((descriptor, data) {
344 TargetedResult result = new TargetedResult(target, descriptor); 357 TargetedResult result = new TargetedResult(target, descriptor);
345 for (TargetedResult dependedOnResult in data.dependedOnResults) { 358 for (TargetedResult dependedOnResult in data.dependedOnResults) {
346 ResultData dependedOnData = _partition._getDataFor(dependedOnResult); 359 ResultData dependedOnData = _partition._getDataFor(dependedOnResult);
347 if (dependedOnData != null) { 360 if (dependedOnData != null) {
348 dependedOnData.dependentResults.remove(result); 361 dependedOnData.dependentResults.remove(result);
349 } 362 }
350 } 363 }
351 }); 364 });
352 _resultMap.clear(); 365 _resultMap.clear();
366 if (target is ElementImpl) {
367 (target as ElementImpl).setModifier(Modifier.CACHE_KEY, false);
368 }
353 } 369 }
354 370
355 /** 371 /**
356 * Fix the state of the [exception] to match the current state of the entry. 372 * Fix the state of the [exception] to match the current state of the entry.
357 */ 373 */
358 void fixExceptionState() { 374 void fixExceptionState() {
359 if (!hasErrorState()) { 375 if (!hasErrorState()) {
360 _exception = null; 376 _exception = null;
361 } 377 }
362 } 378 }
(...skipping 14 matching lines...) Expand all
377 if (data == null) { 393 if (data == null) {
378 return CacheState.INVALID; 394 return CacheState.INVALID;
379 } 395 }
380 return data.state; 396 return data.state;
381 } 397 }
382 398
383 /** 399 /**
384 * Return the value of the result represented by the given [descriptor], or 400 * Return the value of the result represented by the given [descriptor], or
385 * the default value for the result if this entry does not have a valid value. 401 * the default value for the result if this entry does not have a valid value.
386 */ 402 */
387 dynamic /*=V*/ getValue /*<V>*/ (ResultDescriptor /*<V>*/ descriptor) { 403 dynamic/*=V*/ getValue/*<V>*/(ResultDescriptor/*<V>*/ descriptor) {
388 ResultData data = _resultMap[descriptor]; 404 ResultData data = _resultMap[descriptor];
389 if (data == null) { 405 if (data == null) {
390 return descriptor.defaultValue; 406 return descriptor.defaultValue;
391 } 407 }
392 if (_partition != null) { 408 if (_partition != null) {
393 _partition.resultAccessed(target, descriptor); 409 _partition.resultAccessed(target, descriptor);
394 } 410 }
395 return data.value; 411 return data.value;
396 } 412 }
397 413
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
475 // 491 //
476 data.value = descriptor.defaultValue; 492 data.value = descriptor.defaultValue;
477 } 493 }
478 } 494 }
479 } 495 }
480 496
481 /** 497 /**
482 * Set the value of the result represented by the given [descriptor] to the 498 * Set the value of the result represented by the given [descriptor] to the
483 * given [value]. 499 * given [value].
484 */ 500 */
485 void setValue /*<V>*/ (ResultDescriptor /*<V>*/ descriptor, 501 void setValue/*<V>*/(ResultDescriptor/*<V>*/ descriptor, dynamic/*=V*/ value,
486 dynamic /*=V*/ value, List<TargetedResult> dependedOn) { 502 List<TargetedResult> dependedOn) {
487 // { 503 // {
488 // String valueStr = '$value'; 504 // String valueStr = '$value';
489 // if (valueStr.length > 20) { 505 // if (valueStr.length > 20) {
490 // valueStr = valueStr.substring(0, 20) + '...'; 506 // valueStr = valueStr.substring(0, 20) + '...';
491 // } 507 // }
492 // valueStr = valueStr.replaceAll('\n', '\\n'); 508 // valueStr = valueStr.replaceAll('\n', '\\n');
493 // print( 509 // print(
494 // 'setValue $descriptor for $target value=$valueStr $dependedOn=$depen dedOn'); 510 // 'setValue $descriptor for $target value=$valueStr $dependedOn=$depen dedOn');
495 // } 511 // }
496 _validateStateChange(descriptor, CacheState.VALID); 512 _validateStateChange(descriptor, CacheState.VALID);
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
574 for (TargetedResult dependedOnResult in thisData.dependedOnResults) { 590 for (TargetedResult dependedOnResult in thisData.dependedOnResults) {
575 ResultData data = _partition._getDataFor(dependedOnResult); 591 ResultData data = _partition._getDataFor(dependedOnResult);
576 if (data != null && deltaResult != DeltaResult.KEEP_CONTINUE) { 592 if (data != null && deltaResult != DeltaResult.KEEP_CONTINUE) {
577 data.dependentResults.remove(thisResult); 593 data.dependentResults.remove(thisResult);
578 } 594 }
579 } 595 }
580 // Invalidate results that depend on this result. 596 // Invalidate results that depend on this result.
581 _invalidateDependentResults(id, thisData, delta, level + 1); 597 _invalidateDependentResults(id, thisData, delta, level + 1);
582 // If empty and not explicitly added, remove the entry altogether. 598 // If empty and not explicitly added, remove the entry altogether.
583 if (_resultMap.isEmpty && !explicitlyAdded) { 599 if (_resultMap.isEmpty && !explicitlyAdded) {
584 _partition.entryMap.remove(target); 600 var entry = _partition.entryMap.remove(target);
Brian Wilkerson 2016/02/16 15:10:48 Missing type
skybrian 2016/02/17 01:23:41 Done.
601 if (entry != null) {
602 entry.dispose();
603 if (target is ElementImpl) {
604 (target as ElementImpl).setModifier(Modifier.CACHE_KEY, false);
605 }
606 }
585 _partition._removeIfSource(target); 607 _partition._removeIfSource(target);
586 } 608 }
587 // Notify controller. 609 // Notify controller.
588 _partition.onResultInvalidated 610 _partition.onResultInvalidated
589 .add(new InvalidatedResult(this, descriptor, thisData.value)); 611 .add(new InvalidatedResult(this, descriptor, thisData.value));
590 } 612 }
591 613
592 /** 614 /**
593 * Invalidates all the results of this entry, with propagation. 615 * Invalidates all the results of this entry, with propagation.
594 */ 616 */
(...skipping 657 matching lines...) Expand 10 before | Expand all | Expand 10 after
1252 void resultAccessed(TargetedResult result) {} 1274 void resultAccessed(TargetedResult result) {}
1253 1275
1254 @override 1276 @override
1255 List<TargetedResult> resultStored(TargetedResult newResult, newValue) { 1277 List<TargetedResult> resultStored(TargetedResult newResult, newValue) {
1256 return TargetedResult.EMPTY_LIST; 1278 return TargetedResult.EMPTY_LIST;
1257 } 1279 }
1258 1280
1259 @override 1281 @override
1260 void targetRemoved(AnalysisTarget target) {} 1282 void targetRemoved(AnalysisTarget target) {}
1261 } 1283 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698