Bug 1799327 - Ensure cached hashtables used by gfxFont::CheckForFeaturesInvolvingSpace are initialized atomically. r=gfx-reviewers,lsalzman

Differential Revision: https://phabricator.services.mozilla.com/D161434
This commit is contained in:
Jonathan Kew 2022-11-07 15:27:15 +00:00
parent 6af8cfa539
commit 9ced4e3037
2 changed files with 24 additions and 13 deletions

View File

@ -1191,8 +1191,8 @@ static void HasLookupRuleWithGlyph(hb_face_t* aFace, hb_tag_t aTableTag,
hb_set_destroy(otherLookups); hb_set_destroy(otherLookups);
} }
nsTHashMap<nsUint32HashKey, intl::Script>* gfxFont::sScriptTagToCode = nullptr; Atomic<nsTHashMap<nsUint32HashKey, intl::Script>*> gfxFont::sScriptTagToCode;
nsTHashSet<uint32_t>* gfxFont::sDefaultFeatures = nullptr; Atomic<nsTHashSet<uint32_t>*> gfxFont::sDefaultFeatures;
static inline bool HasSubstitution(uint32_t* aBitVector, intl::Script aScript) { static inline bool HasSubstitution(uint32_t* aBitVector, intl::Script aScript) {
return (aBitVector[static_cast<uint32_t>(aScript) >> 5] & return (aBitVector[static_cast<uint32_t>(aScript) >> 5] &
@ -1243,12 +1243,12 @@ void gfxFont::CheckForFeaturesInvolvingSpace() const {
// GSUB lookups - examine per script // GSUB lookups - examine per script
if (hb_ot_layout_has_substitution(face)) { if (hb_ot_layout_has_substitution(face)) {
// set up the script ==> code hashtable if needed // Get the script ==> code hashtable, creating it on first use.
if (!sScriptTagToCode) { nsTHashMap<nsUint32HashKey, Script>* tagToCode = sScriptTagToCode;
sScriptTagToCode = new nsTHashMap<nsUint32HashKey, Script>( if (!tagToCode) {
tagToCode = new nsTHashMap<nsUint32HashKey, Script>(
size_t(Script::NUM_SCRIPT_CODES)); size_t(Script::NUM_SCRIPT_CODES));
sScriptTagToCode->InsertOrUpdate(HB_TAG('D', 'F', 'L', 'T'), tagToCode->InsertOrUpdate(HB_TAG('D', 'F', 'L', 'T'), Script::COMMON);
Script::COMMON);
// Ensure that we don't try to look at script codes beyond what the // Ensure that we don't try to look at script codes beyond what the
// current version of ICU (at runtime -- in case of system ICU) // current version of ICU (at runtime -- in case of system ICU)
// knows about. // knows about.
@ -1264,14 +1264,25 @@ void gfxFont::CheckForFeaturesInvolvingSpace() const {
&scriptCount, scriptTags, nullptr, &scriptCount, scriptTags, nullptr,
nullptr); nullptr);
for (unsigned int i = 0; i < scriptCount; i++) { for (unsigned int i = 0; i < scriptCount; i++) {
sScriptTagToCode->InsertOrUpdate(scriptTags[i], s); tagToCode->InsertOrUpdate(scriptTags[i], s);
} }
} }
if (!sScriptTagToCode.compareExchange(nullptr, tagToCode)) {
// We lost a race! Discard our new table and use the winner.
delete tagToCode;
tagToCode = sScriptTagToCode;
}
}
// Set up the default-features hashset on first use.
if (!sDefaultFeatures) {
uint32_t numDefaultFeatures = ArrayLength(defaultFeatures); uint32_t numDefaultFeatures = ArrayLength(defaultFeatures);
sDefaultFeatures = new nsTHashSet<uint32_t>(numDefaultFeatures); auto* set = new nsTHashSet<uint32_t>(numDefaultFeatures);
for (uint32_t i = 0; i < numDefaultFeatures; i++) { for (uint32_t i = 0; i < numDefaultFeatures; i++) {
sDefaultFeatures->Insert(defaultFeatures[i]); set->Insert(defaultFeatures[i]);
}
if (!sDefaultFeatures.compareExchange(nullptr, set)) {
delete set;
} }
} }
@ -1289,7 +1300,7 @@ void gfxFont::CheckForFeaturesInvolvingSpace() const {
if (!HasLookupRuleWithGlyphByScript( if (!HasLookupRuleWithGlyphByScript(
face, HB_OT_TAG_GSUB, scriptTags[i], offset + i, spaceGlyph, face, HB_OT_TAG_GSUB, scriptTags[i], offset + i, spaceGlyph,
*sDefaultFeatures, isDefaultFeature) || *sDefaultFeatures, isDefaultFeature) ||
!sScriptTagToCode->Get(scriptTags[i], &s)) { !tagToCode->Get(scriptTags[i], &s)) {
continue; continue;
} }
flags = flags | gfxFontEntry::SpaceFeatures::HasFeatures; flags = flags | gfxFontEntry::SpaceFeatures::HasFeatures;

View File

@ -2074,8 +2074,8 @@ class gfxFont {
bool HasFeatureSet(uint32_t aFeature, bool& aFeatureOn); bool HasFeatureSet(uint32_t aFeature, bool& aFeatureOn);
// used when analyzing whether a font has space contextual lookups // used when analyzing whether a font has space contextual lookups
static nsTHashMap<nsUint32HashKey, Script>* sScriptTagToCode; static mozilla::Atomic<nsTHashMap<nsUint32HashKey, Script>*> sScriptTagToCode;
static nsTHashSet<uint32_t>* sDefaultFeatures; static mozilla::Atomic<nsTHashSet<uint32_t>*> sDefaultFeatures;
RefPtr<gfxFontEntry> mFontEntry; RefPtr<gfxFontEntry> mFontEntry;
mutable mozilla::RWLock mLock; mutable mozilla::RWLock mLock;