Version 2.11.0-233.0.dev

Merge commit '13d2937f768180b083ce6ffdcf7d3cd9a4c5440a' into 'dev'
diff --git a/runtime/tests/vm/dart/flutter_regression67803_test.dart b/runtime/tests/vm/dart/flutter_regression67803_test.dart
new file mode 100644
index 0000000..71abd70
--- /dev/null
+++ b/runtime/tests/vm/dart/flutter_regression67803_test.dart
@@ -0,0 +1,372 @@
+// Copyright (c) 2020, 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.
+
+import 'package:expect/expect.dart';
+
+final bool kTrue = int.parse('1') == 1;
+
+main() {
+  // Ensure fields are not inferred to be constants and ensure we use all fields
+  // (to avoid them being tree shaken).
+  final useAllFields = (kTrue ? foo : foo2).toString();
+  for (int i = 0; i <= 64; ++i) {
+    Expect.isTrue(useAllFields.contains('$i'));
+  }
+
+  // Ensure calling dyn:get:field64 returns the right value.
+  Expect.equals(64, ((kTrue ? foo : Baz(10)) as dynamic).field64);
+
+  // Ensure calling get:field64 returns the right value.
+  Expect.equals(64, (kTrue ? foo : Bar(10)).field64);
+
+  // Ensure potentially inlined, direct field load yield right value.
+  Expect.equals(64, (kTrue ? foo : foo2).field64);
+}
+
+final foo = Foo(
+    0,
+    1,
+    2,
+    3,
+    4,
+    5,
+    6,
+    7,
+    8,
+    9,
+    10,
+    11,
+    12,
+    13,
+    14,
+    15,
+    16,
+    17,
+    18,
+    19,
+    20,
+    21,
+    22,
+    23,
+    24,
+    25,
+    26,
+    27,
+    28,
+    29,
+    30,
+    31,
+    32,
+    33,
+    34,
+    35,
+    36,
+    37,
+    38,
+    39,
+    40,
+    41,
+    42,
+    43,
+    44,
+    45,
+    46,
+    47,
+    48,
+    49,
+    50,
+    51,
+    52,
+    53,
+    54,
+    55,
+    56,
+    57,
+    58,
+    59,
+    60,
+    61,
+    62,
+    63,
+    64);
+
+final foo2 = Foo(
+    2 * 0,
+    2 * 1,
+    2 * 2,
+    2 * 3,
+    2 * 4,
+    2 * 5,
+    2 * 6,
+    2 * 7,
+    2 * 8,
+    2 * 9,
+    2 * 10,
+    2 * 11,
+    2 * 12,
+    2 * 13,
+    2 * 14,
+    2 * 15,
+    2 * 16,
+    2 * 17,
+    2 * 18,
+    2 * 19,
+    2 * 20,
+    2 * 21,
+    2 * 22,
+    2 * 23,
+    2 * 24,
+    2 * 25,
+    2 * 26,
+    2 * 27,
+    2 * 28,
+    2 * 29,
+    2 * 30,
+    2 * 31,
+    2 * 32,
+    2 * 33,
+    2 * 34,
+    2 * 35,
+    2 * 36,
+    2 * 37,
+    2 * 38,
+    2 * 39,
+    2 * 40,
+    2 * 41,
+    2 * 42,
+    2 * 43,
+    2 * 44,
+    2 * 45,
+    2 * 46,
+    2 * 47,
+    2 * 48,
+    2 * 49,
+    2 * 50,
+    2 * 51,
+    2 * 52,
+    2 * 53,
+    2 * 54,
+    2 * 55,
+    2 * 56,
+    2 * 57,
+    2 * 58,
+    2 * 59,
+    2 * 60,
+    2 * 61,
+    2 * 62,
+    2 * 63,
+    2 * 64);
+
+class Bar {
+  final int field64;
+  Bar(this.field64);
+}
+
+class Baz {
+  final int field64;
+  Baz(this.field64);
+}
+
+class Foo implements Bar {
+  final int field0;
+  final int field1;
+  final int field2;
+  final int field3;
+  final int field4;
+  final int field5;
+  final int field6;
+  final int field7;
+  final int field8;
+  final int field9;
+  final int field10;
+  final int field11;
+  final int field12;
+  final int field13;
+  final int field14;
+  final int field15;
+  final int field16;
+  final int field17;
+  final int field18;
+  final int field19;
+  final int field20;
+  final int field21;
+  final int field22;
+  final int field23;
+  final int field24;
+  final int field25;
+  final int field26;
+  final int field27;
+  final int field28;
+  final int field29;
+  final int field30;
+  final int field31;
+  final int field32;
+  final int field33;
+  final int field34;
+  final int field35;
+  final int field36;
+  final int field37;
+  final int field38;
+  final int field39;
+  final int field40;
+  final int field41;
+  final int field42;
+  final int field43;
+  final int field44;
+  final int field45;
+  final int field46;
+  final int field47;
+  final int field48;
+  final int field49;
+  final int field50;
+  final int field51;
+  final int field52;
+  final int field53;
+  final int field54;
+  final int field55;
+  final int field56;
+  final int field57;
+  final int field58;
+  final int field59;
+  final int field60;
+  final int field61;
+  final int field62;
+  final int field63;
+  final int field64;
+
+  Foo(
+      this.field0,
+      this.field1,
+      this.field2,
+      this.field3,
+      this.field4,
+      this.field5,
+      this.field6,
+      this.field7,
+      this.field8,
+      this.field9,
+      this.field10,
+      this.field11,
+      this.field12,
+      this.field13,
+      this.field14,
+      this.field15,
+      this.field16,
+      this.field17,
+      this.field18,
+      this.field19,
+      this.field20,
+      this.field21,
+      this.field22,
+      this.field23,
+      this.field24,
+      this.field25,
+      this.field26,
+      this.field27,
+      this.field28,
+      this.field29,
+      this.field30,
+      this.field31,
+      this.field32,
+      this.field33,
+      this.field34,
+      this.field35,
+      this.field36,
+      this.field37,
+      this.field38,
+      this.field39,
+      this.field40,
+      this.field41,
+      this.field42,
+      this.field43,
+      this.field44,
+      this.field45,
+      this.field46,
+      this.field47,
+      this.field48,
+      this.field49,
+      this.field50,
+      this.field51,
+      this.field52,
+      this.field53,
+      this.field54,
+      this.field55,
+      this.field56,
+      this.field57,
+      this.field58,
+      this.field59,
+      this.field60,
+      this.field61,
+      this.field62,
+      this.field63,
+      this.field64);
+
+  toString() => '''
+     $field0;
+     $field1;
+     $field2;
+     $field3;
+     $field4;
+     $field5;
+     $field6;
+     $field7;
+     $field8;
+     $field9;
+    $field10;
+    $field11;
+    $field12;
+    $field13;
+    $field14;
+    $field15;
+    $field16;
+    $field17;
+    $field18;
+    $field19;
+    $field20;
+    $field21;
+    $field22;
+    $field23;
+    $field24;
+    $field25;
+    $field26;
+    $field27;
+    $field28;
+    $field29;
+    $field30;
+    $field31;
+    $field32;
+    $field33;
+    $field34;
+    $field35;
+    $field36;
+    $field37;
+    $field38;
+    $field39;
+    $field40;
+    $field41;
+    $field42;
+    $field43;
+    $field44;
+    $field45;
+    $field46;
+    $field47;
+    $field48;
+    $field49;
+    $field50;
+    $field51;
+    $field52;
+    $field53;
+    $field54;
+    $field55;
+    $field56;
+    $field57;
+    $field58;
+    $field59;
+    $field60;
+    $field61;
+    $field62;
+    $field63;
+    $field64;
+    ''';
+}
diff --git a/runtime/tests/vm/dart_2/flutter_regression67803_test.dart b/runtime/tests/vm/dart_2/flutter_regression67803_test.dart
new file mode 100644
index 0000000..71abd70
--- /dev/null
+++ b/runtime/tests/vm/dart_2/flutter_regression67803_test.dart
@@ -0,0 +1,372 @@
+// Copyright (c) 2020, 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.
+
+import 'package:expect/expect.dart';
+
+final bool kTrue = int.parse('1') == 1;
+
+main() {
+  // Ensure fields are not inferred to be constants and ensure we use all fields
+  // (to avoid them being tree shaken).
+  final useAllFields = (kTrue ? foo : foo2).toString();
+  for (int i = 0; i <= 64; ++i) {
+    Expect.isTrue(useAllFields.contains('$i'));
+  }
+
+  // Ensure calling dyn:get:field64 returns the right value.
+  Expect.equals(64, ((kTrue ? foo : Baz(10)) as dynamic).field64);
+
+  // Ensure calling get:field64 returns the right value.
+  Expect.equals(64, (kTrue ? foo : Bar(10)).field64);
+
+  // Ensure potentially inlined, direct field load yield right value.
+  Expect.equals(64, (kTrue ? foo : foo2).field64);
+}
+
+final foo = Foo(
+    0,
+    1,
+    2,
+    3,
+    4,
+    5,
+    6,
+    7,
+    8,
+    9,
+    10,
+    11,
+    12,
+    13,
+    14,
+    15,
+    16,
+    17,
+    18,
+    19,
+    20,
+    21,
+    22,
+    23,
+    24,
+    25,
+    26,
+    27,
+    28,
+    29,
+    30,
+    31,
+    32,
+    33,
+    34,
+    35,
+    36,
+    37,
+    38,
+    39,
+    40,
+    41,
+    42,
+    43,
+    44,
+    45,
+    46,
+    47,
+    48,
+    49,
+    50,
+    51,
+    52,
+    53,
+    54,
+    55,
+    56,
+    57,
+    58,
+    59,
+    60,
+    61,
+    62,
+    63,
+    64);
+
+final foo2 = Foo(
+    2 * 0,
+    2 * 1,
+    2 * 2,
+    2 * 3,
+    2 * 4,
+    2 * 5,
+    2 * 6,
+    2 * 7,
+    2 * 8,
+    2 * 9,
+    2 * 10,
+    2 * 11,
+    2 * 12,
+    2 * 13,
+    2 * 14,
+    2 * 15,
+    2 * 16,
+    2 * 17,
+    2 * 18,
+    2 * 19,
+    2 * 20,
+    2 * 21,
+    2 * 22,
+    2 * 23,
+    2 * 24,
+    2 * 25,
+    2 * 26,
+    2 * 27,
+    2 * 28,
+    2 * 29,
+    2 * 30,
+    2 * 31,
+    2 * 32,
+    2 * 33,
+    2 * 34,
+    2 * 35,
+    2 * 36,
+    2 * 37,
+    2 * 38,
+    2 * 39,
+    2 * 40,
+    2 * 41,
+    2 * 42,
+    2 * 43,
+    2 * 44,
+    2 * 45,
+    2 * 46,
+    2 * 47,
+    2 * 48,
+    2 * 49,
+    2 * 50,
+    2 * 51,
+    2 * 52,
+    2 * 53,
+    2 * 54,
+    2 * 55,
+    2 * 56,
+    2 * 57,
+    2 * 58,
+    2 * 59,
+    2 * 60,
+    2 * 61,
+    2 * 62,
+    2 * 63,
+    2 * 64);
+
+class Bar {
+  final int field64;
+  Bar(this.field64);
+}
+
+class Baz {
+  final int field64;
+  Baz(this.field64);
+}
+
+class Foo implements Bar {
+  final int field0;
+  final int field1;
+  final int field2;
+  final int field3;
+  final int field4;
+  final int field5;
+  final int field6;
+  final int field7;
+  final int field8;
+  final int field9;
+  final int field10;
+  final int field11;
+  final int field12;
+  final int field13;
+  final int field14;
+  final int field15;
+  final int field16;
+  final int field17;
+  final int field18;
+  final int field19;
+  final int field20;
+  final int field21;
+  final int field22;
+  final int field23;
+  final int field24;
+  final int field25;
+  final int field26;
+  final int field27;
+  final int field28;
+  final int field29;
+  final int field30;
+  final int field31;
+  final int field32;
+  final int field33;
+  final int field34;
+  final int field35;
+  final int field36;
+  final int field37;
+  final int field38;
+  final int field39;
+  final int field40;
+  final int field41;
+  final int field42;
+  final int field43;
+  final int field44;
+  final int field45;
+  final int field46;
+  final int field47;
+  final int field48;
+  final int field49;
+  final int field50;
+  final int field51;
+  final int field52;
+  final int field53;
+  final int field54;
+  final int field55;
+  final int field56;
+  final int field57;
+  final int field58;
+  final int field59;
+  final int field60;
+  final int field61;
+  final int field62;
+  final int field63;
+  final int field64;
+
+  Foo(
+      this.field0,
+      this.field1,
+      this.field2,
+      this.field3,
+      this.field4,
+      this.field5,
+      this.field6,
+      this.field7,
+      this.field8,
+      this.field9,
+      this.field10,
+      this.field11,
+      this.field12,
+      this.field13,
+      this.field14,
+      this.field15,
+      this.field16,
+      this.field17,
+      this.field18,
+      this.field19,
+      this.field20,
+      this.field21,
+      this.field22,
+      this.field23,
+      this.field24,
+      this.field25,
+      this.field26,
+      this.field27,
+      this.field28,
+      this.field29,
+      this.field30,
+      this.field31,
+      this.field32,
+      this.field33,
+      this.field34,
+      this.field35,
+      this.field36,
+      this.field37,
+      this.field38,
+      this.field39,
+      this.field40,
+      this.field41,
+      this.field42,
+      this.field43,
+      this.field44,
+      this.field45,
+      this.field46,
+      this.field47,
+      this.field48,
+      this.field49,
+      this.field50,
+      this.field51,
+      this.field52,
+      this.field53,
+      this.field54,
+      this.field55,
+      this.field56,
+      this.field57,
+      this.field58,
+      this.field59,
+      this.field60,
+      this.field61,
+      this.field62,
+      this.field63,
+      this.field64);
+
+  toString() => '''
+     $field0;
+     $field1;
+     $field2;
+     $field3;
+     $field4;
+     $field5;
+     $field6;
+     $field7;
+     $field8;
+     $field9;
+    $field10;
+    $field11;
+    $field12;
+    $field13;
+    $field14;
+    $field15;
+    $field16;
+    $field17;
+    $field18;
+    $field19;
+    $field20;
+    $field21;
+    $field22;
+    $field23;
+    $field24;
+    $field25;
+    $field26;
+    $field27;
+    $field28;
+    $field29;
+    $field30;
+    $field31;
+    $field32;
+    $field33;
+    $field34;
+    $field35;
+    $field36;
+    $field37;
+    $field38;
+    $field39;
+    $field40;
+    $field41;
+    $field42;
+    $field43;
+    $field44;
+    $field45;
+    $field46;
+    $field47;
+    $field48;
+    $field49;
+    $field50;
+    $field51;
+    $field52;
+    $field53;
+    $field54;
+    $field55;
+    $field56;
+    $field57;
+    $field58;
+    $field59;
+    $field60;
+    $field61;
+    $field62;
+    $field63;
+    $field64;
+    ''';
+}
diff --git a/runtime/vm/compiler/backend/flow_graph.cc b/runtime/vm/compiler/backend/flow_graph.cc
index 82430b4..dc5b713 100644
--- a/runtime/vm/compiler/backend/flow_graph.cc
+++ b/runtime/vm/compiler/backend/flow_graph.cc
@@ -128,6 +128,20 @@
   }
 }
 
