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

Side by Side Diff: pkg/compiler/lib/src/inferrer/locals_handler.dart

Issue 2981613002: Parameterize TypeSystem by its node kind (Closed)
Patch Set: Updated cf. comments Created 3 years, 5 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) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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 locals_handler; 5 library locals_handler;
6 6
7 import 'dart:collection' show IterableMixin; 7 import 'dart:collection' show IterableMixin;
8 8
9 import '../options.dart' show CompilerOptions; 9 import '../options.dart' show CompilerOptions;
10 import '../elements/elements.dart'; 10 import '../elements/elements.dart';
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 } 97 }
98 98
99 String toString() { 99 String toString() {
100 String rest = parent == null ? "null" : parent.toString(); 100 String rest = parent == null ? "null" : parent.toString();
101 return '$variables $rest'; 101 return '$variables $rest';
102 } 102 }
103 } 103 }
104 104
105 /// Tracks initializers via initializations and assignments. 105 /// Tracks initializers via initializations and assignments.
106 class FieldInitializationScope { 106 class FieldInitializationScope {
107 final TypeSystem types; 107 final TypeSystem<Node> types;
108 Map<Element, TypeInformation> fields; 108 Map<Element, TypeInformation> fields;
109 bool isThisExposed; 109 bool isThisExposed;
110 110
111 /// `true` when control flow prevents accumulating definite assignments, 111 /// `true` when control flow prevents accumulating definite assignments,
112 /// e.g. an early return or caught exception. 112 /// e.g. an early return or caught exception.
113 bool isIndefinite; 113 bool isIndefinite;
114 114
115 FieldInitializationScope(this.types) 115 FieldInitializationScope(this.types)
116 : isThisExposed = false, 116 : isThisExposed = false,
117 isIndefinite = false; 117 isIndefinite = false;
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
236 _iteratePositional = false; 236 _iteratePositional = false;
237 return named.moveNext(); 237 return named.moveNext();
238 } 238 }
239 } 239 }
240 240
241 /** 241 /**
242 * Placeholder for inferred types of local variables. 242 * Placeholder for inferred types of local variables.
243 */ 243 */
244 class LocalsHandler { 244 class LocalsHandler {
245 final CompilerOptions options; 245 final CompilerOptions options;
246 final TypeSystem types; 246 final TypeSystem<Node> types;
247 final InferrerEngine inferrer; 247 final InferrerEngine inferrer;
248 final VariableScope locals; 248 final VariableScope locals;
249 final Map<Local, FieldEntity> captured; 249 final Map<Local, FieldEntity> captured;
250 final Map<Local, FieldEntity> capturedAndBoxed; 250 final Map<Local, FieldEntity> capturedAndBoxed;
251 final FieldInitializationScope fieldScope; 251 final FieldInitializationScope fieldScope;
252 LocalsHandler tryBlock; 252 LocalsHandler tryBlock;
253 bool seenReturnOrThrow = false; 253 bool seenReturnOrThrow = false;
254 bool seenBreakOrContinue = false; 254 bool seenBreakOrContinue = false;
255 255
256 bool get aborts { 256 bool get aborts {
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
319 updateLocal() { 319 updateLocal() {
320 TypeInformation currentType = locals[local]; 320 TypeInformation currentType = locals[local];
321 321
322 SendSet send = node != null ? node.asSendSet() : null; 322 SendSet send = node != null ? node.asSendSet() : null;
323 if (send != null && send.isIfNullAssignment && currentType != null) { 323 if (send != null && send.isIfNullAssignment && currentType != null) {
324 // If-null assignments may return either the new or the original value 324 // If-null assignments may return either the new or the original value
325 // narrowed to non-null. 325 // narrowed to non-null.
326 type = types.addPhiInput( 326 type = types.addPhiInput(
327 local, 327 local,
328 types.allocatePhi( 328 types.allocatePhi(
329 locals.block, local, types.narrowNotNull(currentType)), 329 locals.block, local, types.narrowNotNull(currentType),
330 isTry: locals.block is TryStatement),
330 type); 331 type);
331 } 332 }
332 locals[local] = type; 333 locals[local] = type;
333 if (currentType != type) { 334 if (currentType != type) {
334 inferrer.recordLocalUpdate(local, type); 335 inferrer.recordLocalUpdate(local, type);
335 } 336 }
336 } 337 }
337 338
338 if (capturedAndBoxed.containsKey(local)) { 339 if (capturedAndBoxed.containsKey(local)) {
339 inferrer.recordTypeOfNonFinalField(capturedAndBoxed[local], type); 340 inferrer.recordTypeOfNonFinalField(capturedAndBoxed[local], type);
340 } else if (inTryBlock) { 341 } else if (inTryBlock) {
341 // We don'TypeInformation know if an assignment in a try block 342 // We don'TypeInformation know if an assignment in a try block
342 // will be executed, so all assignments in that block are 343 // will be executed, so all assignments in that block are
343 // potential types after we have left it. We update the parent 344 // potential types after we have left it. We update the parent
344 // of the try block so that, at exit of the try block, we get 345 // of the try block so that, at exit of the try block, we get
345 // the right phi for it. 346 // the right phi for it.
346 TypeInformation existing = tryBlock.locals.parent[local]; 347 TypeInformation existing = tryBlock.locals.parent[local];
347 if (existing != null) { 348 if (existing != null) {
348 TypeInformation phiType = 349 TypeInformation phiType = types.allocatePhi(
349 types.allocatePhi(tryBlock.locals.block, local, existing); 350 tryBlock.locals.block, local, existing,
351 isTry: tryBlock.locals.block is TryStatement);
350 TypeInformation inputType = types.addPhiInput(local, phiType, type); 352 TypeInformation inputType = types.addPhiInput(local, phiType, type);
351 tryBlock.locals.parent[local] = inputType; 353 tryBlock.locals.parent[local] = inputType;
352 } 354 }
353 // Update the current handler unconditionnally with the new 355 // Update the current handler unconditionnally with the new
354 // type. 356 // type.
355 updateLocal(); 357 updateLocal();
356 } else { 358 } else {
357 updateLocal(); 359 updateLocal();
358 } 360 }
359 } 361 }
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
498 * overwrites the current type knowledge in this handler. 500 * overwrites the current type knowledge in this handler.
499 */ 501 */
500 bool mergeHandler(LocalsHandler other, [Set<Local> seen]) { 502 bool mergeHandler(LocalsHandler other, [Set<Local> seen]) {
501 if (other.seenReturnOrThrow) return false; 503 if (other.seenReturnOrThrow) return false;
502 bool changed = false; 504 bool changed = false;
503 other.locals.forEachLocalUntilNode(locals.block, (local, otherType) { 505 other.locals.forEachLocalUntilNode(locals.block, (local, otherType) {
504 TypeInformation myType = locals[local]; 506 TypeInformation myType = locals[local];
505 if (myType == null) return; 507 if (myType == null) return;
506 TypeInformation newType; 508 TypeInformation newType;
507 if (seen != null && !seen.contains(local)) { 509 if (seen != null && !seen.contains(local)) {
508 newType = types.allocatePhi(locals.block, local, otherType); 510 newType = types.allocatePhi(locals.block, local, otherType,
511 isTry: locals.block is TryStatement);
509 seen.add(local); 512 seen.add(local);
510 } else { 513 } else {
511 newType = types.addPhiInput(local, myType, otherType); 514 newType = types.addPhiInput(local, myType, otherType);
512 } 515 }
513 if (newType != myType) { 516 if (newType != myType) {
514 changed = true; 517 changed = true;
515 locals[local] = newType; 518 locals[local] = newType;
516 } 519 }
517 }); 520 });
518 return changed; 521 return changed;
519 } 522 }
520 523
521 /** 524 /**
522 * Merge all [LocalsHandler] in [handlers] into this handler. 525 * Merge all [LocalsHandler] in [handlers] into this handler.
523 * Returns whether a local in this handler has changed. 526 * Returns whether a local in this handler has changed.
524 */ 527 */
525 bool mergeAll(List<LocalsHandler> handlers) { 528 bool mergeAll(List<LocalsHandler> handlers) {
526 bool changed = false; 529 bool changed = false;
527 assert(!seenReturnOrThrow); 530 assert(!seenReturnOrThrow);
528 handlers.forEach((other) { 531 handlers.forEach((other) {
529 changed = mergeHandler(other) || changed; 532 changed = mergeHandler(other) || changed;
530 }); 533 });
531 return changed; 534 return changed;
532 } 535 }
533 536
534 void startLoop(Node loop) { 537 void startLoop(Node loop) {
535 locals.forEachLocal((Local variable, TypeInformation type) { 538 locals.forEachLocal((Local variable, TypeInformation type) {
536 TypeInformation newType = types.allocateLoopPhi(loop, variable, type); 539 TypeInformation newType = types.allocateLoopPhi(loop, variable, type,
540 isTry: loop is TryStatement);
537 if (newType != type) { 541 if (newType != type) {
538 locals[variable] = newType; 542 locals[variable] = newType;
539 } 543 }
540 }); 544 });
541 } 545 }
542 546
543 void endLoop(Node loop) { 547 void endLoop(Node loop) {
544 locals.forEachLocal((Local variable, TypeInformation type) { 548 locals.forEachLocal((Local variable, TypeInformation type) {
545 TypeInformation newType = types.simplifyPhi(loop, variable, type); 549 TypeInformation newType = types.simplifyPhi(loop, variable, type);
546 if (newType != type) { 550 if (newType != type) {
547 locals[variable] = newType; 551 locals[variable] = newType;
548 } 552 }
549 }); 553 });
550 } 554 }
551 555
552 void updateField(Element element, TypeInformation type) { 556 void updateField(Element element, TypeInformation type) {
553 fieldScope.updateField(element, type); 557 fieldScope.updateField(element, type);
554 } 558 }
555 } 559 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/inferrer/inferrer_engine.dart ('k') | pkg/compiler/lib/src/inferrer/type_graph_nodes.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698