From faadaa5160e9bf89730543a315e280d827f415ae Mon Sep 17 00:00:00 2001 From: Steve Fink Date: Thu, 3 Dec 2020 23:05:29 +0000 Subject: [PATCH] Bug 1679736 - Prohibit Rooted r=jonco Differential Revision: https://phabricator.services.mozilla.com/D98230 --- js/public/RootingAPI.h | 50 ++++++++++++++++++++++++--------------- js/rust/build.rs | 1 + js/rust/src/rust.rs | 2 +- js/src/gc/RootMarking.cpp | 21 +++++++++------- js/src/vm/Runtime.h | 2 +- 5 files changed, 46 insertions(+), 30 deletions(-) diff --git a/js/public/RootingAPI.h b/js/public/RootingAPI.h index c283fd698426..fe08687cfdb4 100644 --- a/js/public/RootingAPI.h +++ b/js/public/RootingAPI.h @@ -925,15 +925,22 @@ enum class AutoGCRooterKind : uint8_t { Limit }; -// Our instantiations of Rooted and PersistentRooted require an -// instantiation of MapTypeToRootKind. +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` is a compile error. +struct RootListEntry; +} // namespace detail + template <> -struct MapTypeToRootKind { +struct MapTypeToRootKind { static const RootKind kind = RootKind::Traceable; }; using RootedListHeads = - mozilla::EnumeratedArray*>; + mozilla::EnumeratedArray*>; using AutoRooterListHeads = mozilla::EnumeratedArray> { inline void registerWithRootLists(RootedListHeads& roots) { this->stack = &roots[JS::MapTypeToRootKind::kind]; this->prev = *stack; - *stack = reinterpret_cast*>(this); + *stack = reinterpret_cast*>(this); } inline RootedListHeads& rootLists(RootingContext* cx) { @@ -1123,7 +1130,8 @@ class MOZ_RAII Rooted : public js::RootedBase> { } ~Rooted() { - MOZ_ASSERT(*stack == reinterpret_cast*>(this)); + MOZ_ASSERT(*stack == + reinterpret_cast*>(this)); *stack = prev; } @@ -1155,12 +1163,12 @@ class MOZ_RAII Rooted : public js::RootedBase> { private: /* - * These need to be templated on void* to avoid aliasing issues between, for - * example, Rooted and Rooted, which use the same - * stack head pointer for different classes. + * These need to be templated on RootListEntry* to avoid aliasing issues + * between, for example, Rooted and Rooted, which use + * the same stack head pointer for different classes. */ - Rooted** stack; - Rooted* prev; + Rooted** stack; + Rooted* prev; Ptr ptr; @@ -1289,11 +1297,13 @@ inline MutableHandle::MutableHandle(PersistentRooted* root) { ptr = root->address(); } -JS_PUBLIC_API void AddPersistentRoot(RootingContext* cx, RootKind kind, - PersistentRooted* root); +JS_PUBLIC_API void AddPersistentRoot( + RootingContext* cx, RootKind kind, + PersistentRooted* root); -JS_PUBLIC_API void AddPersistentRoot(JSRuntime* rt, RootKind kind, - PersistentRooted* root); +JS_PUBLIC_API void AddPersistentRoot( + JSRuntime* rt, RootKind kind, + PersistentRooted* root); /** * A copyable, assignable global GC root type with arbitrary lifetime, an @@ -1342,15 +1352,17 @@ class PersistentRooted void registerWithRootLists(RootingContext* cx) { MOZ_ASSERT(!initialized()); JS::RootKind kind = JS::MapTypeToRootKind::kind; - AddPersistentRoot(cx, kind, - reinterpret_cast*>(this)); + AddPersistentRoot( + cx, kind, + reinterpret_cast*>(this)); } void registerWithRootLists(JSRuntime* rt) { MOZ_ASSERT(!initialized()); JS::RootKind kind = JS::MapTypeToRootKind::kind; - AddPersistentRoot(rt, kind, - reinterpret_cast*>(this)); + AddPersistentRoot( + rt, kind, + reinterpret_cast*>(this)); } public: diff --git a/js/rust/build.rs b/js/rust/build.rs index 7ea685dcdd19..6d16065b7d6e 100644 --- a/js/rust/build.rs +++ b/js/rust/build.rs @@ -215,6 +215,7 @@ const WHITELIST_TYPES: &'static [&'static str] = &[ "JS::Compartment", "JS::Latin1Char", "JS::detail::RootedPtr", + "JS::detail::RootListEntry", "JS::MutableHandle", "JS::MutableHandleObject", "JS::MutableHandleValue", diff --git a/js/rust/src/rust.rs b/js/rust/src/rust.rs index 269c8c451722..c92554f91e61 100644 --- a/js/rust/src/rust.rs +++ b/js/rust/src/rust.rs @@ -366,7 +366,7 @@ impl JS::Rooted { unsafe fn get_root_stack( cx: *mut JSContext, - ) -> *mut *mut JS::Rooted<*mut ::std::os::raw::c_void> + ) -> *mut *mut JS::Rooted<*mut JS::detail::RootListEntry> where T: RootKind, { diff --git a/js/src/gc/RootMarking.cpp b/js/src/gc/RootMarking.cpp index 4e10c3ef5864..9403ec4c8240 100644 --- a/js/src/gc/RootMarking.cpp +++ b/js/src/gc/RootMarking.cpp @@ -75,9 +75,9 @@ inline void JS::PersistentRooted::trace(JSTracer* trc, const char* name) { } template -static inline void TraceExactStackRootList(JSTracer* trc, - JS::Rooted* listHead, - const char* name) { +static inline void TraceExactStackRootList( + JSTracer* trc, JS::Rooted* listHead, + const char* name) { auto* typedList = reinterpret_cast*>(listHead); for (JS::Rooted* root = typedList; root; root = root->previous()) { root->trace(trc, name); @@ -112,7 +112,8 @@ static void TraceExactStackRoots(JSContext* cx, JSTracer* trc) { template static inline void TracePersistentRootedList( - JSTracer* trc, LinkedList>& list, + JSTracer* trc, + LinkedList>& list, const char* name) { auto& typedList = reinterpret_cast>&>(list); for (PersistentRooted* root : typedList) { @@ -144,7 +145,7 @@ static void TracePersistentRooted(JSRuntime* rt, JSTracer* trc) { template static void FinishPersistentRootedChain( - LinkedList>& listArg) { + LinkedList>& listArg) { auto& list = reinterpret_cast>&>(listArg); while (!list.isEmpty()) { list.getFirst()->reset(); @@ -634,13 +635,15 @@ void GCRuntime::resetBufferedGrayRoots() { } } -JS_PUBLIC_API void JS::AddPersistentRoot(JS::RootingContext* cx, RootKind kind, - PersistentRooted* root) { +JS_PUBLIC_API void JS::AddPersistentRoot( + JS::RootingContext* cx, RootKind kind, + PersistentRooted* root) { static_cast(cx)->runtime()->heapRoots.ref()[kind].insertBack( root); } -JS_PUBLIC_API void JS::AddPersistentRoot(JSRuntime* rt, RootKind kind, - PersistentRooted* root) { +JS_PUBLIC_API void JS::AddPersistentRoot( + JSRuntime* rt, RootKind kind, + PersistentRooted* root) { rt->heapRoots.ref()[kind].insertBack(root); } diff --git a/js/src/vm/Runtime.h b/js/src/vm/Runtime.h index b8d280ee83d9..60cd256645cd 100644 --- a/js/src/vm/Runtime.h +++ b/js/src/vm/Runtime.h @@ -394,7 +394,7 @@ struct JSRuntime { // Heap GC roots for PersistentRooted pointers. js::MainThreadData>>> + mozilla::LinkedList>>> heapRoots; void tracePersistentRoots(JSTracer* trc);