Backed out 7 changesets (bug 1731218) for causing spidermonkey build bustages in RootingAPI. CLOSED TREE

Backed out changeset 0dfcae852026 (bug 1731218)
Backed out changeset e2c59b5af7ea (bug 1731218)
Backed out changeset 3e98b832dcc6 (bug 1731218)
Backed out changeset 57e60277e4ca (bug 1731218)
Backed out changeset 3b264a4bc67e (bug 1731218)
Backed out changeset 304f27af6b95 (bug 1731218)
Backed out changeset 06e7a1992de8 (bug 1731218)
This commit is contained in:
Sandor Molnar 2021-09-21 11:37:12 +03:00
Родитель 2a78d18891
Коммит 10773301cf
8 изменённых файлов: 179 добавлений и 135 удалений

Просмотреть файл

@ -125,17 +125,16 @@ class MutableWrappedPtrOperations
: public WrappedPtrOperations<Element, Wrapper> {};
template <typename T, typename Wrapper>
class RootedOperations : public MutableWrappedPtrOperations<T, Wrapper> {};
class RootedBase : public MutableWrappedPtrOperations<T, Wrapper> {};
template <typename T, typename Wrapper>
class HandleOperations : public WrappedPtrOperations<T, Wrapper> {};
class HandleBase : public WrappedPtrOperations<T, Wrapper> {};
template <typename T, typename Wrapper>
class MutableHandleOperations : public MutableWrappedPtrOperations<T, Wrapper> {
};
class MutableHandleBase : public MutableWrappedPtrOperations<T, Wrapper> {};
template <typename T, typename Wrapper>
class HeapOperations : public MutableWrappedPtrOperations<T, Wrapper> {};
class HeapBase : public MutableWrappedPtrOperations<T, Wrapper> {};
// Cannot use FOR_EACH_HEAP_ABLE_GC_POINTER_TYPE, as this would import too many
// macros into scope
@ -290,7 +289,7 @@ inline void AssertGCThingIsNotNurseryAllocable(js::gc::Cell* cell) {}
* Type T must be a public GC pointer type.
*/
template <typename T>
class MOZ_NON_MEMMOVABLE Heap : public js::HeapOperations<T, Heap<T>> {
class MOZ_NON_MEMMOVABLE Heap : public js::HeapBase<T, Heap<T>> {
// Please note: this can actually also be used by nsXBLMaybeCompiled<T>, for
// legacy reasons.
static_assert(js::IsHeapConstructibleType<T>::value,
@ -450,7 +449,7 @@ inline void AssertObjectIsNotGray(const JS::Heap<JSObject*>& obj) {}
* - It is not possible to store flag bits in a Heap<T>.
*/
template <typename T>
class TenuredHeap : public js::HeapOperations<T, TenuredHeap<T>> {
class TenuredHeap : public js::HeapBase<T, TenuredHeap<T>> {
public:
using ElementType = T;
@ -570,10 +569,10 @@ class PersistentRooted;
* rooted. See "Move GC Stack Rooting" above.
*
* If you want to add additional methods to Handle for a specific
* specialization, define a HandleOperations<T> specialization containing them.
* specialization, define a HandleBase<T> specialization containing them.
*/
template <typename T>
class MOZ_NONHEAP_CLASS Handle : public js::HandleOperations<T, Handle<T>> {
class MOZ_NONHEAP_CLASS Handle : public js::HandleBase<T, Handle<T>> {
friend class MutableHandle<T>;
public:
@ -668,12 +667,12 @@ struct DefineComparisonOps<Handle<T>> : std::true_type {
* useful for outparams.
*
* If you want to add additional methods to MutableHandle for a specific
* specialization, define a MutableHandleOperations<T> specialization containing
* specialization, define a MutableHandleBase<T> specialization containing
* them.
*/
template <typename T>
class MOZ_STACK_CLASS MutableHandle
: public js::MutableHandleOperations<T, MutableHandle<T>> {
: public js::MutableHandleBase<T, MutableHandle<T>> {
public:
using ElementType = T;
@ -878,64 +877,40 @@ struct VirtualTraceable {
virtual void trace(JSTracer* trc, const char* name) = 0;
};
class StackRootedBase {
public:
StackRootedBase* previous() { return prev; }
template <typename T>
struct RootedTraceable final : public VirtualTraceable {
static_assert(JS::MapTypeToRootKind<T>::kind == JS::RootKind::Traceable,
"RootedTraceable is intended only for usage with a Traceable");
protected:
StackRootedBase** stack;
StackRootedBase* prev;
T ptr;
template <typename T>
auto* derived() {
return static_cast<JS::Rooted<T>*>(this);
}
};
template <typename... CtorArgs>
explicit RootedTraceable(std::in_place_t, CtorArgs... args)
: ptr(std::forward<CtorArgs>(args)...) {}
class PersistentRootedBase
: protected mozilla::LinkedListElement<PersistentRootedBase> {
protected:
friend class mozilla::LinkedList<PersistentRootedBase>;
friend class mozilla::LinkedListElement<PersistentRootedBase>;
template <typename U, typename = typename std::is_constructible<T, U>::type>
MOZ_IMPLICIT RootedTraceable(U&& initial) : ptr(std::forward<U>(initial)) {}
template <typename T>
auto* derived() {
return static_cast<JS::PersistentRooted<T>*>(this);
}
};
operator T&() { return ptr; }
operator const T&() const { return ptr; }
struct StackRootedTraceableBase : public StackRootedBase,
public VirtualTraceable {};
class PersistentRootedTraceableBase : public PersistentRootedBase,
public VirtualTraceable {};
template <typename Base, typename T>
class TypedRootedGCThingBase : public Base {
public:
void trace(JSTracer* trc, const char* name);
};
template <typename Base, typename T>
class TypedRootedTraceableBase : public Base {
public:
void trace(JSTracer* trc, const char* name) override {
auto* self = this->template derived<T>();
JS::GCPolicy<T>::trace(trc, self->address(), name);
JS::GCPolicy<T>::trace(trc, &ptr, name);
}
};
template <typename T>
struct RootedTraceableTraits {
using StackRootedBase = TypedRootedTraceableBase<StackRootedTraceableBase, T>;
using PersistentRootedBase =
TypedRootedTraceableBase<PersistentRootedTraceableBase, T>;
static T* address(RootedTraceable<T>& self) { return &self.ptr; }
static const T* address(const RootedTraceable<T>& self) { return &self.ptr; }
static void trace(JSTracer* trc, VirtualTraceable* thingp, const char* name);
};
template <typename T>
struct RootedGCThingTraits {
using StackRootedBase = TypedRootedGCThingBase<StackRootedBase, T>;
using PersistentRootedBase = TypedRootedGCThingBase<PersistentRootedBase, T>;
static T* address(T& self) { return &self; }
static const T* address(const T& self) { return &self; }
static void trace(JSTracer* trc, T* thingp, const char* name);
};
} /* namespace js */
@ -952,8 +927,29 @@ enum class AutoGCRooterKind : uint8_t {
Limit
};
namespace detail {
// Dummy type to store root list entry pointers as. This code does not just use
// the actual type, because then eg JSObject* and JSFunction* would be assumed
// to never alias but they do (they are stored in the same list). Also, do not
// use `void*` so that `Rooted<void*>` is a compile error.
struct RootListEntry;
} // namespace detail
template <>
struct MapTypeToRootKind<detail::RootListEntry*> {
static const RootKind kind = RootKind::Traceable;
};
// Workaround MSVC issue where GCPolicy is needed even though this dummy type is
// never instantiated. Ideally, RootListEntry is removed in the future and an
// appropriate class hierarchy for the Rooted<T> types.
template <>
struct GCPolicy<detail::RootListEntry*>
: public IgnoreGCPolicy<detail::RootListEntry*> {};
using RootedListHeads =
mozilla::EnumeratedArray<RootKind, RootKind::Limit, js::StackRootedBase*>;
mozilla::EnumeratedArray<RootKind, RootKind::Limit,
Rooted<detail::RootListEntry*>*>;
using AutoRooterListHeads =
mozilla::EnumeratedArray<AutoGCRooterKind, AutoGCRooterKind::Limit,
@ -1090,6 +1086,10 @@ template <typename T>
constexpr bool IsTraceable_v =
MapTypeToRootKind<T>::kind == JS::RootKind::Traceable;
template <typename T>
using RootedPtr =
std::conditional_t<IsTraceable_v<T>, js::RootedTraceable<T>, T>;
template <typename T>
using RootedPtrTraits =
std::conditional_t<IsTraceable_v<T>, js::RootedTraceableTraits<T>,
@ -1103,17 +1103,17 @@ using RootedPtrTraits =
* function that requires a handle, e.g. Foo(Root<T>(cx, x)).
*
* If you want to add additional methods to Rooted for a specific
* specialization, define a RootedOperations<T> specialization containing them.
* specialization, define a RootedBase<T> specialization containing them.
*/
template <typename T>
class MOZ_RAII Rooted : public detail::RootedPtrTraits<T>::StackRootedBase,
public js::RootedOperations<T, Rooted<T>> {
class MOZ_RAII Rooted : public js::RootedBase<T, Rooted<T>> {
using Ptr = detail::RootedPtr<T>;
using PtrTraits = detail::RootedPtrTraits<T>;
inline void registerWithRootLists(RootedListHeads& roots) {
this->stack = &roots[JS::MapTypeToRootKind<T>::kind];
this->prev = *this->stack;
*this->stack = this;
this->prev = *stack;
*stack = reinterpret_cast<Rooted<detail::RootListEntry*>*>(this);
}
inline RootedListHeads& rootLists(RootingContext* cx) {
@ -1141,7 +1141,8 @@ class MOZ_RAII Rooted : public detail::RootedPtrTraits<T>::StackRootedBase,
// Provide an initial value. Requires T to be constructible from the given
// argument.
template <typename RootingContext, typename S>
template <typename RootingContext, typename S,
typename = typename std::is_constructible<T, S>::type>
Rooted(const RootingContext& cx, S&& initial)
: ptr(std::forward<S>(initial)) {
MOZ_ASSERT(GCPolicy<T>::isValid(ptr));
@ -1160,16 +1161,19 @@ class MOZ_RAII Rooted : public detail::RootedPtrTraits<T>::StackRootedBase,
typename RootingContext, typename... CtorArgs,
typename = std::enable_if_t<detail::IsTraceable_v<T>, RootingContext>>
explicit Rooted(const RootingContext& cx, CtorArgs... args)
: ptr(std::forward<CtorArgs>(args)...) {
: ptr(std::in_place, std::forward<CtorArgs>(args)...) {
MOZ_ASSERT(GCPolicy<T>::isValid(ptr));
registerWithRootLists(rootLists(cx));
}
~Rooted() {
MOZ_ASSERT(*this->stack == this);
*this->stack = this->prev;
MOZ_ASSERT(*stack ==
reinterpret_cast<Rooted<detail::RootListEntry*>*>(this));
*stack = prev;
}
Rooted<T>* previous() { return reinterpret_cast<Rooted<T>*>(prev); }
/*
* This method is public for Rooted so that Codegen.py can use a Rooted
* interchangeably with a MutableHandleValue.
@ -1189,11 +1193,21 @@ class MOZ_RAII Rooted : public detail::RootedPtrTraits<T>::StackRootedBase,
T& get() { return ptr; }
const T& get() const { return ptr; }
T* address() { return &ptr; }
const T* address() const { return &ptr; }
T* address() { return PtrTraits::address(ptr); }
const T* address() const { return PtrTraits::address(ptr); }
void trace(JSTracer* trc, const char* name);
private:
T ptr;
/*
* These need to be templated on RootListEntry* to avoid aliasing issues
* between, for example, Rooted<JSObject*> and Rooted<JSFunction*>, which use
* the same stack head pointer for different classes.
*/
Rooted<detail::RootListEntry*>** stack;
Rooted<detail::RootListEntry*>* prev;
Ptr ptr;
Rooted(const Rooted&) = delete;
} JS_HAZ_ROOTED;
@ -1253,7 +1267,7 @@ inline ProfilingStack* GetContextProfilingStackIfEnabled(JSContext* cx) {
* Handle<StringObject*> h = rooted;
*/
template <typename Container>
class RootedOperations<JSObject*, Container>
class RootedBase<JSObject*, Container>
: public MutableWrappedPtrOperations<JSObject*, Container> {
public:
template <class U>
@ -1271,7 +1285,7 @@ class RootedOperations<JSObject*, Container>
* Handle<StringObject*> h = rooted;
*/
template <typename Container>
class HandleOperations<JSObject*, Container>
class HandleBase<JSObject*, Container>
: public WrappedPtrOperations<JSObject*, Container> {
public:
template <class U>
@ -1320,11 +1334,13 @@ inline MutableHandle<T>::MutableHandle(PersistentRooted<T>* root) {
ptr = root->address();
}
JS_PUBLIC_API void AddPersistentRoot(RootingContext* cx, RootKind kind,
js::PersistentRootedBase* root);
JS_PUBLIC_API void AddPersistentRoot(
RootingContext* cx, RootKind kind,
PersistentRooted<detail::RootListEntry*>* root);
JS_PUBLIC_API void AddPersistentRoot(JSRuntime* rt, RootKind kind,
js::PersistentRootedBase* root);
JS_PUBLIC_API void AddPersistentRoot(
JSRuntime* rt, RootKind kind,
PersistentRooted<detail::RootListEntry*>* root);
/**
* A copyable, assignable global GC root type with arbitrary lifetime, an
@ -1361,20 +1377,29 @@ JS_PUBLIC_API void AddPersistentRoot(JSRuntime* rt, RootKind kind,
*/
template <typename T>
class PersistentRooted
: public detail::RootedPtrTraits<T>::PersistentRootedBase,
public js::RootedOperations<T, PersistentRooted<T>> {
: public js::RootedBase<T, PersistentRooted<T>>,
private mozilla::LinkedListElement<PersistentRooted<T>> {
using ListBase = mozilla::LinkedListElement<PersistentRooted<T>>;
using Ptr = detail::RootedPtr<T>;
using PtrTraits = detail::RootedPtrTraits<T>;
friend class mozilla::LinkedList<PersistentRooted>;
friend class mozilla::LinkedListElement<PersistentRooted>;
void registerWithRootLists(RootingContext* cx) {
MOZ_ASSERT(!initialized());
JS::RootKind kind = JS::MapTypeToRootKind<T>::kind;
AddPersistentRoot(cx, kind, this);
AddPersistentRoot(
cx, kind,
reinterpret_cast<JS::PersistentRooted<detail::RootListEntry*>*>(this));
}
void registerWithRootLists(JSRuntime* rt) {
MOZ_ASSERT(!initialized());
JS::RootKind kind = JS::MapTypeToRootKind<T>::kind;
AddPersistentRoot(rt, kind, this);
AddPersistentRoot(
rt, kind,
reinterpret_cast<JS::PersistentRooted<detail::RootListEntry*>*>(this));
}
// Used when JSContext type is incomplete and so it is not known to inherit
@ -1406,11 +1431,12 @@ class PersistentRooted
template <typename RootHolder, typename... CtorArgs,
typename = std::enable_if_t<detail::IsTraceable_v<T>, RootHolder>>
explicit PersistentRooted(const RootHolder& cx, CtorArgs... args)
: ptr(std::forward<CtorArgs>(args)...) {
: ptr(std::in_place, std::forward<CtorArgs>(args)...) {
registerWithRootLists(cx);
}
PersistentRooted(const PersistentRooted& rhs) : ptr(rhs.ptr) {
PersistentRooted(const PersistentRooted& rhs)
: mozilla::LinkedListElement<PersistentRooted<T>>(), ptr(rhs.ptr) {
/*
* Copy construction takes advantage of the fact that the original
* is already inserted, and simply adds itself to whatever list the
@ -1422,7 +1448,7 @@ class PersistentRooted
const_cast<PersistentRooted&>(rhs).setNext(this);
}
bool initialized() const { return this->isInList(); }
bool initialized() const { return ListBase::isInList(); }
void init(RootingContext* cx) { init(cx, SafelyInitialized<T>()); }
void init(JSContext* cx) { init(RootingContext::get(cx)); }
@ -1441,7 +1467,7 @@ class PersistentRooted
void reset() {
if (initialized()) {
set(SafelyInitialized<T>());
this->remove();
ListBase::remove();
}
}
@ -1453,9 +1479,9 @@ class PersistentRooted
T* address() {
MOZ_ASSERT(initialized());
return &ptr;
return PtrTraits::address(ptr);
}
const T* address() const { return &ptr; }
const T* address() const { return PtrTraits::address(ptr); }
template <typename U>
void set(U&& value) {
@ -1463,8 +1489,10 @@ class PersistentRooted
ptr = std::forward<U>(value);
}
void trace(JSTracer* trc, const char* name);
private:
T ptr;
Ptr ptr;
} JS_HAZ_ROOTED;
namespace detail {

Просмотреть файл

@ -1217,7 +1217,7 @@ class MutableWrappedPtrOperations<JS::Value, Wrapper>
* type-querying, value-extracting, and mutating operations.
*/
template <typename Wrapper>
class HeapOperations<JS::Value, Wrapper>
class HeapBase<JS::Value, Wrapper>
: public MutableWrappedPtrOperations<JS::Value, Wrapper> {};
MOZ_HAVE_NORETURN MOZ_COLD MOZ_NEVER_INLINE void ReportBadValueTypeAndCrash(

Просмотреть файл

@ -28,7 +28,7 @@ namespace js {
* memory.
*/
template <typename T>
class MOZ_RAII FakeRooted : public RootedOperations<T, FakeRooted<T>> {
class MOZ_RAII FakeRooted : public RootedBase<T, FakeRooted<T>> {
public:
using ElementType = T;
@ -72,7 +72,7 @@ namespace js {
*/
template <typename T>
class FakeMutableHandle
: public js::MutableHandleOperations<T, FakeMutableHandle<T>> {
: public js::MutableHandleBase<T, FakeMutableHandle<T>> {
public:
using ElementType = T;

Просмотреть файл

@ -40,30 +40,47 @@ using RootRange = RootedValueMap::Range;
using RootEntry = RootedValueMap::Entry;
using RootEnum = RootedValueMap::Enum;
template <typename Base, typename T>
inline void TypedRootedGCThingBase<Base, T>::trace(JSTracer* trc,
const char* name) {
auto* self = this->template derived<T>();
TraceNullableRoot(trc, self->address(), name);
// For more detail see JS::Rooted::root and js::RootedTraceable.
//
// The JS::RootKind::Traceable list contains a bunch of totally disparate types,
// but to refer to this list we need /something/ in the type field. We use the
// following type as a compatible stand-in. No actual methods from
// ConcreteTraceable type are actually used at runtime.
struct ConcreteTraceable {
ConcreteTraceable() = delete;
void trace(JSTracer*) = delete;
};
template <typename T>
inline void RootedGCThingTraits<T>::trace(JSTracer* trc, T* thingp,
const char* name) {
TraceNullableRoot(trc, thingp, name);
}
template <typename T>
static inline void TraceExactStackRootList(JSTracer* trc,
StackRootedBase* listHead,
const char* name) {
// Check size of Rooted<T> does not increase.
static_assert(sizeof(Rooted<T>) == sizeof(T) + 2 * sizeof(uintptr_t));
for (StackRootedBase* root = listHead; root; root = root->previous()) {
static_cast<Rooted<T>*>(root)->trace(trc, name);
}
inline void RootedTraceableTraits<T>::trace(JSTracer* trc,
VirtualTraceable* thingp,
const char* name) {
thingp->trace(trc, name);
}
static inline void TraceExactStackRootTraceableList(JSTracer* trc,
StackRootedBase* listHead,
const char* name) {
for (StackRootedBase* root = listHead; root; root = root->previous()) {
static_cast<StackRootedTraceableBase*>(root)->trace(trc, name);
template <typename T>
inline void JS::Rooted<T>::trace(JSTracer* trc, const char* name) {
PtrTraits::trace(trc, &ptr, name);
}
template <typename T>
inline void JS::PersistentRooted<T>::trace(JSTracer* trc, const char* name) {
PtrTraits::trace(trc, &ptr, name);
}
template <typename T>
static inline void TraceExactStackRootList(
JSTracer* trc, JS::Rooted<JS::detail::RootListEntry*>* listHead,
const char* name) {
auto* typedList = reinterpret_cast<JS::Rooted<T>*>(listHead);
for (JS::Rooted<T>* root = typedList; root; root = root->previous()) {
root->trace(trc, name);
}
}
@ -81,8 +98,8 @@ static inline void TraceStackRoots(JSTracer* trc,
// RootedTraceable uses virtual dispatch.
JS::AutoSuppressGCAnalysis nogc;
TraceExactStackRootTraceableList(trc, stackRoots[JS::RootKind::Traceable],
"Traceable");
TraceExactStackRootList<ConcreteTraceable>(
trc, stackRoots[JS::RootKind::Traceable], "Traceable");
}
void JS::RootingContext::traceStackRoots(JSTracer* trc) {
@ -95,16 +112,12 @@ static void TraceExactStackRoots(JSContext* cx, JSTracer* trc) {
template <typename T>
static inline void TracePersistentRootedList(
JSTracer* trc, LinkedList<PersistentRootedBase>& list, const char* name) {
for (PersistentRootedBase* root : list) {
static_cast<PersistentRooted<T>*>(root)->trace(trc, name);
}
}
static inline void TracePersistentRootedTraceableList(
JSTracer* trc, LinkedList<PersistentRootedBase>& list, const char* name) {
for (PersistentRootedBase* root : list) {
static_cast<PersistentRootedTraceableBase*>(root)->trace(trc, name);
JSTracer* trc,
LinkedList<PersistentRooted<JS::detail::RootListEntry*>>& list,
const char* name) {
auto& typedList = reinterpret_cast<LinkedList<PersistentRooted<T>>&>(list);
for (PersistentRooted<T>* root : typedList) {
root->trace(trc, name);
}
}
@ -122,7 +135,7 @@ void JSRuntime::tracePersistentRoots(JSTracer* trc) {
// RootedTraceable uses virtual dispatch.
JS::AutoSuppressGCAnalysis nogc;
TracePersistentRootedTraceableList(
TracePersistentRootedList<ConcreteTraceable>(
trc, heapRoots.ref()[JS::RootKind::Traceable], "persistent-traceable");
}
@ -132,9 +145,10 @@ static void TracePersistentRooted(JSRuntime* rt, JSTracer* trc) {
template <typename T>
static void FinishPersistentRootedChain(
LinkedList<PersistentRootedBase>& list) {
LinkedList<PersistentRooted<JS::detail::RootListEntry*>>& listArg) {
auto& list = reinterpret_cast<LinkedList<PersistentRooted<T>>&>(listArg);
while (!list.isEmpty()) {
static_cast<PersistentRooted<T>*>(list.getFirst())->reset();
list.getFirst()->reset();
}
}
@ -454,13 +468,15 @@ void js::gc::GCRuntime::checkNoRuntimeRoots(AutoGCSession& session) {
#endif // DEBUG
}
JS_PUBLIC_API void JS::AddPersistentRoot(JS::RootingContext* cx, RootKind kind,
PersistentRootedBase* root) {
JSRuntime* rt = static_cast<JSContext*>(cx)->runtime();
rt->heapRoots.ref()[kind].insertBack(root);
JS_PUBLIC_API void JS::AddPersistentRoot(
JS::RootingContext* cx, RootKind kind,
PersistentRooted<JS::detail::RootListEntry*>* root) {
static_cast<JSContext*>(cx)->runtime()->heapRoots.ref()[kind].insertBack(
root);
}
JS_PUBLIC_API void JS::AddPersistentRoot(JSRuntime* rt, RootKind kind,
PersistentRootedBase* root) {
JS_PUBLIC_API void JS::AddPersistentRoot(
JSRuntime* rt, RootKind kind,
PersistentRooted<JS::detail::RootListEntry*>* root) {
rt->heapRoots.ref()[kind].insertBack(root);
}

Просмотреть файл

@ -123,7 +123,7 @@ BEGIN_TEST(testGCRootedStaticStructInternalStackStorageAugmented) {
JS::Rooted<Value> rv(cx);
CHECK_EQUAL(r1.constructor(), 1); // direct SafelyInitialized<T>
CHECK_EQUAL(r1.constructor(), 101); // copy of SafelyInitialized<T>
CHECK_EQUAL(r2.constructor(), 2); // direct MyContainer(3.4)
CHECK_EQUAL(r3.constructor(), 103); // copy of MyContainer(cx)
CHECK_EQUAL(r4.constructor(), 3); // direct MyContainer(cx)
@ -169,7 +169,7 @@ BEGIN_TEST(testGCRootedStaticStructInternalStackStorageAugmented) {
JS::PersistentRooted<MyContainer> cp3(cx, cx);
JS::PersistentRooted<MyContainer> cp4(cx, cx, cx, cx);
CHECK_EQUAL(cp1.constructor(), 1); // direct SafelyInitialized<T>
CHECK_EQUAL(cp1.constructor(), 101); // copy of SafelyInitialized<T>
CHECK_EQUAL(cp2.constructor(), 2); // direct MyContainer(double)
CHECK_EQUAL(cp3.constructor(), 3); // direct MyContainer(cx)
CHECK_EQUAL(cp4.constructor(), 4); // direct MyContainer(cx, cx, cx)

Просмотреть файл

@ -1793,7 +1793,7 @@ static MOZ_ALWAYS_INLINE void InitElemArrayOperation(JSContext* cx,
*/
template <typename T>
class ReservedRooted : public RootedOperations<T, ReservedRooted<T>> {
class ReservedRooted : public RootedBase<T, ReservedRooted<T>> {
Rooted<T>* savedRoot;
public:

Просмотреть файл

@ -564,7 +564,7 @@ inline bool JSObject::is<JSObject>() const {
template <typename Wrapper>
template <typename U>
MOZ_ALWAYS_INLINE JS::Handle<U*> js::RootedOperations<JSObject*, Wrapper>::as()
MOZ_ALWAYS_INLINE JS::Handle<U*> js::RootedBase<JSObject*, Wrapper>::as()
const {
const Wrapper& self = *static_cast<const Wrapper*>(this);
MOZ_ASSERT(self->template is<U>());
@ -574,7 +574,7 @@ MOZ_ALWAYS_INLINE JS::Handle<U*> js::RootedOperations<JSObject*, Wrapper>::as()
template <typename Wrapper>
template <class U>
MOZ_ALWAYS_INLINE JS::Handle<U*> js::HandleOperations<JSObject*, Wrapper>::as()
MOZ_ALWAYS_INLINE JS::Handle<U*> js::HandleBase<JSObject*, Wrapper>::as()
const {
const JS::Handle<JSObject*>& self =
*static_cast<const JS::Handle<JSObject*>*>(this);

Просмотреть файл

@ -432,9 +432,9 @@ struct JSRuntime {
js::GeckoProfilerRuntime& geckoProfiler() { return geckoProfiler_.ref(); }
// Heap GC roots for PersistentRooted pointers.
js::MainThreadData<
mozilla::EnumeratedArray<JS::RootKind, JS::RootKind::Limit,
mozilla::LinkedList<js::PersistentRootedBase>>>
js::MainThreadData<mozilla::EnumeratedArray<
JS::RootKind, JS::RootKind::Limit,
mozilla::LinkedList<JS::PersistentRooted<JS::detail::RootListEntry*>>>>
heapRoots;
void tracePersistentRoots(JSTracer* trc);