summaryrefslogtreecommitdiffstats
path: root/xpcom/glue
diff options
context:
space:
mode:
Diffstat (limited to 'xpcom/glue')
-rw-r--r--xpcom/glue/nsCycleCollectionParticipant.h45
-rw-r--r--xpcom/glue/nsTArray.h18
2 files changed, 50 insertions, 13 deletions
diff --git a/xpcom/glue/nsCycleCollectionParticipant.h b/xpcom/glue/nsCycleCollectionParticipant.h
index 2dfbb6750..5d03acd26 100644
--- a/xpcom/glue/nsCycleCollectionParticipant.h
+++ b/xpcom/glue/nsCycleCollectionParticipant.h
@@ -113,11 +113,38 @@ private:
class NS_NO_VTABLE nsCycleCollectionParticipant
{
public:
- constexpr nsCycleCollectionParticipant() : mMightSkip(false) {}
- constexpr explicit nsCycleCollectionParticipant(bool aSkip) : mMightSkip(aSkip) {}
+ constexpr nsCycleCollectionParticipant()
+ : mMightSkip(false)
+ , mTraverseShouldTrace(false)
+ {
+ }
+
+ constexpr explicit nsCycleCollectionParticipant(bool aSkip,
+ bool aTraverseShouldTrace = false)
+ : mMightSkip(aSkip)
+ , mTraverseShouldTrace(aTraverseShouldTrace)
+ {
+ }
NS_IMETHOD Traverse(void* aPtr, nsCycleCollectionTraversalCallback& aCb) = 0;
+ nsresult TraverseNativeAndJS(void* aPtr,
+ nsCycleCollectionTraversalCallback& aCb)
+ {
+ nsresult rv = Traverse(aPtr, aCb);
+ if (mTraverseShouldTrace) {
+ // Note, we always call Trace, even if Traverse returned
+ // NS_SUCCESS_INTERRUPTED_TRAVERSE.
+ TraceCallbackFunc noteJsChild(&nsCycleCollectionParticipant::NoteJSChild);
+ Trace(aPtr, noteJsChild, &aCb);
+ }
+ return rv;
+ }
+
+ // Implemented in nsCycleCollectorTraceJSHelpers.cpp.
+ static void NoteJSChild(JS::GCCellPtr aGCThing, const char* aName,
+ void* aClosure);
+
NS_IMETHOD_(void) Root(void* aPtr) = 0;
NS_IMETHOD_(void) Unlink(void* aPtr) = 0;
NS_IMETHOD_(void) Unroot(void* aPtr) = 0;
@@ -172,26 +199,24 @@ protected:
private:
const bool mMightSkip;
+ const bool mTraverseShouldTrace;
};
class NS_NO_VTABLE nsScriptObjectTracer : public nsCycleCollectionParticipant
{
public:
constexpr nsScriptObjectTracer()
- : nsCycleCollectionParticipant(false)
+ : nsCycleCollectionParticipant(false, true)
{
}
constexpr explicit nsScriptObjectTracer(bool aSkip)
- : nsCycleCollectionParticipant(aSkip)
+ : nsCycleCollectionParticipant(aSkip, true)
{
}
NS_IMETHOD_(void) Trace(void* aPtr, const TraceCallbacks& aCb,
void* aClosure) override = 0;
- // Implemented in nsCycleCollectorTraceJSHelpers.cpp.
- static void NoteJSChild(JS::GCCellPtr aGCThing, const char* aName,
- void* aClosure);
};
class NS_NO_VTABLE nsXPCOMCycleCollectionParticipant : public nsScriptObjectTracer
@@ -440,12 +465,6 @@ DowncastCCParticipant(void* aPtr)
#define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_RAWPTR(_field) \
CycleCollectionNoteChild(cb, tmp->_field, #_field);
-#define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS \
- { \
- TraceCallbackFunc noteJsChild(&nsScriptObjectTracer::NoteJSChild); \
- Trace(p, noteJsChild, &cb); \
- }
-
#define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END \
(void)tmp; \
return NS_OK; \
diff --git a/xpcom/glue/nsTArray.h b/xpcom/glue/nsTArray.h
index 82586a79a..64af17bbb 100644
--- a/xpcom/glue/nsTArray.h
+++ b/xpcom/glue/nsTArray.h
@@ -1503,6 +1503,24 @@ public:
mozilla::Forward<Item>(aItem));
}
+ // Reconstruct the element at the given index, and return a pointer to the
+ // reconstructed element. This will destroy the existing element and
+ // default-construct a new one, giving you a state much like what single-arg
+ // InsertElementAt(), or no-arg AppendElement() does, but without changing the
+ // length of the array.
+ //
+ // array[idx] = T()
+ //
+ // would accomplish the same thing as long as T has the appropriate moving
+ // operator=, but some types don't for various reasons.
+ elem_type* ReconstructElementAt(index_type aIndex)
+ {
+ elem_type* elem = &ElementAt(aIndex);
+ elem_traits::Destruct(elem);
+ elem_traits::Construct(elem);
+ return elem;
+ }
+
// This method searches for the smallest index of an element that is strictly
// greater than |aItem|. If |aItem| is inserted at this index, the array will
// remain sorted and |aItem| would come after all elements that are equal to