Skip to content

Commit

Permalink
Bug 1235598 - Part 1: Add better SpiderMonkey API support for tracing…
Browse files Browse the repository at this point in the history
… in C++; r=sfink

--HG--
extra : rebase_source : 8e2a38d3eedc0bc795be696ca36759c153e3b34e
  • Loading branch information
Terrence Cole committed Dec 30, 2015
1 parent 2b36133 commit dbe0679
Show file tree
Hide file tree
Showing 7 changed files with 54 additions and 82 deletions.
47 changes: 18 additions & 29 deletions js/public/TracingAPI.h
Original file line number Diff line number Diff line change
Expand Up @@ -281,40 +281,29 @@ JSTracer::asCallbackTracer()
return static_cast<JS::CallbackTracer*>(this);
}

// The JS_Call*Tracer family of functions traces the given GC thing reference.
// This performs the tracing action configured on the given JSTracer:
// typically calling the JSTracer::callback or marking the thing as live.
//
// The argument to JS_Call*Tracer is an in-out param: when the function
// returns, the garbage collector might have moved the GC thing. In this case,
// the reference passed to JS_Call*Tracer will be updated to the object's new
// location. Callers of this method are responsible for updating any state
// that is dependent on the object's address. For example, if the object's
// address is used as a key in a hashtable, then the object must be removed
// and re-inserted with the correct hash.
//
extern JS_PUBLIC_API(void)
JS_CallValueTracer(JSTracer* trc, JS::Heap<JS::Value>* valuep, const char* name);

extern JS_PUBLIC_API(void)
JS_CallIdTracer(JSTracer* trc, JS::Heap<jsid>* idp, const char* name);

extern JS_PUBLIC_API(void)
JS_CallObjectTracer(JSTracer* trc, JS::Heap<JSObject*>* objp, const char* name);

extern JS_PUBLIC_API(void)
JS_CallStringTracer(JSTracer* trc, JS::Heap<JSString*>* strp, const char* name);

extern JS_PUBLIC_API(void)
JS_CallScriptTracer(JSTracer* trc, JS::Heap<JSScript*>* scriptp, const char* name);
namespace JS {

// The JS::TraceEdge family of functions traces the given GC thing reference.
// This performs the tracing action configured on the given JSTracer: typically
// calling the JSTracer::callback or marking the thing as live.
//
// The argument to JS::TraceEdge is an in-out param: when the function returns,
// the garbage collector might have moved the GC thing. In this case, the
// reference passed to JS::TraceEdge will be updated to the thing's new
// location. Callers of this method are responsible for updating any state that
// is dependent on the object's address. For example, if the object's address
// is used as a key in a hashtable, then the object must be removed and
// re-inserted with the correct hash.
template <typename T>
extern JS_PUBLIC_API(void)
JS_CallFunctionTracer(JSTracer* trc, JS::Heap<JSFunction*>* funp, const char* name);
TraceEdge(JSTracer* trc, JS::Heap<T>* edgep, const char* name);

namespace JS {
// As with JS::TraceEdge, but checks if *edgep is a nullptr before proceeding.
// Note that edgep itself must always be non-null.
template <typename T>
extern JS_PUBLIC_API(void)
TraceEdge(JSTracer* trc, JS::Heap<T>* edgep, const char* name);
TraceNullableEdge(JSTracer* trc, JS::Heap<T>* edgep, const char* name);

} // namespace JS

// The following JS_CallUnbarriered*Tracer functions should only be called where
Expand Down
12 changes: 6 additions & 6 deletions js/src/ctypes/CTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4106,10 +4106,10 @@ CType::Trace(JSTracer* trc, JSObject* obj)
MOZ_ASSERT(fninfo);

// Identify our objects to the tracer.
JS_CallObjectTracer(trc, &fninfo->mABI, "abi");
JS_CallObjectTracer(trc, &fninfo->mReturnType, "returnType");
JS::TraceEdge(trc, &fninfo->mABI, "abi");
JS::TraceEdge(trc, &fninfo->mReturnType, "returnType");
for (size_t i = 0; i < fninfo->mArgTypes.length(); ++i)
JS_CallObjectTracer(trc, &fninfo->mArgTypes[i], "argType");
JS::TraceEdge(trc, &fninfo->mArgTypes[i], "argType");

break;
}
Expand Down Expand Up @@ -6904,10 +6904,10 @@ CClosure::Trace(JSTracer* trc, JSObject* obj)

