Symbol* Symbol::for_(js::ExclusiveContext* cx, HandleString description) { JSAtom* atom = AtomizeString(cx, description); if (!atom) return nullptr; AutoLockForExclusiveAccess lock(cx); SymbolRegistry& registry = cx->symbolRegistry(lock); SymbolRegistry::AddPtr p = registry.lookupForAdd(atom); if (p) return *p; AutoCompartment ac(cx, cx->atomsCompartment(lock), &lock); Symbol* sym = newInternal(cx, SymbolCode::InSymbolRegistry, atom->hash(), atom, lock); if (!sym) return nullptr; // p is still valid here because we have held the lock since the // lookupForAdd call, and newInternal can't GC. if (!registry.add(p, sym)) { // SystemAllocPolicy does not report OOM. ReportOutOfMemory(cx); return nullptr; } return sym; }
Symbol* Symbol::for_(JSContext* cx, HandleString description) { JSAtom* atom = AtomizeString(cx, description); if (!atom) return nullptr; AutoLockForExclusiveAccess lock(cx); SymbolRegistry& registry = cx->symbolRegistry(lock); SymbolRegistry::AddPtr p = registry.lookupForAdd(atom); if (p) { cx->markAtom(*p); return *p; } Symbol* sym; { AutoAtomsCompartment ac(cx, lock); // Rehash the hash of the atom to give the corresponding symbol a hash // that is different than the hash of the corresponding atom. HashNumber hash = mozilla::HashGeneric(atom->hash()); sym = newInternal(cx, SymbolCode::InSymbolRegistry, hash, atom, lock); if (!sym) return nullptr; // p is still valid here because we have held the lock since the // lookupForAdd call, and newInternal can't GC. if (!registry.add(p, sym)) { // SystemAllocPolicy does not report OOM. ReportOutOfMemory(cx); return nullptr; } } cx->markAtom(sym); return sym; }