Bug 1235598 - Part 1: Add better SpiderMonkey API support for tracing in C++; r=sfink

--HG--
extra : rebase_source : 777e1dd17331f38b482fc12ef1e2d96ec61fb02d
This commit is contained in:
Terrence Cole 2015-12-30 08:52:12 -08:00
Родитель 02332a2395
Коммит 14bc095b59
7 изменённых файлов: 55 добавлений и 83 удалений

Просмотреть файл

@ -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);
extern JS_PUBLIC_API(void)
JS_CallFunctionTracer(JSTracer* trc, JS::Heap<JSFunction*>* funp, 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)
TraceEdge(JSTracer* trc, JS::Heap<T>* edgep, const char* name);
// 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)
TraceNullableEdge(JSTracer* trc, JS::Heap<T>* edgep, const char* name);
} // namespace JS
// The following JS_CallUnbarriered*Tracer functions should only be called where

Просмотреть файл

@ -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;
}
@ -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

Просмотреть файл

@ -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");
}
};

Просмотреть файл

@ -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)
@ -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*); \
@ -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,

Просмотреть файл

@ -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)
{

Просмотреть файл

@ -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*)

Просмотреть файл

@ -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*) \
@ -65,8 +77,6 @@ enum State {
D(ArrayBufferViewObject*) \
D(DebugScopeObject*) \
D(GlobalObject*) \
D(JSObject*) \
D(JSFunction*) \
D(ModuleObject*) \
D(ModuleEnvironmentObject*) \
D(ModuleNamespaceObject*) \
@ -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. */