зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1268805 - Implement PrivateGCThingValue. (r=terrence)
This commit is contained in:
Родитель
f820965675
Коммит
e841ff15ad
|
@ -394,6 +394,9 @@ GCThingIsMarkedGray(GCCellPtr thing)
|
|||
return js::gc::detail::CellIsMarkedGray(thing.asCell());
|
||||
}
|
||||
|
||||
extern JS_PUBLIC_API(JS::TraceKind)
|
||||
GCThingTraceKind(js::gc::Cell* thing);
|
||||
|
||||
} /* namespace JS */
|
||||
|
||||
namespace js {
|
||||
|
|
|
@ -76,8 +76,9 @@ JS_ENUM_HEADER(JSValueType, uint8_t)
|
|||
JSVAL_TYPE_MAGIC = 0x04,
|
||||
JSVAL_TYPE_STRING = 0x05,
|
||||
JSVAL_TYPE_SYMBOL = 0x06,
|
||||
JSVAL_TYPE_NULL = 0x07,
|
||||
JSVAL_TYPE_OBJECT = 0x08,
|
||||
JSVAL_TYPE_PRIVATE_GCTHING = 0x07,
|
||||
JSVAL_TYPE_NULL = 0x08,
|
||||
JSVAL_TYPE_OBJECT = 0x0c,
|
||||
|
||||
/* These never appear in a jsval; they are only provided as an out-of-band value. */
|
||||
JSVAL_TYPE_UNKNOWN = 0x20,
|
||||
|
@ -100,7 +101,8 @@ JS_ENUM_HEADER(JSValueTag, uint32_t)
|
|||
JSVAL_TAG_BOOLEAN = JSVAL_TAG_CLEAR | JSVAL_TYPE_BOOLEAN,
|
||||
JSVAL_TAG_MAGIC = JSVAL_TAG_CLEAR | JSVAL_TYPE_MAGIC,
|
||||
JSVAL_TAG_NULL = JSVAL_TAG_CLEAR | JSVAL_TYPE_NULL,
|
||||
JSVAL_TAG_OBJECT = JSVAL_TAG_CLEAR | JSVAL_TYPE_OBJECT
|
||||
JSVAL_TAG_OBJECT = JSVAL_TAG_CLEAR | JSVAL_TYPE_OBJECT,
|
||||
JSVAL_TAG_PRIVATE_GCTHING = JSVAL_TAG_CLEAR | JSVAL_TYPE_PRIVATE_GCTHING
|
||||
} JS_ENUM_FOOTER(JSValueTag);
|
||||
|
||||
static_assert(sizeof(JSValueTag) == sizeof(uint32_t),
|
||||
|
@ -119,7 +121,8 @@ JS_ENUM_HEADER(JSValueTag, uint32_t)
|
|||
JSVAL_TAG_BOOLEAN = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_BOOLEAN,
|
||||
JSVAL_TAG_MAGIC = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_MAGIC,
|
||||
JSVAL_TAG_NULL = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_NULL,
|
||||
JSVAL_TAG_OBJECT = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_OBJECT
|
||||
JSVAL_TAG_OBJECT = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_OBJECT,
|
||||
JSVAL_TAG_PRIVATE_GCTHING = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_PRIVATE_GCTHING
|
||||
} JS_ENUM_FOOTER(JSValueTag);
|
||||
|
||||
static_assert(sizeof(JSValueTag) == sizeof(uint32_t),
|
||||
|
@ -127,15 +130,16 @@ static_assert(sizeof(JSValueTag) == sizeof(uint32_t),
|
|||
|
||||
JS_ENUM_HEADER(JSValueShiftedTag, uint64_t)
|
||||
{
|
||||
JSVAL_SHIFTED_TAG_MAX_DOUBLE = ((((uint64_t)JSVAL_TAG_MAX_DOUBLE) << JSVAL_TAG_SHIFT) | 0xFFFFFFFF),
|
||||
JSVAL_SHIFTED_TAG_INT32 = (((uint64_t)JSVAL_TAG_INT32) << JSVAL_TAG_SHIFT),
|
||||
JSVAL_SHIFTED_TAG_UNDEFINED = (((uint64_t)JSVAL_TAG_UNDEFINED) << JSVAL_TAG_SHIFT),
|
||||
JSVAL_SHIFTED_TAG_STRING = (((uint64_t)JSVAL_TAG_STRING) << JSVAL_TAG_SHIFT),
|
||||
JSVAL_SHIFTED_TAG_SYMBOL = (((uint64_t)JSVAL_TAG_SYMBOL) << JSVAL_TAG_SHIFT),
|
||||
JSVAL_SHIFTED_TAG_BOOLEAN = (((uint64_t)JSVAL_TAG_BOOLEAN) << JSVAL_TAG_SHIFT),
|
||||
JSVAL_SHIFTED_TAG_MAGIC = (((uint64_t)JSVAL_TAG_MAGIC) << JSVAL_TAG_SHIFT),
|
||||
JSVAL_SHIFTED_TAG_NULL = (((uint64_t)JSVAL_TAG_NULL) << JSVAL_TAG_SHIFT),
|
||||
JSVAL_SHIFTED_TAG_OBJECT = (((uint64_t)JSVAL_TAG_OBJECT) << JSVAL_TAG_SHIFT)
|
||||
JSVAL_SHIFTED_TAG_MAX_DOUBLE = ((((uint64_t)JSVAL_TAG_MAX_DOUBLE) << JSVAL_TAG_SHIFT) | 0xFFFFFFFF),
|
||||
JSVAL_SHIFTED_TAG_INT32 = (((uint64_t)JSVAL_TAG_INT32) << JSVAL_TAG_SHIFT),
|
||||
JSVAL_SHIFTED_TAG_UNDEFINED = (((uint64_t)JSVAL_TAG_UNDEFINED) << JSVAL_TAG_SHIFT),
|
||||
JSVAL_SHIFTED_TAG_STRING = (((uint64_t)JSVAL_TAG_STRING) << JSVAL_TAG_SHIFT),
|
||||
JSVAL_SHIFTED_TAG_SYMBOL = (((uint64_t)JSVAL_TAG_SYMBOL) << JSVAL_TAG_SHIFT),
|
||||
JSVAL_SHIFTED_TAG_BOOLEAN = (((uint64_t)JSVAL_TAG_BOOLEAN) << JSVAL_TAG_SHIFT),
|
||||
JSVAL_SHIFTED_TAG_MAGIC = (((uint64_t)JSVAL_TAG_MAGIC) << JSVAL_TAG_SHIFT),
|
||||
JSVAL_SHIFTED_TAG_NULL = (((uint64_t)JSVAL_TAG_NULL) << JSVAL_TAG_SHIFT),
|
||||
JSVAL_SHIFTED_TAG_OBJECT = (((uint64_t)JSVAL_TAG_OBJECT) << JSVAL_TAG_SHIFT),
|
||||
JSVAL_SHIFTED_TAG_PRIVATE_GCTHING = (((uint64_t)JSVAL_TAG_PRIVATE_GCTHING) << JSVAL_TAG_SHIFT)
|
||||
} JS_ENUM_FOOTER(JSValueShiftedTag);
|
||||
|
||||
static_assert(sizeof(JSValueShiftedTag) == sizeof(uint64_t),
|
||||
|
@ -163,8 +167,9 @@ typedef uint8_t JSValueType;
|
|||
#define JSVAL_TYPE_MAGIC ((uint8_t)0x04)
|
||||
#define JSVAL_TYPE_STRING ((uint8_t)0x05)
|
||||
#define JSVAL_TYPE_SYMBOL ((uint8_t)0x06)
|
||||
#define JSVAL_TYPE_NULL ((uint8_t)0x07)
|
||||
#define JSVAL_TYPE_OBJECT ((uint8_t)0x08)
|
||||
#define JSVAL_TYPE_PRIVATE_GCTHING ((uint8_t)0x07)
|
||||
#define JSVAL_TYPE_NULL ((uint8_t)0x08)
|
||||
#define JSVAL_TYPE_OBJECT ((uint8_t)0x0c)
|
||||
#define JSVAL_TYPE_UNKNOWN ((uint8_t)0x20)
|
||||
|
||||
#if defined(JS_NUNBOX32)
|
||||
|
@ -179,6 +184,7 @@ typedef uint32_t JSValueTag;
|
|||
#define JSVAL_TAG_MAGIC ((uint32_t)(JSVAL_TAG_CLEAR | JSVAL_TYPE_MAGIC))
|
||||
#define JSVAL_TAG_NULL ((uint32_t)(JSVAL_TAG_CLEAR | JSVAL_TYPE_NULL))
|
||||
#define JSVAL_TAG_OBJECT ((uint32_t)(JSVAL_TAG_CLEAR | JSVAL_TYPE_OBJECT))
|
||||
#define JSVAL_TAG_PRIVATE_GCTHING ((uint32_t)(JSVAL_TAG_CLEAR | JSVAL_TYPE_PRIVATE_GCTHING))
|
||||
|
||||
#elif defined(JS_PUNBOX64)
|
||||
|
||||
|
@ -192,17 +198,19 @@ typedef uint32_t JSValueTag;
|
|||
#define JSVAL_TAG_MAGIC (uint32_t)(JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_MAGIC)
|
||||
#define JSVAL_TAG_NULL (uint32_t)(JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_NULL)
|
||||
#define JSVAL_TAG_OBJECT (uint32_t)(JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_OBJECT)
|
||||
#define JSVAL_TAG_PRIVATE_GCTHING (uint32_t)(JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_PRIVATE_GCTHING)
|
||||
|
||||
typedef uint64_t JSValueShiftedTag;
|
||||
#define JSVAL_SHIFTED_TAG_MAX_DOUBLE ((((uint64_t)JSVAL_TAG_MAX_DOUBLE) << JSVAL_TAG_SHIFT) | 0xFFFFFFFF)
|
||||
#define JSVAL_SHIFTED_TAG_INT32 (((uint64_t)JSVAL_TAG_INT32) << JSVAL_TAG_SHIFT)
|
||||
#define JSVAL_SHIFTED_TAG_UNDEFINED (((uint64_t)JSVAL_TAG_UNDEFINED) << JSVAL_TAG_SHIFT)
|
||||
#define JSVAL_SHIFTED_TAG_STRING (((uint64_t)JSVAL_TAG_STRING) << JSVAL_TAG_SHIFT)
|
||||
#define JSVAL_SHIFTED_TAG_SYMBOL (((uint64_t)JSVAL_TAG_SYMBOL) << JSVAL_TAG_SHIFT)
|
||||
#define JSVAL_SHIFTED_TAG_BOOLEAN (((uint64_t)JSVAL_TAG_BOOLEAN) << JSVAL_TAG_SHIFT)
|
||||
#define JSVAL_SHIFTED_TAG_MAGIC (((uint64_t)JSVAL_TAG_MAGIC) << JSVAL_TAG_SHIFT)
|
||||
#define JSVAL_SHIFTED_TAG_NULL (((uint64_t)JSVAL_TAG_NULL) << JSVAL_TAG_SHIFT)
|
||||
#define JSVAL_SHIFTED_TAG_OBJECT (((uint64_t)JSVAL_TAG_OBJECT) << JSVAL_TAG_SHIFT)
|
||||
#define JSVAL_SHIFTED_TAG_MAX_DOUBLE ((((uint64_t)JSVAL_TAG_MAX_DOUBLE) << JSVAL_TAG_SHIFT) | 0xFFFFFFFF)
|
||||
#define JSVAL_SHIFTED_TAG_INT32 (((uint64_t)JSVAL_TAG_INT32) << JSVAL_TAG_SHIFT)
|
||||
#define JSVAL_SHIFTED_TAG_UNDEFINED (((uint64_t)JSVAL_TAG_UNDEFINED) << JSVAL_TAG_SHIFT)
|
||||
#define JSVAL_SHIFTED_TAG_STRING (((uint64_t)JSVAL_TAG_STRING) << JSVAL_TAG_SHIFT)
|
||||
#define JSVAL_SHIFTED_TAG_SYMBOL (((uint64_t)JSVAL_TAG_SYMBOL) << JSVAL_TAG_SHIFT)
|
||||
#define JSVAL_SHIFTED_TAG_BOOLEAN (((uint64_t)JSVAL_TAG_BOOLEAN) << JSVAL_TAG_SHIFT)
|
||||
#define JSVAL_SHIFTED_TAG_MAGIC (((uint64_t)JSVAL_TAG_MAGIC) << JSVAL_TAG_SHIFT)
|
||||
#define JSVAL_SHIFTED_TAG_NULL (((uint64_t)JSVAL_TAG_NULL) << JSVAL_TAG_SHIFT)
|
||||
#define JSVAL_SHIFTED_TAG_OBJECT (((uint64_t)JSVAL_TAG_OBJECT) << JSVAL_TAG_SHIFT)
|
||||
#define JSVAL_SHIFTED_TAG_PRIVATE_GCTHING (((uint64_t)JSVAL_TAG_PRIVATE_GCTHING) << JSVAL_TAG_SHIFT)
|
||||
|
||||
#endif /* JS_PUNBOX64 */
|
||||
#endif /* !defined(__SUNPRO_CC) && !defined(__xlC__) */
|
||||
|
@ -632,6 +640,29 @@ JSVAL_TO_PRIVATE_PTR_IMPL(jsval_layout l)
|
|||
return l.s.payload.ptr;
|
||||
}
|
||||
|
||||
static inline jsval_layout
|
||||
PRIVATE_GCTHING_TO_JSVAL_IMPL(js::gc::Cell* cell)
|
||||
{
|
||||
MOZ_ASSERT(JS::GCThingTraceKind(cell) != JS::TraceKind::String,
|
||||
"Private GC thing Values must not be strings. Make a StringValue instead.");
|
||||
MOZ_ASSERT(JS::GCThingTraceKind(cell) != JS::TraceKind::Symbol,
|
||||
"Private GC thing Values must not be symbols. Make a SymbolValue instead.");
|
||||
MOZ_ASSERT(JS::GCThingTraceKind(cell) != JS::TraceKind::Object,
|
||||
"Private GC thing Values must not be objects. Make an ObjectValue instead.");
|
||||
|
||||
jsval_layout l;
|
||||
MOZ_ASSERT(uintptr_t(cell) > 0x1000);
|
||||
l.s.tag = JSVAL_TAG_PRIVATE_GCTHING;
|
||||
l.s.payload.cell = ptr;
|
||||
return l;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
JSVAL_IS_PRIVATE_GCTHING_IMPL(jsval_layout l)
|
||||
{
|
||||
return l.s.tag == JSVAL_TAG_PRIVATE_GCTHING;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
JSVAL_IS_GCTHING_IMPL(jsval_layout l)
|
||||
{
|
||||
|
@ -654,6 +685,8 @@ JSVAL_TRACE_KIND_IMPL(jsval_layout l)
|
|||
"Value type tags must correspond with JS::TraceKinds.");
|
||||
static_assert((JSVAL_TAG_OBJECT & 0x03) == size_t(JS::TraceKind::Object),
|
||||
"Value type tags must correspond with JS::TraceKinds.");
|
||||
if (MOZ_UNLIKELY(JSVAL_IS_PRIVATE_GCTHING_IMPL(l)))
|
||||
return (uint32_t)JS::GCThingTraceKind(JSVAL_TO_GCTHING_IMPL(l));
|
||||
return l.s.tag & 0x03;
|
||||
}
|
||||
|
||||
|
@ -872,6 +905,12 @@ JSVAL_IS_NULL_IMPL(jsval_layout l)
|
|||
return l.asBits == JSVAL_SHIFTED_TAG_NULL;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
JSVAL_IS_PRIVATE_GCTHING_IMPL(jsval_layout l)
|
||||
{
|
||||
return (l.asBits >> JSVAL_TAG_SHIFT) == JSVAL_TAG_PRIVATE_GCTHING;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
JSVAL_IS_GCTHING_IMPL(jsval_layout l)
|
||||
{
|
||||
|
@ -895,6 +934,8 @@ JSVAL_TRACE_KIND_IMPL(jsval_layout l)
|
|||
"Value type tags must correspond with JS::TraceKinds.");
|
||||
static_assert((JSVAL_TAG_OBJECT & 0x03) == size_t(JS::TraceKind::Object),
|
||||
"Value type tags must correspond with JS::TraceKinds.");
|
||||
if (MOZ_UNLIKELY(JSVAL_IS_PRIVATE_GCTHING_IMPL(l)))
|
||||
return (uint32_t)JS::GCThingTraceKind(JSVAL_TO_GCTHING_IMPL(l));
|
||||
return (uint32_t)(l.asBits >> JSVAL_TAG_SHIFT) & 0x03;
|
||||
}
|
||||
|
||||
|
@ -916,6 +957,24 @@ JSVAL_TO_PRIVATE_PTR_IMPL(jsval_layout l)
|
|||
return (void*)(l.asBits << 1);
|
||||
}
|
||||
|
||||
static inline jsval_layout
|
||||
PRIVATE_GCTHING_TO_JSVAL_IMPL(js::gc::Cell* cell)
|
||||
{
|
||||
MOZ_ASSERT(JS::GCThingTraceKind(cell) != JS::TraceKind::String,
|
||||
"Private GC thing Values must not be strings. Make a StringValue instead.");
|
||||
MOZ_ASSERT(JS::GCThingTraceKind(cell) != JS::TraceKind::Symbol,
|
||||
"Private GC thing Values must not be symbols. Make a SymbolValue instead.");
|
||||
MOZ_ASSERT(JS::GCThingTraceKind(cell) != JS::TraceKind::Object,
|
||||
"Private GC thing Values must not be objects. Make an ObjectValue instead.");
|
||||
|
||||
jsval_layout l;
|
||||
uint64_t cellBits = (uint64_t)cell;
|
||||
MOZ_ASSERT(uintptr_t(cellBits) > 0x1000);
|
||||
MOZ_ASSERT((cellBits >> JSVAL_TAG_SHIFT) == 0);
|
||||
l.asBits = cellBits | JSVAL_SHIFTED_TAG_PRIVATE_GCTHING;
|
||||
return l;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
JSVAL_IS_SPECIFIC_INT32_IMPL(jsval_layout l, int32_t i32)
|
||||
{
|
||||
|
@ -1341,6 +1400,23 @@ class Value
|
|||
return uint32_t(toInt32());
|
||||
}
|
||||
|
||||
/*
|
||||
* Private GC Thing API
|
||||
*
|
||||
* Non-JSObject, JSString, and JS::Symbol cells may be put into the 64-bit
|
||||
* payload as private GC things. Such Values are considered isMarkable()
|
||||
* and isGCThing(), and as such, automatically marked. Their traceKind()
|
||||
* is gotten via their cells.
|
||||
*/
|
||||
|
||||
void setPrivateGCThing(js::gc::Cell* cell) {
|
||||
data = PRIVATE_GCTHING_TO_JSVAL_IMPL(cell);
|
||||
}
|
||||
|
||||
bool isPrivateGCThing() const {
|
||||
return JSVAL_IS_PRIVATE_GCTHING_IMPL(data);
|
||||
}
|
||||
|
||||
/*
|
||||
* An unmarked value is just a void* cast as a Value. Thus, the Value is
|
||||
* not safe for GC and must not be marked. This API avoids raw casts
|
||||
|
@ -1683,6 +1759,14 @@ PrivateUint32Value(uint32_t ui)
|
|||
return v;
|
||||
}
|
||||
|
||||
static inline Value
|
||||
PrivateGCThingValue(js::gc::Cell* cell)
|
||||
{
|
||||
Value v;
|
||||
v.setPrivateGCThing(cell);
|
||||
return v;
|
||||
}
|
||||
|
||||
inline bool
|
||||
SameType(const Value& lhs, const Value& rhs)
|
||||
{
|
||||
|
@ -1801,6 +1885,7 @@ class MutableValueOperations : public ValueOperations<Outer>
|
|||
void setSymbol(JS::Symbol* sym) { this->value().setSymbol(sym); }
|
||||
void setObject(JSObject& obj) { this->value().setObject(obj); }
|
||||
void setObjectOrNull(JSObject* arg) { this->value().setObjectOrNull(arg); }
|
||||
void setPrivateGCThing(js::gc::Cell* cell) { this->value().setPrivateGCThing(cell); }
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -1829,6 +1914,7 @@ class HeapBase<JS::Value> : public ValueOperations<JS::Heap<JS::Value> >
|
|||
void setString(JSString* str) { setBarriered(JS::StringValue(str)); }
|
||||
void setSymbol(JS::Symbol* sym) { setBarriered(JS::SymbolValue(sym)); }
|
||||
void setObject(JSObject& obj) { setBarriered(JS::ObjectValue(obj)); }
|
||||
void setPrivateGCThing(js::gc::Cell* cell) { setBarriered(JS::PrivateGCThingValue(cell)); }
|
||||
|
||||
bool setNumber(uint32_t ui) {
|
||||
if (ui > JSVAL_INT_MAX) {
|
||||
|
@ -1890,6 +1976,8 @@ DispatchTyped(F f, const JS::Value& val, Args&&... args)
|
|||
return f(&val.toObject(), mozilla::Forward<Args>(args)...);
|
||||
if (val.isSymbol())
|
||||
return f(val.toSymbol(), mozilla::Forward<Args>(args)...);
|
||||
if (MOZ_UNLIKELY(val.isPrivateGCThing()))
|
||||
return DispatchTyped(f, val.toGCCellPtr(), mozilla::Forward<Args>(args)...);
|
||||
MOZ_ASSERT(!val.isMarkable());
|
||||
return F::defaultValue(val);
|
||||
}
|
||||
|
|
|
@ -80,9 +80,13 @@ ReadBarrierFunctor<S>::operator()(T* t)
|
|||
{
|
||||
InternalBarrierMethods<T*>::readBarrier(t);
|
||||
}
|
||||
template void ReadBarrierFunctor<JS::Value>::operator()<JS::Symbol>(JS::Symbol*);
|
||||
template void ReadBarrierFunctor<JS::Value>::operator()<JSObject>(JSObject*);
|
||||
template void ReadBarrierFunctor<JS::Value>::operator()<JSString>(JSString*);
|
||||
|
||||
// All GC things may be held in a Value, either publicly or as a private GC
|
||||
// thing.
|
||||
#define JS_EXPAND_DEF(name, type, _) \
|
||||
template void ReadBarrierFunctor<JS::Value>::operator()<type>(type*);
|
||||
JS_FOR_EACH_TRACEKIND(JS_EXPAND_DEF);
|
||||
#undef JS_EXPAND_DEF
|
||||
|
||||
template <typename S>
|
||||
template <typename T>
|
||||
|
@ -91,9 +95,14 @@ PreBarrierFunctor<S>::operator()(T* t)
|
|||
{
|
||||
InternalBarrierMethods<T*>::preBarrier(t);
|
||||
}
|
||||
template void PreBarrierFunctor<JS::Value>::operator()<JS::Symbol>(JS::Symbol*);
|
||||
template void PreBarrierFunctor<JS::Value>::operator()<JSObject>(JSObject*);
|
||||
template void PreBarrierFunctor<JS::Value>::operator()<JSString>(JSString*);
|
||||
|
||||
// All GC things may be held in a Value, either publicly or as a private GC
|
||||
// thing.
|
||||
#define JS_EXPAND_DEF(name, type, _) \
|
||||
template void PreBarrierFunctor<JS::Value>::operator()<type>(type*);
|
||||
JS_FOR_EACH_TRACEKIND(JS_EXPAND_DEF);
|
||||
#undef JS_EXPAND_DEF
|
||||
|
||||
template void PreBarrierFunctor<jsid>::operator()<JS::Symbol>(JS::Symbol*);
|
||||
template void PreBarrierFunctor<jsid>::operator()<JSString>(JSString*);
|
||||
|
||||
|
|
|
@ -261,7 +261,7 @@ struct InternalBarrierMethods<T*>
|
|||
static void readBarrier(T* v) { T::readBarrier(v); }
|
||||
};
|
||||
|
||||
template <typename S> struct PreBarrierFunctor : VoidDefaultAdaptor<S> {
|
||||
template <typename S> struct PreBarrierFunctor : public VoidDefaultAdaptor<S> {
|
||||
template <typename T> void operator()(T* t);
|
||||
};
|
||||
|
||||
|
|
|
@ -2021,7 +2021,7 @@ template <typename S>
|
|||
struct TenuringTraversalFunctor : public IdentityDefaultAdaptor<S> {
|
||||
template <typename T> S operator()(T* t, TenuringTracer* trc) {
|
||||
trc->traverse(&t);
|
||||
return js::gc::RewrapTaggedPointer<S, T*>::wrap(t);
|
||||
return js::gc::RewrapTaggedPointer<S, T>::wrap(t);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -2427,7 +2427,7 @@ template <typename S>
|
|||
struct IsMarkedFunctor : public IdentityDefaultAdaptor<S> {
|
||||
template <typename T> S operator()(T* t, bool* rv) {
|
||||
*rv = IsMarkedInternal(&t);
|
||||
return js::gc::RewrapTaggedPointer<S, T*>::wrap(t);
|
||||
return js::gc::RewrapTaggedPointer<S, T>::wrap(t);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -2486,7 +2486,7 @@ template <typename S>
|
|||
struct IsAboutToBeFinalizedFunctor : public IdentityDefaultAdaptor<S> {
|
||||
template <typename T> S operator()(T* t, bool* rv) {
|
||||
*rv = IsAboutToBeFinalizedInternal(&t);
|
||||
return js::gc::RewrapTaggedPointer<S, T*>::wrap(t);
|
||||
return js::gc::RewrapTaggedPointer<S, T>::wrap(t);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -420,14 +420,34 @@ template <typename S, typename T>
|
|||
struct RewrapTaggedPointer{};
|
||||
#define DECLARE_REWRAP(S, T, method, prefix) \
|
||||
template <> struct RewrapTaggedPointer<S, T> { \
|
||||
static S wrap(T thing) { return method ( prefix thing ); } \
|
||||
static S wrap(T* thing) { return method ( prefix thing ); } \
|
||||
}
|
||||
DECLARE_REWRAP(JS::Value, JSObject*, JS::ObjectOrNullValue, );
|
||||
DECLARE_REWRAP(JS::Value, JSString*, JS::StringValue, );
|
||||
DECLARE_REWRAP(JS::Value, JS::Symbol*, JS::SymbolValue, );
|
||||
DECLARE_REWRAP(jsid, JSString*, NON_INTEGER_ATOM_TO_JSID, (JSAtom*));
|
||||
DECLARE_REWRAP(jsid, JS::Symbol*, SYMBOL_TO_JSID, );
|
||||
DECLARE_REWRAP(js::TaggedProto, JSObject*, js::TaggedProto, );
|
||||
DECLARE_REWRAP(JS::Value, JSObject, JS::ObjectOrNullValue, );
|
||||
DECLARE_REWRAP(JS::Value, JSString, JS::StringValue, );
|
||||
DECLARE_REWRAP(JS::Value, JS::Symbol, JS::SymbolValue, );
|
||||
DECLARE_REWRAP(jsid, JSString, NON_INTEGER_ATOM_TO_JSID, (JSAtom*));
|
||||
DECLARE_REWRAP(jsid, JS::Symbol, SYMBOL_TO_JSID, );
|
||||
DECLARE_REWRAP(js::TaggedProto, JSObject, js::TaggedProto, );
|
||||
#undef DECLARE_REWRAP
|
||||
|
||||
template <typename T>
|
||||
struct IsPrivateGCThingInValue
|
||||
: public mozilla::EnableIf<mozilla::IsBaseOf<Cell, T>::value &&
|
||||
!mozilla::IsBaseOf<JSObject, T>::value &&
|
||||
!mozilla::IsBaseOf<JSString, T>::value &&
|
||||
!mozilla::IsBaseOf<JS::Symbol, T>::value, T>
|
||||
{
|
||||
static_assert(!mozilla::IsSame<Cell, T>::value && !mozilla::IsSame<TenuredCell, T>::value,
|
||||
"T must not be Cell or TenuredCell");
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct RewrapTaggedPointer<Value, T>
|
||||
{
|
||||
static Value wrap(typename IsPrivateGCThingInValue<T>::Type* thing) {
|
||||
return JS::PrivateGCThingValue(thing);
|
||||
}
|
||||
};
|
||||
|
||||
} /* namespace gc */
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@ JS_FOR_EACH_TRACEKIND(INSTANTIATE_ALL_VALID_TRACE_FUNCTIONS);
|
|||
template <typename S>
|
||||
struct DoCallbackFunctor : public IdentityDefaultAdaptor<S> {
|
||||
template <typename T> S operator()(T* t, JS::CallbackTracer* trc, const char* name) {
|
||||
return js::gc::RewrapTaggedPointer<S, T*>::wrap(DoCallback(trc, &t, name));
|
||||
return js::gc::RewrapTaggedPointer<S, T>::wrap(DoCallback(trc, &t, name));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -733,7 +733,7 @@ class ICGetElemNativeCompiler : public ICStubCompiler
|
|||
protected:
|
||||
virtual int32_t getKey() const {
|
||||
MOZ_ASSERT(static_cast<int32_t>(acctype_) <= 7);
|
||||
MOZ_ASSERT(static_cast<int32_t>(unboxedType_) <= 8);
|
||||
MOZ_ASSERT(static_cast<int32_t>(unboxedType_) <= 15);
|
||||
return static_cast<int32_t>(engine_) |
|
||||
(static_cast<int32_t>(kind) << 1) |
|
||||
(static_cast<int32_t>(needsAtomize_) << 17) |
|
||||
|
|
|
@ -68,6 +68,7 @@ UNIFIED_SOURCES += [
|
|||
'testParseJSON.cpp',
|
||||
'testPersistentRooted.cpp',
|
||||
'testPreserveJitCode.cpp',
|
||||
'testPrivateGCThingValue.cpp',
|
||||
'testProfileStrings.cpp',
|
||||
'testPropCache.cpp',
|
||||
'testRegExp.cpp',
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=8 sts=4 et sw=4 tw=99:
|
||||
*/
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "jsapi.h"
|
||||
|
||||
#include "js/HeapAPI.h"
|
||||
#include "jsapi-tests/tests.h"
|
||||
|
||||
class TestTracer : public JS::CallbackTracer
|
||||
{
|
||||
void onChild(const JS::GCCellPtr& thing) override {
|
||||
if (thing.asCell() == expectedCell && thing.kind() == expectedKind)
|
||||
found = true;
|
||||
}
|
||||
|
||||
public:
|
||||
js::gc::Cell* expectedCell;
|
||||
JS::TraceKind expectedKind;
|
||||
bool found;
|
||||
|
||||
explicit TestTracer(JSContext* cx)
|
||||
: JS::CallbackTracer(JS_GetRuntime(cx)),
|
||||
found(false)
|
||||
{ }
|
||||
};
|
||||
|
||||
static const JSClass TestClass = {
|
||||
"TestClass",
|
||||
JSCLASS_HAS_RESERVED_SLOTS(1)
|
||||
};
|
||||
|
||||
BEGIN_TEST(testPrivateGCThingValue)
|
||||
{
|
||||
JS::RootedObject obj(cx, JS_NewObject(cx, &TestClass));
|
||||
CHECK(obj);
|
||||
|
||||
// Make a JSScript to stick into a PrivateGCThingValue.
|
||||
JS::RootedScript script(cx);
|
||||
const char code[] = "'objet petit a'";
|
||||
JS::CompileOptions options(cx);
|
||||
options.setFileAndLine(__FILE__, __LINE__);
|
||||
CHECK(JS_CompileScript(cx, code, sizeof(code) - 1, options, &script));
|
||||
JS_SetReservedSlot(obj, 0, PrivateGCThingValue(script));
|
||||
|
||||
TestTracer trc(cx);
|
||||
trc.expectedCell = script;
|
||||
trc.expectedKind = JS::TraceKind::Script;
|
||||
JS::TraceChildren(&trc, JS::GCCellPtr(obj, JS::TraceKind::Object));
|
||||
CHECK(trc.found);
|
||||
|
||||
return true;
|
||||
}
|
||||
END_TEST(testPrivateGCThingValue)
|
|
@ -6542,3 +6542,10 @@ JS::GetObjectZone(JSObject* obj)
|
|||
{
|
||||
return obj->zone();
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JS::TraceKind)
|
||||
JS::GCThingTraceKind(js::gc::Cell* thing)
|
||||
{
|
||||
MOZ_ASSERT(thing);
|
||||
return thing->getTraceKind();
|
||||
}
|
||||
|
|
|
@ -581,13 +581,6 @@ js::ZoneGlobalsAreAllGray(JS::Zone* zone)
|
|||
return true;
|
||||
}
|
||||
|
||||
JS_FRIEND_API(JS::TraceKind)
|
||||
js::GCThingTraceKind(void* thing)
|
||||
{
|
||||
MOZ_ASSERT(thing);
|
||||
return static_cast<js::gc::Cell*>(thing)->getTraceKind();
|
||||
}
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
js::VisitGrayWrapperTargets(Zone* zone, GCThingCallback callback, void* closure)
|
||||
{
|
||||
|
|
|
@ -507,9 +507,6 @@ VisitGrayWrapperTargets(JS::Zone* zone, GCThingCallback callback, void* closure)
|
|||
extern JS_FRIEND_API(JSObject*)
|
||||
GetWeakmapKeyDelegate(JSObject* key);
|
||||
|
||||
JS_FRIEND_API(JS::TraceKind)
|
||||
GCThingTraceKind(void* thing);
|
||||
|
||||
/**
|
||||
* Invoke cellCallback on every gray JS_OBJECT in the given zone.
|
||||
*/
|
||||
|
|
|
@ -7417,6 +7417,8 @@ JS::GCCellPtr::GCCellPtr(const Value& v)
|
|||
ptr = checkedCast(&v.toObject(), JS::TraceKind::Object);
|
||||
else if (v.isSymbol())
|
||||
ptr = checkedCast(v.toSymbol(), JS::TraceKind::Symbol);
|
||||
else if (v.isPrivateGCThing())
|
||||
ptr = checkedCast(v.toGCThing(), v.toGCThing()->getTraceKind());
|
||||
else
|
||||
ptr = checkedCast(nullptr, JS::TraceKind::Null);
|
||||
}
|
||||
|
|
|
@ -1145,7 +1145,7 @@ Forwarded(T* t)
|
|||
|
||||
struct ForwardedFunctor : public IdentityDefaultAdaptor<Value> {
|
||||
template <typename T> inline Value operator()(T* t) {
|
||||
return js::gc::RewrapTaggedPointer<Value, T*>::wrap(Forwarded(t));
|
||||
return js::gc::RewrapTaggedPointer<Value, T>::wrap(Forwarded(t));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -299,7 +299,7 @@ JSGCThingParticipant::Traverse(void* aPtr,
|
|||
reinterpret_cast<char*>(this) - offsetof(CycleCollectedJSRuntime,
|
||||
mGCThingCycleCollectorGlobal));
|
||||
|
||||
JS::GCCellPtr cellPtr(aPtr, js::GCThingTraceKind(aPtr));
|
||||
JS::GCCellPtr cellPtr(aPtr, JS::GCThingTraceKind(aPtr));
|
||||
runtime->TraverseGCThing(CycleCollectedJSRuntime::TRAVERSE_FULL, cellPtr, aCb);
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -3076,7 +3076,7 @@ nsCycleCollector::ScanIncrementalRoots()
|
|||
// If the object is still marked gray by the GC, nothing could have gotten
|
||||
// hold of it, so it isn't an incremental root.
|
||||
if (pi->mParticipant == jsParticipant) {
|
||||
JS::GCCellPtr ptr(pi->mPointer, js::GCThingTraceKind(pi->mPointer));
|
||||
JS::GCCellPtr ptr(pi->mPointer, JS::GCThingTraceKind(pi->mPointer));
|
||||
if (GCThingIsGrayCCThing(ptr)) {
|
||||
continue;
|
||||
}
|
||||
|
@ -3291,7 +3291,7 @@ nsCycleCollector::CollectWhite()
|
|||
++numWhiteJSZones;
|
||||
zone = static_cast<JS::Zone*>(pinfo->mPointer);
|
||||
} else {
|
||||
JS::GCCellPtr ptr(pinfo->mPointer, js::GCThingTraceKind(pinfo->mPointer));
|
||||
JS::GCCellPtr ptr(pinfo->mPointer, JS::GCThingTraceKind(pinfo->mPointer));
|
||||
zone = JS::GetTenuredGCThingZone(ptr);
|
||||
}
|
||||
mJSRuntime->AddZoneWaitingForGC(zone);
|
||||
|
|
Загрузка…
Ссылка в новой задаче