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

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

Issue 2994363002: Fix the local variable lookup in the locals handler. (Closed)
Patch Set: stephen comments Created 3 years, 4 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) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, 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 import '../closure.dart'; 5 import '../closure.dart';
6 import '../common.dart'; 6 import '../common.dart';
7 import '../elements/elements.dart'; 7 import '../elements/elements.dart';
8 import '../elements/entities.dart'; 8 import '../elements/entities.dart';
9 import '../elements/types.dart'; 9 import '../elements/types.dart';
10 import '../io/source_information.dart'; 10 import '../io/source_information.dart';
11 import '../js_backend/native_data.dart'; 11 import '../js_backend/native_data.dart';
12 import '../js_backend/interceptor_data.dart'; 12 import '../js_backend/interceptor_data.dart';
13 import '../js_model/closure.dart' show JBoxedField, JClosureField;
13 import '../tree/tree.dart' as ast; 14 import '../tree/tree.dart' as ast;
14 import '../types/types.dart'; 15 import '../types/types.dart';
15 import '../world.dart' show ClosedWorld; 16 import '../world.dart' show ClosedWorld;
16 17
17 import 'graph_builder.dart'; 18 import 'graph_builder.dart';
18 import 'nodes.dart'; 19 import 'nodes.dart';
19 import 'types.dart'; 20 import 'types.dart';
20 21
21 /// Keeps track of locals (including parameters and phis) when building. The 22 /// Keeps track of locals (including parameters and phis) when building. The
22 /// 'this' reference is treated as parameter and hence handled by this class, 23 /// 'this' reference is treated as parameter and hence handled by this class,
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
296 return !redirectionMapping.containsKey(local) && 297 return !redirectionMapping.containsKey(local) &&
297 !scopeInfo.localIsUsedInTryOrSync(local); 298 !scopeInfo.localIsUsedInTryOrSync(local);
298 } 299 }
299 300
300 bool isStoredInClosureField(Local local) { 301 bool isStoredInClosureField(Local local) {
301 assert(local != null); 302 assert(local != null);
302 if (isAccessedDirectly(local)) return false; 303 if (isAccessedDirectly(local)) return false;
303 if (scopeInfo is! ClosureRepresentationInfo) return false; 304 if (scopeInfo is! ClosureRepresentationInfo) return false;
304 FieldEntity redirectTarget = redirectionMapping[local]; 305 FieldEntity redirectTarget = redirectionMapping[local];
305 if (redirectTarget == null) return false; 306 if (redirectTarget == null) return false;
306 return redirectTarget is ClosureFieldElement; 307 return redirectTarget is ClosureFieldElement ||
308 redirectTarget is JClosureField;
307 } 309 }
308 310
309 bool isBoxed(Local local) { 311 bool isBoxed(Local local) {
310 if (isAccessedDirectly(local)) return false; 312 if (isAccessedDirectly(local)) return false;
311 if (isStoredInClosureField(local)) return false; 313 if (isStoredInClosureField(local)) return false;
312 return redirectionMapping.containsKey(local); 314 return redirectionMapping.containsKey(local);
313 } 315 }
314 316
315 bool _isUsedInTryOrGenerator(Local local) { 317 bool _isUsedInTryOrGenerator(Local local) {
316 return scopeInfo.localIsUsedInTryOrSync(local); 318 return scopeInfo.localIsUsedInTryOrSync(local);
(...skipping 18 matching lines...) Expand all
335 } 337 }
336 } 338 }
337 HInstruction value = directLocals[local]; 339 HInstruction value = directLocals[local];
338 if (sourceInformation != null) { 340 if (sourceInformation != null) {
339 value = new HRef(value, sourceInformation); 341 value = new HRef(value, sourceInformation);
340 builder.add(value); 342 builder.add(value);
341 } 343 }
342 return value; 344 return value;
343 } else if (isStoredInClosureField(local)) { 345 } else if (isStoredInClosureField(local)) {
344 ClosureRepresentationInfo closureData = scopeInfo; 346 ClosureRepresentationInfo closureData = scopeInfo;
345 ClosureFieldElement redirect = redirectionMapping[local]; 347 FieldEntity redirect = redirectionMapping[local];
346 HInstruction receiver = readLocal(closureData.closureEntity); 348 HInstruction receiver = readLocal(closureData.closureEntity);
347 TypeMask type = local is BoxLocal 349 TypeMask type = local is BoxLocal
348 ? commonMasks.nonNullType 350 ? commonMasks.nonNullType
349 : getTypeOfCapturedVariable(redirect); 351 : getTypeOfCapturedVariable(redirect);
350 HInstruction fieldGet = new HFieldGet(redirect, receiver, type); 352 HInstruction fieldGet = new HFieldGet(redirect, receiver, type);
351 builder.add(fieldGet); 353 builder.add(fieldGet);
352 return fieldGet..sourceInformation = sourceInformation; 354 return fieldGet..sourceInformation = sourceInformation;
353 } else if (isBoxed(local)) { 355 } else if (isBoxed(local)) {
354 BoxFieldElement redirect = redirectionMapping[local]; 356 FieldEntity redirect = redirectionMapping[local];
357 BoxLocal localBox;
355 // In the function that declares the captured variable the box is 358 // In the function that declares the captured variable the box is
356 // accessed as direct local. Inside the nested closure the box is 359 // accessed as direct local. Inside the nested closure the box is
357 // accessed through a closure-field. 360 // accessed through a closure-field.
358 // Calling [readLocal] makes sure we generate the correct code to get 361 // Calling [readLocal] makes sure we generate the correct code to get
359 // the box. 362 // the box.
360 HInstruction box = readLocal(redirect.box); 363 if (redirect is BoxFieldElement) {
364 localBox = redirect.box;
365 } else if (redirect is JBoxedField) {
366 localBox = redirect.box;
367 }
368 assert(localBox != null);
369
370 HInstruction box = readLocal(localBox);
361 HInstruction lookup = 371 HInstruction lookup =
362 new HFieldGet(redirect, box, getTypeOfCapturedVariable(redirect)); 372 new HFieldGet(redirect, box, getTypeOfCapturedVariable(redirect));
363 builder.add(lookup); 373 builder.add(lookup);
364 return lookup..sourceInformation = sourceInformation; 374 return lookup..sourceInformation = sourceInformation;
365 } else { 375 } else {
366 assert(_isUsedInTryOrGenerator(local)); 376 assert(_isUsedInTryOrGenerator(local));
367 HLocalValue localValue = getLocal(local); 377 HLocalValue localValue = getLocal(local);
368 HInstruction instruction = new HLocalGet( 378 HInstruction instruction = new HLocalGet(
369 local, localValue, commonMasks.dynamicType, sourceInformation); 379 local, localValue, commonMasks.dynamicType, sourceInformation);
370 builder.add(instruction); 380 builder.add(instruction);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
409 void updateLocal(Local local, HInstruction value, 419 void updateLocal(Local local, HInstruction value,
410 {SourceInformation sourceInformation}) { 420 {SourceInformation sourceInformation}) {
411 if (value is HRef) { 421 if (value is HRef) {
412 HRef ref = value; 422 HRef ref = value;
413 value = ref.value; 423 value = ref.value;
414 } 424 }
415 assert(!isStoredInClosureField(local)); 425 assert(!isStoredInClosureField(local));
416 if (isAccessedDirectly(local)) { 426 if (isAccessedDirectly(local)) {
417 directLocals[local] = value; 427 directLocals[local] = value;
418 } else if (isBoxed(local)) { 428 } else if (isBoxed(local)) {
419 BoxFieldElement redirect = redirectionMapping[local]; 429 FieldEntity redirect = redirectionMapping[local];
430 assert(redirect != null);
431 BoxLocal localBox;
432 if (redirect is BoxFieldElement) {
433 localBox = redirect.box;
434 } else if (redirect is JBoxedField) {
435 localBox = redirect.box;
436 }
437 assert(localBox != null);
438
420 // The box itself could be captured, or be local. A local variable that 439 // The box itself could be captured, or be local. A local variable that
421 // is captured will be boxed, but the box itself will be a local. 440 // is captured will be boxed, but the box itself will be a local.
422 // Inside the closure the box is stored in a closure-field and cannot 441 // Inside the closure the box is stored in a closure-field and cannot
423 // be accessed directly. 442 // be accessed directly.
424 HInstruction box = readLocal(redirect.box); 443 HInstruction box = readLocal(localBox);
425 builder.add(new HFieldSet(redirect, box, value) 444 builder.add(new HFieldSet(redirect, box, value)
426 ..sourceInformation = sourceInformation); 445 ..sourceInformation = sourceInformation);
427 } else { 446 } else {
428 assert(_isUsedInTryOrGenerator(local)); 447 assert(_isUsedInTryOrGenerator(local));
429 HLocalValue localValue = getLocal(local); 448 HLocalValue localValue = getLocal(local);
430 builder.add(new HLocalSet(local, localValue, value) 449 builder.add(new HLocalSet(local, localValue, value)
431 ..sourceInformation = sourceInformation); 450 ..sourceInformation = sourceInformation);
432 } 451 }
433 } 452 }
434 453
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
636 // simplicity, we mark the type as an interface type. 655 // simplicity, we mark the type as an interface type.
637 result = new TypeMask.nonNullSubtype(cls, closedWorld); 656 result = new TypeMask.nonNullSubtype(cls, closedWorld);
638 } else { 657 } else {
639 result = new TypeMask.nonNullSubclass(cls, closedWorld); 658 result = new TypeMask.nonNullSubclass(cls, closedWorld);
640 } 659 }
641 cachedTypeOfThis = result; 660 cachedTypeOfThis = result;
642 } 661 }
643 return result; 662 return result;
644 } 663 }
645 664
646 Map<Element, TypeMask> cachedTypesOfCapturedVariables = 665 Map<FieldEntity, TypeMask> cachedTypesOfCapturedVariables =
647 new Map<Element, TypeMask>(); 666 new Map<FieldEntity, TypeMask>();
648 667
649 TypeMask getTypeOfCapturedVariable(FieldElement element) { 668 TypeMask getTypeOfCapturedVariable(FieldEntity element) {
650 return cachedTypesOfCapturedVariables.putIfAbsent(element, () { 669 return cachedTypesOfCapturedVariables.putIfAbsent(element, () {
651 return TypeMaskFactory.inferredTypeForMember( 670 return TypeMaskFactory.inferredTypeForMember(
652 element, _globalInferenceResults); 671 element, _globalInferenceResults);
653 }); 672 });
654 } 673 }
655 674
656 /// Variables stored in the current activation. These variables are 675 /// Variables stored in the current activation. These variables are
657 /// being updated in try/catch blocks, and should be 676 /// being updated in try/catch blocks, and should be
658 /// accessed indirectly through [HLocalGet] and [HLocalSet]. 677 /// accessed indirectly through [HLocalGet] and [HLocalSet].
659 Map<Local, HLocalValue> activationVariables = <Local, HLocalValue>{}; 678 Map<Local, HLocalValue> activationVariables = <Local, HLocalValue>{};
(...skipping 13 matching lines...) Expand all
673 final MemberEntity memberContext; 692 final MemberEntity memberContext;
674 693
675 // Avoid slow Object.hashCode. 694 // Avoid slow Object.hashCode.
676 final int hashCode = _nextHashCode = (_nextHashCode + 1).toUnsigned(30); 695 final int hashCode = _nextHashCode = (_nextHashCode + 1).toUnsigned(30);
677 static int _nextHashCode = 0; 696 static int _nextHashCode = 0;
678 697
679 SyntheticLocal(this.name, this.executableContext, this.memberContext); 698 SyntheticLocal(this.name, this.executableContext, this.memberContext);
680 699
681 toString() => 'SyntheticLocal($name)'; 700 toString() => 'SyntheticLocal($name)';
682 } 701 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/ssa/kernel_ast_adapter.dart ('k') | tests/compiler/dart2js_extra/dart2js_extra.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698