Version 2.14.0-377.4.beta

* Cherry-pick d9bb68f93af6d960ddac8c25e58481aad08b2f22 to beta
* Cherry-pick b225582593e3a6603abc06de23da8aab35171ddd to beta
* Cherry-pick 3097b72b2b0383eea6a0500e7158e0c8db3673fc to beta
diff --git a/pkg/vm_service/test/cpu_samples_stream_test.dart b/pkg/vm_service/test/cpu_samples_stream_test.dart
index d6846ef..8ef6ff6 100644
--- a/pkg/vm_service/test/cpu_samples_stream_test.dart
+++ b/pkg/vm_service/test/cpu_samples_stream_test.dart
@@ -4,7 +4,8 @@
 
 import 'dart:async';
 
-import 'package:test/test.dart';
+// TODO(bkonyi): re-import after sample streaming is fixed.
+// import 'package:test/test.dart';
 import 'package:vm_service/vm_service.dart';
 
 import 'common/service_test_common.dart';
@@ -31,7 +32,9 @@
 
 var tests = <IsolateTest>[
   (VmService service, IsolateRef isolate) async {
-    final completer = Completer<void>();
+    // TODO(bkonyi): re-enable after sample streaming is fixed.
+    // See https://github.com/dart-lang/sdk/issues/46825
+    /*final completer = Completer<void>();
     int count = 0;
     int previousOrigin = 0;
     sub = service.onProfilerEvent.listen((event) async {
@@ -56,6 +59,7 @@
 
     await completer.future;
     await service.streamCancel(EventStreams.kProfiler);
+    */
   },
 ];
 
diff --git a/runtime/vm/datastream.h b/runtime/vm/datastream.h
index 7da4532..c0c642f 100644
--- a/runtime/vm/datastream.h
+++ b/runtime/vm/datastream.h
@@ -85,7 +85,7 @@
   };
 
   // Reads 'len' bytes from the stream.
-  void ReadBytes(uint8_t* addr, intptr_t len) {
+  void ReadBytes(void* addr, intptr_t len) {
     ASSERT((end_ - current_) >= len);
     if (len != 0) {
       memmove(addr, current_, len);
diff --git a/runtime/vm/message_snapshot.cc b/runtime/vm/message_snapshot.cc
index 37bb767..3eca655 100644
--- a/runtime/vm/message_snapshot.cc
+++ b/runtime/vm/message_snapshot.cc
@@ -145,7 +145,7 @@
   void WriteWordWith32BitWrites(uword value) {
     stream_.WriteWordWith32BitWrites(value);
   }
-  void WriteBytes(const uint8_t* addr, intptr_t len) {
+  void WriteBytes(const void* addr, intptr_t len) {
     stream_.WriteBytes(addr, len);
   }
   void WriteAscii(const String& str) {
@@ -344,7 +344,7 @@
   }
   intptr_t ReadUnsigned() { return stream_.ReadUnsigned(); }
   uword ReadWordWith32BitReads() { return stream_.ReadWordWith32BitReads(); }
-  void ReadBytes(uint8_t* addr, intptr_t len) { stream_.ReadBytes(addr, len); }
+  void ReadBytes(void* addr, intptr_t len) { stream_.ReadBytes(addr, len); }
   const char* ReadAscii() {
     intptr_t len = ReadUnsigned();
     const char* result = reinterpret_cast<const char*>(CurrentBufferAddress());
@@ -1572,8 +1572,7 @@
       d->AssignRef(data.ptr());
       const intptr_t length_in_bytes = length * element_size;
       NoSafepointScope no_safepoint;
-      uint8_t* cdata = reinterpret_cast<uint8_t*>(data.untag()->data());
-      d->ReadBytes(cdata, length_in_bytes);
+      d->ReadBytes(data.untag()->data(), length_in_bytes);
     }
   }
 
@@ -2066,6 +2065,60 @@
   }
 };
 
+class Simd128MessageSerializationCluster : public MessageSerializationCluster {
+ public:
+  explicit Simd128MessageSerializationCluster(intptr_t cid)
+      : MessageSerializationCluster("Simd128",
+                                    MessagePhase::kBeforeTypes,
+                                    cid) {}
+  ~Simd128MessageSerializationCluster() {}
+
+  void Trace(MessageSerializer* s, Object* object) { objects_.Add(object); }
+
+  void WriteNodes(MessageSerializer* s) {
+    intptr_t count = objects_.length();
+    s->WriteUnsigned(count);
+    for (intptr_t i = 0; i < count; i++) {
+      Object* vector = objects_[i];
+      s->AssignRef(vector);
+      ASSERT_EQUAL(Int32x4::value_offset(), Float32x4::value_offset());
+      ASSERT_EQUAL(Int32x4::value_offset(), Float64x2::value_offset());
+      s->WriteBytes(&(static_cast<Int32x4Ptr>(vector->ptr())->untag()->value_),
+                    sizeof(simd128_value_t));
+    }
+  }
+
+ private:
+  GrowableArray<Object*> objects_;
+};
+
+class Simd128MessageDeserializationCluster
+    : public MessageDeserializationCluster {
+ public:
+  explicit Simd128MessageDeserializationCluster(intptr_t cid)
+      : MessageDeserializationCluster("Simd128"), cid_(cid) {}
+  ~Simd128MessageDeserializationCluster() {}
+
+  void ReadNodes(MessageDeserializer* d) {
+    intptr_t count = d->ReadUnsigned();
+    for (intptr_t i = 0; i < count; i++) {
+      ASSERT_EQUAL(Int32x4::InstanceSize(), Float32x4::InstanceSize());
+      ASSERT_EQUAL(Int32x4::InstanceSize(), Float64x2::InstanceSize());
+      ObjectPtr vector =
+          Object::Allocate(cid_, Int32x4::InstanceSize(), Heap::kNew,
+                           Int32x4::ContainsCompressedPointers());
+      d->AssignRef(vector);
+      ASSERT_EQUAL(Int32x4::value_offset(), Float32x4::value_offset());
+      ASSERT_EQUAL(Int32x4::value_offset(), Float64x2::value_offset());
+      d->ReadBytes(&(static_cast<Int32x4Ptr>(vector)->untag()->value_),
+                   sizeof(simd128_value_t));
+    }
+  }
+
+ private:
+  const intptr_t cid_;
+};
+
 class RegExpMessageSerializationCluster : public MessageSerializationCluster {
  public:
   RegExpMessageSerializationCluster()
@@ -3233,6 +3286,10 @@
       return new (Z) OneByteStringMessageSerializationCluster(Z, is_canonical);
     case kTwoByteStringCid:
       return new (Z) TwoByteStringMessageSerializationCluster(Z, is_canonical);
+    case kInt32x4Cid:
+    case kFloat32x4Cid:
+    case kFloat64x2Cid:
+      return new (Z) Simd128MessageSerializationCluster(cid);
     default:
       break;
   }
@@ -3321,6 +3378,11 @@
       return new (Z) OneByteStringMessageDeserializationCluster(is_canonical);
     case kTwoByteStringCid:
       return new (Z) TwoByteStringMessageDeserializationCluster(is_canonical);
+    case kInt32x4Cid:
+    case kFloat32x4Cid:
+    case kFloat64x2Cid:
+      ASSERT(!is_canonical);
+      return new (Z) Simd128MessageDeserializationCluster(cid);
     default:
       break;
   }
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index a1b8649..30650c6 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -8949,9 +8949,11 @@
         }
       }
     }
