Bug 1188445 - Allow PersistentRooted to store StaticTraceable; r=sfink

--HG--
extra : rebase_source : 822ae00de85dc8c32158628fb89ae1463e185aea
This commit is contained in:
Terrence Cole 2015-07-28 09:21:32 -07:00
parent 59f4a2e6df
commit 3940b5fcb7
4 changed files with 58 additions and 2 deletions

View File

@ -1021,6 +1021,7 @@ class PersistentRooted : public js::PersistentRootedBase<T>,
kind == js::THING_ROOT_STRING ||
kind == js::THING_ROOT_ID ||
kind == js::THING_ROOT_VALUE ||
kind == js::THING_ROOT_STATIC_TRACEABLE ||
kind == js::THING_ROOT_DYNAMIC_TRACEABLE);
}
@ -1101,7 +1102,13 @@ class PersistentRooted : public js::PersistentRootedBase<T>,
ptr = value;
}
T ptr;
// See the comment above Rooted::ptr.
using MaybeWrapped = typename mozilla::Conditional<
mozilla::IsBaseOf<StaticTraceable, T>::value,
js::DispatchWrapper<T>,
T>::Type;
MaybeWrapped ptr;
};
class JS_PUBLIC_API(ObjectPtr)

View File

@ -333,10 +333,15 @@ js::gc::MarkPersistentRootedChainsInLists(RootLists& roots, JSTracer* trc)
PersistentRootedMarker<Value>::markChain(trc, roots.getPersistentRootedList<Value>(),
"PersistentRooted<Value>");
PersistentRootedMarker<JS::StaticTraceable>::markChain<
js::DispatchWrapper<JS::StaticTraceable>::TraceWrapped>(trc,
reinterpret_cast<mozilla::LinkedList<JS::PersistentRooted<JS::StaticTraceable>>&>(
roots.heapRoots_[THING_ROOT_STATIC_TRACEABLE]),
"PersistentRooted<StaticTraceable>");
PersistentRootedMarker<ConcreteTraceable>::markChain<MarkDynamicTraceable>(trc,
reinterpret_cast<mozilla::LinkedList<JS::PersistentRooted<ConcreteTraceable>>&>(
roots.heapRoots_[THING_ROOT_DYNAMIC_TRACEABLE]),
"PersistentRooted<Value>");
"PersistentRooted<DynamicTraceable>");
}
void

View File

@ -60,6 +60,15 @@ struct RootedBase<MyContainer> {
RelocatablePtrObject& obj() { return static_cast<Rooted<MyContainer>*>(this)->get().obj; }
RelocatablePtrString& str() { return static_cast<Rooted<MyContainer>*>(this)->get().str; }
};
template <>
struct PersistentRootedBase<MyContainer> {
RelocatablePtrObject& obj() {
return static_cast<PersistentRooted<MyContainer>*>(this)->get().obj;
}
RelocatablePtrString& str() {
return static_cast<PersistentRooted<MyContainer>*>(this)->get().str;
}
};
} // namespace js
BEGIN_TEST(testGCRootedStaticStructInternalStackStorage)
@ -90,6 +99,40 @@ BEGIN_TEST(testGCRootedStaticStructInternalStackStorageAugmented)
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<MyContainer> 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(testGCRootedStaticStructInternalStackStorageAugmented)

View File

@ -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_STATIC_TRACEABLE]);
FinishPersistentRootedChain(roots.heapRoots_[THING_ROOT_DYNAMIC_TRACEABLE]);
}