Skip to content

Commit 62396ca

Browse files
rmacnak-googlecommit-bot@chromium.org
authored andcommitted
[vm] Handle sentinel in the IL serializer and Array-backed hash maps.
Fixes crashes in vm/dart when use_nnbd = true. Change-Id: Ieeb45227208cc6219f536130df38249d902dfe7f Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/137462 Reviewed-by: Siva Annamalai <[email protected]> Commit-Queue: Ryan Macnak <[email protected]>
1 parent 3d6c8cc commit 62396ca

File tree

4 files changed

+17
-5
lines changed

4 files changed

+17
-5
lines changed

runtime/vm/compiler/backend/il_deserializer.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1432,6 +1432,10 @@ bool FlowGraphDeserializer::ParseDartValue(SExpression* sexp, Object* out) {
14321432
// We'll use the null value in *out as a marker later, so go ahead and exit
14331433
// early if we parse one.
14341434
if (sym->Equals("null")) return true;
1435+
if (sym->Equals("sentinel")) {
1436+
*out = Object::sentinel().raw();
1437+
return true;
1438+
}
14351439

14361440
// The only other symbols that should appear in Dart value position are
14371441
// names of constant definitions.
@@ -1662,6 +1666,8 @@ bool FlowGraphDeserializer::ParseInstance(SExpList* list, Object* out) {
16621666
return false;
16631667
}
16641668

1669+
ASSERT(cid_sexp->value() != kNullCid); // Must use canonical instances.
1670+
ASSERT(cid_sexp->value() != kBoolCid); // Must use canonical instances.
16651671
instance_class_ = table->At(cid_sexp->value());
16661672
*out = Instance::New(instance_class_, Heap::kOld);
16671673
auto& instance = Instance::Cast(*out);

runtime/vm/compiler/backend/il_serializer.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -670,6 +670,9 @@ SExpression* FlowGraphSerializer::ObjectToSExp(const Object& dartval) {
670670
if (dartval.IsNull()) {
671671
return new (zone()) SExpSymbol("null");
672672
}
673+
if (dartval.raw() == Object::sentinel().raw()) {
674+
return new (zone()) SExpSymbol("sentinel");
675+
}
673676
if (dartval.IsString()) {
674677
return new (zone()) SExpString(dartval.ToCString());
675678
}

runtime/vm/hash_table.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ namespace dart {
6262
// Each entry contains a key, followed by zero or more payload components,
6363
// and has 3 possible states: unused, occupied, or deleted.
6464
// The header tracks the number of entries in each state.
65-
// Any object except Object::sentinel() and Object::transition_sentinel()
65+
// Any object except the backing storage array and Object::transition_sentinel()
6666
// may be stored as a key. Any object may be stored in a payload.
6767
//
6868
// Parameters
@@ -138,7 +138,7 @@ class HashTable : public ValueObject {
138138
#endif // !defined(PRODUCT)
139139

140140
for (intptr_t i = kHeaderSize; i < data_->Length(); ++i) {
141-
data_->SetAt(i, Object::sentinel());
141+
data_->SetAt(i, *data_);
142142
}
143143
}
144144

@@ -225,6 +225,9 @@ class HashTable : public ValueObject {
225225
// Sets the key of a previously unoccupied entry. This must not be the last
226226
// unoccupied entry.
227227
void InsertKey(intptr_t entry, const Object& key) const {
228+
ASSERT(key.raw() != data_->raw());
229+
ASSERT(key.raw() != Object::transition_sentinel().raw());
230+
228231
ASSERT(!IsOccupied(entry));
229232
AdjustSmiValueAt(kOccupiedEntriesIndex, 1);
230233
if (IsDeleted(entry)) {
@@ -238,7 +241,7 @@ class HashTable : public ValueObject {
238241
}
239242

240243
bool IsUnused(intptr_t entry) const {
241-
return InternalGetKey(entry) == Object::sentinel().raw();
244+
return InternalGetKey(entry) == data_->raw();
242245
}
243246
bool IsOccupied(intptr_t entry) const {
244247
return !IsUnused(entry) && !IsDeleted(entry);

runtime/vm/object.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17245,8 +17245,8 @@ bool Instance::CanonicalizeEquals(const Instance& other) const {
1724517245
}
1724617246

1724717247
uint32_t Instance::CanonicalizeHash() const {
17248-
if (IsNull()) {
17249-
return 2011;
17248+
if (GetClassId() == kNullCid) {
17249+
return 2011; // Matches null_patch.dart.
1725017250
}
1725117251
Thread* thread = Thread::Current();
1725217252
uint32_t hash = thread->heap()->GetCanonicalHash(raw());

0 commit comments

Comments
 (0)