mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1188197 - Allow PersistentRooted to store DynamicTraceable; r=sfink
This commit is contained in:
parent
5b850bd74e
commit
0d78b57012
@ -997,6 +997,10 @@ template<typename T>
|
||||
class PersistentRooted : public js::PersistentRootedBase<T>,
|
||||
private mozilla::LinkedListElement<PersistentRooted<T>>
|
||||
{
|
||||
static_assert(!mozilla::IsConvertible<T, StaticTraceable*>::value &&
|
||||
!mozilla::IsConvertible<T, DynamicTraceable*>::value,
|
||||
"Rooted takes pointer or Traceable types but not Traceable* type");
|
||||
|
||||
typedef mozilla::LinkedListElement<PersistentRooted<T>> ListBase;
|
||||
|
||||
friend class mozilla::LinkedList<PersistentRooted>;
|
||||
@ -1016,7 +1020,8 @@ class PersistentRooted : public js::PersistentRootedBase<T>,
|
||||
kind == js::THING_ROOT_SCRIPT ||
|
||||
kind == js::THING_ROOT_STRING ||
|
||||
kind == js::THING_ROOT_ID ||
|
||||
kind == js::THING_ROOT_VALUE);
|
||||
kind == js::THING_ROOT_VALUE ||
|
||||
kind == js::THING_ROOT_DYNAMIC_TRACEABLE);
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -304,13 +304,14 @@ struct PersistentRootedMarker
|
||||
{
|
||||
typedef PersistentRooted<T> Element;
|
||||
typedef mozilla::LinkedList<Element> List;
|
||||
typedef void (*MarkFunc)(JSTracer* trc, T* ref, const char* name);
|
||||
using TraceFunc = void (*)(JSTracer* trc, T* ref, const char* name);
|
||||
|
||||
template <TraceFunction<T> TraceFn = TraceNullableRoot>
|
||||
static void
|
||||
markChain(JSTracer* trc, List& list, const char* name)
|
||||
{
|
||||
for (Element* r = list.getFirst(); r; r = r->getNext())
|
||||
TraceNullableRoot(trc, r->address(), name);
|
||||
TraceFn(trc, r->address(), name);
|
||||
}
|
||||
};
|
||||
|
||||
@ -331,6 +332,11 @@ js::gc::MarkPersistentRootedChainsInLists(RootLists& roots, JSTracer* trc)
|
||||
"PersistentRooted<jsid>");
|
||||
PersistentRootedMarker<Value>::markChain(trc, roots.getPersistentRootedList<Value>(),
|
||||
"PersistentRooted<Value>");
|
||||
|
||||
PersistentRootedMarker<ConcreteTraceable>::markChain<MarkDynamicTraceable>(trc,
|
||||
reinterpret_cast<mozilla::LinkedList<JS::PersistentRooted<ConcreteTraceable>>&>(
|
||||
roots.heapRoots_[THING_ROOT_DYNAMIC_TRACEABLE]),
|
||||
"PersistentRooted<Value>");
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -123,6 +123,15 @@ struct RootedBase<DynamicContainer> {
|
||||
RelocatablePtrObject& obj() { return static_cast<Rooted<DynamicContainer>*>(this)->get().obj; }
|
||||
RelocatablePtrString& str() { return static_cast<Rooted<DynamicContainer>*>(this)->get().str; }
|
||||
};
|
||||
template <>
|
||||
struct PersistentRootedBase<DynamicContainer> {
|
||||
RelocatablePtrObject& obj() {
|
||||
return static_cast<PersistentRooted<DynamicContainer>*>(this)->get().obj;
|
||||
}
|
||||
RelocatablePtrString& str() {
|
||||
return static_cast<PersistentRooted<DynamicContainer>*>(this)->get().str;
|
||||
}
|
||||
};
|
||||
} // namespace js
|
||||
|
||||
BEGIN_TEST(testGCRootedDynamicStructInternalStackStorage)
|
||||
@ -153,6 +162,40 @@ BEGIN_TEST(testGCRootedDynamicStructInternalStackStorageAugmented)
|
||||
JS::RootedObject obj(cx, container.obj());
|
||||
JS::RootedValue val(cx, StringValue(container.str()));
|
||||
CHECK(JS_SetProperty(cx, obj, "foo", val));
|
||||
obj = nullptr;
|
||||
val = UndefinedValue();
|
||||
|
||||
{
|
||||
JS::RootedString actual(cx);
|
||||
bool same;
|
||||
|
||||
// Automatic move from stack to heap.
|
||||
JS::PersistentRooted<DynamicContainer> heap(cx, container);
|
||||
|
||||
// clear prior rooting.
|
||||
container.obj() = nullptr;
|
||||
container.str() = nullptr;
|
||||
|
||||
obj = heap.obj();
|
||||
CHECK(JS_GetProperty(cx, obj, "foo", &val));
|
||||
actual = val.toString();
|
||||
CHECK(JS_StringEqualsAscii(cx, actual, "Hello", &same));
|
||||
CHECK(same);
|
||||
obj = nullptr;
|
||||
actual = nullptr;
|
||||
|
||||
JS_GC(cx->runtime());
|
||||
JS_GC(cx->runtime());
|
||||
|
||||
obj = heap.obj();
|
||||
CHECK(JS_GetProperty(cx, obj, "foo", &val));
|
||||
actual = val.toString();
|
||||
CHECK(JS_StringEqualsAscii(cx, actual, "Hello", &same));
|
||||
CHECK(same);
|
||||
obj = nullptr;
|
||||
actual = nullptr;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
END_TEST(testGCRootedDynamicStructInternalStackStorageAugmented)
|
||||
@ -232,6 +275,16 @@ BEGIN_TEST(testGCHandleHashMap)
|
||||
|
||||
CHECK(CheckMyHashMap(cx, map));
|
||||
|
||||
// Unfortunately, the type of get() needs to be non-const ref, so
|
||||
// we need to explicitly Move the storage.
|
||||
JS::PersistentRooted<MyHashMap> heapMap(cx, mozilla::Move(map.get()));
|
||||
CHECK(CheckMyHashMap(cx, heapMap));
|
||||
|
||||
JS_GC(rt);
|
||||
JS_GC(rt);
|
||||
|
||||
CHECK(CheckMyHashMap(cx, heapMap));
|
||||
|
||||
return true;
|
||||
}
|
||||
END_TEST(testGCHandleHashMap)
|
||||
|
@ -1371,6 +1371,7 @@ js::gc::FinishPersistentRootedChains(RootLists& roots)
|
||||
FinishPersistentRootedChain(roots.getPersistentRootedList<JSString*>());
|
||||
FinishPersistentRootedChain(roots.getPersistentRootedList<jsid>());
|
||||
FinishPersistentRootedChain(roots.getPersistentRootedList<Value>());
|
||||
FinishPersistentRootedChain(roots.heapRoots_[THING_ROOT_DYNAMIC_TRACEABLE]);
|
||||
}
|
||||
|
||||
void
|
||||
|
Loading…
Reference in New Issue
Block a user