| // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| // Test various setter situations, testing special cases in optimizing compiler. |
| // VMOptions=--optimization-counter-threshold=10 --no-use-osr |
| |
| // @dart = 2.9 |
| |
| import "package:expect/expect.dart"; |
| |
| class A { |
| int field = 0; |
| } |
| |
| class B extends A {} |
| |
| void sameImplicitSetter() { |
| oneTarget(var a, var v) { |
| a.field = v; |
| } |
| |
| A a = new A(); |
| B b = new B(); |
| // Optimize 'oneTarget' for one class, one target. |
| for (int i = 0; i < 20; i++) { |
| oneTarget(a, 5); |
| Expect.equals(5, a.field); |
| } |
| // Deoptimize 'oneTarget', since class B is not expected. |
| oneTarget(b, 6); |
| Expect.equals(6, b.field); |
| // Optimize 'oneTarget' for A and B classes, one target. |
| for (int i = 0; i < 20; i++) { |
| oneTarget(a, 7); |
| Expect.equals(7, a.field); |
| } |
| oneTarget(b, 8); |
| Expect.equals(8, b.field); |
| } |
| |
| // Deoptimize when no feedback exists. |
| void setterNoFeedback() { |
| maybeSet(var a, var v, bool set_it) { |
| if (set_it) { |
| return a.field = v; |
| } |
| return -1; |
| } |
| |
| A a = new A(); |
| for (int i = 0; i < 20; i++) { |
| var r = maybeSet(a, 5, false); |
| Expect.equals(0, a.field); |
| Expect.equals(-1, r); |
| } |
| var r = maybeSet(a, 5, true); |
| Expect.equals(5, a.field); |
| Expect.equals(5, r); |
| for (int i = 0; i < 20; i++) { |
| var r = maybeSet(a, 6, true); |
| Expect.equals(6, a.field); |
| Expect.equals(6, r); |
| } |
| } |
| |
| // Check non-implicit setter |
| class X { |
| int pField = 0; |
| set field(v) { |
| pField = v; |
| } |
| |
| get field => 10; |
| } |
| |
| void sameNotImplicitSetter() { |
| oneTarget(var a, var v) { |
| return a.field = v; |
| } |
| |
| incField(var a) { |
| a.field++; |
| } |
| |
| X x = new X(); |
| for (int i = 0; i < 20; i++) { |
| var r = oneTarget(x, 3); |
| Expect.equals(3, x.pField); |
| Expect.equals(3, r); |
| } |
| oneTarget(x, 0); |
| for (int i = 0; i < 20; i++) { |
| incField(x); |
| } |
| Expect.equals(11, x.pField); |
| } |
| |
| class Y { |
| int field = 0; |
| } |
| |
| multiImplicitSetter() { |
| oneTarget(var a, var v) { |
| return a.field = v; |
| } |
| |
| // Both classes 'Y' and 'A' have a distinct field getter. |
| A a = new A(); |
| Y y = new Y(); |
| for (int i = 0; i < 20; i++) { |
| var r = oneTarget(a, 5); |
| Expect.equals(5, a.field); |
| Expect.equals(5, r); |
| r = oneTarget(y, 6); |
| Expect.equals(6, y.field); |
| Expect.equals(6, r); |
| } |
| } |
| |
| class Z { |
| int pField = 0; |
| set field(v) { |
| pField = v; |
| } |
| |
| get field => 10; |
| } |
| |
| multiNotImplicitSetter() { |
| oneTarget(var a, var v) { |
| return a.field = v; |
| } |
| |
| Y y = new Y(); |
| Z z = new Z(); |
| for (int i = 0; i < 20; i++) { |
| var r = oneTarget(y, 8); |
| Expect.equals(8, y.field); |
| Expect.equals(8, r); |
| r = oneTarget(z, 12); |
| Expect.equals(12, z.pField); |
| Expect.equals(12, r); |
| } |
| A a = new A(); |
| var r = oneTarget(a, 11); |
| Expect.equals(11, a.field); |
| Expect.equals(11, r); |
| } |
| |
| void main() { |
| sameImplicitSetter(); |
| setterNoFeedback(); |
| sameNotImplicitSetter(); |
| |
| multiImplicitSetter(); |
| multiNotImplicitSetter(); |
| } |