// Identify our objects to the tracer. (There's no need to identify
// 'closureObj', since that's us.)
JS_CallObjectTracer(trc, &cinfo->typeObj, "typeObj");
JS_CallObjectTracer(trc, &cinfo->jsfnObj, "jsfnObj");
JS::TraceEdge(trc, &cinfo->typeObj, "typeObj");
JS::TraceEdge(trc, &cinfo->jsfnObj, "jsfnObj");
if (cinfo->thisObj)
JS_CallObjectTracer(trc, &cinfo->thisObj, "thisObj");
JS::TraceEdge(trc, &cinfo->thisObj, "thisObj");
}

void
Expand Down
2 changes: 1 addition & 1 deletion js/src/ctypes/CTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ struct FieldInfo
size_t mOffset; // offset of the field in the struct, in bytes

void trace(JSTracer* trc) {
JS_CallObjectTracer(trc, &mType, "fieldType");
JS::TraceEdge(trc, &mType, "fieldType");
}
};

Expand Down
17 changes: 16 additions & 1 deletion js/src/gc/Marking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,15 @@ JS::TraceEdge(JSTracer* trc, JS::Heap<T>* thingp, const char* name)
DispatchToTracer(trc, ConvertToBase(thingp->unsafeGet()), name);
}

template <typename T>
JS_PUBLIC_API(void)
JS::TraceNullableEdge(JSTracer* trc, JS::Heap<T>* thingp, const char* name)
{
MOZ_ASSERT(thingp);
if (InternalGCMethods<T>::isMarkable(thingp->get()))
DispatchToTracer(trc, ConvertToBase(thingp->unsafeGet()), name);
}

template <typename T>
void
js::TraceManuallyBarrieredEdge(JSTracer* trc, T* thingp, const char* name)
Expand Down Expand Up @@ -483,7 +492,6 @@ js::TraceRootRange(JSTracer* trc, size_t len, T* vec, const char* name)
// Instantiate a copy of the Tracing templates for each derived type.
#define INSTANTIATE_ALL_VALID_TRACE_FUNCTIONS(type) \
template void js::TraceEdge<type>(JSTracer*, WriteBarrieredBase<type>*, const char*); \
template JS_PUBLIC_API(void) JS::TraceEdge<type>(JSTracer*, JS::Heap<type>*, const char*); \
template void js::TraceManuallyBarrieredEdge<type>(JSTracer*, type*, const char*); \
template void js::TraceWeakEdge<type>(JSTracer*, WeakRef<type>*, const char*); \
template void js::TraceRoot<type>(JSTracer*, type*, const char*); \
Expand All @@ -495,6 +503,13 @@ js::TraceRootRange(JSTracer* trc, size_t len, T* vec, const char* name)
FOR_EACH_GC_POINTER_TYPE(INSTANTIATE_ALL_VALID_TRACE_FUNCTIONS)
#undef INSTANTIATE_ALL_VALID_TRACE_FUNCTIONS

#define INSTANTIATE_PUBLIC_TRACE_FUNCTIONS(type) \
template JS_PUBLIC_API(void) JS::TraceEdge<type>(JSTracer*, JS::Heap<type>*, const char*); \
template JS_PUBLIC_API(void) JS::TraceNullableEdge<type>(JSTracer*, JS::Heap<type>*, \
const char*);
FOR_EACH_PUBLIC_GC_POINTER_TYPE(INSTANTIATE_PUBLIC_TRACE_FUNCTIONS)
#undef INSTANTIATE_PUBLIC_TRACE_FUNCTIONS

