1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 * vim: set ts=8 sts=4 et sw=4 tw=99:
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
15 * Used to add entries to a js::HashMap or HashSet where the key depends on a GC
16 * thing that may be moved by generational or compacting GC between the call to
17 * lookupForAdd() and relookupOrAdd().
20 struct DependentAddPtr
22 typedef typename
T::AddPtr AddPtr
;
23 typedef typename
T::Entry Entry
;
25 template <class Lookup
>
26 DependentAddPtr(const ExclusiveContext
* cx
, const T
& table
, const Lookup
& lookup
)
27 : addPtr(table
.lookupForAdd(lookup
))
28 , originalGcNumber(cx
->zone()->gcNumber())
31 template <class KeyInput
, class ValueInput
>
32 bool add(const ExclusiveContext
* cx
, T
& table
, const KeyInput
& key
, const ValueInput
& value
) {
33 bool gcHappened
= originalGcNumber
!= cx
->zone()->gcNumber();
35 addPtr
= table
.lookupForAdd(key
);
36 return table
.relookupOrAdd(addPtr
, key
, value
);
39 typedef void (DependentAddPtr::* ConvertibleToBool
)();
42 bool found() const { return addPtr
.found(); }
43 operator ConvertibleToBool() const { return found() ? &DependentAddPtr::nonNull
: 0; }
44 const Entry
& operator*() const { return *addPtr
; }
45 const Entry
* operator->() const { return &*addPtr
; }
49 const uint64_t originalGcNumber
;
51 DependentAddPtr() = delete;
52 DependentAddPtr(const DependentAddPtr
&) = delete;
53 DependentAddPtr
& operator=(const DependentAddPtr
&) = delete;