Skip to content

Commit 112dbab

Browse files
rmacnak-googlecommit-bot@chromium.org
authored andcommitted
[vm] Update Megamorphic::filled_entry_count_ under the megamorphic lock.
Otherwise the background compiler may see 0 when the mutator grows the megamorphic cache. Bug: #37257 Change-Id: I64a31937391ad6c0f086f8f175501ca4ef06c305 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/105969 Commit-Queue: Ryan Macnak <rmacnak@google.com> Reviewed-by: Alexander Markov <alexmarkov@google.com>
1 parent 0f91731 commit 112dbab

File tree

7 files changed

+27
-15
lines changed

7 files changed

+27
-15
lines changed

runtime/vm/compiler/backend/il.cc

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -776,7 +776,7 @@ void Cids::CreateHelper(Zone* zone,
776776
if (ic_data.is_megamorphic()) {
777777
const MegamorphicCache& cache =
778778
MegamorphicCache::Handle(zone, ic_data.AsMegamorphicCache());
779-
SafepointMutexLocker ml(Isolate::Current()->megamorphic_lookup_mutex());
779+
SafepointMutexLocker ml(Isolate::Current()->megamorphic_mutex());
780780
MegamorphicCacheEntries entries(Array::Handle(zone, cache.buckets()));
781781
for (intptr_t i = 0; i < entries.Length(); i++) {
782782
const intptr_t id =
@@ -787,8 +787,10 @@ void Cids::CreateHelper(Zone* zone,
787787
if (include_targets) {
788788
Function& function = Function::ZoneHandle(zone);
789789
function ^= entries[i].Get<MegamorphicCache::kTargetFunctionIndex>();
790+
const intptr_t filled_entry_count = cache.filled_entry_count();
791+
ASSERT(filled_entry_count > 0);
790792
cid_ranges_.Add(new (zone) TargetInfo(
791-
id, id, &function, Usage(function) / cache.filled_entry_count(),
793+
id, id, &function, Usage(function) / filled_entry_count,
792794
StaticTypeExactnessState::NotTracking()));
793795
} else {
794796
cid_ranges_.Add(new (zone) CidRange(id, id));

runtime/vm/isolate.cc

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -892,8 +892,7 @@ Isolate::Isolate(const Dart_IsolateFlags& api_flags)
892892
NOT_IN_PRODUCT("Isolate::type_canonicalization_mutex_")),
893893
constant_canonicalization_mutex_(
894894
NOT_IN_PRODUCT("Isolate::constant_canonicalization_mutex_")),
895-
megamorphic_lookup_mutex_(
896-
NOT_IN_PRODUCT("Isolate::megamorphic_lookup_mutex_")),
895+
megamorphic_mutex_(NOT_IN_PRODUCT("Isolate::megamorphic_mutex_")),
897896
kernel_data_lib_cache_mutex_(
898897
NOT_IN_PRODUCT("Isolate::kernel_data_lib_cache_mutex_")),
899898
kernel_data_class_cache_mutex_(

runtime/vm/isolate.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,7 @@ class Isolate : public BaseIsolate {
355355
Mutex* constant_canonicalization_mutex() {
356356
return &constant_canonicalization_mutex_;
357357
}
358-
Mutex* megamorphic_lookup_mutex() { return &megamorphic_lookup_mutex_; }
358+
Mutex* megamorphic_mutex() { return &megamorphic_mutex_; }
359359

360360
Mutex* kernel_data_lib_cache_mutex() { return &kernel_data_lib_cache_mutex_; }
361361
Mutex* kernel_data_class_cache_mutex() {
@@ -1027,7 +1027,8 @@ class Isolate : public BaseIsolate {
10271027
Mutex symbols_mutex_; // Protects concurrent access to the symbol table.
10281028
Mutex type_canonicalization_mutex_; // Protects type canonicalization.
10291029
Mutex constant_canonicalization_mutex_; // Protects const canonicalization.
1030-
Mutex megamorphic_lookup_mutex_; // Protects megamorphic table lookup.
1030+
Mutex megamorphic_mutex_; // Protects the table of megamorphic caches and
1031+
// their entries.
10311032
Mutex kernel_data_lib_cache_mutex_;
10321033
Mutex kernel_data_class_cache_mutex_;
10331034
Mutex kernel_constants_mutex_;

runtime/vm/megamorphic_cache_table.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ RawMegamorphicCache* MegamorphicCacheTable::Lookup(Isolate* isolate,
1616
const String& name,
1717
const Array& descriptor) {
1818
// Multiple compilation threads could access this lookup.
19-
SafepointMutexLocker ml(isolate->megamorphic_lookup_mutex());
19+
SafepointMutexLocker ml(isolate->megamorphic_mutex());
2020
ASSERT(name.IsSymbol());
2121
// TODO(rmacnak): ASSERT(descriptor.IsCanonical());
2222

runtime/vm/object.cc

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14175,7 +14175,7 @@ bool ICData::HasOneTarget() const {
1417514175
if (is_megamorphic()) {
1417614176
const MegamorphicCache& cache =
1417714177
MegamorphicCache::Handle(AsMegamorphicCache());
14178-
SafepointMutexLocker ml(Isolate::Current()->megamorphic_lookup_mutex());
14178+
SafepointMutexLocker ml(Isolate::Current()->megamorphic_mutex());
1417914179
MegamorphicCacheEntries entries(Array::Handle(cache.buckets()));
1418014180
for (intptr_t i = 0; i < entries.Length(); i++) {
1418114181
const intptr_t id =
@@ -15672,7 +15672,14 @@ RawMegamorphicCache* MegamorphicCache::New(const String& target_name,
1567215672
return result.raw();
1567315673
}
1567415674

15675-
void MegamorphicCache::EnsureCapacity() const {
15675+
void MegamorphicCache::Insert(const Smi& class_id, const Object& target) const {
15676+
SafepointMutexLocker ml(Isolate::Current()->megamorphic_mutex());
15677+
EnsureCapacityLocked();
15678+
InsertLocked(class_id, target);
15679+
}
15680+
15681+
void MegamorphicCache::EnsureCapacityLocked() const {
15682+
ASSERT(Isolate::Current()->megamorphic_mutex()->IsOwnedByCurrentThread());
1567615683
intptr_t old_capacity = mask() + 1;
1567715684
double load_limit = kLoadFactor * static_cast<double>(old_capacity);
1567815685
if (static_cast<double>(filled_entry_count() + 1) > load_limit) {
@@ -15696,16 +15703,18 @@ void MegamorphicCache::EnsureCapacity() const {
1569615703
class_id ^= GetClassId(old_buckets, i);
1569715704
if (class_id.Value() != kIllegalCid) {
1569815705
target = GetTargetFunction(old_buckets, i);
15699-
Insert(class_id, target);
15706+
InsertLocked(class_id, target);
1570015707
}
1570115708
}
1570215709
}
1570315710
}
1570415711

15705-
void MegamorphicCache::Insert(const Smi& class_id, const Object& target) const {
15712+
void MegamorphicCache::InsertLocked(const Smi& class_id,
15713+
const Object& target) const {
15714+
ASSERT(Isolate::Current()->megamorphic_mutex()->IsOwnedByCurrentThread());
15715+
ASSERT(Thread::Current()->IsMutatorThread());
1570615716
ASSERT(static_cast<double>(filled_entry_count() + 1) <=
1570715717
(kLoadFactor * static_cast<double>(mask() + 1)));
15708-
SafepointMutexLocker ml(Isolate::Current()->megamorphic_lookup_mutex());
1570915718
const Array& backing_array = Array::Handle(buckets());
1571015719
intptr_t id_mask = mask();
1571115720
intptr_t index = (class_id.Value() * kSpreadFactor) & id_mask;

runtime/vm/object.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5836,8 +5836,6 @@ class MegamorphicCache : public Object {
58365836
static RawMegamorphicCache* New(const String& target_name,
58375837
const Array& arguments_descriptor);
58385838

5839-
void EnsureCapacity() const;
5840-
58415839
void Insert(const Smi& class_id, const Object& target) const;
58425840

58435841
void SwitchToBareInstructions();
@@ -5856,6 +5854,10 @@ class MegamorphicCache : public Object {
58565854
void set_target_name(const String& value) const;
58575855
void set_arguments_descriptor(const Array& value) const;
58585856

5857+
// The caller must hold Isolate::megamorphic_mutex().
5858+
void EnsureCapacityLocked() const;
5859+
void InsertLocked(const Smi& class_id, const Object& target) const;
5860+
58595861
static inline void SetEntry(const Array& array,
58605862
intptr_t index,
58615863
const Smi& class_id,

runtime/vm/runtime_entry.cc

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1786,7 +1786,6 @@ DEFINE_RUNTIME_ENTRY(MegamorphicCacheMissHandler, 3) {
17861786
} else {
17871787
const MegamorphicCache& cache = MegamorphicCache::Cast(ic_data_or_cache);
17881788
// Insert function found into cache and return it.
1789-
cache.EnsureCapacity();
17901789
const Smi& class_id = Smi::Handle(zone, Smi::New(cls.id()));
17911790
cache.Insert(class_id, target_function);
17921791
}

0 commit comments

Comments
 (0)