michael@0: /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- michael@0: * vim: set ts=8 sts=4 et sw=4 tw=99: michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef jshashutil_h michael@0: #define jshashutil_h michael@0: michael@0: #include "jscntxt.h" michael@0: michael@0: namespace js { michael@0: michael@0: /* michael@0: * Used to add entries to a js::HashMap or HashSet where the key depends on a GC michael@0: * thing that may be moved by generational collection between the call to michael@0: * lookupForAdd() and relookupOrAdd(). michael@0: */ michael@0: template michael@0: struct DependentAddPtr michael@0: { michael@0: typedef typename T::AddPtr AddPtr; michael@0: typedef typename T::Entry Entry; michael@0: michael@0: template michael@0: DependentAddPtr(const ExclusiveContext *cx, const T &table, const Lookup &lookup) michael@0: : addPtr(table.lookupForAdd(lookup)) michael@0: #ifdef JSGC_GENERATIONAL michael@0: , originalGcNumber(cx->zone()->gcNumber()) michael@0: #endif michael@0: {} michael@0: michael@0: template michael@0: bool add(const ExclusiveContext *cx, T &table, const KeyInput &key, const ValueInput &value) { michael@0: #ifdef JSGC_GENERATIONAL michael@0: bool gcHappened = originalGcNumber != cx->zone()->gcNumber(); michael@0: if (gcHappened) michael@0: addPtr = table.lookupForAdd(key); michael@0: #endif michael@0: return table.relookupOrAdd(addPtr, key, value); michael@0: } michael@0: michael@0: typedef void (DependentAddPtr::* ConvertibleToBool)(); michael@0: void nonNull() {} michael@0: michael@0: bool found() const { return addPtr.found(); } michael@0: operator ConvertibleToBool() const { return found() ? &DependentAddPtr::nonNull : 0; } michael@0: const Entry &operator*() const { return *addPtr; } michael@0: const Entry *operator->() const { return &*addPtr; } michael@0: michael@0: private: michael@0: AddPtr addPtr ; michael@0: #ifdef JSGC_GENERATIONAL michael@0: const uint64_t originalGcNumber; michael@0: #endif michael@0: michael@0: DependentAddPtr() MOZ_DELETE; michael@0: DependentAddPtr(const DependentAddPtr&) MOZ_DELETE; michael@0: DependentAddPtr& operator=(const DependentAddPtr&) MOZ_DELETE; michael@0: }; michael@0: michael@0: } // namespace js michael@0: michael@0: #endif