mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-29 20:07:30 +09:00
Merge remote-tracking branch 'origin/tracking' into custom
This commit is contained in:
commit
beb68187e5
98 changed files with 13981 additions and 982 deletions
|
|
@ -72,6 +72,7 @@
|
|||
#include "mozilla/dom/ScriptSettings.h"
|
||||
#include "jsprf.h"
|
||||
#include "js/Debug.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsCycleCollectionNoteRootCallback.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
|
|
@ -642,25 +643,33 @@ CycleCollectedJSContext::NoteGCThingXPCOMChildren(const js::Class* aClasp,
|
|||
}
|
||||
// XXX This test does seem fragile, we should probably whitelist classes
|
||||
// that do hold a strong reference, but that might not be possible.
|
||||
else if (aClasp->flags & JSCLASS_HAS_PRIVATE &&
|
||||
aClasp->flags & JSCLASS_PRIVATE_IS_NSISUPPORTS) {
|
||||
if (aClasp->flags & JSCLASS_HAS_PRIVATE &&
|
||||
aClasp->flags & JSCLASS_PRIVATE_IS_NSISUPPORTS) {
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCb, "js::GetObjectPrivate(obj)");
|
||||
aCb.NoteXPCOMChild(static_cast<nsISupports*>(js::GetObjectPrivate(aObj)));
|
||||
} else {
|
||||
const DOMJSClass* domClass = GetDOMClass(aObj);
|
||||
if (domClass) {
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCb, "UnwrapDOMObject(obj)");
|
||||
// It's possible that our object is an unforgeable holder object, in
|
||||
// which case it doesn't actually have a C++ DOM object associated with
|
||||
// it. Use UnwrapPossiblyNotInitializedDOMObject, which produces null in
|
||||
// that case, since NoteXPCOMChild/NoteNativeChild are null-safe.
|
||||
if (domClass->mDOMObjectIsISupports) {
|
||||
aCb.NoteXPCOMChild(UnwrapPossiblyNotInitializedDOMObject<nsISupports>(aObj));
|
||||
} else if (domClass->mParticipant) {
|
||||
aCb.NoteNativeChild(UnwrapPossiblyNotInitializedDOMObject<void>(aObj),
|
||||
domClass->mParticipant);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const DOMJSClass* domClass = GetDOMClass(aObj);
|
||||
if (domClass) {
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCb, "UnwrapDOMObject(obj)");
|
||||
// It's possible that our object is an unforgeable holder object, in
|
||||
// which case it doesn't actually have a C++ DOM object associated with
|
||||
// it. Use UnwrapPossiblyNotInitializedDOMObject, which produces null in
|
||||
// that case, since NoteXPCOMChild/NoteNativeChild are null-safe.
|
||||
if (domClass->mDOMObjectIsISupports) {
|
||||
aCb.NoteXPCOMChild(
|
||||
UnwrapPossiblyNotInitializedDOMObject<nsISupports>(aObj));
|
||||
} else if (domClass->mParticipant) {
|
||||
aCb.NoteNativeChild(UnwrapPossiblyNotInitializedDOMObject<void>(aObj),
|
||||
domClass->mParticipant);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
JS::Value value = js::MaybeGetScriptPrivate(aObj);
|
||||
if (!value.isUndefined()) {
|
||||
aCb.NoteXPCOMChild(static_cast<nsISupports*>(value.toPrivate()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -568,6 +568,13 @@
|
|||
ERROR(NS_ERROR_DOM_INVALID_STATE_XHR_CHUNKED_RESPONSETYPES_UNSUPPORTED_FOR_SYNC, FAILURE(1027)),
|
||||
ERROR(NS_ERROR_DOM_INVALID_ACCESS_XHR_TIMEOUT_AND_RESPONSETYPE_UNSUPPORTED_FOR_SYNC, FAILURE(1028)),
|
||||
|
||||
|
||||
/* When manipulating the bytecode cache with the JS API, some transcoding
|
||||
* errors, such as a different bytecode format can cause failures of the
|
||||
* decoding process.
|
||||
*/
|
||||
ERROR(NS_ERROR_DOM_JS_DECODING_ERROR, FAILURE(1030)),
|
||||
|
||||
/* May be used to indicate when e.g. setting a property value didn't
|
||||
* actually change the value, like for obj.foo = "bar"; obj.foo = "bar";
|
||||
* the second assignment throws NS_SUCCESS_DOM_NO_OPERATION.
|
||||
|
|
|
|||
|
|
@ -337,7 +337,7 @@ public:
|
|||
// Base types
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct PtrInfo;
|
||||
class PtrInfo;
|
||||
|
||||
class EdgePool
|
||||
{
|
||||
|
|
@ -533,13 +533,15 @@ enum NodeColor { black, white, grey };
|
|||
// hundreds of thousands of them to be allocated and touched
|
||||
// repeatedly during each cycle collection.
|
||||
|
||||
struct PtrInfo
|
||||
class PtrInfo final
|
||||
{
|
||||
public:
|
||||
void* mPointer;
|
||||
nsCycleCollectionParticipant* mParticipant;
|
||||
uint32_t mColor : 2;
|
||||
uint32_t mInternalRefs : 30;
|
||||
uint32_t mRefCount;
|
||||
|
||||
private:
|
||||
EdgePool::Iterator mFirstChild;
|
||||
|
||||
|
|
@ -609,8 +611,29 @@ public:
|
|||
CC_GRAPH_ASSERT(aLastChild.Initialized());
|
||||
(this + 1)->mFirstChild = aLastChild;
|
||||
}
|
||||
|
||||
void AnnotatedReleaseAssert(bool aCondition, const char* aMessage);
|
||||
};
|
||||
|
||||
void
|
||||
PtrInfo::AnnotatedReleaseAssert(bool aCondition, const char* aMessage)
|
||||
{
|
||||
if (aCondition) {
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
const char* piName = "Unknown";
|
||||
if (mParticipant) {
|
||||
piName = mParticipant->ClassName();
|
||||
}
|
||||
nsPrintfCString msg("%s, for class %s", aMessage, piName);
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("CycleCollector"), msg);
|
||||
#endif
|
||||
|
||||
MOZ_CRASH();
|
||||
}
|
||||
|
||||
/**
|
||||
* A structure designed to be used like a linked list of PtrInfo, except
|
||||
* it allocates many PtrInfos at a time.
|
||||
|
|
@ -2297,8 +2320,10 @@ CCGraphBuilder::NoteNativeRoot(void* aRoot,
|
|||
NS_IMETHODIMP_(void)
|
||||
CCGraphBuilder::DescribeRefCountedNode(nsrefcnt aRefCount, const char* aObjName)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(aRefCount != 0, "CCed refcounted object has zero refcount");
|
||||
MOZ_RELEASE_ASSERT(aRefCount != UINT32_MAX, "CCed refcounted object has overflowing refcount");
|
||||
mCurrPi->AnnotatedReleaseAssert(aRefCount != 0,
|
||||
"CCed refcounted object has zero refcount");
|
||||
mCurrPi->AnnotatedReleaseAssert(aRefCount != UINT32_MAX,
|
||||
"CCed refcounted object has overflowing refcount");
|
||||
|
||||
mResults.mVisitedRefCounted++;
|
||||
|
||||
|
|
@ -3112,9 +3137,8 @@ nsCycleCollector::ScanWhiteNodes(bool aFullySynchGraphBuild)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (pi->mInternalRefs > pi->mRefCount) {
|
||||
MOZ_CRASH();
|
||||
}
|
||||
pi->AnnotatedReleaseAssert(pi->mInternalRefs <= pi->mRefCount,
|
||||
"More references to an object than its refcount");
|
||||
|
||||
// This node will get marked black in the next pass.
|
||||
}
|
||||
|
|
|
|||
|
|
@ -322,6 +322,20 @@ protected:
|
|||
*/
|
||||
virtual void NotifyExpiredLocked(T*, const AutoLock&) = 0;
|
||||
|
||||
/**
|
||||
* This may be overridden to perform any post-aging work that needs to be
|
||||
* done while still holding the lock. It will be called once after each timer
|
||||
* event, and each low memory event has been handled.
|
||||
*/
|
||||
virtual void NotifyHandlerEndLocked(const AutoLock&) { };
|
||||
|
||||
/**
|
||||
* This may be overridden to perform any post-aging work that needs to be
|
||||
* done outside the lock. It will be called once after each
|
||||
* NotifyEndTransactionLocked call.
|
||||
*/
|
||||
virtual void NotifyHandlerEnd() { };
|
||||
|
||||
virtual Mutex& GetMutex() = 0;
|
||||
|
||||
private:
|
||||
|
|
@ -364,18 +378,26 @@ private:
|
|||
};
|
||||
|
||||
void HandleLowMemory() {
|
||||
AutoLock lock(GetMutex());
|
||||
AgeAllGenerationsLocked(lock);
|
||||
{
|
||||
AutoLock lock(GetMutex());
|
||||
AgeAllGenerationsLocked(lock);
|
||||
NotifyHandlerEndLocked(lock);
|
||||
}
|
||||
NotifyHandlerEnd();
|
||||
}
|
||||
|
||||
void HandleTimeout() {
|
||||
AutoLock lock(GetMutex());
|
||||
AgeOneGenerationLocked(lock);
|
||||
// Cancel the timer if we have no objects to track
|
||||
if (IsEmptyLocked(lock)) {
|
||||
mTimer->Cancel();
|
||||
mTimer = nullptr;
|
||||
{
|
||||
AutoLock lock(GetMutex());
|
||||
AgeOneGenerationLocked(lock);
|
||||
// Cancel the timer if we have no objects to track
|
||||
if (IsEmptyLocked(lock)) {
|
||||
mTimer->Cancel();
|
||||
mTimer = nullptr;
|
||||
}
|
||||
NotifyHandlerEndLocked(lock);
|
||||
}
|
||||
NotifyHandlerEnd();
|
||||
}
|
||||
|
||||
static void TimerCallback(nsITimer* aTimer, void* aThis)
|
||||
|
|
@ -449,6 +471,14 @@ class nsExpirationTracker : protected ::detail::SingleThreadedExpirationTracker<
|
|||
NotifyExpired(aObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Since there are no users of these callbacks in the single threaded case,
|
||||
* we mark them as final with the hope that the compiler can optimize the
|
||||
* method calls out entirely.
|
||||
*/
|
||||
void NotifyHandlerEndLocked(const AutoLock&) final override { }
|
||||
void NotifyHandlerEnd() final override { }
|
||||
|
||||
protected:
|
||||
virtual void NotifyExpired(T* aObj) = 0;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue