[vm, compiler] Fix incorrect derivation of a concrete cid from FutureOr.
Bug: https://github.com/dart-lang/sdk/issues/34128
Change-Id: I694b3b7556ee999de3c67c1cd4a8a98654365c24
Reviewed-on: https://dart-review.googlesource.com/69480
Commit-Queue: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Aart Bik <ajcbik@google.com>
Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
diff --git a/runtime/vm/compiler/assembler/assembler_arm.cc b/runtime/vm/compiler/assembler/assembler_arm.cc
index 5d079b7..3e7de20 100644
--- a/runtime/vm/compiler/assembler/assembler_arm.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm.cc
@@ -1548,6 +1548,12 @@
// And the result with the negated space bit of the object.
bic(IP, IP, Operand(object));
} else {
+#if defined(DEBUG)
+ Label okay;
+ BranchIfNotSmi(value, &okay);
+ Stop("Unexpected Smi!");
+ Bind(&okay);
+#endif
bic(IP, value, Operand(object));
}
tst(IP, Operand(kNewObjectAlignmentOffset));
diff --git a/runtime/vm/compiler/assembler/assembler_arm64.cc b/runtime/vm/compiler/assembler/assembler_arm64.cc
index 2199fd6..3a4b8de 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm64.cc
@@ -915,6 +915,12 @@
// Write-barrier triggers if the value is in the new space (has bit set) and
// the object is in the old space (has bit cleared).
if (value_can_be_smi == kValueIsNotSmi) {
+#if defined(DEBUG)
+ Label okay;
+ BranchIfNotSmi(value, &okay);
+ Stop("Unexpected Smi!");
+ Bind(&okay);
+#endif
// To check that, we compute value & ~object and skip the write barrier
// if the bit is not set. We can't destroy the object.
bic(TMP, value, Operand(object));
@@ -954,7 +960,7 @@
ASSERT(object != value);
str(value, dest);
Label done;
- StoreIntoObjectFilter(object, value, &done, kValueCanBeSmi, kJumpToNoUpdate);
+ StoreIntoObjectFilter(object, value, &done, can_be_smi, kJumpToNoUpdate);
if (!lr_reserved) Push(LR);
ldr(LR, Address(THR, Thread::update_store_buffer_wrappers_offset(object)));
blr(LR);
diff --git a/runtime/vm/compiler/assembler/assembler_ia32.cc b/runtime/vm/compiler/assembler/assembler_ia32.cc
index b566572..88d0063 100644
--- a/runtime/vm/compiler/assembler/assembler_ia32.cc
+++ b/runtime/vm/compiler/assembler/assembler_ia32.cc
@@ -1840,6 +1840,12 @@
CanBeSmi can_be_smi,
BarrierFilterMode how_to_jump) {
if (can_be_smi == kValueIsNotSmi) {
+#if defined(DEBUG)
+ Label okay;
+ BranchIfNotSmi(value, &okay);
+ Stop("Unexpected Smi!");
+ Bind(&okay);
+#endif
COMPILE_ASSERT((kNewObjectAlignmentOffset == kWordSize) &&
(kOldObjectAlignmentOffset == 0));
// Write-barrier triggers if the value is in the new space (has bit set) and
diff --git a/runtime/vm/compiler/assembler/assembler_x64.cc b/runtime/vm/compiler/assembler/assembler_x64.cc
index 353b8ed..5b61175 100644
--- a/runtime/vm/compiler/assembler/assembler_x64.cc
+++ b/runtime/vm/compiler/assembler/assembler_x64.cc
@@ -1224,6 +1224,12 @@
(kOldObjectAlignmentOffset == 0));
if (can_be_smi == kValueIsNotSmi) {
+#if defined(DEBUG)
+ Label okay;
+ BranchIfNotSmi(value, &okay);
+ Stop("Unexpected Smi!");
+ Bind(&okay);
+#endif
// Write-barrier triggers if the value is in the new space (has bit set) and
// the object is in the old space (has bit cleared).
// To check that we could compute value & ~object and skip the write barrier
diff --git a/runtime/vm/compiler/backend/type_propagator.cc b/runtime/vm/compiler/backend/type_propagator.cc
index 7b6458c..d0d8793 100644
--- a/runtime/vm/compiler/backend/type_propagator.cc
+++ b/runtime/vm/compiler/backend/type_propagator.cc
@@ -662,6 +662,10 @@
cid_ = kClosureCid;
} else if (type_->HasResolvedTypeClass()) {
const Class& type_class = Class::Handle(type_->type_class());
+ if (type_class.IsFutureOrClass()) {
+ // FutureOr<T> may be Future<T> or T.
+ return cid_ = kDynamicCid;
+ }
Thread* thread = Thread::Current();
CHA* cha = thread->cha();
// Don't infer a cid from an abstract type since there can be multiple