+Representation FlowGraph::UnboxedFieldRepresentationOf(const Field& field) {
+  switch (field.UnboxedFieldCid()) {
+    case kDoubleCid:
+      return kUnboxedDouble;
+    case kFloat32x4Cid:
+      return kUnboxedFloat32x4;
+    case kFloat64x2Cid:
+      return kUnboxedFloat64x2;
+    default:
+      RELEASE_ASSERT(field.is_non_nullable_integer());
+      return kUnboxedInt64;
+  }
+}
+
 void FlowGraph::ReplaceCurrentInstruction(ForwardInstructionIterator* iterator,
                                           Instruction* current,
                                           Instruction* replacement) {
diff --git a/runtime/vm/compiler/backend/flow_graph.h b/runtime/vm/compiler/backend/flow_graph.h
index bac38c8..50ea5ec 100644
--- a/runtime/vm/compiler/backend/flow_graph.h
+++ b/runtime/vm/compiler/backend/flow_graph.h
@@ -147,6 +147,8 @@
 
   static Representation ReturnRepresentationOf(const Function& function);
 
+  static Representation UnboxedFieldRepresentationOf(const Field& field);
+
   // The number of variables (or boxes) inside the functions frame - meaning
   // below the frame pointer.  This does not include the expression stack.
   intptr_t num_stack_locals() const {
diff --git a/runtime/vm/compiler/backend/il.cc b/runtime/vm/compiler/backend/il.cc
index 11262f0..93da803 100644
--- a/runtime/vm/compiler/backend/il.cc
+++ b/runtime/vm/compiler/backend/il.cc
@@ -1034,21 +1034,7 @@
   ASSERT((index == 0) || (index == 1));
   if ((index == 1) && IsUnboxedStore()) {
     const Field& field = slot().field();
-    const intptr_t cid = field.UnboxedFieldCid();
-    switch (cid) {
-      case kDoubleCid:
-        return kUnboxedDouble;
-      case kFloat32x4Cid:
-        return kUnboxedFloat32x4;
-      case kFloat64x2Cid:
-        return kUnboxedFloat64x2;
-      default:
-        if (field.is_non_nullable_integer()) {
-          return kUnboxedInt64;
-        } else {
-          UNREACHABLE();
-        }
-    }
+    return FlowGraph::UnboxedFieldRepresentationOf(field);
   }
   return kTagged;
 }
diff --git a/runtime/vm/compiler/graph_intrinsifier.cc b/runtime/vm/compiler/graph_intrinsifier.cc
index 45595ce..418b930 100644
--- a/runtime/vm/compiler/graph_intrinsifier.cc
+++ b/runtime/vm/compiler/graph_intrinsifier.cc
@@ -1117,8 +1117,23 @@
   BlockBuilder builder(flow_graph, normal_entry);
 
   auto receiver = builder.AddParameter(0, /*with_frame=*/false);
-  auto field_value = builder.AddDefinition(new (zone) LoadFieldInstr(
+  Definition* field_value = builder.AddDefinition(new (zone) LoadFieldInstr(
       new (zone) Value(receiver), slot, builder.TokenPos()));
+
+  // We only support cases where we do not have to create a box (whose
+  // allocation could fail).
+  ASSERT(function.HasUnboxedReturnValue() ||
+         !FlowGraphCompiler::IsUnboxedField(field));
+
+  // We might need to unbox the field value before returning.
+  if (function.HasUnboxedReturnValue() &&
+      !FlowGraphCompiler::IsUnboxedField(field)) {
+    ASSERT(FLAG_precompiled_mode);
+    field_value = builder.AddUnboxInstr(
+        FlowGraph::ReturnRepresentationOf(flow_graph->function()),
+        new Value(field_value), /*is_checked=*/true);
+  }
+
   builder.AddReturn(new (zone) Value(field_value));
   return true;
 }
@@ -1157,25 +1172,9 @@
     // We do not support storing to possibly guarded fields in JIT in graph
     // intrinsics.
     ASSERT(FLAG_precompiled_mode);
-
-    Representation representation = kNoRepresentation;
-    switch (field.guarded_cid()) {
-      case kDoubleCid:
-        representation = kUnboxedDouble;
-        break;
-      case kFloat32x4Cid:
-        representation = kUnboxedFloat32x4;
-        break;
-      case kFloat64x2Cid:
-        representation = kUnboxedFloat64x2;
-        break;
-      default:
-        ASSERT(field.is_non_nullable_integer());
-        representation = kUnboxedInt64;
-        break;
-    }
-    value = builder.AddUnboxInstr(representation, new Value(value),
-                                  /*is_checked=*/true);
+    value = builder.AddUnboxInstr(
+        FlowGraph::UnboxedFieldRepresentationOf(field), new Value(value),
+        /*is_checked=*/true);
   }
 
   builder.AddInstruction(new (zone) StoreInstanceFieldInstr(
diff --git a/runtime/vm/compiler/intrinsifier.cc b/runtime/vm/compiler/intrinsifier.cc
index a1f21f1..35ade83 100644
--- a/runtime/vm/compiler/intrinsifier.cc
+++ b/runtime/vm/compiler/intrinsifier.cc
@@ -113,9 +113,9 @@
         return false;
       }
     } else {
-      // If the field is boxed, then the getter cannot return an unboxed value
-      // either (if it could, we would know the field itself can be unboxed).
-      RELEASE_ASSERT(!function.HasUnboxedReturnValue());
+      // If the field is boxed, then we can either return the box directly or
+      // unbox it and return unboxed representation.
+      return true;
     }
   } else {
     ASSERT(is_setter);
diff --git a/tools/VERSION b/tools/VERSION
index 13bec29..bb98264 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 11
 PATCH 0
-PRERELEASE 232
+PRERELEASE 233
 PRERELEASE_PATCH 0
\ No newline at end of file