Hold intern table lock for AddImageStringsToTable
Fixes a correctness issue where another thread adding an intern string
after the visitor could cause duplicate strings.
Reduces how often the intern table lock is acquired, probably
improving performance.
Bug: 116059983
Test: test-art-host
Change-Id: I5ba6ca3ba7535de6d4ad5cb46750bd23a6e9aadc
diff --git a/runtime/intern_table-inl.h b/runtime/intern_table-inl.h
index 8c7fb42..84754fa 100644
--- a/runtime/intern_table-inl.h
+++ b/runtime/intern_table-inl.h
@@ -39,11 +39,15 @@
inline size_t InternTable::AddTableFromMemory(const uint8_t* ptr, const Visitor& visitor) {
size_t read_count = 0;
UnorderedSet set(ptr, /*make copy*/false, &read_count);
- // Visit the unordered set, may remove elements.
- visitor(set);
- if (!set.empty()) {
+ {
+ // Hold the lock while calling the visitor to prevent possible race
+ // conditions with another thread adding intern strings.
MutexLock mu(Thread::Current(), *Locks::intern_table_lock_);
- strong_interns_.AddInternStrings(std::move(set));
+ // Visit the unordered set, may remove elements.
+ visitor(set);
+ if (!set.empty()) {
+ strong_interns_.AddInternStrings(std::move(set));
+ }
}
return read_count;
}