author | Terrence Cole <terrence@mozilla.com> |
Tue, 12 Jan 2016 13:07:53 -0800 | |
changeset 314815 | 560e1ee498a5662d02806b21db11107359f95d13 |
parent 314814 | cf9a5f6f14db0c2e914285a3ef36de9b8dd3cc6a |
child 314816 | a9935197c5b73c8f8fe2e736587393379ec38ffc |
push id | 5703 |
push user | raliiev@mozilla.com |
push date | Mon, 07 Mar 2016 14:18:41 +0000 |
treeherder | mozilla-beta@31e373ad5b5f [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | sfink |
bugs | 1238786 |
milestone | 46.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
js/public/TracingAPI.h | file | annotate | diff | comparison | revisions | |
js/src/gc/Marking.cpp | file | annotate | diff | comparison | revisions |
--- a/js/public/TracingAPI.h +++ b/js/public/TracingAPI.h @@ -289,32 +289,32 @@ namespace JS { // // 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. +// +// Note that while |edgep| must never be null, it is fine for |*edgep| to be +// nullptr. 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); - -extern JS_PUBLIC_API(void) -TraceNullableEdge(JSTracer* trc, JS::TenuredHeap<JSObject*>* edgep, const char* name); +TraceEdge(JSTracer* trc, JS::TenuredHeap<JSObject*>* edgep, const char* name); // Edges that are always traced as part of root marking do not require // incremental barriers. This function allows for marking non-barriered // pointers, but asserts that this happens during root marking. +// +// Note that while |edgep| must never be null, it is fine for |*edgep| to be +// nullptr. template <typename T> extern JS_PUBLIC_API(void) UnsafeTraceRoot(JSTracer* trc, T* edgep, const char* name); extern JS_PUBLIC_API(void) TraceChildren(JSTracer* trc, GCCellPtr thing); typedef js::HashSet<Zone*, js::DefaultHasher<Zone*>, js::SystemAllocPolicy> ZoneSet; @@ -327,16 +327,22 @@ typedef js::HashSet<Zone*, js::DefaultHa extern JS_PUBLIC_API(void) JS_TraceIncomingCCWs(JSTracer* trc, const JS::ZoneSet& zones); extern JS_PUBLIC_API(void) JS_GetTraceThingInfo(char* buf, size_t bufsize, JSTracer* trc, void* thing, JS::TraceKind kind, bool includeDetails); namespace js { + +// Trace an edge that is not a GC root and is not wrapped in a barriered +// wrapper for some reason. +// +// This method does not check if |*edgep| is non-null before tracing through +// it, so callers must check any nullable pointer before calling this method. template <typename T> extern JS_PUBLIC_API(void) UnsafeTraceManuallyBarrieredEdge(JSTracer* trc, T* edgep, const char* name); namespace gc { template <typename T> extern JS_PUBLIC_API(bool) EdgeNeedsSweep(JS::Heap<T>* edgep);
--- a/js/src/gc/Marking.cpp +++ b/js/src/gc/Marking.cpp @@ -397,30 +397,23 @@ js::TraceEdge(JSTracer* trc, WriteBarrie { DispatchToTracer(trc, ConvertToBase(thingp->unsafeUnbarrieredForTracing()), name); } template <typename T> JS_PUBLIC_API(void) 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); } JS_PUBLIC_API(void) -JS::TraceNullableEdge(JSTracer* trc, JS::TenuredHeap<JSObject*>* thingp, const char* name) +JS::TraceEdge(JSTracer* trc, JS::TenuredHeap<JSObject*>* thingp, const char* name) { MOZ_ASSERT(thingp); if (JSObject* ptr = thingp->getPtr()) { DispatchToTracer(trc, &ptr, name); thingp->setPtr(ptr); } } @@ -454,23 +447,16 @@ template <typename T> void js::TraceRoot(JSTracer* trc, T* thingp, const char* name) { AssertRootMarkingPhase(trc); DispatchToTracer(trc, ConvertToBase(thingp), name); } template <typename T> -JS_PUBLIC_API(void) -JS::UnsafeTraceRoot(JSTracer* trc, T* thingp, const char* name) -{ - js::TraceRoot(trc, thingp, name); -} - -template <typename T> void js::TraceRoot(JSTracer* trc, ReadBarriered<T>* thingp, const char* name) { TraceRoot(trc, thingp->unsafeGet(), name); } template <typename T> void @@ -484,16 +470,24 @@ js::TraceNullableRoot(JSTracer* trc, T* template <typename T> void js::TraceNullableRoot(JSTracer* trc, ReadBarriered<T>* thingp, const char* name) { TraceNullableRoot(trc, thingp->unsafeGet(), name); } template <typename T> +JS_PUBLIC_API(void) +JS::UnsafeTraceRoot(JSTracer* trc, T* thingp, const char* name) +{ + MOZ_ASSERT(thingp); + js::TraceNullableRoot(trc, thingp, name); +} + +template <typename T> void js::TraceRange(JSTracer* trc, size_t len, WriteBarrieredBase<T>* vec, const char* name) { JS::AutoTracingIndex index(trc); for (auto i : MakeRange(len)) { if (InternalGCMethods<T>::isMarkable(vec[i].get())) DispatchToTracer(trc, ConvertToBase(vec[i].unsafeUnbarrieredForTracing()), name); ++index; @@ -524,18 +518,16 @@ js::TraceRootRange(JSTracer* trc, size_t template void js::TraceNullableRoot<type>(JSTracer*, ReadBarriered<type>*, const char*); \ template void js::TraceRange<type>(JSTracer*, size_t, WriteBarrieredBase<type>*, const char*); \ template void js::TraceRootRange<type>(JSTracer*, size_t, type*, const char*); 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*); \ template JS_PUBLIC_API(void) JS::UnsafeTraceRoot<type>(JSTracer*, type*, const char*); \ template JS_PUBLIC_API(void) js::UnsafeTraceManuallyBarrieredEdge<type>(JSTracer*, type*, \ const char*); FOR_EACH_PUBLIC_GC_POINTER_TYPE(INSTANTIATE_PUBLIC_TRACE_FUNCTIONS) #undef INSTANTIATE_PUBLIC_TRACE_FUNCTIONS template <typename T> void