Bug 1634435 - Replace AutoValueArray and AutoArrayRooter implementations with Rooted<> r=jandem

We can make these kinds use the existing Rooted infrastructure.

Differential Revision: https://phabricator.services.mozilla.com/D73293
This commit is contained in:
Jon Coppeard 2020-05-04 16:49:59 +00:00
parent 2a62f49c9a
commit 7699bb2b02
5 changed files with 85 additions and 65 deletions

View File

@ -918,8 +918,6 @@ namespace JS {
class JS_PUBLIC_API AutoGCRooter;
enum class AutoGCRooterKind : uint8_t {
Array, /* js::AutoArrayRooter */
ValueArray, /* js::AutoValueArray */
Parser, /* js::frontend::Parser */
BinASTParser, /* js::frontend::BinASTParser; only used if built with
* JS_BUILD_BINAST support */

View File

@ -20,39 +20,30 @@
#include "js/RootingAPI.h" // JS::AutoGCRooter, JS::{,Mutable}Handle
#include "js/Value.h" // JS::Value
namespace js {
JS_PUBLIC_API void TraceValueArray(JSTracer* trc, size_t length,
JS::Value* elements);
} // namespace js
namespace JS {
/* A fixed-size array of values, for use inside Rooted<>. */
template <size_t N>
struct ValueArray {
Value elements[N];
void trace(JSTracer* trc) { js::TraceValueArray(trc, N, elements); }
};
/** AutoValueArray roots an internal fixed-size array of Values. */
template <size_t N>
class MOZ_RAII AutoValueArray : public AutoGCRooter {
const size_t length_;
Value elements_[N];
using AutoValueArray = Rooted<ValueArray<N>>;
public:
explicit AutoValueArray(JSContext* cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
: AutoGCRooter(cx, AutoGCRooter::Kind::ValueArray), length_(N) {
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
}
unsigned length() const { return length_; }
const Value* begin() const { return elements_; }
Value* begin() { return elements_; }
Handle<Value> operator[](unsigned i) const {
MOZ_ASSERT(i < N);
return Handle<Value>::fromMarkedLocation(&elements_[i]);
}
MutableHandle<Value> operator[](unsigned i) {
MOZ_ASSERT(i < N);
return MutableHandleValue::fromMarkedLocation(&elements_[i]);
}
void trace(JSTracer* trc);
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
};
/** A handle to an array of rooted values. */
/**
* A generic handle to an array of rooted values.
*
* The rooted array refernced can take several forms, therfore this is not the
* same as Handle<js::ValueArray>.
*/
class HandleValueArray {
const size_t length_;
const Value* const elements_;
@ -100,4 +91,41 @@ class HandleValueArray {
} // namespace JS
namespace js {
template <size_t N, typename Container>
class WrappedPtrOperations<JS::ValueArray<N>, Container> {
const JS::ValueArray<N>& array() const {
return static_cast<const Container*>(this)->get();
}
public:
size_t length() const { return N; }
const JS::Value* begin() const { return array().elements; }
JS::HandleValue operator[](size_t i) const {
MOZ_ASSERT(i < N);
return JS::HandleValue::fromMarkedLocation(&array().elements[i]);
}
};
template <size_t N, typename Container>
class MutableWrappedPtrOperations<JS::ValueArray<N>, Container>
: public WrappedPtrOperations<JS::ValueArray<N>, Container> {
using Base = WrappedPtrOperations<JS::ValueArray<N>, Container>;
JS::ValueArray<N>& array() { return static_cast<Container*>(this)->get(); }
public:
using Base::begin;
JS::Value* begin() { return array().elements; }
using Base::operator[];
JS::MutableHandleValue operator[](size_t i) {
MOZ_ASSERT(i < N);
return JS::MutableHandleValue::fromMarkedLocation(&array().elements[i]);
}
};
} // namespace js
#endif // js_ValueArray_h

View File

@ -156,6 +156,11 @@ void JSRuntime::finishPersistentRoots() {
// See the comment on RootLists::~RootLists for details.
}
JS_PUBLIC_API void js::TraceValueArray(JSTracer* trc, size_t length,
Value* elements) {
TraceRootRange(trc, length, elements, "JS::AutoValueArray");
}
void AutoGCRooter::trace(JSTracer* trc) {
switch (kind_) {
case Kind::Parser:
@ -168,15 +173,6 @@ void AutoGCRooter::trace(JSTracer* trc) {
break;
#endif // defined(JS_BUILD_BINAST)
case Kind::ValueArray: {
/*
* We don't know the template size parameter, but we can safely treat it
* as an AutoValueArray<1> because the length is stored separately.
*/
static_cast<AutoValueArray<1>*>(this)->trace(trc);
break;
}
case Kind::Wrapper:
static_cast<AutoWrapperRooter*>(this)->trace(trc);
break;
@ -189,22 +185,12 @@ void AutoGCRooter::trace(JSTracer* trc) {
static_cast<JS::CustomAutoRooter*>(this)->trace(trc);
break;
case Kind::Array: {
static_cast<AutoArrayRooter*>(this)->trace(trc);
break;
}
default:
MOZ_CRASH("Bad AutoGCRooter::Kind");
break;
}
}
template <size_t N>
void JS::AutoValueArray<N>::trace(JSTracer* trc) {
TraceRootRange(trc, length(), begin(), "js::AutoValueArray");
}
void AutoWrapperRooter::trace(JSTracer* trc) {
/*
* We need to use TraceManuallyBarrieredEdge here because we trace wrapper
@ -226,12 +212,6 @@ void AutoWrapperVector::trace(JSTracer* trc) {
}
}
void AutoArrayRooter::trace(JSTracer* trc) {
if (Value* vp = begin()) {
TraceRootRange(trc, length(), vp, "js::AutoArrayRooter");
}
}
void JS::RootingContext::traceAllGCRooters(JSTracer* trc) {
for (AutoGCRooter* list : autoGCRooters_) {
traceGCRooterList(trc, list);

View File

@ -1183,6 +1183,12 @@ AutoKeepAtoms::AutoKeepAtoms(
AutoKeepAtoms::~AutoKeepAtoms() { cx->zone()->releaseAtoms(); };
void ExternalValueArray::trace(JSTracer* trc) {
if (Value* vp = begin()) {
TraceRootRange(trc, length(), vp, "js::ExternalValueArray");
}
}
#ifdef DEBUG
AutoUnsafeCallWithABI::AutoUnsafeCallWithABI(UnsafeABIStrictness strictness)
: cx_(TlsContext.get()),

View File

@ -1098,19 +1098,15 @@ namespace js {
/************************************************************************/
/* AutoArrayRooter roots an external array of Values. */
class MOZ_RAII AutoArrayRooter : public JS::AutoGCRooter {
/*
* Encapsulates an external array of values and adds a trace method, for use in
* Rooted.
*/
class MOZ_STACK_CLASS ExternalValueArray {
public:
AutoArrayRooter(JSContext* cx, size_t len,
Value* vec MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
: JS::AutoGCRooter(cx, JS::AutoGCRooter::Kind::Array),
array_(vec),
length_(len) {
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
}
ExternalValueArray(size_t len, Value* vec) : array_(vec), length_(len) {}
Value* begin() { return array_; }
size_t length() { return length_; }
void trace(JSTracer* trc);
@ -1118,6 +1114,18 @@ class MOZ_RAII AutoArrayRooter : public JS::AutoGCRooter {
private:
Value* array_;
size_t length_;
};
/* AutoArrayRooter roots an external array of Values. */
class MOZ_RAII AutoArrayRooter : public JS::Rooted<ExternalValueArray> {
public:
AutoArrayRooter(JSContext* cx, size_t len,
Value* vec MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
: JS::Rooted<ExternalValueArray>(cx, ExternalValueArray(len, vec)) {
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
}
private:
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
};