-    // Compare flags (IsGenericCovariantImpl).
-    if (!Array::Equals(type_params.flags(), other_type_params.flags())) {
-      return false;
+    if (kind != TypeEquality::kInSubtypeTest) {
+      // Compare flags (IsGenericCovariantImpl).
+      if (!Array::Equals(type_params.flags(), other_type_params.flags())) {
+        return false;
+      }
     }
   }
   return true;
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index eb0d9e3..ce45815 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -859,6 +859,7 @@
   friend void UntaggedObject::Validate(IsolateGroup* isolate_group) const;
   friend class Closure;
   friend class InstanceDeserializationCluster;
+  friend class Simd128MessageDeserializationCluster;
   friend class OneByteString;
   friend class TwoByteString;
   friend class ExternalOneByteString;
diff --git a/runtime/vm/profiler.cc b/runtime/vm/profiler.cc
index 2436574..fae638f 100644
--- a/runtime/vm/profiler.cc
+++ b/runtime/vm/profiler.cc
@@ -306,6 +306,12 @@
   Sample* sample = nullptr;
   if (block != nullptr) {
     sample = block->ReserveSample();
+    if (sample != nullptr && block->is_full()) {
+      // TODO(bkonyi): remove once streaming is re-enabled.
+      // https://github.com/dart-lang/sdk/issues/46825
+      block->evictable_ = true;
+      FreeBlock(block);
+    }
   }
   if (sample != nullptr) {
     return sample;
@@ -330,8 +336,11 @@
     isolate->set_current_sample_block(next);
   }
   next->set_is_allocation_block(allocation_sample);
+
   can_process_block_.store(true);
-  isolate->mutator_thread()->ScheduleInterrupts(Thread::kVMInterrupt);
+  // TODO(bkonyi): re-enable after block streaming is fixed.
+  // See https://github.com/dart-lang/sdk/issues/46825
+  // isolate->mutator_thread()->ScheduleInterrupts(Thread::kVMInterrupt);
   return ReserveSampleImpl(isolate, allocation_sample);
 }
 
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index 3d442b2..885d79d 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -3024,6 +3024,8 @@
 
   ALIGN8 int32_t value_[4];
 
+  friend class Simd128MessageSerializationCluster;
+  friend class Simd128MessageDeserializationCluster;
 
  public:
   int32_t x() const { return value_[0]; }
