Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 75c1d50

Browse files
aamcommit-bot@chromium.org
authored andcommitted
[vm/slots] Use atomics for native slots.
This is to ensure that there are no data races when intitializing and accessing native slots. Fixes dart-lang/sdk#44368 TEST=build dart on mac with tsan Change-Id: I311ae050a84b2d832799f5116d56b835e3d48f38 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/174841 Reviewed-by: Ryan Macnak <rmacnak@google.com> Commit-Queue: Alexander Aprelev <aam@google.com>
1 parent 3e7b5b2 commit 75c1d50

File tree

2 files changed

+26
-10
lines changed

2 files changed

+26
-10
lines changed

runtime/vm/compiler/backend/slot.cc

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -110,10 +110,18 @@ static classid_t GetUnboxedNativeSlotCid(Representation rep) {
110110
return kIllegalCid;
111111
}
112112

113+
AcqRelAtomic<Slot*> Slot::native_fields_(nullptr);
114+
115+
enum NativeSlotsEnumeration {
116+
#define DECLARE_KIND(CN, __, FN, ___, ____) k##CN##_##FN,
117+
NATIVE_SLOTS_LIST(DECLARE_KIND)
118+
#undef DECLARE_KIND
119+
kNativeSlotsCount
120+
};
121+
113122
const Slot& Slot::GetNativeSlot(Kind kind) {
114-
// There is a fixed statically known number of native slots so we cache
115-
// them statically.
116-
static const Slot fields[] = {
123+
if (native_fields_.load() == nullptr) {
124+
Slot* new_value = new Slot[kNativeSlotsCount]{
117125
#define NULLABLE_FIELD_FINAL \
118126
(IsNullableBit::encode(true) | IsImmutableBit::encode(true))
119127
#define NULLABLE_FIELD_VAR (IsNullableBit::encode(true))
@@ -123,7 +131,7 @@ const Slot& Slot::GetNativeSlot(Kind kind) {
123131
k##cid##Cid, compiler::target::ClassName::FieldName##_offset(), \
124132
#ClassName "." #FieldName, nullptr, kTagged),
125133

126-
NULLABLE_BOXED_NATIVE_SLOTS_LIST(DEFINE_NULLABLE_BOXED_NATIVE_FIELD)
134+
NULLABLE_BOXED_NATIVE_SLOTS_LIST(DEFINE_NULLABLE_BOXED_NATIVE_FIELD)
127135

128136
#undef DEFINE_NULLABLE_BOXED_NATIVE_FIELD
129137
#undef NULLABLE_FIELD_FINAL
@@ -137,8 +145,8 @@ const Slot& Slot::GetNativeSlot(Kind kind) {
137145
k##cid##Cid, compiler::target::ClassName::FieldName##_offset(), \
138146
#ClassName "." #FieldName, nullptr, kTagged),
139147

140-
NONNULLABLE_BOXED_NATIVE_SLOTS_LIST(
141-
DEFINE_NONNULLABLE_BOXED_NATIVE_FIELD)
148+
NONNULLABLE_BOXED_NATIVE_SLOTS_LIST(
149+
DEFINE_NONNULLABLE_BOXED_NATIVE_FIELD)
142150

143151
#undef DEFINE_NONNULLABLE_BOXED_NATIVE_FIELD
144152
#define DEFINE_UNBOXED_NATIVE_FIELD(ClassName, UnderlyingType, FieldName, \
@@ -148,15 +156,20 @@ const Slot& Slot::GetNativeSlot(Kind kind) {
148156
compiler::target::ClassName::FieldName##_offset(), \
149157
#ClassName "." #FieldName, nullptr, kUnboxed##representation),
150158

151-
UNBOXED_NATIVE_SLOTS_LIST(DEFINE_UNBOXED_NATIVE_FIELD)
159+
UNBOXED_NATIVE_SLOTS_LIST(DEFINE_UNBOXED_NATIVE_FIELD)
152160

153161
#undef DEFINE_UNBOXED_NATIVE_FIELD
154162
#undef NONNULLABLE_FIELD_VAR
155163
#undef NONNULLABLE_FIELD_FINAL
156-
};
164+
};
165+
Slot* old_value = nullptr;
166+
if (!native_fields_.compare_exchange_strong(old_value, new_value)) {
167+
delete[] new_value;
168+
}
169+
}
157170

158-
ASSERT(static_cast<uint8_t>(kind) < ARRAY_SIZE(fields));
159-
return fields[static_cast<uint8_t>(kind)];
171+
ASSERT(static_cast<uint8_t>(kind) < kNativeSlotsCount);
172+
return native_fields_.load()[static_cast<uint8_t>(kind)];
160173
}
161174

162175
// Note: should only be called with cids of array-like classes.

runtime/vm/compiler/backend/slot.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,9 @@ class Slot : public ZoneAllocated {
295295
return static_cast<const T*>(data_);
296296
}
297297

298+
// There is a fixed statically known number of native slots so we cache
299+
// them statically.
300+
static AcqRelAtomic<Slot*> native_fields_;
298301
static const Slot& GetNativeSlot(Kind kind);
299302

300303
const Kind kind_;

0 commit comments

Comments
 (0)