mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-26 19:55:39 +00:00
Bug 1417123 - Move rooting-related classes from jspubtd.h to public/RootingAPI.h r=sfink
This commit is contained in:
parent
65b7a83d09
commit
28fca947a5
@ -108,7 +108,19 @@ MOZ_ALWAYS_INLINE bool IsInsideNursery(const js::gc::Cell* cell);
|
||||
} /* namespace js */
|
||||
|
||||
namespace JS {
|
||||
struct Zone;
|
||||
|
||||
/*
|
||||
* This list enumerates the different types of conceptual stacks we have in
|
||||
* SpiderMonkey. In reality, they all share the C stack, but we allow different
|
||||
* stack limits depending on the type of code running.
|
||||
*/
|
||||
enum StackKind
|
||||
{
|
||||
StackForSystemCode, // C++, such as the GC, running on behalf of the VM.
|
||||
StackForTrustedScript, // Script running with trusted principals.
|
||||
StackForUntrustedScript, // Script running with untrusted principals.
|
||||
StackKindCount
|
||||
};
|
||||
|
||||
/*
|
||||
* Default size for the generational nursery in bytes.
|
||||
|
@ -770,6 +770,124 @@ class alignas(8) DispatchWrapper
|
||||
|
||||
namespace JS {
|
||||
|
||||
class JS_PUBLIC_API(AutoGCRooter);
|
||||
|
||||
// Our instantiations of Rooted<void*> and PersistentRooted<void*> require an
|
||||
// instantiation of MapTypeToRootKind.
|
||||
template <>
|
||||
struct MapTypeToRootKind<void*> {
|
||||
static const RootKind kind = RootKind::Traceable;
|
||||
};
|
||||
|
||||
using RootedListHeads = mozilla::EnumeratedArray<RootKind, RootKind::Limit,
|
||||
Rooted<void*>*>;
|
||||
|
||||
// Superclass of JSContext which can be used for rooting data in use by the
|
||||
// current thread but that does not provide all the functions of a JSContext.
|
||||
class RootingContext
|
||||
{
|
||||
// Stack GC roots for Rooted GC heap pointers.
|
||||
RootedListHeads stackRoots_;
|
||||
template <typename T> friend class JS::Rooted;
|
||||
|
||||
// Stack GC roots for AutoFooRooter classes.
|
||||
JS::AutoGCRooter* autoGCRooters_;
|
||||
friend class JS::AutoGCRooter;
|
||||
|
||||
public:
|
||||
RootingContext();
|
||||
|
||||
void traceStackRoots(JSTracer* trc);
|
||||
void checkNoGCRooters();
|
||||
|
||||
protected:
|
||||
// The remaining members in this class should only be accessed through
|
||||
// JSContext pointers. They are unrelated to rooting and are in place so
|
||||
// that inlined API functions can directly access the data.
|
||||
|
||||
/* The current compartment. */
|
||||
JSCompartment* compartment_;
|
||||
|
||||
/* The current zone. */
|
||||
JS::Zone* zone_;
|
||||
|
||||
public:
|
||||
/* Limit pointer for checking native stack consumption. */
|
||||
uintptr_t nativeStackLimit[StackKindCount];
|
||||
|
||||
static const RootingContext* get(const JSContext* cx) {
|
||||
return reinterpret_cast<const RootingContext*>(cx);
|
||||
}
|
||||
|
||||
static RootingContext* get(JSContext* cx) {
|
||||
return reinterpret_cast<RootingContext*>(cx);
|
||||
}
|
||||
|
||||
friend JSCompartment* js::GetContextCompartment(const JSContext* cx);
|
||||
friend JS::Zone* js::GetContextZone(const JSContext* cx);
|
||||
};
|
||||
|
||||
class JS_PUBLIC_API(AutoGCRooter)
|
||||
{
|
||||
public:
|
||||
AutoGCRooter(JSContext* cx, ptrdiff_t tag)
|
||||
: AutoGCRooter(JS::RootingContext::get(cx), tag)
|
||||
{}
|
||||
AutoGCRooter(JS::RootingContext* cx, ptrdiff_t tag)
|
||||
: down(cx->autoGCRooters_),
|
||||
tag_(tag),
|
||||
stackTop(&cx->autoGCRooters_)
|
||||
{
|
||||
MOZ_ASSERT(this != *stackTop);
|
||||
*stackTop = this;
|
||||
}
|
||||
|
||||
~AutoGCRooter() {
|
||||
MOZ_ASSERT(this == *stackTop);
|
||||
*stackTop = down;
|
||||
}
|
||||
|
||||
/* Implemented in gc/RootMarking.cpp. */
|
||||
inline void trace(JSTracer* trc);
|
||||
static void traceAll(const js::CooperatingContext& target, JSTracer* trc);
|
||||
static void traceAllWrappers(const js::CooperatingContext& target, JSTracer* trc);
|
||||
|
||||
protected:
|
||||
AutoGCRooter * const down;
|
||||
|
||||
/*
|
||||
* Discriminates actual subclass of this being used. If non-negative, the
|
||||
* subclass roots an array of values of the length stored in this field.
|
||||
* If negative, meaning is indicated by the corresponding value in the enum
|
||||
* below. Any other negative value indicates some deeper problem such as
|
||||
* memory corruption.
|
||||
*/
|
||||
ptrdiff_t tag_;
|
||||
|
||||
enum {
|
||||
VALARRAY = -2, /* js::AutoValueArray */
|
||||
PARSER = -3, /* js::frontend::Parser */
|
||||
VALVECTOR = -10, /* js::AutoValueVector */
|
||||
IDVECTOR = -11, /* js::AutoIdVector */
|
||||
OBJVECTOR = -14, /* js::AutoObjectVector */
|
||||
IONMASM = -19, /* js::jit::MacroAssembler */
|
||||
WRAPVECTOR = -20, /* js::AutoWrapperVector */
|
||||
WRAPPER = -21, /* js::AutoWrapperRooter */
|
||||
CUSTOM = -26 /* js::CustomAutoRooter */
|
||||
};
|
||||
|
||||
static ptrdiff_t GetTag(const Value& value) { return VALVECTOR; }
|
||||
static ptrdiff_t GetTag(const jsid& id) { return IDVECTOR; }
|
||||
static ptrdiff_t GetTag(JSObject* obj) { return OBJVECTOR; }
|
||||
|
||||
private:
|
||||
AutoGCRooter ** const stackTop;
|
||||
|
||||
/* No copy or assignment semantics. */
|
||||
AutoGCRooter(AutoGCRooter& ida) = delete;
|
||||
void operator=(AutoGCRooter& ida) = delete;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
/*
|
||||
@ -873,6 +991,28 @@ class MOZ_RAII Rooted : public js::RootedBase<T, Rooted<T>>
|
||||
|
||||
namespace js {
|
||||
|
||||
/*
|
||||
* Inlinable accessors for JSContext.
|
||||
*
|
||||
* - These must not be available on the more restricted superclasses of
|
||||
* JSContext, so we can't simply define them on RootingContext.
|
||||
*
|
||||
* - They're perfectly ordinary JSContext functionality, so ought to be
|
||||
* usable without resorting to jsfriendapi.h, and when JSContext is an
|
||||
* incomplete type.
|
||||
*/
|
||||
inline JSCompartment*
|
||||
GetContextCompartment(const JSContext* cx)
|
||||
{
|
||||
return JS::RootingContext::get(cx)->compartment_;
|
||||
}
|
||||
|
||||
inline JS::Zone*
|
||||
GetContextZone(const JSContext* cx)
|
||||
{
|
||||
return JS::RootingContext::get(cx)->zone_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Augment the generic Rooted<T> interface when T = JSObject* with
|
||||
* class-querying and downcasting operations.
|
||||
|
@ -15,8 +15,6 @@
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/PodOperations.h"
|
||||
|
||||
#include "jscntxt.h"
|
||||
|
||||
#include "gc/RelocationOverlay.h"
|
||||
#include "gc/Zone.h"
|
||||
#include "vm/HelperThreads.h"
|
||||
|
159
js/src/jspubtd.h
159
js/src/jspubtd.h
@ -201,167 +201,8 @@ class MOZ_STACK_CLASS JS_PUBLIC_API(AutoEnterCycleCollection)
|
||||
#endif
|
||||
};
|
||||
|
||||
class RootingContext;
|
||||
|
||||
// Our instantiations of Rooted<void*> and PersistentRooted<void*> require an
|
||||
// instantiation of MapTypeToRootKind.
|
||||
template <>
|
||||
struct MapTypeToRootKind<void*> {
|
||||
static const RootKind kind = RootKind::Traceable;
|
||||
};
|
||||
|
||||
using RootedListHeads = mozilla::EnumeratedArray<RootKind, RootKind::Limit,
|
||||
Rooted<void*>*>;
|
||||
|
||||
/*
|
||||
* This list enumerates the different types of conceptual stacks we have in
|
||||
* SpiderMonkey. In reality, they all share the C stack, but we allow different
|
||||
* stack limits depending on the type of code running.
|
||||
*/
|
||||
enum StackKind
|
||||
{
|
||||
StackForSystemCode, // C++, such as the GC, running on behalf of the VM.
|
||||
StackForTrustedScript, // Script running with trusted principals.
|
||||
StackForUntrustedScript, // Script running with untrusted principals.
|
||||
StackKindCount
|
||||
};
|
||||
|
||||
class JS_PUBLIC_API(AutoGCRooter);
|
||||
|
||||
// Superclass of JSContext which can be used for rooting data in use by the
|
||||
// current thread but that does not provide all the functions of a JSContext.
|
||||
class RootingContext
|
||||
{
|
||||
// Stack GC roots for Rooted GC heap pointers.
|
||||
RootedListHeads stackRoots_;
|
||||
template <typename T> friend class JS::Rooted;
|
||||
|
||||
// Stack GC roots for AutoFooRooter classes.
|
||||
JS::AutoGCRooter* autoGCRooters_;
|
||||
friend class JS::AutoGCRooter;
|
||||
|
||||
public:
|
||||
RootingContext();
|
||||
|
||||
void traceStackRoots(JSTracer* trc);
|
||||
void checkNoGCRooters();
|
||||
|
||||
protected:
|
||||
// The remaining members in this class should only be accessed through
|
||||
// JSContext pointers. They are unrelated to rooting and are in place so
|
||||
// that inlined API functions can directly access the data.
|
||||
|
||||
/* The current compartment. */
|
||||
JSCompartment* compartment_;
|
||||
|
||||
/* The current zone. */
|
||||
JS::Zone* zone_;
|
||||
|
||||
public:
|
||||
/* Limit pointer for checking native stack consumption. */
|
||||
uintptr_t nativeStackLimit[StackKindCount];
|
||||
|
||||
static const RootingContext* get(const JSContext* cx) {
|
||||
return reinterpret_cast<const RootingContext*>(cx);
|
||||
}
|
||||
|
||||
static RootingContext* get(JSContext* cx) {
|
||||
return reinterpret_cast<RootingContext*>(cx);
|
||||
}
|
||||
|
||||
friend JSCompartment* js::GetContextCompartment(const JSContext* cx);
|
||||
friend JS::Zone* js::GetContextZone(const JSContext* cx);
|
||||
};
|
||||
|
||||
class JS_PUBLIC_API(AutoGCRooter)
|
||||
{
|
||||
public:
|
||||
AutoGCRooter(JSContext* cx, ptrdiff_t tag)
|
||||
: AutoGCRooter(JS::RootingContext::get(cx), tag)
|
||||
{}
|
||||
AutoGCRooter(JS::RootingContext* cx, ptrdiff_t tag)
|
||||
: down(cx->autoGCRooters_),
|
||||
tag_(tag),
|
||||
stackTop(&cx->autoGCRooters_)
|
||||
{
|
||||
MOZ_ASSERT(this != *stackTop);
|
||||
*stackTop = this;
|
||||
}
|
||||
|
||||
~AutoGCRooter() {
|
||||
MOZ_ASSERT(this == *stackTop);
|
||||
*stackTop = down;
|
||||
}
|
||||
|
||||
/* Implemented in gc/RootMarking.cpp. */
|
||||
inline void trace(JSTracer* trc);
|
||||
static void traceAll(const js::CooperatingContext& target, JSTracer* trc);
|
||||
static void traceAllWrappers(const js::CooperatingContext& target, JSTracer* trc);
|
||||
|
||||
protected:
|
||||
AutoGCRooter * const down;
|
||||
|
||||
/*
|
||||
* Discriminates actual subclass of this being used. If non-negative, the
|
||||
* subclass roots an array of values of the length stored in this field.
|
||||
* If negative, meaning is indicated by the corresponding value in the enum
|
||||
* below. Any other negative value indicates some deeper problem such as
|
||||
* memory corruption.
|
||||
*/
|
||||
ptrdiff_t tag_;
|
||||
|
||||
enum {
|
||||
VALARRAY = -2, /* js::AutoValueArray */
|
||||
PARSER = -3, /* js::frontend::Parser */
|
||||
VALVECTOR = -10, /* js::AutoValueVector */
|
||||
IDVECTOR = -11, /* js::AutoIdVector */
|
||||
OBJVECTOR = -14, /* js::AutoObjectVector */
|
||||
IONMASM = -19, /* js::jit::MacroAssembler */
|
||||
WRAPVECTOR = -20, /* js::AutoWrapperVector */
|
||||
WRAPPER = -21, /* js::AutoWrapperRooter */
|
||||
CUSTOM = -26 /* js::CustomAutoRooter */
|
||||
};
|
||||
|
||||
static ptrdiff_t GetTag(const Value& value) { return VALVECTOR; }
|
||||
static ptrdiff_t GetTag(const jsid& id) { return IDVECTOR; }
|
||||
static ptrdiff_t GetTag(JSObject* obj) { return OBJVECTOR; }
|
||||
|
||||
private:
|
||||
AutoGCRooter ** const stackTop;
|
||||
|
||||
/* No copy or assignment semantics. */
|
||||
AutoGCRooter(AutoGCRooter& ida) = delete;
|
||||
void operator=(AutoGCRooter& ida) = delete;
|
||||
};
|
||||
|
||||
} /* namespace JS */
|
||||
|
||||
namespace js {
|
||||
|
||||
/*
|
||||
* Inlinable accessors for JSContext.
|
||||
*
|
||||
* - These must not be available on the more restricted superclasses of
|
||||
* JSContext, so we can't simply define them on RootingContext.
|
||||
*
|
||||
* - They're perfectly ordinary JSContext functionality, so ought to be
|
||||
* usable without resorting to jsfriendapi.h, and when JSContext is an
|
||||
* incomplete type.
|
||||
*/
|
||||
inline JSCompartment*
|
||||
GetContextCompartment(const JSContext* cx)
|
||||
{
|
||||
return JS::RootingContext::get(cx)->compartment_;
|
||||
}
|
||||
|
||||
inline JS::Zone*
|
||||
GetContextZone(const JSContext* cx)
|
||||
{
|
||||
return JS::RootingContext::get(cx)->zone_;
|
||||
}
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
MOZ_BEGIN_EXTERN_C
|
||||
|
||||
// Defined in NSPR prio.h.
|
||||
|
Loading…
Reference in New Issue
Block a user