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

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: post-review cleanup 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
« no previous file with comments | « no previous file | pkg/analyzer/lib/src/dart/element/element.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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;
scheglov 2016/02/17 02:34:25 Do we want to introduce Element dependency into ca
skybrian 2016/02/17 03:05:57 To avoid this import statement, an alternative mig
Brian Wilkerson 2016/02/17 04:03:54 I definitely do not want to add a temporary method
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 CacheEntry entry = partition.remove(target);
245 if (entry != null) {
246 entry.dispose();
247 }
248 return entry;
243 } 249 }
244 } 250 }
245 return null; 251 return null;
246 } 252 }
247 253
248 /** 254 /**
249 * Return the number of targets that are mapped to cache entries. 255 * Return the number of targets that are mapped to cache entries.
250 */ 256 */
251 int size() { 257 int size() {
252 int size = 0; 258 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. 306 * A bit-encoding of boolean flags associated with this entry's target.
301 */ 307 */
302 int _flags = 0; 308 int _flags = 0;
303 309
304 /** 310 /**
305 * A table mapping result descriptors to the cached values of those results. 311 * A table mapping result descriptors to the cached values of those results.
306 */ 312 */
307 Map<ResultDescriptor, ResultData> _resultMap = 313 Map<ResultDescriptor, ResultData> _resultMap =
308 new HashMap<ResultDescriptor, ResultData>(); 314 new HashMap<ResultDescriptor, ResultData>();
309 315
310 CacheEntry(this.target); 316 CacheEntry(this.target) {
317 if (target is ElementImpl) {
318 (target as ElementImpl).setModifier(Modifier.CACHE_KEY, true);
319 }
320 }
311 321
312 /** 322 /**
313 * The exception that caused one or more values to have a state of 323 * The exception that caused one or more values to have a state of
314 * [CacheState.ERROR]. 324 * [CacheState.ERROR].
315 */ 325 */
316 CaughtException get exception => _exception; 326 CaughtException get exception => _exception;
317 327
318 /** 328 /**
319 * Return `true` if the source was explicitly added to the context or `false` 329 * 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 330 * if the source was implicitly added because it was referenced by another
(...skipping 22 matching lines...) Expand all
343 _resultMap.forEach((descriptor, data) { 353 _resultMap.forEach((descriptor, data) {
344 TargetedResult result = new TargetedResult(target, descriptor); 354 TargetedResult result = new TargetedResult(target, descriptor);
345 for (TargetedResult dependedOnResult in data.dependedOnResults) { 355 for (TargetedResult dependedOnResult in data.dependedOnResults) {
346 ResultData dependedOnData = _partition._getDataFor(dependedOnResult); 356 ResultData dependedOnData = _partition._getDataFor(dependedOnResult);
347 if (dependedOnData != null) { 357 if (dependedOnData != null) {
348 dependedOnData.dependentResults.remove(result); 358 dependedOnData.dependentResults.remove(result);
349 } 359 }
350 } 360 }
351 }); 361 });
352 _resultMap.clear(); 362 _resultMap.clear();
363 if (target is ElementImpl) {
364 (target as ElementImpl).setModifier(Modifier.CACHE_KEY, false);
365 }
353 } 366 }
354 367
355 /** 368 /**
356 * Fix the state of the [exception] to match the current state of the entry. 369 * Fix the state of the [exception] to match the current state of the entry.
357 */ 370 */
358 void fixExceptionState() { 371 void fixExceptionState() {
359 if (!hasErrorState()) { 372 if (!hasErrorState()) {
360 _exception = null; 373 _exception = null;
361 } 374 }
362 } 375 }
(...skipping 14 matching lines...) Expand all
377 if (data == null) { 390 if (data == null) {
378 return CacheState.INVALID; 391 return CacheState.INVALID;
379 } 392 }
380 return data.state; 393 return data.state;
381 } 394 }
382 395
383 /** 396 /**
384 * Return the value of the result represented by the given [descriptor], or 397 * 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. 398 * the default value for the result if this entry does not have a valid value.
386 */ 399 */
387 dynamic /*=V*/ getValue /*<V>*/ (ResultDescriptor /*<V>*/ descriptor) { 400 dynamic/*=V*/ getValue/*<V>*/(ResultDescriptor/*<V>*/ descriptor) {
388 ResultData data = _resultMap[descriptor]; 401 ResultData data = _resultMap[descriptor];
389 if (data == null) { 402 if (data == null) {
390 return descriptor.defaultValue; 403 return descriptor.defaultValue;
391 } 404 }
392 if (_partition != null) { 405 if (_partition != null) {
393 _partition.resultAccessed(target, descriptor); 406 _partition.resultAccessed(target, descriptor);
394 } 407 }
395 return data.value; 408 return data.value;
396 } 409 }
397 410
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
475 // 488 //
476 data.value = descriptor.defaultValue; 489 data.value = descriptor.defaultValue;
477 } 490 }
478 } 491 }
479 } 492 }
480 493
481 /** 494 /**
482 * Set the value of the result represented by the given [descriptor] to the 495 * Set the value of the result represented by the given [descriptor] to the
483 * given [value]. 496 * given [value].
484 */ 497 */
485 void setValue /*<V>*/ (ResultDescriptor /*<V>*/ descriptor, 498 void setValue/*<V>*/(ResultDescriptor/*<V>*/ descriptor, dynamic/*=V*/ value,
486 dynamic /*=V*/ value, List<TargetedResult> dependedOn) { 499 List<TargetedResult> dependedOn) {
487 // { 500 // {
488 // String valueStr = '$value'; 501 // String valueStr = '$value';
489 // if (valueStr.length > 20) { 502 // if (valueStr.length > 20) {
490 // valueStr = valueStr.substring(0, 20) + '...'; 503 // valueStr = valueStr.substring(0, 20) + '...';
491 // } 504 // }
492 // valueStr = valueStr.replaceAll('\n', '\\n'); 505 // valueStr = valueStr.replaceAll('\n', '\\n');
493 // print( 506 // print(
494 // 'setValue $descriptor for $target value=$valueStr $dependedOn=$depen dedOn'); 507 // 'setValue $descriptor for $target value=$valueStr $dependedOn=$depen dedOn');
495 // } 508 // }
496 _validateStateChange(descriptor, CacheState.VALID); 509 _validateStateChange(descriptor, CacheState.VALID);
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
574 for (TargetedResult dependedOnResult in thisData.dependedOnResults) { 587 for (TargetedResult dependedOnResult in thisData.dependedOnResults) {
575 ResultData data = _partition._getDataFor(dependedOnResult); 588 ResultData data = _partition._getDataFor(dependedOnResult);
576 if (data != null && deltaResult != DeltaResult.KEEP_CONTINUE) { 589 if (data != null && deltaResult != DeltaResult.KEEP_CONTINUE) {
577 data.dependentResults.remove(thisResult); 590 data.dependentResults.remove(thisResult);
578 } 591 }
579 } 592 }
580 // Invalidate results that depend on this result. 593 // Invalidate results that depend on this result.
581 _invalidateDependentResults(id, thisData, delta, level + 1); 594 _invalidateDependentResults(id, thisData, delta, level + 1);
582 // If empty and not explicitly added, remove the entry altogether. 595 // If empty and not explicitly added, remove the entry altogether.
583 if (_resultMap.isEmpty && !explicitlyAdded) { 596 if (_resultMap.isEmpty && !explicitlyAdded) {
584 _partition.entryMap.remove(target); 597 CacheEntry entry = _partition.entryMap.remove(target);
598 if (entry != null) {
599 entry.dispose();
600 }
585 _partition._removeIfSource(target); 601 _partition._removeIfSource(target);
586 } 602 }
587 // Notify controller. 603 // Notify controller.
588 _partition.onResultInvalidated 604 _partition.onResultInvalidated
589 .add(new InvalidatedResult(this, descriptor, thisData.value)); 605 .add(new InvalidatedResult(this, descriptor, thisData.value));
590 } 606 }
591 607
592 /** 608 /**
593 * Invalidates all the results of this entry, with propagation. 609 * Invalidates all the results of this entry, with propagation.
594 */ 610 */
(...skipping 657 matching lines...) Expand 10 before | Expand all | Expand 10 after
1252 void resultAccessed(TargetedResult result) {} 1268 void resultAccessed(TargetedResult result) {}
1253 1269
1254 @override 1270 @override
1255 List<TargetedResult> resultStored(TargetedResult newResult, newValue) { 1271 List<TargetedResult> resultStored(TargetedResult newResult, newValue) {
1256 return TargetedResult.EMPTY_LIST; 1272 return TargetedResult.EMPTY_LIST;
1257 } 1273 }
1258 1274
1259 @override 1275 @override
1260 void targetRemoved(AnalysisTarget target) {} 1276 void targetRemoved(AnalysisTarget target) {}
1261 } 1277 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analyzer/lib/src/dart/element/element.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698