diff options
Diffstat (limited to 'js/src/gc/Zone-inl.h')
-rw-r--r-- | js/src/gc/Zone-inl.h | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/js/src/gc/Zone-inl.h b/js/src/gc/Zone-inl.h new file mode 100644 index 0000000000..8bcb9802cf --- /dev/null +++ b/js/src/gc/Zone-inl.h @@ -0,0 +1,106 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * vim: set ts=8 sts=2 et sw=2 tw=80: + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef gc_Zone_inl_h +#define gc_Zone_inl_h + +#include "gc/Zone.h" + +#include "vm/Runtime.h" + +/* static */ inline js::HashNumber JS::Zone::UniqueIdToHash(uint64_t uid) { + return mozilla::HashGeneric(uid); +} + +inline bool JS::Zone::getHashCode(js::gc::Cell* cell, js::HashNumber* hashp) { + uint64_t uid; + if (!getOrCreateUniqueId(cell, &uid)) { + return false; + } + *hashp = UniqueIdToHash(uid); + return true; +} + +inline bool JS::Zone::maybeGetUniqueId(js::gc::Cell* cell, uint64_t* uidp) { + MOZ_ASSERT(uidp); + MOZ_ASSERT(js::CurrentThreadCanAccessZone(this) || + js::CurrentThreadIsPerformingGC()); + + // Get an existing uid, if one has been set. + auto p = uniqueIds().readonlyThreadsafeLookup(cell); + if (p) { + *uidp = p->value(); + } + + return p.found(); +} + +inline bool JS::Zone::getOrCreateUniqueId(js::gc::Cell* cell, uint64_t* uidp) { + MOZ_ASSERT(uidp); + MOZ_ASSERT(js::CurrentThreadCanAccessZone(this) || + js::CurrentThreadIsPerformingGC()); + + // Get an existing uid, if one has been set. + auto p = uniqueIds().lookupForAdd(cell); + if (p) { + *uidp = p->value(); + return true; + } + + MOZ_ASSERT(js::CurrentThreadCanAccessZone(this)); + + // Set a new uid on the cell. + *uidp = js::gc::NextCellUniqueId(runtimeFromAnyThread()); + if (!uniqueIds().add(p, cell, *uidp)) { + return false; + } + + // If the cell was in the nursery, hopefully unlikely, then we need to + // tell the nursery about it so that it can sweep the uid if the thing + // does not get tenured. + if (IsInsideNursery(cell) && + !runtimeFromMainThread()->gc.nursery().addedUniqueIdToCell(cell)) { + uniqueIds().remove(cell); + return false; + } + + return true; +} + +inline js::HashNumber JS::Zone::getHashCodeInfallible(js::gc::Cell* cell) { + return UniqueIdToHash(getUniqueIdInfallible(cell)); +} + +inline uint64_t JS::Zone::getUniqueIdInfallible(js::gc::Cell* cell) { + uint64_t uid; + js::AutoEnterOOMUnsafeRegion oomUnsafe; + if (!getOrCreateUniqueId(cell, &uid)) { + oomUnsafe.crash("failed to allocate uid"); + } + return uid; +} + +inline bool JS::Zone::hasUniqueId(js::gc::Cell* cell) { + MOZ_ASSERT(js::CurrentThreadCanAccessZone(this) || + js::CurrentThreadIsPerformingGC()); + return uniqueIds().has(cell); +} + +inline void JS::Zone::transferUniqueId(js::gc::Cell* tgt, js::gc::Cell* src) { + MOZ_ASSERT(src != tgt); + MOZ_ASSERT(!IsInsideNursery(tgt)); + MOZ_ASSERT(js::CurrentThreadCanAccessRuntime(runtimeFromMainThread())); + MOZ_ASSERT(js::CurrentThreadCanAccessZone(this)); + MOZ_ASSERT(!uniqueIds().has(tgt)); + uniqueIds().rekeyIfMoved(src, tgt); +} + +inline void JS::Zone::removeUniqueId(js::gc::Cell* cell) { + MOZ_ASSERT(js::CurrentThreadCanAccessZone(this)); + uniqueIds().remove(cell); +} + +#endif // gc_Zone_inl_h |