Bug 1858921 - Part 5: Remove use of JS::RootingContext in the allocator r=sfink

With the preceding changes we no longer need to use JS::RootingContext but can
replace this with JSContext instead. This we previously necessary due to this
header getting included as a dependency of JSContext.h.

Differential Revision: https://phabricator.services.mozilla.com/D190930
This commit is contained in:
Jon Coppeard 2023-10-23 15:10:25 +00:00
parent 36aa9d6701
commit 792f5f051f
5 changed files with 53 additions and 69 deletions

View File

@ -1020,8 +1020,6 @@ class RootingContext {
js::GeckoProfilerThread& geckoProfiler() { return geckoProfiler_; }
JS::Zone* zoneUnchecked() const { return zone_; }
js::Nursery& nursery() const {
MOZ_ASSERT(nursery_);
return *nursery_;

View File

@ -26,17 +26,17 @@ namespace js {
namespace gc {
template <typename T, AllowGC allowGC, typename... Args>
T* CellAllocator::NewCell(JS::RootingContext* rcx, Args&&... args) {
T* CellAllocator::NewCell(JSContext* cx, Args&&... args) {
static_assert(std::is_base_of_v<gc::Cell, T>);
// Objects. See the valid parameter list in NewObject, above.
if constexpr (std::is_base_of_v<JSObject, T>) {
return NewObject<T, allowGC>(rcx, std::forward<Args>(args)...);
return NewObject<T, allowGC>(cx, std::forward<Args>(args)...);
}
// BigInt
else if constexpr (std::is_base_of_v<JS::BigInt, T>) {
return NewBigInt<T, allowGC>(rcx, std::forward<Args>(args)...);
return NewBigInt<T, allowGC>(cx, std::forward<Args>(args)...);
}
// "Normal" strings (all of which can be nursery allocated). Atoms and
@ -46,25 +46,24 @@ T* CellAllocator::NewCell(JS::RootingContext* rcx, Args&&... args) {
else if constexpr (std::is_base_of_v<JSString, T> &&
!std::is_base_of_v<JSAtom, T> &&
!std::is_base_of_v<JSExternalString, T>) {
return NewString<T, allowGC>(rcx, std::forward<Args>(args)...);
return NewString<T, allowGC>(cx, std::forward<Args>(args)...);
}
else {
// Allocate a new tenured GC thing that's not nursery-allocatable. Use
// cx->newCell<T>(...), where the parameters are forwarded to the type's
// constructor.
return NewTenuredCell<T, allowGC>(rcx, std::forward<Args>(args)...);
return NewTenuredCell<T, allowGC>(cx, std::forward<Args>(args)...);
}
}
template <typename T, AllowGC allowGC, typename... Args>
/* static */
T* CellAllocator::NewString(JS::RootingContext* rcx, gc::Heap heap,
Args&&... args) {
T* CellAllocator::NewString(JSContext* cx, gc::Heap heap, Args&&... args) {
static_assert(std::is_base_of_v<JSString, T>);
gc::AllocKind kind = gc::MapTypeToAllocKind<T>::kind;
void* ptr = AllocNurseryOrTenuredCell<JS::TraceKind::String, allowGC>(
rcx, kind, sizeof(T), heap, nullptr);
cx, kind, sizeof(T), heap, nullptr);
if (MOZ_UNLIKELY(!ptr)) {
return nullptr;
}
@ -73,9 +72,9 @@ T* CellAllocator::NewString(JS::RootingContext* rcx, gc::Heap heap,
template <typename T, AllowGC allowGC>
/* static */
T* CellAllocator::NewBigInt(JS::RootingContext* rcx, Heap heap) {
T* CellAllocator::NewBigInt(JSContext* cx, Heap heap) {
void* ptr = AllocNurseryOrTenuredCell<JS::TraceKind::BigInt, allowGC>(
rcx, gc::AllocKind::BIGINT, sizeof(T), heap, nullptr);
cx, gc::AllocKind::BIGINT, sizeof(T), heap, nullptr);
if (MOZ_UNLIKELY(!ptr)) {
return nullptr;
}
@ -84,16 +83,15 @@ T* CellAllocator::NewBigInt(JS::RootingContext* rcx, Heap heap) {
template <typename T, AllowGC allowGC>
/* static */
T* CellAllocator::NewObject(JS::RootingContext* rcx, gc::AllocKind kind,
gc::Heap heap, const JSClass* clasp,
gc::AllocSite* site) {
T* CellAllocator::NewObject(JSContext* cx, gc::AllocKind kind, gc::Heap heap,
const JSClass* clasp, gc::AllocSite* site) {
MOZ_ASSERT(IsObjectAllocKind(kind));
MOZ_ASSERT_IF(heap != gc::Heap::Tenured && clasp->hasFinalize() &&
!clasp->isProxyObject(),
CanNurseryAllocateFinalizedClass(clasp));
size_t thingSize = JSObject::thingSize(kind);
void* cell = AllocNurseryOrTenuredCell<JS::TraceKind::Object, allowGC>(
rcx, kind, thingSize, heap, site);
cx, kind, thingSize, heap, site);
if (MOZ_UNLIKELY(!cell)) {
return nullptr;
}
@ -102,7 +100,7 @@ T* CellAllocator::NewObject(JS::RootingContext* rcx, gc::AllocKind kind,
template <JS::TraceKind traceKind, AllowGC allowGC>
/* static */
void* CellAllocator::AllocNurseryOrTenuredCell(JS::RootingContext* rcx,
void* CellAllocator::AllocNurseryOrTenuredCell(JSContext* cx,
gc::AllocKind allocKind,
size_t thingSize, gc::Heap heap,
AllocSite* site) {
@ -112,27 +110,27 @@ void* CellAllocator::AllocNurseryOrTenuredCell(JS::RootingContext* rcx,
MOZ_ASSERT_IF(site && site->initialHeap() == Heap::Tenured,
heap == Heap::Tenured);
if (!PreAllocChecks<allowGC>(rcx, allocKind)) {
if (!PreAllocChecks<allowGC>(cx, allocKind)) {
return nullptr;
}
JS::Zone* zone = rcx->zoneUnchecked();
JS::Zone* zone = cx->zone();
gc::Heap minHeapToTenure = CheckedHeap(zone->minHeapToTenure(traceKind));
if (CheckedHeap(heap) < minHeapToTenure) {
if (!site) {
site = zone->unknownAllocSite(traceKind);
}
void* ptr = rcx->nursery().tryAllocateCell(site, thingSize, traceKind);
void* ptr = cx->nursery().tryAllocateCell(site, thingSize, traceKind);
if (MOZ_LIKELY(ptr)) {
return ptr;
}
return RetryNurseryAlloc<allowGC>(rcx, traceKind, allocKind, thingSize,
return RetryNurseryAlloc<allowGC>(cx, traceKind, allocKind, thingSize,
site);
}
return TryNewTenuredCell<allowGC>(rcx, allocKind, thingSize);
return TryNewTenuredCell<allowGC>(cx, allocKind, thingSize);
}
/* static */
@ -148,9 +146,9 @@ MOZ_ALWAYS_INLINE gc::Heap CellAllocator::CheckedHeap(gc::Heap heap) {
template <typename T, AllowGC allowGC, typename... Args>
/* static */
T* CellAllocator::NewTenuredCell(JS::RootingContext* rcx, Args&&... args) {
T* CellAllocator::NewTenuredCell(JSContext* cx, Args&&... args) {
gc::AllocKind kind = gc::MapTypeToAllocKind<T>::kind;
void* cell = AllocTenuredCell<allowGC>(rcx, kind, sizeof(T));
void* cell = AllocTenuredCell<allowGC>(cx, kind, sizeof(T));
if (MOZ_UNLIKELY(!cell)) {
return nullptr;
}

View File

@ -58,7 +58,7 @@ void Zone::setNurseryAllocFlags(bool allocObjects, bool allocStrings,
#define INSTANTIATE_ALLOC_NURSERY_CELL(traceKind, allowGc) \
template void* \
gc::CellAllocator::AllocNurseryOrTenuredCell<traceKind, allowGc>( \
JS::RootingContext*, AllocKind, size_t, gc::Heap, AllocSite*);
JSContext*, AllocKind, size_t, gc::Heap, AllocSite*);
INSTANTIATE_ALLOC_NURSERY_CELL(JS::TraceKind::Object, NoGC)
INSTANTIATE_ALLOC_NURSERY_CELL(JS::TraceKind::Object, CanGC)
INSTANTIATE_ALLOC_NURSERY_CELL(JS::TraceKind::String, NoGC)
@ -71,12 +71,11 @@ INSTANTIATE_ALLOC_NURSERY_CELL(JS::TraceKind::BigInt, CanGC)
// the nursery or there is an OOM, this method will return nullptr.
template <AllowGC allowGC>
/* static */
MOZ_NEVER_INLINE void* CellAllocator::RetryNurseryAlloc(JS::RootingContext* rcx,
MOZ_NEVER_INLINE void* CellAllocator::RetryNurseryAlloc(JSContext* cx,
JS::TraceKind traceKind,
AllocKind allocKind,
size_t thingSize,
AllocSite* site) {
auto* cx = JSContext::from(rcx);
MOZ_ASSERT(cx->isNurseryAllocAllowed());
MOZ_ASSERT(cx->zone() == site->zone());
MOZ_ASSERT(!cx->zone()->isAtomsZone());
@ -115,40 +114,38 @@ MOZ_NEVER_INLINE void* CellAllocator::RetryNurseryAlloc(JS::RootingContext* rcx,
return TryNewTenuredCell<allowGC>(cx, allocKind, thingSize);
}
template void* CellAllocator::RetryNurseryAlloc<NoGC>(JS::RootingContext* rcx,
template void* CellAllocator::RetryNurseryAlloc<NoGC>(JSContext* cx,
JS::TraceKind traceKind,
AllocKind allocKind,
size_t thingSize,
AllocSite* site);
template void* CellAllocator::RetryNurseryAlloc<CanGC>(JS::RootingContext* rcx,
template void* CellAllocator::RetryNurseryAlloc<CanGC>(JSContext* cx,
JS::TraceKind traceKind,
AllocKind allocKind,
size_t thingSize,
AllocSite* site);
template <AllowGC allowGC /* = CanGC */>
void* gc::CellAllocator::AllocTenuredCell(JS::RootingContext* rcx,
gc::AllocKind kind, size_t size) {
void* gc::CellAllocator::AllocTenuredCell(JSContext* cx, gc::AllocKind kind,
size_t size) {
MOZ_ASSERT(!IsNurseryAllocable(kind));
MOZ_ASSERT(size == Arena::thingSize(kind));
if (!PreAllocChecks<allowGC>(rcx, kind)) {
if (!PreAllocChecks<allowGC>(cx, kind)) {
return nullptr;
}
return TryNewTenuredCell<allowGC>(rcx, kind, size);
return TryNewTenuredCell<allowGC>(cx, kind, size);
}
template void* gc::CellAllocator::AllocTenuredCell<NoGC>(JS::RootingContext*,
AllocKind, size_t);
template void* gc::CellAllocator::AllocTenuredCell<CanGC>(JS::RootingContext*,
AllocKind, size_t);
template void* gc::CellAllocator::AllocTenuredCell<NoGC>(JSContext*, AllocKind,
size_t);
template void* gc::CellAllocator::AllocTenuredCell<CanGC>(JSContext*, AllocKind,
size_t);
template <AllowGC allowGC>
/* static */
void* CellAllocator::TryNewTenuredCell(JS::RootingContext* rcx, AllocKind kind,
void* CellAllocator::TryNewTenuredCell(JSContext* cx, AllocKind kind,
size_t thingSize) {
auto* cx = JSContext::from(rcx);
if constexpr (allowGC) {
// Invoking the interrupt callback can fail and we can't usefully
// handle that here. Just check in case we need to collect instead.
@ -193,10 +190,10 @@ void* CellAllocator::TryNewTenuredCell(JS::RootingContext* rcx, AllocKind kind,
return ptr;
}
template void* CellAllocator::TryNewTenuredCell<NoGC>(JS::RootingContext* rcx,
template void* CellAllocator::TryNewTenuredCell<NoGC>(JSContext* cx,
AllocKind kind,
size_t thingSize);
template void* CellAllocator::TryNewTenuredCell<CanGC>(JS::RootingContext* rcx,
template void* CellAllocator::TryNewTenuredCell<CanGC>(JSContext* cx,
AllocKind kind,
size_t thingSize);
@ -242,9 +239,7 @@ static inline void CheckAllocZone(Zone* zone, AllocKind kind) {
//
// This is a no-op in release builds.
template <AllowGC allowGC>
bool CellAllocator::PreAllocChecks(JS::RootingContext* rcx, AllocKind kind) {
auto* cx = JSContext::from(rcx);
bool CellAllocator::PreAllocChecks(JSContext* cx, AllocKind kind) {
MOZ_ASSERT(CurrentThreadCanAccessRuntime(cx->runtime()));
CheckAllocZone(cx->zone(), kind);
@ -275,9 +270,9 @@ bool CellAllocator::PreAllocChecks(JS::RootingContext* rcx, AllocKind kind) {
return true;
}
template bool CellAllocator::PreAllocChecks<NoGC>(JS::RootingContext* cx,
template bool CellAllocator::PreAllocChecks<NoGC>(JSContext* cx,
AllocKind kind);
template bool CellAllocator::PreAllocChecks<CanGC>(JS::RootingContext* cx,
template bool CellAllocator::PreAllocChecks<CanGC>(JSContext* cx,
AllocKind kind);
#endif // DEBUG || JS_GC_ZEAL || JS_OOM_BREAKPOINT

View File

@ -15,10 +15,6 @@
#include "gc/GCEnum.h"
#include "js/TypeDecls.h"
namespace JS {
class RootingContext;
} // namespace JS
namespace js {
namespace gc {
@ -53,23 +49,23 @@ class CellAllocator {
// ensure that GC tracing never sees junk values stored in the partially
// initialized thing.
template <typename T, js::AllowGC allowGC = CanGC, typename... Args>
static inline T* NewCell(JS::RootingContext* rcx, Args&&... args);
static inline T* NewCell(JSContext* cx, Args&&... args);
private:
template <AllowGC allowGC>
static void* RetryNurseryAlloc(JS::RootingContext* rcx,
JS::TraceKind traceKind, AllocKind allocKind,
size_t thingSize, AllocSite* site);
static void* RetryNurseryAlloc(JSContext* cx, JS::TraceKind traceKind,
AllocKind allocKind, size_t thingSize,
AllocSite* site);
template <AllowGC allowGC>
static void* TryNewTenuredCell(JS::RootingContext* rcx, AllocKind kind,
static void* TryNewTenuredCell(JSContext* cx, AllocKind kind,
size_t thingSize);
#if defined(DEBUG) || defined(JS_GC_ZEAL) || defined(JS_OOM_BREAKPOINT)
template <AllowGC allowGC>
static bool PreAllocChecks(JS::RootingContext* rcx, AllocKind kind);
static bool PreAllocChecks(JSContext* cx, AllocKind kind);
#else
template <AllowGC allowGC>
static bool PreAllocChecks(JS::RootingContext* rcx, AllocKind kind) {
static bool PreAllocChecks(JSContext* cx, AllocKind kind) {
return true;
}
#endif
@ -83,15 +79,13 @@ class CellAllocator {
// Allocate a cell in the nursery, unless |heap| is Heap::Tenured or nursery
// allocation is disabled for |traceKind| in the current zone.
template <JS::TraceKind traceKind, AllowGC allowGC = CanGC>
static void* AllocNurseryOrTenuredCell(JS::RootingContext* rcx,
gc::AllocKind allocKind,
static void* AllocNurseryOrTenuredCell(JSContext* cx, gc::AllocKind allocKind,
size_t thingSize, gc::Heap heap,
AllocSite* site);
// Allocate a cell in the tenured heap.
template <AllowGC allowGC = CanGC>
static void* AllocTenuredCell(JS::RootingContext* rcx, gc::AllocKind kind,
size_t size);
static void* AllocTenuredCell(JSContext* cx, gc::AllocKind kind, size_t size);
// Allocate a string. Use cx->newCell<T>([heap]).
//
@ -99,19 +93,18 @@ class CellAllocator {
// type. Non-nursery-allocatable strings will go through the fallback
// tenured-only allocation path.
template <typename T, AllowGC allowGC = CanGC, typename... Args>
static T* NewString(JS::RootingContext* rcx, gc::Heap heap, Args&&... args);
static T* NewString(JSContext* cx, gc::Heap heap, Args&&... args);
template <typename T, AllowGC allowGC /* = CanGC */>
static T* NewBigInt(JS::RootingContext* rcx, Heap heap);
static T* NewBigInt(JSContext* cx, Heap heap);
template <typename T, AllowGC allowGC = CanGC>
static T* NewObject(JS::RootingContext* rcx, gc::AllocKind kind,
gc::Heap heap, const JSClass* clasp,
gc::AllocSite* site = nullptr);
static T* NewObject(JSContext* cx, gc::AllocKind kind, gc::Heap heap,
const JSClass* clasp, gc::AllocSite* site = nullptr);
// Allocate all other kinds of GC thing.
template <typename T, AllowGC allowGC = CanGC, typename... Args>
static T* NewTenuredCell(JS::RootingContext* rcx, Args&&... args);
static T* NewTenuredCell(JSContext* cx, Args&&... args);
};
} // namespace gc

View File

@ -292,7 +292,7 @@ struct JS_PUBLIC_API JSContext : public JS::RootingContext,
JS::Zone* zone() const {
MOZ_ASSERT_IF(!realm() && zone_, inAtomsZone());
MOZ_ASSERT_IF(realm(), js::GetRealmZone(realm()) == zone_);
return zoneUnchecked();
return zone_;
}
// For JIT use.