mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1189809 - Remove the ill-fated DynamicTraceable; r=jonco
This commit is contained in:
parent
7986b6b982
commit
e6ed4bf78a
@ -567,26 +567,15 @@ struct GCMethods<JSFunction*>
|
||||
|
||||
namespace JS {
|
||||
|
||||
// If a class containing GC pointers has (or can gain) a vtable, then it can be
|
||||
// trivially used with Rooted/Handle/MutableHandle by deriving from
|
||||
// DynamicTraceable and overriding |void trace(JSTracer*)|.
|
||||
class DynamicTraceable
|
||||
// Non pointer types -- structs or classes that contain GC pointers, either as
|
||||
// a member or in a more complex container layout -- can also be stored in a
|
||||
// [Persistent]Rooted if it derives from JS::Traceable. A JS::Traceable stored
|
||||
// in a [Persistent]Rooted must implement the method:
|
||||
// |static void trace(T*, JSTracer*)|
|
||||
class Traceable
|
||||
{
|
||||
public:
|
||||
static js::ThingRootKind rootKind() { return js::THING_ROOT_DYNAMIC_TRACEABLE; }
|
||||
|
||||
virtual ~DynamicTraceable() {}
|
||||
virtual void trace(JSTracer* trc) = 0;
|
||||
};
|
||||
|
||||
// To use a static class or struct (e.g. not containing a vtable) as part of a
|
||||
// Rooted/Handle/MutableHandle, ensure that it derives from StaticTraceable
|
||||
// (i.e. so that automatic upcast via calls works) and ensure that a method
|
||||
// |static void trace(T*, JSTracer*)| exists on the class.
|
||||
class StaticTraceable
|
||||
{
|
||||
public:
|
||||
static js::ThingRootKind rootKind() { return js::THING_ROOT_STATIC_TRACEABLE; }
|
||||
static js::ThingRootKind rootKind() { return js::THING_ROOT_TRACEABLE; }
|
||||
};
|
||||
|
||||
} /* namespace JS */
|
||||
@ -596,8 +585,8 @@ namespace js {
|
||||
template <typename T>
|
||||
class DispatchWrapper
|
||||
{
|
||||
static_assert(mozilla::IsBaseOf<JS::StaticTraceable, T>::value,
|
||||
"DispatchWrapper is intended only for usage with a StaticTraceable");
|
||||
static_assert(mozilla::IsBaseOf<JS::Traceable, T>::value,
|
||||
"DispatchWrapper is intended only for usage with a Traceable");
|
||||
|
||||
using TraceFn = void (*)(T*, JSTracer*);
|
||||
TraceFn tracer;
|
||||
@ -620,7 +609,7 @@ class DispatchWrapper
|
||||
|
||||
// Trace the contained storage (of unknown type) using the trace function
|
||||
// we set aside when we did know the type.
|
||||
static void TraceWrapped(JSTracer* trc, JS::StaticTraceable* thingp, const char* name) {
|
||||
static void TraceWrapped(JSTracer* trc, JS::Traceable* thingp, const char* name) {
|
||||
auto wrapper = reinterpret_cast<DispatchWrapper*>(
|
||||
uintptr_t(thingp) - offsetof(DispatchWrapper, storage));
|
||||
wrapper->tracer(&wrapper->storage, trc);
|
||||
@ -666,8 +655,7 @@ namespace JS {
|
||||
template <typename T>
|
||||
class MOZ_STACK_CLASS Rooted : public js::RootedBase<T>
|
||||
{
|
||||
static_assert(!mozilla::IsConvertible<T, StaticTraceable*>::value &&
|
||||
!mozilla::IsConvertible<T, DynamicTraceable*>::value,
|
||||
static_assert(!mozilla::IsConvertible<T, Traceable*>::value,
|
||||
"Rooted takes pointer or Traceable types but not Traceable* type");
|
||||
|
||||
/* Note: CX is a subclass of either ContextFriendFields or PerThreadDataFriendFields. */
|
||||
@ -730,13 +718,13 @@ class MOZ_STACK_CLASS Rooted : public js::RootedBase<T>
|
||||
/*
|
||||
* For pointer types, the TraceKind for tracing is based on the list it is
|
||||
* in (selected via rootKind), so no additional storage is required here.
|
||||
* All StaticTraceable, however, share the same list, so the function to
|
||||
* All Traceable, however, share the same list, so the function to
|
||||
* call for tracing is stored adjacent to the struct. Since C++ cannot
|
||||
* templatize on storage class, this is implemented via the wrapper class
|
||||
* DispatchWrapper.
|
||||
*/
|
||||
using MaybeWrapped = typename mozilla::Conditional<
|
||||
mozilla::IsBaseOf<StaticTraceable, T>::value,
|
||||
mozilla::IsBaseOf<Traceable, T>::value,
|
||||
js::DispatchWrapper<T>,
|
||||
T>::Type;
|
||||
MaybeWrapped ptr;
|
||||
|
@ -34,14 +34,15 @@ template <typename Key,
|
||||
typename KeyTraceFunc = DefaultTracer<Key>,
|
||||
typename ValueTraceFunc = DefaultTracer<Value>>
|
||||
class TraceableHashMap : public HashMap<Key, Value, HashPolicy, AllocPolicy>,
|
||||
public JS::DynamicTraceable
|
||||
public JS::Traceable
|
||||
{
|
||||
using Base = HashMap<Key, Value, HashPolicy, AllocPolicy>;
|
||||
|
||||
public:
|
||||
explicit TraceableHashMap(AllocPolicy a = AllocPolicy()) : Base(a) {}
|
||||
|
||||
void trace(JSTracer* trc) override {
|
||||
static void trace(TraceableHashMap* map, JSTracer* trc) { map->trace(trc); }
|
||||
void trace(JSTracer* trc) {
|
||||
if (!this->initialized())
|
||||
return;
|
||||
for (typename Base::Enum e(*this); !e.empty(); e.popFront()) {
|
||||
|
@ -37,7 +37,7 @@ class TraceableVector
|
||||
MinInlineCapacity,
|
||||
AllocPolicy,
|
||||
TraceableVector<T, MinInlineCapacity, AllocPolicy, TraceFunc>>,
|
||||
public JS::DynamicTraceable
|
||||
public JS::Traceable
|
||||
{
|
||||
using Base = mozilla::VectorBase<T, MinInlineCapacity, AllocPolicy, TraceableVector>;
|
||||
|
||||
@ -48,7 +48,8 @@ class TraceableVector
|
||||
return Base::operator=(mozilla::Forward<TraceableVector>(vec));
|
||||
}
|
||||
|
||||
void trace(JSTracer* trc) override {
|
||||
static void trace(TraceableVector* vec, JSTracer* trc) { vec->trace(trc); }
|
||||
void trace(JSTracer* trc) {
|
||||
for (size_t i = 0; i < this->length(); ++i)
|
||||
TraceFunc::trace(trc, &Base::operator[](i), "vector element");
|
||||
}
|
||||
|
@ -40,20 +40,6 @@ typedef RootedValueMap::Range RootRange;
|
||||
typedef RootedValueMap::Entry RootEntry;
|
||||
typedef RootedValueMap::Enum RootEnum;
|
||||
|
||||
// We cannot instantiate (even indirectly) the abstract JS::DynamicTraceable.
|
||||
// Instead we cast to a ConcreteTraceable, then upcast before calling trace so
|
||||
// that we get the implementation defined dynamically in the vtable.
|
||||
struct ConcreteTraceable : public JS::DynamicTraceable
|
||||
{
|
||||
void trace(JSTracer* trc) override {}
|
||||
};
|
||||
|
||||
static void
|
||||
MarkDynamicTraceable(JSTracer* trc, ConcreteTraceable* t, const char* name)
|
||||
{
|
||||
static_cast<JS::DynamicTraceable*>(t)->trace(trc);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
using TraceFunction = void (*)(JSTracer* trc, T* ref, const char* name);
|
||||
|
||||
@ -76,8 +62,7 @@ MarkExactStackRootsAcrossTypes(T context, JSTracer* trc)
|
||||
MarkExactStackRootList<JSObject*>(trc, context, "exact-object");
|
||||
MarkExactStackRootList<Shape*>(trc, context, "exact-shape");
|
||||
MarkExactStackRootList<BaseShape*>(trc, context, "exact-baseshape");
|
||||
MarkExactStackRootList<ObjectGroup*>(
|
||||
trc, context, "exact-objectgroup");
|
||||
MarkExactStackRootList<ObjectGroup*>(trc, context, "exact-objectgroup");
|
||||
MarkExactStackRootList<JSString*>(trc, context, "exact-string");
|
||||
MarkExactStackRootList<JS::Symbol*>(trc, context, "exact-symbol");
|
||||
MarkExactStackRootList<jit::JitCode*>(trc, context, "exact-jitcode");
|
||||
@ -85,11 +70,8 @@ MarkExactStackRootsAcrossTypes(T context, JSTracer* trc)
|
||||
MarkExactStackRootList<LazyScript*>(trc, context, "exact-lazy-script");
|
||||
MarkExactStackRootList<jsid>(trc, context, "exact-id");
|
||||
MarkExactStackRootList<Value>(trc, context, "exact-value");
|
||||
MarkExactStackRootList<JS::StaticTraceable,
|
||||
js::DispatchWrapper<JS::StaticTraceable>::TraceWrapped>(
|
||||
trc, context, "StaticTraceable");
|
||||
MarkExactStackRootList<ConcreteTraceable, MarkDynamicTraceable>(
|
||||
trc, context, "DynamicTraceable");
|
||||
MarkExactStackRootList<JS::Traceable, js::DispatchWrapper<JS::Traceable>::TraceWrapped>(
|
||||
trc, context, "Traceable");
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -40,7 +40,7 @@ BEGIN_TEST(testGCSuppressions)
|
||||
}
|
||||
END_TEST(testGCSuppressions)
|
||||
|
||||
struct MyContainer : public JS::StaticTraceable
|
||||
struct MyContainer : public JS::Traceable
|
||||
{
|
||||
RelocatablePtrObject obj;
|
||||
RelocatablePtrString str;
|
||||
@ -62,22 +62,6 @@ struct RootedBase<MyContainer> {
|
||||
};
|
||||
} // namespace js
|
||||
|
||||
BEGIN_TEST(testGCRootedStaticStructInternalStackStorage)
|
||||
{
|
||||
JS::Rooted<MyContainer> container(cx);
|
||||
container.get().obj = JS_NewObject(cx, nullptr);
|
||||
container.get().str = JS_NewStringCopyZ(cx, "Hello");
|
||||
|
||||
JS_GC(cx->runtime());
|
||||
JS_GC(cx->runtime());
|
||||
|
||||
JS::RootedObject obj(cx, container.get().obj);
|
||||
JS::RootedValue val(cx, StringValue(container.get().str));
|
||||
CHECK(JS_SetProperty(cx, obj, "foo", val));
|
||||
return true;
|
||||
}
|
||||
END_TEST(testGCRootedStaticStructInternalStackStorage)
|
||||
|
||||
BEGIN_TEST(testGCRootedStaticStructInternalStackStorageAugmented)
|
||||
{
|
||||
JS::Rooted<MyContainer> container(cx);
|
||||
@ -94,69 +78,6 @@ BEGIN_TEST(testGCRootedStaticStructInternalStackStorageAugmented)
|
||||
}
|
||||
END_TEST(testGCRootedStaticStructInternalStackStorageAugmented)
|
||||
|
||||
struct DynamicBase : public JS::DynamicTraceable
|
||||
{
|
||||
RelocatablePtrObject obj;
|
||||
DynamicBase() : obj(nullptr) {}
|
||||
|
||||
void trace(JSTracer* trc) override {
|
||||
if (obj)
|
||||
js::TraceEdge(trc, &obj, "test container");
|
||||
}
|
||||
};
|
||||
|
||||
struct DynamicContainer : public DynamicBase
|
||||
{
|
||||
RelocatablePtrString str;
|
||||
DynamicContainer() : str(nullptr) {}
|
||||
|
||||
void trace(JSTracer* trc) override {
|
||||
this->DynamicBase::trace(trc);
|
||||
if (str)
|
||||
js::TraceEdge(trc, &str, "test container");
|
||||
}
|
||||
};
|
||||
|
||||
namespace js {
|
||||
template <>
|
||||
struct RootedBase<DynamicContainer> {
|
||||
RelocatablePtrObject& obj() { return static_cast<Rooted<DynamicContainer>*>(this)->get().obj; }
|
||||
RelocatablePtrString& str() { return static_cast<Rooted<DynamicContainer>*>(this)->get().str; }
|
||||
};
|
||||
} // namespace js
|
||||
|
||||
BEGIN_TEST(testGCRootedDynamicStructInternalStackStorage)
|
||||
{
|
||||
JS::Rooted<DynamicContainer> container(cx);
|
||||
container.get().obj = JS_NewObject(cx, nullptr);
|
||||
container.get().str = JS_NewStringCopyZ(cx, "Hello");
|
||||
|
||||
JS_GC(cx->runtime());
|
||||
JS_GC(cx->runtime());
|
||||
|
||||
JS::RootedObject obj(cx, container.get().obj);
|
||||
JS::RootedValue val(cx, StringValue(container.get().str));
|
||||
CHECK(JS_SetProperty(cx, obj, "foo", val));
|
||||
return true;
|
||||
}
|
||||
END_TEST(testGCRootedDynamicStructInternalStackStorage)
|
||||
|
||||
BEGIN_TEST(testGCRootedDynamicStructInternalStackStorageAugmented)
|
||||
{
|
||||
JS::Rooted<DynamicContainer> container(cx);
|
||||
container.obj() = JS_NewObject(cx, nullptr);
|
||||
container.str() = JS_NewStringCopyZ(cx, "Hello");
|
||||
|
||||
JS_GC(cx->runtime());
|
||||
JS_GC(cx->runtime());
|
||||
|
||||
JS::RootedObject obj(cx, container.obj());
|
||||
JS::RootedValue val(cx, StringValue(container.str()));
|
||||
CHECK(JS_SetProperty(cx, obj, "foo", val));
|
||||
return true;
|
||||
}
|
||||
END_TEST(testGCRootedDynamicStructInternalStackStorageAugmented)
|
||||
|
||||
using MyHashMap = js::TraceableHashMap<js::Shape*, JSObject*>;
|
||||
|
||||
BEGIN_TEST(testGCRootedHashMap)
|
||||
@ -236,9 +157,10 @@ BEGIN_TEST(testGCHandleHashMap)
|
||||
}
|
||||
END_TEST(testGCHandleHashMap)
|
||||
|
||||
using ShapeVec = TraceableVector<Shape*>;
|
||||
|
||||
BEGIN_TEST(testGCRootedVector)
|
||||
{
|
||||
using ShapeVec = TraceableVector<Shape*>;
|
||||
JS::Rooted<ShapeVec> shapes(cx, ShapeVec(cx));
|
||||
|
||||
for (size_t i = 0; i < 10; ++i) {
|
||||
@ -311,8 +233,6 @@ receiveMutableHandleToShapeVector(JS::MutableHandle<TraceableVector<Shape*>> han
|
||||
}
|
||||
END_TEST(testGCRootedVector)
|
||||
|
||||
using ShapeVec = TraceableVector<Shape*>;
|
||||
|
||||
static bool
|
||||
FillVector(JSContext* cx, MutableHandle<ShapeVec> shapes)
|
||||
{
|
||||
|
@ -2507,7 +2507,7 @@ JS_New(JSContext* cx, JS::HandleObject ctor, const JS::HandleValueArray& args);
|
||||
|
||||
/*** Property descriptors ************************************************************************/
|
||||
|
||||
struct JSPropertyDescriptor : public JS::StaticTraceable {
|
||||
struct JSPropertyDescriptor : public JS::Traceable {
|
||||
JSObject* obj;
|
||||
unsigned attrs;
|
||||
JSGetterOp getter;
|
||||
|
@ -285,8 +285,7 @@ enum ThingRootKind
|
||||
THING_ROOT_LAZY_SCRIPT,
|
||||
THING_ROOT_ID,
|
||||
THING_ROOT_VALUE,
|
||||
THING_ROOT_STATIC_TRACEABLE,
|
||||
THING_ROOT_DYNAMIC_TRACEABLE,
|
||||
THING_ROOT_TRACEABLE,
|
||||
THING_ROOT_LIMIT
|
||||
};
|
||||
|
||||
|
@ -206,7 +206,7 @@ JS_STATIC_ASSERT(sizeof(Binding) == sizeof(uintptr_t));
|
||||
* both function and top-level scripts (the latter is needed to track names in
|
||||
* strict mode eval code, to give such code its own lexical environment).
|
||||
*/
|
||||
class Bindings : public JS::StaticTraceable
|
||||
class Bindings : public JS::Traceable
|
||||
{
|
||||
friend class BindingIter;
|
||||
friend class AliasedFormalIter;
|
||||
|
@ -1173,7 +1173,7 @@ struct DefaultHasher<AbstractFramePtr> {
|
||||
// entries that must be scanned through, and to avoid the headaches of
|
||||
// maintaining a cache for each compartment and invalidating stale cache entries
|
||||
// in the presence of cross-compartment calls.
|
||||
class LiveSavedFrameCache : public JS::StaticTraceable
|
||||
class LiveSavedFrameCache : public JS::Traceable
|
||||
{
|
||||
public:
|
||||
using FramePtr = mozilla::Variant<AbstractFramePtr, jit::CommonFrameLayout*>;
|
||||
|
@ -272,7 +272,7 @@ class TypeSet
|
||||
// Information about a single concrete type. We pack this into one word,
|
||||
// where small values are particular primitive or other singleton types and
|
||||
// larger values are either specific JS objects or object groups.
|
||||
class Type : public JS::StaticTraceable
|
||||
class Type : public JS::Traceable
|
||||
{
|
||||
friend class TypeSet;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user