author | Wes Kocher <wkocher@mozilla.com> |
Wed, 30 Dec 2015 16:34:18 -0800 | |
changeset 277995 | 22f51211915bf7daff076180847a7140d35aa353 |
parent 277994 | ee14715f713146f3e9298fedd5f955b7dbbe45ff |
child 277996 | 23d99eb297e44d559f5583a565cdd670338f34df |
child 278163 | 6f4ef2a14886bafda5d255b2ddf36bc5e4ee8817 |
child 278164 | 4c891eee4b0d83ff52f0a9a10dc052a0944c17f9 |
push id | 69667 |
push user | kwierso@gmail.com |
push date | Thu, 31 Dec 2015 01:42:20 +0000 |
treeherder | mozilla-inbound@23d99eb297e4 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | merge |
bugs | 1120016 |
milestone | 46.0a1 |
backs out | 0d55a6e4e98e6e420ca9810688f9921434a94eef |
first release with | nightly linux32
22f51211915b
/
46.0a1
/
20151231030214
/
files
nightly linux64
22f51211915b
/
46.0a1
/
20151231030214
/
files
nightly mac
22f51211915b
/
46.0a1
/
20151231030214
/
files
nightly win32
22f51211915b
/
46.0a1
/
20151231030214
/
files
nightly win64
22f51211915b
/
46.0a1
/
20151231030214
/
files
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
releases | nightly linux32
46.0a1
/
20151231030214
/
pushlog to previous
nightly linux64
46.0a1
/
20151231030214
/
pushlog to previous
nightly mac
46.0a1
/
20151231030214
/
pushlog to previous
nightly win32
46.0a1
/
20151231030214
/
pushlog to previous
nightly win64
46.0a1
/
20151231030214
/
pushlog to previous
|
--- a/dom/base/nsWrapperCache.cpp +++ b/dom/base/nsWrapperCache.cpp @@ -4,51 +4,36 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsWrapperCacheInlines.h" #include "js/Class.h" #include "js/Proxy.h" #include "mozilla/dom/DOMJSProxyHandler.h" -#include "mozilla/CycleCollectedJSRuntime.h" #include "mozilla/HoldDropJSObjects.h" #include "nsCycleCollectionTraversalCallback.h" #include "nsCycleCollector.h" using namespace mozilla; using namespace mozilla::dom; #ifdef DEBUG /* static */ bool nsWrapperCache::HasJSObjectMovedOp(JSObject* aWrapper) { return js::HasObjectMovedOp(aWrapper); } #endif -void +/* static */ void nsWrapperCache::HoldJSObjects(void* aScriptObjectHolder, nsScriptObjectTracer* aTracer) { cyclecollector::HoldJSObjectsImpl(aScriptObjectHolder, aTracer); - if (mWrapper && !JS::ObjectIsTenured(mWrapper)) { - CycleCollectedJSRuntime::Get()->NurseryWrapperPreserved(mWrapper); - } -} - -void -nsWrapperCache::SetWrapperJSObject(JSObject* aWrapper) -{ - mWrapper = aWrapper; - UnsetWrapperFlags(kWrapperFlagsMask & ~WRAPPER_IS_NOT_DOM_BINDING); - - if (aWrapper && !JS::ObjectIsTenured(aWrapper)) { - CycleCollectedJSRuntime::Get()->NurseryWrapperAdded(this); - } } void nsWrapperCache::ReleaseWrapper(void* aScriptObjectHolder) { if (PreservingWrapper()) { // PreserveWrapper puts new DOM bindings in the JS holders hash, but they // can also be in the DOM expando hash, so we need to try to remove them
--- a/dom/base/nsWrapperCache.h +++ b/dom/base/nsWrapperCache.h @@ -253,25 +253,24 @@ public: } void ReleaseWrapper(void* aScriptObjectHolder); protected: void TraceWrapper(JSTracer* aTrc, const char* name) { if (mWrapper) { - JS_CallUnbarrieredObjectTracer(aTrc, &mWrapper, name); + JS_CallObjectTracer(aTrc, &mWrapper, name); } } void PoisonWrapper() { if (mWrapper) { - // See setToCrashOnTouch() in RootingAPI.h - mWrapper = reinterpret_cast<JSObject*>(1); + mWrapper.setToCrashOnTouch(); } } private: friend class mozilla::dom::TabChildGlobal; friend class mozilla::dom::ProcessGlobal; friend class SandboxPrivate; friend class nsInProcessTabChildGlobal; @@ -283,17 +282,23 @@ private: SetWrapperFlags(WRAPPER_IS_NOT_DOM_BINDING); } JSObject *GetWrapperJSObject() const { return mWrapper; } - void SetWrapperJSObject(JSObject* aWrapper); + void SetWrapperJSObject(JSObject* aWrapper) + { + mWrapper = aWrapper; + UnsetWrapperFlags(kWrapperFlagsMask & ~WRAPPER_IS_NOT_DOM_BINDING); + } + + void TraceWrapperJSObject(JSTracer* aTrc, const char* aName); FlagsType GetWrapperFlags() const { return mFlags & kWrapperFlagsMask; } bool HasWrapperFlag(FlagsType aFlag) const { @@ -308,18 +313,18 @@ private: } void UnsetWrapperFlags(FlagsType aFlagsToUnset) { MOZ_ASSERT((aFlagsToUnset & ~kWrapperFlagsMask) == 0, "Bad wrapper flag bits"); mFlags &= ~aFlagsToUnset; } - void HoldJSObjects(void* aScriptObjectHolder, - nsScriptObjectTracer* aTracer); + static void HoldJSObjects(void* aScriptObjectHolder, + nsScriptObjectTracer* aTracer); #ifdef DEBUG public: void CheckCCWrapperTraversal(void* aScriptObjectHolder, nsScriptObjectTracer* aTracer); private: #endif // DEBUG @@ -339,18 +344,18 @@ private: /** * If this bit is set then the wrapper for the native object is not a DOM * binding. */ enum { WRAPPER_IS_NOT_DOM_BINDING = 1 << 1 }; enum { kWrapperFlagsMask = (WRAPPER_BIT_PRESERVED | WRAPPER_IS_NOT_DOM_BINDING) }; - JSObject* mWrapper; - FlagsType mFlags; + JS::Heap<JSObject*> mWrapper; + FlagsType mFlags; }; enum { WRAPPER_CACHE_FLAGS_BITS_USED = 2 }; NS_DEFINE_STATIC_IID_ACCESSOR(nsWrapperCache, NS_WRAPPERCACHE_IID) #define NS_WRAPPERCACHE_INTERFACE_TABLE_ENTRY \ if ( aIID.Equals(NS_GET_IID(nsWrapperCache)) ) { \
--- a/dom/base/nsWrapperCacheInlines.h +++ b/dom/base/nsWrapperCacheInlines.h @@ -48,9 +48,15 @@ nsWrapperCache::HasNothingToTrace(nsISup } inline bool nsWrapperCache::IsBlackAndDoesNotNeedTracing(nsISupports* aThis) { return IsBlack() && HasNothingToTrace(aThis); } +inline void +nsWrapperCache::TraceWrapperJSObject(JSTracer* aTrc, const char* aName) +{ + JS_CallObjectTracer(aTrc, &mWrapper, aName); +} + #endif /* nsWrapperCache_h___ */
--- a/dom/bindings/Codegen.py +++ b/dom/bindings/Codegen.py @@ -417,18 +417,16 @@ class CGDOMJSClass(CGThing): if self.descriptor.isGlobal(): classFlags += "JSCLASS_DOM_GLOBAL | JSCLASS_GLOBAL_FLAGS_WITH_SLOTS(DOM_GLOBAL_SLOTS)" traceHook = "JS_GlobalObjectTraceHook" reservedSlots = "JSCLASS_GLOBAL_APPLICATION_SLOTS" else: classFlags += "JSCLASS_HAS_RESERVED_SLOTS(%d)" % slotCount traceHook = 'nullptr' reservedSlots = slotCount - if self.descriptor.interface.isProbablyShortLivingObject(): - classFlags += " | JSCLASS_SKIP_NURSERY_FINALIZE" if self.descriptor.interface.getExtendedAttribute("NeedResolve"): resolveHook = RESOLVE_HOOK_NAME mayResolveHook = MAY_RESOLVE_HOOK_NAME enumerateHook = ENUMERATE_HOOK_NAME elif self.descriptor.isGlobal(): resolveHook = "mozilla::dom::ResolveGlobal" mayResolveHook = "mozilla::dom::MayResolveGlobal" enumerateHook = "mozilla::dom::EnumerateGlobal"
--- a/dom/bindings/parser/WebIDL.py +++ b/dom/bindings/parser/WebIDL.py @@ -559,19 +559,16 @@ class IDLExternalInterface(IDLObjectWith pass def getJSImplementation(self): return None def isJSImplemented(self): return False - def isProbablyShortLivingObject(self): - return False - def getNavigatorProperty(self): return None def _getDependentObjects(self): return set() class IDLPartialInterface(IDLObject): @@ -1406,18 +1403,17 @@ class IDLInterface(IDLObjectWithScope, I self.parentScope.globalNames.add(self.identifier.name) self.parentScope.globalNameMapping[self.identifier.name].add(self.identifier.name) self._isOnGlobalProtoChain = True elif (identifier == "NeedResolve" or identifier == "OverrideBuiltins" or identifier == "ChromeOnly" or identifier == "Unforgeable" or identifier == "UnsafeInPrerendering" or - identifier == "LegacyEventInit" or - identifier == "ProbablyShortLivingObject"): + identifier == "LegacyEventInit"): # Known extended attributes that do not take values if not attr.noArguments(): raise WebIDLError("[%s] must take no arguments" % identifier, [attr.location]) elif identifier == "Exposed": convertExposedAttrToGlobalNameSet(attr, self._exposureGlobalNames) elif (identifier == "Pref" or @@ -1521,24 +1517,16 @@ class IDLInterface(IDLObjectWithScope, I return classId assert isinstance(classId, list) assert len(classId) == 1 return classId[0] def isJSImplemented(self): return bool(self.getJSImplementation()) - def isProbablyShortLivingObject(self): - current = self - while current: - if current.getExtendedAttribute("ProbablyShortLivingObject"): - return True - current = current.parent - return False - def getNavigatorProperty(self): naviProp = self.getExtendedAttribute("NavigatorProperty") if not naviProp: return None assert len(naviProp) == 1 assert isinstance(naviProp, list) assert len(naviProp[0]) != 0 return naviProp[0]
--- a/dom/events/Event.cpp +++ b/dom/events/Event.cpp @@ -232,16 +232,19 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN( NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOwner) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END JSObject* Event::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) { + if (mIsMainThreadEvent && !GetWrapperPreserveColor()) { + nsJSContext::LikelyShortLivingObjectCreated(); + } return WrapObjectInternal(aCx, aGivenProto); } JSObject* Event::WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) { return EventBinding::Wrap(aCx, this, aGivenProto); }
--- a/dom/webidl/Event.webidl +++ b/dom/webidl/Event.webidl @@ -6,17 +6,17 @@ * The origin of this IDL file is * http://www.w3.org/TR/2012/WD-dom-20120105/ * * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C * liability, trademark and document use rules apply. */ [Constructor(DOMString type, optional EventInit eventInitDict), - Exposed=(Window,Worker,System), ProbablyShortLivingObject] + Exposed=(Window,Worker,System)] interface Event { [Pure] readonly attribute DOMString type; [Pure] readonly attribute EventTarget? target; [Pure] readonly attribute EventTarget? currentTarget;
--- a/dom/webidl/MutationObserver.webidl +++ b/dom/webidl/MutationObserver.webidl @@ -2,17 +2,16 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * The origin of this IDL file is * http://dom.spec.whatwg.org */ -[ProbablyShortLivingObject] interface MutationRecord { [Constant] readonly attribute DOMString type; // .target is not nullable per the spec, but in order to prevent crashes, // if there are GC/CC bugs in Gecko, we let the property to be null. [Constant] readonly attribute Node? target; [Constant]
--- a/js/src/devtools/rootAnalysis/annotations.js +++ b/js/src/devtools/rootAnalysis/annotations.js @@ -73,18 +73,17 @@ var ignoreCallees = { "JSRuntime.destroyPrincipals" : true, "icu_50::UObject.__deleting_dtor" : true, // destructors in ICU code can't cause GC "mozilla::CycleCollectedJSRuntime.DescribeCustomObjects" : true, // During tracing, cannot GC. "mozilla::CycleCollectedJSRuntime.NoteCustomGCThingXPCOMChildren" : true, // During tracing, cannot GC. "PLDHashTableOps.hashKey" : true, "z_stream_s.zfree" : true, "GrGLInterface.fCallback" : true, "std::strstreambuf._M_alloc_fun" : true, - "std::strstreambuf._M_free_fun" : true, - "struct js::gc::Callback<void (*)(JSRuntime*, void*)>.op" : true, + "std::strstreambuf._M_free_fun" : true }; function fieldCallCannotGC(csu, fullfield) { if (csu in ignoreClasses) return true; if (fullfield in ignoreCallees) return true; @@ -183,18 +182,16 @@ var ignoreFunctions = { // particular runnable it posts can't even GC, but the analysis isn't // currently smart enough to determine that. In either case, this is (a) // only in GTests, and (b) only when the Gtest has already failed. We have // static and dynamic checks for no GC in the non-test code, and in the test // code we fall back to only the dynamic checks. "void test::RingbufferDumper::OnTestPartResult(testing::TestPartResult*)" : true, "float64 JS_GetCurrentEmbedderTime()" : true, - - "uint64 js::TenuringTracer::moveObjectToTenured(JSObject*, JSObject*, int32)" : true, }; function isProtobuf(name) { return name.match(/\bgoogle::protobuf\b/) || name.match(/\bmozilla::devtools::protobuf\b/); }
--- a/js/src/gc/GCRuntime.h +++ b/js/src/gc/GCRuntime.h @@ -751,19 +751,16 @@ class GCRuntime int32_t getMallocBytes() const { return mallocBytesUntilGC; } void resetMallocBytes(); bool isTooMuchMalloc() const { return mallocBytesUntilGC <= 0; } void updateMallocCounter(JS::Zone* zone, size_t nbytes); void onTooMuchMalloc(); void setGCCallback(JSGCCallback callback, void* data); void callGCCallback(JSGCStatus status) const; - void setObjectsTenuredCallback(JSObjectsTenuredCallback callback, - void* data); - void callObjectsTenuredCallback(); bool addFinalizeCallback(JSFinalizeCallback callback, void* data); void removeFinalizeCallback(JSFinalizeCallback func); bool addWeakPointerZoneGroupCallback(JSWeakPointerZoneGroupCallback callback, void* data); void removeWeakPointerZoneGroupCallback(JSWeakPointerZoneGroupCallback callback); bool addWeakPointerCompartmentCallback(JSWeakPointerCompartmentCallback callback, void* data); void removeWeakPointerCompartmentCallback(JSWeakPointerCompartmentCallback callback); JS::GCSliceCallback setSliceCallback(JS::GCSliceCallback callback); @@ -1271,17 +1268,16 @@ class GCRuntime js::Vector<JSObject*, 0, js::SystemAllocPolicy> selectedForMarking; #endif bool validate; bool fullCompartmentChecks; Callback<JSGCCallback> gcCallback; - Callback<JSObjectsTenuredCallback> tenuredCallback; CallbackVector<JSFinalizeCallback> finalizeCallbacks; CallbackVector<JSWeakPointerZoneGroupCallback> updateWeakPointerZoneGroupCallbacks; CallbackVector<JSWeakPointerCompartmentCallback> updateWeakPointerCompartmentCallbacks; /* * Malloc counter to measure memory pressure for GC scheduling. It runs * from maxMallocBytes down to zero. */
--- a/js/src/gc/Marking.cpp +++ b/js/src/gc/Marking.cpp @@ -2210,18 +2210,16 @@ js::TenuringTracer::moveObjectToTenured( if (src->getClass()->flags & JSCLASS_SKIP_NURSERY_FINALIZE) { if (src->is<InlineTypedObject>()) { InlineTypedObject::objectMovedDuringMinorGC(this, dst, src); } else if (src->is<UnboxedArrayObject>()) { tenuredSize += UnboxedArrayObject::objectMovedDuringMinorGC(this, dst, src, dstKind); } else if (src->is<ArgumentsObject>()) { tenuredSize += ArgumentsObject::objectMovedDuringMinorGC(this, dst, src); - } else if (JSObjectMovedOp op = dst->getClass()->ext.objectMovedOp) { - op(dst, src); } else { // Objects with JSCLASS_SKIP_NURSERY_FINALIZE need to be handled above // to ensure any additional nursery buffers they hold are moved. MOZ_CRASH("Unhandled JSCLASS_SKIP_NURSERY_FINALIZE Class"); } } return tenuredSize;
--- a/js/src/gc/Nursery.cpp +++ b/js/src/gc/Nursery.cpp @@ -491,20 +491,16 @@ js::Nursery::collect(JSRuntime* rt, JS:: TIME_END(sweepArrayBufferViewList); // Update any slot or element pointers whose destination has been tenured. TIME_START(updateJitActivations); js::jit::UpdateJitActivationsForMinorGC(rt, &mover); forwardedBuffers.finish(); TIME_END(updateJitActivations); - TIME_START(objectsTenuredCallback); - rt->gc.callObjectsTenuredCallback(); - TIME_END(objectsTenuredCallback); - // Sweep. TIME_START(freeMallocedBuffers); freeMallocedBuffers(); TIME_END(freeMallocedBuffers); TIME_START(sweep); sweep(); TIME_END(sweep); @@ -575,17 +571,16 @@ js::Nursery::collect(JSRuntime* rt, JS:: {"mkSlts", TIME_TOTAL(traceSlots)}, {"mcWCll", TIME_TOTAL(traceWholeCells)}, {"mkGnrc", TIME_TOTAL(traceGenericEntries)}, {"ckTbls", TIME_TOTAL(checkHashTables)}, {"mkRntm", TIME_TOTAL(markRuntime)}, {"mkDbgr", TIME_TOTAL(markDebugger)}, {"clrNOC", TIME_TOTAL(clearNewObjectCache)}, {"collct", TIME_TOTAL(collectToFP)}, - {" tenCB", TIME_TOTAL(objectsTenuredCallback)}, {"swpABO", TIME_TOTAL(sweepArrayBufferViewList)}, {"updtIn", TIME_TOTAL(updateJitActivations)}, {"frSlts", TIME_TOTAL(freeMallocedBuffers)}, {" clrSB", TIME_TOTAL(clearStoreBuffer)}, {" sweep", TIME_TOTAL(sweep)}, {"resize", TIME_TOTAL(resize)}, {"pretnr", TIME_TOTAL(pretenure)}, {"logPtT", TIME_TOTAL(logPromotionsToTenured)}
--- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -1390,24 +1390,16 @@ JS_MaybeGC(JSContext* cx) JS_PUBLIC_API(void) JS_SetGCCallback(JSRuntime* rt, JSGCCallback cb, void* data) { AssertHeapIsIdle(rt); rt->gc.setGCCallback(cb, data); } -JS_PUBLIC_API(void) -JS_SetObjectsTenuredCallback(JSRuntime* rt, JSObjectsTenuredCallback cb, - void* data) -{ - AssertHeapIsIdle(rt); - rt->gc.setObjectsTenuredCallback(cb, data); -} - JS_PUBLIC_API(bool) JS_AddFinalizeCallback(JSRuntime* rt, JSFinalizeCallback cb, void* data) { AssertHeapIsIdle(rt); return rt->gc.addFinalizeCallback(cb, data); } JS_PUBLIC_API(void)
--- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -567,19 +567,16 @@ typedef bool typedef enum JSGCStatus { JSGC_BEGIN, JSGC_END } JSGCStatus; typedef void (* JSGCCallback)(JSRuntime* rt, JSGCStatus status, void* data); -typedef void -(* JSObjectsTenuredCallback)(JSRuntime* rt, void* data); - typedef enum JSFinalizeStatus { /** * Called when preparing to sweep a group of compartments, before anything * has been swept. The collector will not yield to the mutator before * calling the callback with JSFINALIZE_GROUP_END status. */ JSFINALIZE_GROUP_START, @@ -1652,20 +1649,16 @@ extern JS_PUBLIC_API(void) JS_GC(JSRuntime* rt); extern JS_PUBLIC_API(void) JS_MaybeGC(JSContext* cx); extern JS_PUBLIC_API(void) JS_SetGCCallback(JSRuntime* rt, JSGCCallback cb, void* data); -extern JS_PUBLIC_API(void) -JS_SetObjectsTenuredCallback(JSRuntime* rt, JSObjectsTenuredCallback cb, - void* data); - extern JS_PUBLIC_API(bool) JS_AddFinalizeCallback(JSRuntime* rt, JSFinalizeCallback cb, void* data); extern JS_PUBLIC_API(void) JS_RemoveFinalizeCallback(JSRuntime* rt, JSFinalizeCallback cb); /* * Weak pointers and garbage collection
--- a/js/src/jsgc.cpp +++ b/js/src/jsgc.cpp @@ -1601,31 +1601,16 @@ GCRuntime::setGCCallback(JSGCCallback ca void GCRuntime::callGCCallback(JSGCStatus status) const { if (gcCallback.op) gcCallback.op(rt, status, gcCallback.data); } -void -GCRuntime::setObjectsTenuredCallback(JSObjectsTenuredCallback callback, - void* data) -{ - tenuredCallback.op = callback; - tenuredCallback.data = data; -} - -void -GCRuntime::callObjectsTenuredCallback() -{ - if (tenuredCallback.op) - tenuredCallback.op(rt, tenuredCallback.data); -} - namespace { class AutoNotifyGCActivity { public: explicit AutoNotifyGCActivity(GCRuntime& gc) : gc_(gc) { if (!gc_.isIncrementalGCInProgress()) { gcstats::AutoPhase ap(gc_.stats, gcstats::PHASE_GC_BEGIN); gc_.callGCCallback(JSGC_BEGIN);
--- a/xpcom/base/CycleCollectedJSRuntime.cpp +++ b/xpcom/base/CycleCollectedJSRuntime.cpp @@ -68,17 +68,16 @@ #include "jsprf.h" #include "js/Debug.h" #include "nsContentUtils.h" #include "nsCycleCollectionNoteRootCallback.h" #include "nsCycleCollectionParticipant.h" #include "nsCycleCollector.h" #include "nsDOMJSUtils.h" #include "nsJSUtils.h" -#include "nsWrapperCache.h" #ifdef MOZ_CRASHREPORTER #include "nsExceptionHandler.h" #endif #include "nsIException.h" #include "nsThread.h" #include "nsThreadUtils.h" @@ -393,22 +392,16 @@ NoteJSChildGrayWrapperShim(void* aData, * purple buffer during every CC, which may contain the last reference to a garbage * cycle.) */ // NB: This is only used to initialize the participant in // CycleCollectedJSRuntime. It should never be used directly. static const JSZoneParticipant sJSZoneCycleCollectorGlobal; -static -void JSObjectsTenuredCb(JSRuntime* aRuntime, void* aData) -{ - static_cast<CycleCollectedJSRuntime*>(aData)->JSObjectsTenured(aRuntime); -} - CycleCollectedJSRuntime::CycleCollectedJSRuntime(JSRuntime* aParentRuntime, uint32_t aMaxBytes, uint32_t aMaxNurseryBytes) : mGCThingCycleCollectorGlobal(sGCThingCycleCollectorGlobal) , mJSZoneCycleCollectorGlobal(sJSZoneCycleCollectorGlobal) , mJSRuntime(nullptr) , mPrevGCSliceCallback(nullptr) , mJSHolders(256) @@ -432,17 +425,16 @@ CycleCollectedJSRuntime::CycleCollectedJ } if (!JS_AddExtraGCRootsTracer(mJSRuntime, TraceBlackJS, this)) { MOZ_CRASH(); } JS_SetGrayGCRootsTracer(mJSRuntime, TraceGrayJS, this); JS_SetGCCallback(mJSRuntime, GCCallback, this); mPrevGCSliceCallback = JS::SetGCSliceCallback(mJSRuntime, GCSliceCallback); - JS_SetObjectsTenuredCallback(mJSRuntime, JSObjectsTenuredCb, this); JS::SetOutOfMemoryCallback(mJSRuntime, OutOfMemoryCallback, this); JS::SetLargeAllocationFailureCallback(mJSRuntime, LargeAllocationFailureCallback, this); JS_SetContextCallback(mJSRuntime, ContextCallback, this); JS_SetDestroyZoneCallback(mJSRuntime, XPCStringConvert::FreeZoneCache); JS_SetSweepZoneCallback(mJSRuntime, XPCStringConvert::ClearZoneCache); static js::DOMCallbacks DOMcallbacks = { @@ -788,21 +780,16 @@ struct JsGcTracer : public TraceCallback { JS_CallIdTracer(static_cast<JSTracer*>(aClosure), aPtr, aName); } virtual void Trace(JS::Heap<JSObject*>* aPtr, const char* aName, void* aClosure) const override { JS_CallObjectTracer(static_cast<JSTracer*>(aClosure), aPtr, aName); } - virtual void Trace(JSObject** aPtr, const char* aName, - void* aClosure) const override - { - JS_CallUnbarrieredObjectTracer(static_cast<JSTracer*>(aClosure), aPtr, aName); - } virtual void Trace(JS::TenuredHeap<JSObject*>* aPtr, const char* aName, void* aClosure) const override { JS_CallTenuredObjectTracer(static_cast<JSTracer*>(aClosure), aPtr, aName); } virtual void Trace(JS::Heap<JSString*>* aPtr, const char* aName, void* aClosure) const override { @@ -860,22 +847,16 @@ struct ClearJSHolder : TraceCallbacks *aPtr = JSID_VOID; } virtual void Trace(JS::Heap<JSObject*>* aPtr, const char*, void*) const override { *aPtr = nullptr; } - virtual void Trace(JSObject** aPtr, const char* aName, - void* aClosure) const override - { - *aPtr = nullptr; - } - virtual void Trace(JS::TenuredHeap<JSObject*>* aPtr, const char*, void*) const override { *aPtr = nullptr; } virtual void Trace(JS::Heap<JSString*>* aPtr, const char*, void*) const override { *aPtr = nullptr; @@ -1023,56 +1004,16 @@ CycleCollectedJSRuntime::GarbageCollect( MOZ_ASSERT(aReason < JS::gcreason::NUM_REASONS); JS::gcreason::Reason gcreason = static_cast<JS::gcreason::Reason>(aReason); JS::PrepareForFullGC(mJSRuntime); JS::GCForReason(mJSRuntime, GC_NORMAL, gcreason); } void -CycleCollectedJSRuntime::JSObjectsTenured(JSRuntime* aRuntime) -{ - for (auto iter = mNurseryObjects.Iter(); !iter.Done(); iter.Next()) { - nsWrapperCache* cache = iter.Get(); - JSObject* wrapper = cache->GetWrapperPreserveColor(); - MOZ_ASSERT(wrapper); - if (!JS::ObjectIsTenured(wrapper)) { - MOZ_ASSERT(!cache->PreservingWrapper()); - const JSClass* jsClass = js::GetObjectJSClass(wrapper); - jsClass->finalize(nullptr, wrapper); - } - } - -#ifdef DEBUG -for (auto iter = mPreservedNurseryObjects.Iter(); !iter.Done(); iter.Next()) { - MOZ_ASSERT(JS::ObjectIsTenured(iter.Get().get())); -} -#endif - - mNurseryObjects.Clear(); - mPreservedNurseryObjects.Clear(); -} - -void -CycleCollectedJSRuntime::NurseryWrapperAdded(nsWrapperCache* aCache) -{ - MOZ_ASSERT(aCache); - MOZ_ASSERT(aCache->GetWrapperPreserveColor()); - MOZ_ASSERT(!JS::ObjectIsTenured(aCache->GetWrapperPreserveColor())); - mNurseryObjects.InfallibleAppend(aCache); -} - -void -CycleCollectedJSRuntime::NurseryWrapperPreserved(JSObject* aWrapper) -{ - mPreservedNurseryObjects.InfallibleAppend( - JS::PersistentRooted<JSObject*>(mJSRuntime, aWrapper)); -} - -void CycleCollectedJSRuntime::DeferredFinalize(DeferredFinalizeAppendFunction aAppendFunc, DeferredFinalizeFunction aFunc, void* aThing) { void* thingArray = nullptr; bool hadThingArray = mDeferredFinalizerTable.Get(aFunc, &thingArray); thingArray = aAppendFunc(thingArray, aThing);
--- a/xpcom/base/CycleCollectedJSRuntime.h +++ b/xpcom/base/CycleCollectedJSRuntime.h @@ -5,31 +5,28 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef mozilla_CycleCollectedJSRuntime_h__ #define mozilla_CycleCollectedJSRuntime_h__ #include <queue> #include "mozilla/DeferredFinalize.h" -#include "mozilla/mozalloc.h" #include "mozilla/MemoryReporting.h" -#include "mozilla/SegmentedVector.h" #include "jsapi.h" #include "nsCycleCollectionParticipant.h" #include "nsDataHashtable.h" #include "nsHashKeys.h" #include "nsTArray.h" class nsCycleCollectionNoteRootCallback; class nsIException; class nsIRunnable; class nsThread; -class nsWrapperCache; namespace js { struct Class; } // namespace js namespace mozilla { class JSGCThingParticipant: public nsCycleCollectionParticipant @@ -278,20 +275,16 @@ public: nsCycleCollectionParticipant* ZoneParticipant(); nsresult TraverseRoots(nsCycleCollectionNoteRootCallback& aCb); bool UsefulToMergeZones() const; void FixWeakMappingGrayBits() const; bool AreGCGrayBitsValid() const; void GarbageCollect(uint32_t aReason) const; - void NurseryWrapperAdded(nsWrapperCache* aCache); - void NurseryWrapperPreserved(JSObject* aWrapper); - void JSObjectsTenured(JSRuntime* aRuntime); - void DeferredFinalize(DeferredFinalizeAppendFunction aAppendFunc, DeferredFinalizeFunction aFunc, void* aThing); void DeferredFinalize(nsISupports* aSupports); void DumpJSHeap(FILE* aFile); virtual void PrepareForForgetSkippable() = 0; @@ -363,23 +356,16 @@ private: nsTArray<nsCOMPtr<nsIRunnable>> mStableStateEvents; nsTArray<RunInMetastableStateData> mMetastableStateEvents; uint32_t mBaseRecursionDepth; bool mDoingStableStates; OOMState mOutOfMemoryState; OOMState mLargeAllocationFailureState; - - static const size_t kSegmentSize = 512; - SegmentedVector<nsWrapperCache*, kSegmentSize, InfallibleAllocPolicy> - mNurseryObjects; - SegmentedVector<JS::PersistentRooted<JSObject*>, kSegmentSize, - InfallibleAllocPolicy> - mPreservedNurseryObjects; }; void TraceScriptHolder(nsISupports* aHolder, JSTracer* aTracer); // Returns true if the JS::TraceKind is one the cycle collector cares about. inline bool AddToCCKind(JS::TraceKind aKind) { return aKind == JS::TraceKind::Object || aKind == JS::TraceKind::Script;
--- a/xpcom/base/nsCycleCollector.cpp +++ b/xpcom/base/nsCycleCollector.cpp @@ -2672,67 +2672,61 @@ public: } bool HasSnowWhiteObjects() const { return !mObjects.IsEmpty(); } virtual void Trace(JS::Heap<JS::Value>* aValue, const char* aName, - void* aClosure) const override + void* aClosure) const { if (aValue->isMarkable() && ValueIsGrayCCThing(*aValue)) { MOZ_ASSERT(!js::gc::IsInsideNursery(aValue->toGCThing())); mCollector->GetJSPurpleBuffer()->mValues.InfallibleAppend(*aValue); } } virtual void Trace(JS::Heap<jsid>* aId, const char* aName, - void* aClosure) const override + void* aClosure) const { } void AppendJSObjectToPurpleBuffer(JSObject* obj) const { if (obj && JS::ObjectIsMarkedGray(obj)) { MOZ_ASSERT(JS::ObjectIsTenured(obj)); mCollector->GetJSPurpleBuffer()->mObjects.InfallibleAppend(obj); } } virtual void Trace(JS::Heap<JSObject*>* aObject, const char* aName, - void* aClosure) const override - { - AppendJSObjectToPurpleBuffer(*aObject); - } - - virtual void Trace(JSObject** aObject, const char* aName, - void* aClosure) const override + void* aClosure) const { AppendJSObjectToPurpleBuffer(*aObject); } virtual void Trace(JS::TenuredHeap<JSObject*>* aObject, const char* aName, - void* aClosure) const override + void* aClosure) const { AppendJSObjectToPurpleBuffer(*aObject); } virtual void Trace(JS::Heap<JSString*>* aString, const char* aName, - void* aClosure) const override + void* aClosure) const { } virtual void Trace(JS::Heap<JSScript*>* aScript, const char* aName, - void* aClosure) const override + void* aClosure) const { } virtual void Trace(JS::Heap<JSFunction*>* aFunction, const char* aName, - void* aClosure) const override + void* aClosure) const { } private: RefPtr<nsCycleCollector> mCollector; ObjectsVector mObjects; };
--- a/xpcom/base/nsCycleCollectorTraceJSHelpers.cpp +++ b/xpcom/base/nsCycleCollectorTraceJSHelpers.cpp @@ -57,23 +57,16 @@ TraceCallbackFunc::Trace(JS::Heap<jsid>* void TraceCallbackFunc::Trace(JS::Heap<JSObject*>* aPtr, const char* aName, void* aClosure) const { mCallback(JS::GCCellPtr(aPtr->get()), aName, aClosure); } void -TraceCallbackFunc::Trace(JSObject** aPtr, const char* aName, - void* aClosure) const -{ - mCallback(JS::GCCellPtr(*aPtr), aName, aClosure); -} - -void TraceCallbackFunc::Trace(JS::TenuredHeap<JSObject*>* aPtr, const char* aName, void* aClosure) const { mCallback(JS::GCCellPtr(aPtr->getPtr()), aName, aClosure); } void TraceCallbackFunc::Trace(JS::Heap<JSFunction*>* aPtr, const char* aName,
--- a/xpcom/glue/nsCycleCollectionParticipant.h +++ b/xpcom/glue/nsCycleCollectionParticipant.h @@ -59,18 +59,16 @@ template<class T> class Heap; struct TraceCallbacks { virtual void Trace(JS::Heap<JS::Value>* aPtr, const char* aName, void* aClosure) const = 0; virtual void Trace(JS::Heap<jsid>* aPtr, const char* aName, void* aClosure) const = 0; virtual void Trace(JS::Heap<JSObject*>* aPtr, const char* aName, void* aClosure) const = 0; - virtual void Trace(JSObject** aPtr, const char* aName, - void* aClosure) const = 0; virtual void Trace(JS::TenuredHeap<JSObject*>* aPtr, const char* aName, void* aClosure) const = 0; virtual void Trace(JS::Heap<JSString*>* aPtr, const char* aName, void* aClosure) const = 0; virtual void Trace(JS::Heap<JSScript*>* aPtr, const char* aName, void* aClosure) const = 0; virtual void Trace(JS::Heap<JSFunction*>* aPtr, const char* aName, void* aClosure) const = 0; @@ -87,18 +85,16 @@ struct TraceCallbackFunc : public TraceC explicit TraceCallbackFunc(Func aCb) : mCallback(aCb) {} virtual void Trace(JS::Heap<JS::Value>* aPtr, const char* aName, void* aClosure) const override; virtual void Trace(JS::Heap<jsid>* aPtr, const char* aName, void* aClosure) const override; virtual void Trace(JS::Heap<JSObject*>* aPtr, const char* aName, void* aClosure) const override; - virtual void Trace(JSObject** aPtr, const char* aName, - void* aClosure) const override; virtual void Trace(JS::TenuredHeap<JSObject*>* aPtr, const char* aName, void* aClosure) const override; virtual void Trace(JS::Heap<JSString*>* aPtr, const char* aName, void* aClosure) const override; virtual void Trace(JS::Heap<JSScript*>* aPtr, const char* aName, void* aClosure) const override; virtual void Trace(JS::Heap<JSFunction*>* aPtr, const char* aName, void* aClosure) const override;