diff --git a/tests/language/regress/regress46816_test.dart b/tests/language/regress/regress46816_test.dart
new file mode 100644
index 0000000..bccc6d2
--- /dev/null
+++ b/tests/language/regress/regress46816_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2021, 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';
+
+class A<X extends num> {
+  void f<Y extends X>(Y y) {}
+}
+
+typedef Func = void Function<Y extends int>(Y);
+
+main() {
+  A<num> a = new A<int>();
+  dynamic f = (a as A<int>).f;
+  Expect.isTrue(f is Func);
+  print(f as Func);
+}
diff --git a/tests/language_2/regress/regress46816_test.dart b/tests/language_2/regress/regress46816_test.dart
new file mode 100644
index 0000000..9d39bac
--- /dev/null
+++ b/tests/language_2/regress/regress46816_test.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2021, 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.
+
+// @dart=2.9
+
+import 'package:expect/expect.dart';
+
+class A<X extends num> {
+  void f<Y extends X>(Y y) {}
+}
+
+typedef Func = void Function<Y extends int>(Y);
+
+main() {
+  A<num> a = new A<int>();
+  dynamic f = (a as A<int>).f;
+  Expect.isTrue(f is Func);
+  print(f as Func);
+}
diff --git a/tests/lib/isolate/simd_vectors_message_test.dart b/tests/lib/isolate/simd_vectors_message_test.dart
new file mode 100644
index 0000000..324d4ef
--- /dev/null
+++ b/tests/lib/isolate/simd_vectors_message_test.dart
@@ -0,0 +1,48 @@
+// Copyright (c) 2021, 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.
+
+// See https://github.com/dart-lang/sdk/issues/46793
+
+import "dart:async";
+import "dart:isolate";
+import "dart:typed_data";
+
+import "package:async_helper/async_helper.dart";
+import "package:expect/expect.dart";
+
+main() {
+  asyncStart();
+  var port;
+  port = new RawReceivePort((message) {
+    print("Receive $message");
+
+    var int32x4 = message[0] as Int32x4;
+    Expect.equals(-1, int32x4.x);
+    Expect.equals(0, int32x4.y);
+    Expect.equals(1, int32x4.z);
+    Expect.equals(2, int32x4.w);
+
+    var float32x4 = message[1] as Float32x4;
+    Expect.equals(-2.5, float32x4.x);
+    Expect.equals(0.0, float32x4.y);
+    Expect.equals(1.25, float32x4.z);
+    Expect.equals(2.125, float32x4.w);
+
+    var float64x2 = message[2] as Float64x2;
+    Expect.equals(16.5, float64x2.x);
+    Expect.equals(-32.25, float64x2.y);
+
+    port.close();
+    asyncEnd();
+  });
+
+
+  var list = [
+    new Int32x4(-1, 0, 1, 2),
+    new Float32x4(-2.5, 0.0, 1.25, 2.125),
+    new Float64x2(16.5, -32.25),
+  ];
+  print("Send $list");
+  port.sendPort.send(list);
+}
diff --git a/tests/lib_2/isolate/simd_vectors_message_test.dart b/tests/lib_2/isolate/simd_vectors_message_test.dart
new file mode 100644
index 0000000..fedd5a0
--- /dev/null
+++ b/tests/lib_2/isolate/simd_vectors_message_test.dart
@@ -0,0 +1,50 @@
+// Copyright (c) 2021, 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.
+
+// See https://github.com/dart-lang/sdk/issues/46793
+
+// @dart = 2.9
+
+import "dart:async";
+import "dart:isolate";
+import "dart:typed_data";
+
+import "package:async_helper/async_helper.dart";
+import "package:expect/expect.dart";
+
+main() {
+  asyncStart();
+  var port;
+  port = new RawReceivePort((message) {
+    print("Receive $message");
+
+    var int32x4 = message[0] as Int32x4;
+    Expect.equals(-1, int32x4.x);
+    Expect.equals(0, int32x4.y);
+    Expect.equals(1, int32x4.z);
+    Expect.equals(2, int32x4.w);
+
+    var float32x4 = message[1] as Float32x4;
+    Expect.equals(-2.5, float32x4.x);
+    Expect.equals(0.0, float32x4.y);
+    Expect.equals(1.25, float32x4.z);
+    Expect.equals(2.125, float32x4.w);
+
+    var float64x2 = message[2] as Float64x2;
+    Expect.equals(16.5, float64x2.x);
+    Expect.equals(-32.25, float64x2.y);
+
+    port.close();
+    asyncEnd();
+  });
+
+
+  var list = [
+    new Int32x4(-1, 0, 1, 2),
+    new Float32x4(-2.5, 0.0, 1.25, 2.125),
+    new Float64x2(16.5, -32.25),
+  ];
+  print("Send $list");
+  port.sendPort.send(list);
+}
diff --git a/tools/VERSION b/tools/VERSION
index c8fc427..8741365 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -28,4 +28,4 @@
 MINOR 14
 PATCH 0
 PRERELEASE 377
-PRERELEASE_PATCH 1
\ No newline at end of file
+PRERELEASE_PATCH 4
\ No newline at end of file