template <typename T>
void
js::TraceManuallyBarrieredCrossCompartmentEdge(JSTracer* trc, JSObject* src, T* dst,
Expand Down
36 changes: 0 additions & 36 deletions js/src/gc/Tracer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,42 +135,6 @@ JS_CallUnbarrieredScriptTracer(JSTracer* trc, JSScript** scriptp, const char* na
TraceManuallyBarrieredEdge(trc, scriptp, name);
}

JS_PUBLIC_API(void)
JS_CallValueTracer(JSTracer* trc, JS::Heap<JS::Value>* valuep, const char* name)
{
TraceManuallyBarrieredEdge(trc, valuep->unsafeGet(), name);
}

JS_PUBLIC_API(void)
JS_CallIdTracer(JSTracer* trc, JS::Heap<jsid>* idp, const char* name)
{
TraceManuallyBarrieredEdge(trc, idp->unsafeGet(), name);
}

JS_PUBLIC_API(void)
JS_CallObjectTracer(JSTracer* trc, JS::Heap<JSObject*>* objp, const char* name)
{
TraceManuallyBarrieredEdge(trc, objp->unsafeGet(), name);
}

JS_PUBLIC_API(void)
JS_CallStringTracer(JSTracer* trc, JS::Heap<JSString*>* strp, const char* name)
{
TraceManuallyBarrieredEdge(trc, strp->unsafeGet(), name);
}

JS_PUBLIC_API(void)
JS_CallScriptTracer(JSTracer* trc, JS::Heap<JSScript*>* scriptp, const char* name)
{
TraceManuallyBarrieredEdge(trc, scriptp->unsafeGet(), name);
}

JS_PUBLIC_API(void)
JS_CallFunctionTracer(JSTracer* trc, JS::Heap<JSFunction*>* funp, const char* name)
{
TraceManuallyBarrieredEdge(trc, funp->unsafeGet(), name);
}

JS_PUBLIC_API(void)
JS_CallTenuredObjectTracer(JSTracer* trc, JS::TenuredHeap<JSObject*>* objp, const char* name)
{
Expand Down
2 changes: 1 addition & 1 deletion js/src/jsfriendapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1072,7 +1072,7 @@ JS::ObjectPtr::updateWeakPointerAfterGC()
void
JS::ObjectPtr::trace(JSTracer* trc, const char* name)
{
JS_CallObjectTracer(trc, &value, name);
JS::TraceEdge(trc, &value, name);
}

JS_FRIEND_API(JSObject*)
Expand Down
20 changes: 12 additions & 8 deletions js/src/jsgc.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,20 @@ enum State {
COMPACT
};

// Expand the given macro D for each publicly exposed GC reference type.
#define FOR_EACH_PUBLIC_GC_POINTER_TYPE(D) \
D(JS::Symbol*) \
D(JSAtom*) \
D(JSFunction*) \
D(JSObject*) \
D(JSScript*) \
D(JSString*) \
D(JS::Value) \
D(jsid)

// Expand the given macro D for each valid GC reference type.
#define FOR_EACH_GC_POINTER_TYPE(D) \
FOR_EACH_PUBLIC_GC_POINTER_TYPE(D) \
D(AccessorShape*) \
D(BaseShape*) \
D(UnownedBaseShape*) \
Expand All @@ -65,8 +77,6 @@ enum State {
D(ArrayBufferViewObject*) \
D(DebugScopeObject*) \
D(GlobalObject*) \
D(JSObject*) \
D(JSFunction*) \
D(ModuleObject*) \
D(ModuleEnvironmentObject*) \
D(ModuleNamespaceObject*) \
Expand All @@ -78,18 +88,12 @@ enum State {
D(SharedArrayBufferObject*) \
D(ImportEntryObject*) \
D(ExportEntryObject*) \
D(JSScript*) \
D(LazyScript*) \
D(Shape*) \
D(JSAtom*) \
D(JSString*) \
D(JSFlatString*) \
D(JSLinearString*) \
D(PropertyName*) \
D(JS::Symbol*) \
D(js::ObjectGroup*) \
D(Value) \
D(jsid) \
D(TaggedProto)

/* Map from C++ type to alloc kind. JSObject does not have a 1:1 mapping, so must use Arena::thingSize. */
Expand Down

0 comments on commit dbe0679

Please sign in to comment.