Bug 1205454 - Consolidate the tagged pointer marking methods; r=sfink

This commit is contained in:
Terrence Cole 2015-09-17 10:57:55 -07:00
parent b46913f17d
commit d4611b5958
14 changed files with 92 additions and 158 deletions

View File

@ -245,6 +245,24 @@ operator!=(const GCCellPtr& ptr1, const GCCellPtr& ptr2)
return !(ptr1 == ptr2); return !(ptr1 == ptr2);
} }
// Unwraps the given GCCellPtr and calls the given functor with a template
// argument of the actual type of the pointer.
template <typename F, typename... Args>
auto
DispatchTyped(F f, GCCellPtr thing, Args&&... args)
-> decltype(f(static_cast<JSObject*>(nullptr), mozilla::Forward<Args>(args)...))
{
switch (thing.kind()) {
#define JS_EXPAND_DEF(name, type, _) \
case JS::TraceKind::name: \
return f(&thing.as<type>(), mozilla::Forward<Args>(args)...);
JS_FOR_EACH_TRACEKIND(JS_EXPAND_DEF);
#undef JS_EXPAND_DEF
default:
MOZ_CRASH("Invalid trace kind in DispatchTyped for GCCellPtr.");
}
}
} /* namespace JS */ } /* namespace JS */
namespace js { namespace js {

View File

@ -178,7 +178,7 @@ template <> struct GCMethods<jsid>
// the pointer. If the jsid is not a GC type, calls F::defaultValue. // the pointer. If the jsid is not a GC type, calls F::defaultValue.
template <typename F, typename... Args> template <typename F, typename... Args>
auto auto
DispatchIdTyped(F f, jsid& id, Args&&... args) DispatchTyped(F f, jsid& id, Args&&... args)
-> decltype(f(static_cast<JSString*>(nullptr), mozilla::Forward<Args>(args)...)) -> decltype(f(static_cast<JSString*>(nullptr), mozilla::Forward<Args>(args)...))
{ {
if (JSID_IS_STRING(id)) if (JSID_IS_STRING(id))

View File

@ -125,7 +125,7 @@ DispatchTraceKindTyped(F f, JS::TraceKind traceKind, Args&&... args)
template <typename F, typename... Args> template <typename F, typename... Args>
auto auto
DispatchTraceKindTyped(F f, void* thing, JS::TraceKind traceKind, Args&&... args) DispatchTraceKindTyped(F f, void* thing, JS::TraceKind traceKind, Args&&... args)
-> decltype(f(reinterpret_cast<JSObject*>(0), mozilla::Forward<Args>(args)...)) -> decltype(f(static_cast<JSObject*>(nullptr), mozilla::Forward<Args>(args)...))
{ {
switch (traceKind) { switch (traceKind) {
#define JS_EXPAND_DEF(name, type, _) \ #define JS_EXPAND_DEF(name, type, _) \

View File

@ -1832,7 +1832,7 @@ class PersistentRootedBase<JS::Value> : public MutableValueOperations<JS::Persis
*/ */
template <typename F, typename... Args> template <typename F, typename... Args>
auto auto
DispatchValueTyped(F f, const JS::Value& val, Args&&... args) DispatchTyped(F f, const JS::Value& val, Args&&... args)
-> decltype(f(static_cast<JSObject*>(nullptr), mozilla::Forward<Args>(args)...)) -> decltype(f(static_cast<JSObject*>(nullptr), mozilla::Forward<Args>(args)...))
{ {
if (val.isString()) if (val.isString())

View File

@ -261,7 +261,7 @@ struct InternalGCMethods<Value>
static bool isMarkableTaggedPointer(Value v) { return isMarkable(v); } static bool isMarkableTaggedPointer(Value v) { return isMarkable(v); }
static void preBarrier(Value v) { static void preBarrier(Value v) {
DispatchValueTyped(PreBarrierFunctor<Value>(), v); DispatchTyped(PreBarrierFunctor<Value>(), v);
} }
static void postBarrier(Value* vp, const Value& prev, const Value& next) { static void postBarrier(Value* vp, const Value& prev, const Value& next) {
@ -286,7 +286,7 @@ struct InternalGCMethods<Value>
} }
static void readBarrier(const Value& v) { static void readBarrier(const Value& v) {
DispatchValueTyped(ReadBarrierFunctor<Value>(), v); DispatchTyped(ReadBarrierFunctor<Value>(), v);
} }
}; };
@ -296,7 +296,7 @@ struct InternalGCMethods<jsid>
static bool isMarkable(jsid id) { return JSID_IS_STRING(id) || JSID_IS_SYMBOL(id); } static bool isMarkable(jsid id) { return JSID_IS_STRING(id) || JSID_IS_SYMBOL(id); }
static bool isMarkableTaggedPointer(jsid id) { return isMarkable(id); } static bool isMarkableTaggedPointer(jsid id) { return isMarkable(id); }
static void preBarrier(jsid id) { DispatchIdTyped(PreBarrierFunctor<jsid>(), id); } static void preBarrier(jsid id) { DispatchTyped(PreBarrierFunctor<jsid>(), id); }
static void postBarrier(jsid* idp, jsid prev, jsid next) {} static void postBarrier(jsid* idp, jsid prev, jsid next) {}
}; };

View File

@ -172,7 +172,7 @@ template <> bool ThingIsPermanentAtomOrWellKnownSymbol<JS::Symbol>(JS::Symbol* s
template<typename T> template<typename T>
void void
js::CheckTracedThing(JSTracer* trc, T thing) js::CheckTracedThing(JSTracer* trc, T* thing)
{ {
#ifdef DEBUG #ifdef DEBUG
MOZ_ASSERT(trc); MOZ_ASSERT(trc);
@ -242,30 +242,16 @@ struct CheckTracedFunctor : public VoidDefaultAdaptor<S> {
template <typename T> void operator()(T* t, JSTracer* trc) { CheckTracedThing(trc, t); } template <typename T> void operator()(T* t, JSTracer* trc) { CheckTracedThing(trc, t); }
}; };
template<typename T>
void
js::CheckTracedThing(JSTracer* trc, T thing)
{
DispatchTyped(CheckTracedFunctor<T>(), thing, trc);
}
namespace js { namespace js {
template<>
void
CheckTracedThing<Value>(JSTracer* trc, Value val)
{
DispatchValueTyped(CheckTracedFunctor<Value>(), val, trc);
}
template <>
void
CheckTracedThing<jsid>(JSTracer* trc, jsid id)
{
DispatchIdTyped(CheckTracedFunctor<jsid>(), id, trc);
}
template <>
void
CheckTracedThing<TaggedProto>(JSTracer* trc, TaggedProto proto)
{
DispatchTaggedProtoTyped(CheckTracedFunctor<TaggedProto>(), proto, trc);
}
#define IMPL_CHECK_TRACED_THING(_, type, __) \ #define IMPL_CHECK_TRACED_THING(_, type, __) \
template void CheckTracedThing<type*>(JSTracer*, type*); template void CheckTracedThing<type>(JSTracer*, type*);
JS_FOR_EACH_TRACEKIND(IMPL_CHECK_TRACED_THING); JS_FOR_EACH_TRACEKIND(IMPL_CHECK_TRACED_THING);
#undef IMPL_CHECK_TRACED_THING #undef IMPL_CHECK_TRACED_THING
} // namespace js } // namespace js
@ -427,10 +413,7 @@ JS_FOR_EACH_TRACEKIND(IMPL_BASE_GC_TYPE);
// share the definitions with Value and jsid. Thus, we need to strip the // share the definitions with Value and jsid. Thus, we need to strip the
// pointer before sending the type to BaseGCType and re-add it on the other // pointer before sending the type to BaseGCType and re-add it on the other
// side. As such: // side. As such:
template <typename T> struct PtrBaseGCType {}; template <typename T> struct PtrBaseGCType { typedef T type; };
template <> struct PtrBaseGCType<Value> { typedef Value type; };
template <> struct PtrBaseGCType<jsid> { typedef jsid type; };
template <> struct PtrBaseGCType<TaggedProto> { typedef TaggedProto type; };
template <typename T> struct PtrBaseGCType<T*> { typedef typename BaseGCType<T>::type* type; }; template <typename T> struct PtrBaseGCType<T*> { typedef typename BaseGCType<T>::type* type; };
template <typename T> template <typename T>
@ -442,6 +425,7 @@ ConvertToBase(T* thingp)
template <typename T> void DispatchToTracer(JSTracer* trc, T* thingp, const char* name); template <typename T> void DispatchToTracer(JSTracer* trc, T* thingp, const char* name);
template <typename T> T DoCallback(JS::CallbackTracer* trc, T* thingp, const char* name); template <typename T> T DoCallback(JS::CallbackTracer* trc, T* thingp, const char* name);
template <typename T> void DoMarking(GCMarker* gcmarker, T* thing);
template <typename T> void DoMarking(GCMarker* gcmarker, T thing); template <typename T> void DoMarking(GCMarker* gcmarker, T thing);
template <typename T> template <typename T>
@ -735,7 +719,7 @@ MustSkipMarking<JS::Symbol*>(JS::Symbol* sym)
template <typename T> template <typename T>
void void
DoMarking(GCMarker* gcmarker, T thing) DoMarking(GCMarker* gcmarker, T* thing)
{ {
// Do per-type marking precondition checks. // Do per-type marking precondition checks.
if (MustSkipMarking(thing)) if (MustSkipMarking(thing))
@ -753,26 +737,11 @@ struct DoMarkingFunctor : public VoidDefaultAdaptor<S> {
template <typename T> void operator()(T* t, GCMarker* gcmarker) { DoMarking(gcmarker, t); } template <typename T> void operator()(T* t, GCMarker* gcmarker) { DoMarking(gcmarker, t); }
}; };
template <> template <typename T>
void void
DoMarking<Value>(GCMarker* gcmarker, Value val) DoMarking(GCMarker* gcmarker, T thing)
{ {
DispatchValueTyped(DoMarkingFunctor<Value>(), val, gcmarker); DispatchTyped(DoMarkingFunctor<T>(), thing, gcmarker);
}
template <>
void
DoMarking<jsid>(GCMarker* gcmarker, jsid id)
{
DispatchIdTyped(DoMarkingFunctor<jsid>(), id, gcmarker);
}
template <>
void
DoMarking<TaggedProto>(GCMarker* gcmarker, TaggedProto proto)
{
if (proto.isObject())
DoMarking<JSObject*>(gcmarker, proto.toObject());
} }
// The simplest traversal calls out to the fully generic traceChildren function // The simplest traversal calls out to the fully generic traceChildren function
@ -843,7 +812,7 @@ GCMarker::traverse(AccessorShape* thing) {
template <typename S, typename T> template <typename S, typename T>
void void
js::GCMarker::traverseEdge(S source, T target) js::GCMarker::traverseEdge(S source, T* target)
{ {
// Atoms and Symbols do not have or mark their internal pointers, respectively. // Atoms and Symbols do not have or mark their internal pointers, respectively.
MOZ_ASSERT(!ThingIsPermanentAtomOrWellKnownSymbol(source)); MOZ_ASSERT(!ThingIsPermanentAtomOrWellKnownSymbol(source));
@ -869,18 +838,11 @@ template <typename V, typename S> struct TraverseEdgeFunctor : public VoidDefaul
} }
}; };
template <typename S> template <typename S, typename T>
void void
js::GCMarker::traverseEdge(S source, jsid id) js::GCMarker::traverseEdge(S source, T thing)
{ {
DispatchIdTyped(TraverseEdgeFunctor<jsid, S>(), id, this, source); DispatchTyped(TraverseEdgeFunctor<T, S>(), thing, this, source);
}
template <typename S>
void
js::GCMarker::traverseEdge(S source, Value v)
{
DispatchValueTyped(TraverseEdgeFunctor<Value, S>(), v, this, source);
} }
template <typename T> template <typename T>
@ -1897,6 +1859,12 @@ GCMarker::sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const
/*** Tenuring Tracer *****************************************************************************/ /*** Tenuring Tracer *****************************************************************************/
namespace js { namespace js {
template <typename T>
void
TenuringTracer::traverse(T** tp)
{
}
template <> template <>
void void
TenuringTracer::traverse(JSObject** objp) TenuringTracer::traverse(JSObject** objp)
@ -1908,39 +1876,20 @@ TenuringTracer::traverse(JSObject** objp)
*objp = moveToTenured(*objp); *objp = moveToTenured(*objp);
} }
template <> 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);
}
};
template <typename T>
void void
TenuringTracer::traverse(Value* valp) TenuringTracer::traverse(T* thingp)
{ {
if (!valp->isObject()) *thingp = DispatchTyped(TenuringTraversalFunctor<T>(), *thingp, this);
return;
JSObject *obj = &valp->toObject();
traverse(&obj);
valp->setObject(*obj);
} }
template <>
void
TenuringTracer::traverse(TaggedProto* protop)
{
if (!protop->isObject())
return;
JSObject *obj = protop->toObject();
traverse(&obj);
*protop = TaggedProto(obj);
}
template <> void js::TenuringTracer::traverse(js::BaseShape**) {}
template <> void js::TenuringTracer::traverse(js::jit::JitCode**) {}
template <> void js::TenuringTracer::traverse(JSScript**) {}
template <> void js::TenuringTracer::traverse(js::LazyScript**) {}
template <> void js::TenuringTracer::traverse(js::Shape**) {}
template <> void js::TenuringTracer::traverse(JSString**) {}
template <> void js::TenuringTracer::traverse(JS::Symbol**) {}
template <> void js::TenuringTracer::traverse(js::ObjectGroup**) {}
template <> void js::TenuringTracer::traverse(jsid*) {}
} // namespace js } // namespace js
template <typename T> template <typename T>
@ -2310,13 +2259,13 @@ IsMarkedInternalCommon(T* thingp)
template <typename T> template <typename T>
static bool static bool
IsMarkedInternal(T* thingp) IsMarkedInternal(T** thingp)
{ {
return IsMarkedInternalCommon(thingp); return IsMarkedInternalCommon(thingp);
} }
template <typename T> template <>
static bool /* static */ bool
IsMarkedInternal(JSObject** thingp) IsMarkedInternal(JSObject** thingp)
{ {
if (IsInsideNursery(*thingp)) { if (IsInsideNursery(*thingp)) {
@ -2335,39 +2284,21 @@ struct IsMarkedFunctor : public IdentityDefaultAdaptor<S> {
} }
}; };
template <> template <typename T>
bool static bool
IsMarkedInternal<Value>(Value* valuep) IsMarkedInternal(T* thingp)
{ {
bool rv = true; bool rv = true;
*valuep = DispatchValueTyped(IsMarkedFunctor<Value>(), *valuep, &rv); *thingp = DispatchTyped(IsMarkedFunctor<T>(), *thingp, &rv);
return rv;
}
template <>
bool
IsMarkedInternal<jsid>(jsid* idp)
{
bool rv = true;
*idp = DispatchIdTyped(IsMarkedFunctor<jsid>(), *idp, &rv);
return rv;
}
template <>
bool
IsMarkedInternal<TaggedProto>(TaggedProto* protop)
{
bool rv = true;
*protop = DispatchTaggedProtoTyped(IsMarkedFunctor<TaggedProto>(), *protop, &rv);
return rv; return rv;
} }
template <typename T> template <typename T>
static bool static bool
IsAboutToBeFinalizedInternal(T* thingp) IsAboutToBeFinalizedInternal(T** thingp)
{ {
CheckIsMarkedThing(thingp); CheckIsMarkedThing(thingp);
T thing = *thingp; T* thing = *thingp;
JSRuntime* rt = thing->runtimeFromAnyThread(); JSRuntime* rt = thing->runtimeFromAnyThread();
/* Permanent atoms are never finalized by non-owning runtimes. */ /* Permanent atoms are never finalized by non-owning runtimes. */
@ -2404,30 +2335,12 @@ struct IsAboutToBeFinalizedFunctor : public IdentityDefaultAdaptor<S> {
} }
}; };
template <> template <typename T>
bool static bool
IsAboutToBeFinalizedInternal<Value>(Value* valuep) IsAboutToBeFinalizedInternal(T* thingp)
{ {
bool rv = false; bool rv = false;
*valuep = DispatchValueTyped(IsAboutToBeFinalizedFunctor<Value>(), *valuep, &rv); *thingp = DispatchTyped(IsAboutToBeFinalizedFunctor<T>(), *thingp, &rv);
return rv;
}
template <>
bool
IsAboutToBeFinalizedInternal<jsid>(jsid* idp)
{
bool rv = false;
*idp = DispatchIdTyped(IsAboutToBeFinalizedFunctor<jsid>(), *idp, &rv);
return rv;
}
template <>
bool
IsAboutToBeFinalizedInternal<TaggedProto>(TaggedProto* protop)
{
bool rv = false;
*protop = DispatchTaggedProtoTyped(IsAboutToBeFinalizedFunctor<TaggedProto>(), *protop, &rv);
return rv; return rv;
} }

View File

@ -183,10 +183,8 @@ class GCMarker : public JSTracer
template <typename T> void traverse(T thing); template <typename T> void traverse(T thing);
// Calls traverse on target after making additional assertions. // Calls traverse on target after making additional assertions.
template <typename S, typename T> void traverseEdge(S source, T* target);
template <typename S, typename T> void traverseEdge(S source, T target); template <typename S, typename T> void traverseEdge(S source, T target);
// C++ requires explicit declarations of partial template instantiations.
template <typename S> void traverseEdge(S source, jsid target);
template <typename S> void traverseEdge(S source, Value target);
/* /*
* Care must be taken changing the mark color from gray to black. The cycle * Care must be taken changing the mark color from gray to black. The cycle
@ -471,6 +469,10 @@ DECLARE_REWRAP(js::TaggedProto, JSObject*, js::TaggedProto, );
bool bool
UnmarkGrayShapeRecursively(Shape* shape); UnmarkGrayShapeRecursively(Shape* shape);
template<typename T>
void
CheckTracedThing(JSTracer* trc, T* thing);
template<typename T> template<typename T>
void void
CheckTracedThing(JSTracer* trc, T thing); CheckTracedThing(JSTracer* trc, T thing);

View File

@ -66,6 +66,7 @@ class TenuringTracer : public JSTracer
const Nursery& nursery() const { return nursery_; } const Nursery& nursery() const { return nursery_; }
// Returns true if the pointer was updated. // Returns true if the pointer was updated.
template <typename T> void traverse(T** thingp);
template <typename T> void traverse(T* thingp); template <typename T> void traverse(T* thingp);
void insertIntoFixupList(gc::RelocationOverlay* entry); void insertIntoFixupList(gc::RelocationOverlay* entry);

View File

@ -413,7 +413,7 @@ BufferGrayRootsTracer::onChild(const JS::GCCellPtr& thing)
// objects and scripts. We rely on gray root buffering for this to work, // objects and scripts. We rely on gray root buffering for this to work,
// but we only need to worry about uncollected dead compartments during // but we only need to worry about uncollected dead compartments during
// incremental GCs (when we do gray root buffering). // incremental GCs (when we do gray root buffering).
DispatchTraceKindTyped(SetMaybeAliveFunctor(), tenured, thing.kind()); DispatchTyped(SetMaybeAliveFunctor(), thing);
if (!zone->gcGrayRoots.append(tenured)) if (!zone->gcGrayRoots.append(tenured))
bufferingGrayRootsFailed = true; bufferingGrayRootsFailed = true;

View File

@ -67,7 +67,7 @@ template <>
Value Value
DoCallback<Value>(JS::CallbackTracer* trc, Value* vp, const char* name) DoCallback<Value>(JS::CallbackTracer* trc, Value* vp, const char* name)
{ {
*vp = DispatchValueTyped(DoCallbackFunctor<Value>(), *vp, trc, name); *vp = DispatchTyped(DoCallbackFunctor<Value>(), *vp, trc, name);
return *vp; return *vp;
} }
@ -75,7 +75,7 @@ template <>
jsid jsid
DoCallback<jsid>(JS::CallbackTracer* trc, jsid* idp, const char* name) DoCallback<jsid>(JS::CallbackTracer* trc, jsid* idp, const char* name)
{ {
*idp = DispatchIdTyped(DoCallbackFunctor<jsid>(), *idp, trc, name); *idp = DispatchTyped(DoCallbackFunctor<jsid>(), *idp, trc, name);
return *idp; return *idp;
} }
@ -83,7 +83,7 @@ template <>
TaggedProto TaggedProto
DoCallback<TaggedProto>(JS::CallbackTracer* trc, TaggedProto* protop, const char* name) DoCallback<TaggedProto>(JS::CallbackTracer* trc, TaggedProto* protop, const char* name)
{ {
*protop = DispatchTaggedProtoTyped(DoCallbackFunctor<TaggedProto>(), *protop, trc, name); *protop = DispatchTyped(DoCallbackFunctor<TaggedProto>(), *protop, trc, name);
return *protop; return *protop;
} }

View File

@ -3763,7 +3763,7 @@ CompartmentCheckTracer::onChild(const JS::GCCellPtr& thing)
{ {
TenuredCell* tenured = TenuredCell::fromPointer(thing.asCell()); TenuredCell* tenured = TenuredCell::fromPointer(thing.asCell());
JSCompartment* comp = DispatchTraceKindTyped(MaybeCompartmentFunctor(), tenured, thing.kind()); JSCompartment* comp = DispatchTyped(MaybeCompartmentFunctor(), thing);
if (comp && compartment) { if (comp && compartment) {
MOZ_ASSERT(comp == compartment || runtime()->isAtomsCompartment(comp) || MOZ_ASSERT(comp == compartment || runtime()->isAtomsCompartment(comp) ||
(srcKind == JS::TraceKind::Object && (srcKind == JS::TraceKind::Object &&
@ -7332,7 +7332,7 @@ JS::IncrementalReferenceBarrier(GCCellPtr thing)
if (!thing) if (!thing)
return; return;
DispatchTraceKindTyped(IncrementalReferenceBarrierFunctor(), thing.asCell(), thing.kind()); DispatchTyped(IncrementalReferenceBarrierFunctor(), thing);
} }
JS_PUBLIC_API(void) JS_PUBLIC_API(void)

View File

@ -1189,7 +1189,7 @@ struct IsForwardedFunctor : public BoolDefaultAdaptor<Value, false> {
inline bool inline bool
IsForwarded(const JS::Value& value) IsForwarded(const JS::Value& value)
{ {
return DispatchValueTyped(IsForwardedFunctor(), value); return DispatchTyped(IsForwardedFunctor(), value);
} }
template <typename T> template <typename T>
@ -1210,7 +1210,7 @@ struct ForwardedFunctor : public IdentityDefaultAdaptor<Value> {
inline Value inline Value
Forwarded(const JS::Value& value) Forwarded(const JS::Value& value)
{ {
return DispatchValueTyped(ForwardedFunctor(), value); return DispatchTyped(ForwardedFunctor(), value);
} }
template <typename T> template <typename T>
@ -1246,7 +1246,7 @@ struct CheckValueAfterMovingGCFunctor : public VoidDefaultAdaptor<Value> {
inline void inline void
CheckValueAfterMovingGC(const JS::Value& value) CheckValueAfterMovingGC(const JS::Value& value)
{ {
DispatchValueTyped(CheckValueAfterMovingGCFunctor(), value); DispatchTyped(CheckValueAfterMovingGCFunctor(), value);
} }
#endif // JSGC_HASH_TABLE_CHECKS #endif // JSGC_HASH_TABLE_CHECKS

View File

@ -104,7 +104,7 @@ class BarrieredBaseMixins<TaggedProto> : public TaggedProtoOperations<HeapPtr<Ta
// with the pointer. If the TaggedProto is lazy, calls F::defaultValue. // with the pointer. If the TaggedProto is lazy, calls F::defaultValue.
template <typename F, typename... Args> template <typename F, typename... Args>
auto auto
DispatchTaggedProtoTyped(F f, TaggedProto& proto, Args&&... args) DispatchTyped(F f, TaggedProto& proto, Args&&... args)
-> decltype(f(static_cast<JSObject*>(nullptr), mozilla::Forward<Args>(args)...)) -> decltype(f(static_cast<JSObject*>(nullptr), mozilla::Forward<Args>(args)...))
{ {
if (proto.isObject()) if (proto.isObject())

View File

@ -37,7 +37,7 @@
using mozilla::Some; using mozilla::Some;
using mozilla::RangedPtr; using mozilla::RangedPtr;
using mozilla::UniquePtr; using mozilla::UniquePtr;
using JS::DispatchTraceKindTyped; using JS::DispatchTyped;
using JS::HandleValue; using JS::HandleValue;
using JS::Value; using JS::Value;
using JS::ZoneSet; using JS::ZoneSet;
@ -166,12 +166,12 @@ struct Node::ConstructFunctor : public js::BoolDefaultAdaptor<Value, false> {
Node::Node(const JS::GCCellPtr &thing) Node::Node(const JS::GCCellPtr &thing)
{ {
DispatchTraceKindTyped(ConstructFunctor(), thing.asCell(), thing.kind(), this); DispatchTyped(ConstructFunctor(), thing, this);
} }
Node::Node(HandleValue value) Node::Node(HandleValue value)
{ {
if (!DispatchValueTyped(ConstructFunctor(), value, this)) if (!DispatchTyped(ConstructFunctor(), value, this))
construct<void>(nullptr); construct<void>(nullptr);
} }