Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/base/nsWrapperCache.h
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3
/* This Source Code Form is subject to the terms of the Mozilla Public
4
 * License, v. 2.0. If a copy of the MPL was not distributed with this
5
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#ifndef nsWrapperCache_h___
8
#define nsWrapperCache_h___
9
10
#include "nsCycleCollectionParticipant.h"
11
#include "mozilla/Assertions.h"
12
#include "js/Id.h"          // must come before js/RootingAPI.h
13
#include "js/Value.h"       // must come before js/RootingAPI.h
14
#include "js/RootingAPI.h"
15
#include "js/TracingAPI.h"
16
17
namespace mozilla {
18
namespace dom {
19
class ContentProcessMessageManager;
20
class InProcessTabChildMessageManager;
21
class TabChildMessageManager;
22
} // namespace dom
23
} // namespace mozilla
24
class SandboxPrivate;
25
class nsWindowRoot;
26
27
#define NS_WRAPPERCACHE_IID \
28
{ 0x6f3179a1, 0x36f7, 0x4a5c, \
29
  { 0x8c, 0xf1, 0xad, 0xc8, 0x7c, 0xde, 0x3e, 0x87 } }
30
31
// There are two sets of flags used by DOM nodes. One comes from reusing the
32
// remaining bits of the inherited nsWrapperCache flags (mFlags), and another is
33
// exclusive to nsINode (mBoolFlags).
34
//
35
// Both sets of flags are 32 bits. On 64-bit platforms, this can cause two
36
// wasted 32-bit fields due to alignment requirements. Some compilers are
37
// smart enough to coalesce the fields if we make mBoolFlags the first member
38
// of nsINode, but others (such as MSVC) are not.
39
//
40
// So we just store mBoolFlags directly on nsWrapperCache on 64-bit platforms.
41
// This may waste space for some other nsWrapperCache-derived objects that have
42
// a 32-bit field as their first member, but those objects are unlikely to be as
43
// numerous or performance-critical as DOM nodes.
44
#ifdef HAVE_64BIT_BUILD
45
static_assert(sizeof(void*) == 8, "These architectures should be 64-bit");
46
#define BOOL_FLAGS_ON_WRAPPER_CACHE
47
#else
48
static_assert(sizeof(void*) == 4, "Only support 32-bit and 64-bit");
49
#endif
50
51
/**
52
 * Class to store the wrapper for an object. This can only be used with objects
53
 * that only have one non-security wrapper at a time (for an XPCWrappedNative
54
 * this is usually ensured by setting an explicit parent in the PreCreate hook
55
 * for the class).
56
 *
57
 * An instance of nsWrapperCache can be gotten from an object that implements
58
 * a wrapper cache by calling QueryInterface on it. Note that this breaks XPCOM
59
 * rules a bit (this object doesn't derive from nsISupports).
60
 *
61
 * The cache can store objects other than wrappers. We allow wrappers to use a
62
 * separate JSObject to store their state (mostly expandos). If the wrapper is
63
 * collected and we want to preserve this state we actually store the state
64
 * object in the cache.
65
 *
66
 * The cache can store 3 types of objects: a DOM binding object (regular JS object or
67
 * proxy), an nsOuterWindowProxy or an XPCWrappedNative wrapper.
68
 *
69
 * The finalizer for the wrapper clears the cache.
70
 *
71
 * A compacting GC can move the wrapper object. Pointers to moved objects are
72
 * usually found and updated by tracing the heap, however non-preserved wrappers
73
 * are weak references and are not traced, so another approach is
74
 * necessary. Instead a class hook (objectMovedOp) is provided that is called
75
 * when an object is moved and is responsible for ensuring pointers are
76
 * updated. It does this by calling UpdateWrapper() on the wrapper
77
 * cache. SetWrapper() asserts that the hook is implemented for any wrapper set.
78
 *
79
 * A number of the methods are implemented in nsWrapperCacheInlines.h because we
80
 * have to include some JS headers that don't play nicely with the rest of the
81
 * codebase. Include nsWrapperCacheInlines.h if you need to call those methods.
82
 *
83
 * When recording or replaying an execution, wrapper caches are instrumented so
84
 * that they behave consistently even if the GC executes at different points
85
 * and collects different objects.
86
 */
87
88
class nsWrapperCache
89
{
90
public:
91
  NS_DECLARE_STATIC_IID_ACCESSOR(NS_WRAPPERCACHE_IID)
92
93
  nsWrapperCache()
94
    : mWrapper(nullptr)
95
    , mFlags(0)
96
#ifdef BOOL_FLAGS_ON_WRAPPER_CACHE
97
    , mBoolFlags(0)
98
#endif
99
  {
100
  }
101
  ~nsWrapperCache()
102
  {
103
    // Clear any JS root associated with this cache while replaying.
104
    if (mozilla::recordreplay::IsReplaying()) {
105
      mozilla::recordreplay::SetWeakPointerJSRoot(this, nullptr);
106
    }
107
    MOZ_ASSERT(!PreservingWrapper(),
108
               "Destroying cache with a preserved wrapper!");
109
  }
110
111
  /**
112
   * Get the cached wrapper.
113
   *
114
   * This getter clears the gray bit before handing out the JSObject which means
115
   * that the object is guaranteed to be kept alive past the next CC.
116
   */
117
  JSObject* GetWrapper() const;
118
119
  /**
120
   * Get the cached wrapper.
121
   *
122
   * This getter does not change the color of the JSObject meaning that the
123
   * object returned is not guaranteed to be kept alive past the next CC.
124
   *
125
   * This should only be called if you are certain that the return value won't
126
   * be passed into a JSAPI function and that it won't be stored without being
127
   * rooted (or otherwise signaling the stored value to the CC).
128
   */
129
  JSObject* GetWrapperPreserveColor() const;
130
131
  /**
132
   * Get the cached wrapper.
133
   *
134
   * This getter does not check whether the wrapper is dead and in the process
135
   * of being finalized.
136
   *
137
   * This should only be called if you really need to see the raw contents of
138
   * this cache, for example as part of finalization. Don't store the result
139
   * anywhere or pass it into JSAPI functions that may cause the value to
140
   * escape.
141
   */
142
  JSObject* GetWrapperMaybeDead() const
143
  {
144
    // Keep track of accesses on the cache when recording or replaying an
145
    // execution. Accesses during a GC (when thread events are disallowed)
146
    // fetch the underlying object without making sure the returned value
147
    // is consistent between recording and replay.
148
    if (mozilla::recordreplay::IsRecordingOrReplaying() &&
149
        !mozilla::recordreplay::AreThreadEventsDisallowed() &&
150
        !mozilla::recordreplay::HasDivergedFromRecording()) {
151
      bool success = mozilla::recordreplay::RecordReplayValue(!!mWrapper);
152
      if (mozilla::recordreplay::IsReplaying()) {
153
        if (success) {
154
          MOZ_RELEASE_ASSERT(mWrapper);
155
        } else {
156
          const_cast<nsWrapperCache*>(this)->ClearWrapper();
157
        }
158
      }
159
    }
160
161
    return mWrapper;
162
  }
163
164
#ifdef DEBUG
165
private:
166
  static bool HasJSObjectMovedOp(JSObject* aWrapper);
167
168
public:
169
#endif
170
171
  void SetWrapper(JSObject* aWrapper)
172
  {
173
    MOZ_ASSERT(!PreservingWrapper(), "Clearing a preserved wrapper!");
174
    MOZ_ASSERT(aWrapper, "Use ClearWrapper!");
175
    MOZ_ASSERT(HasJSObjectMovedOp(aWrapper),
176
               "Object has not provided the hook to update the wrapper if it is moved");
177
178
    SetWrapperJSObject(aWrapper);
179
  }
180
181
  /**
182
   * Clear the cache.
183
   */
184
  void ClearWrapper()
185
  {
186
    MOZ_ASSERT(!PreservingWrapper(), "Clearing a preserved wrapper!");
187
    SetWrapperJSObject(nullptr);
188
  }
189
190
  /**
191
   * Clear the cache if it still contains a specific wrapper object. This should
192
   * be called from the finalizer for the wrapper.
193
   */
194
  void ClearWrapper(JSObject* obj)
195
  {
196
    if (obj == mWrapper) {
197
      ClearWrapper();
198
    }
199
  }
200
201
  /**
202
   * Update the wrapper if the object it contains is moved.
203
   *
204
   * This method must be called from the objectMovedOp class extension hook for
205
   * any wrapper cached object.
206
   */
207
  void UpdateWrapper(JSObject* aNewObject, const JSObject* aOldObject)
208
  {
209
    if (mWrapper) {
210
      MOZ_ASSERT(mWrapper == aOldObject);
211
      mWrapper = aNewObject;
212
    }
213
  }
214
215
  bool PreservingWrapper() const
216
  {
217
    return HasWrapperFlag(WRAPPER_BIT_PRESERVED);
218
  }
219
220
  /**
221
   * Wrap the object corresponding to this wrapper cache. If non-null is
222
   * returned, the object has already been stored in the wrapper cache.
223
   */
224
  virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) = 0;
225
226
  /**
227
   * Returns true if the object has a wrapper that is known live from the point
228
   * of view of cycle collection.
229
   */
230
  bool HasKnownLiveWrapper() const;
231
232
  /**
233
   * Returns true if the object has a known-live wrapper (from the CC point of
234
   * view) and all the GC things it is keeping alive are already known-live from
235
   * CC's point of view.
236
   */
237
  bool HasKnownLiveWrapperAndDoesNotNeedTracing(nsISupports* aThis);
238
239
  bool HasNothingToTrace(nsISupports* aThis);
240
241
  /**
242
   * Mark our wrapper, if any, as live as far as the CC is concerned.
243
   */
244
  void MarkWrapperLive();
245
246
  // Only meant to be called by code that preserves a wrapper.
247
  void SetPreservingWrapper(bool aPreserve)
248
  {
249
    if(aPreserve) {
250
      SetWrapperFlags(WRAPPER_BIT_PRESERVED);
251
    }
252
    else {
253
      UnsetWrapperFlags(WRAPPER_BIT_PRESERVED);
254
    }
255
  }
256
257
  void TraceWrapper(const TraceCallbacks& aCallbacks, void* aClosure)
258
  {
259
    if (PreservingWrapper() && mWrapper) {
260
      aCallbacks.Trace(&mWrapper, "Preserved wrapper", aClosure);
261
    }
262
  }
263
264
  /*
265
   * The following methods for getting and manipulating flags allow the unused
266
   * bits of mFlags to be used by derived classes.
267
   */
268
269
  typedef uint32_t FlagsType;
270
271
  FlagsType GetFlags() const
272
  {
273
    return mFlags & ~kWrapperFlagsMask;
274
  }
275
276
  bool HasFlag(FlagsType aFlag) const
277
  {
278
    MOZ_ASSERT((aFlag & kWrapperFlagsMask) == 0, "Bad flag mask");
279
    return !!(mFlags & aFlag);
280
  }
281
282
  // Identical to HasFlag, but more explicit about its handling of multiple
283
  // flags.
284
  bool HasAnyOfFlags(FlagsType aFlags) const
285
  {
286
    MOZ_ASSERT((aFlags & kWrapperFlagsMask) == 0, "Bad flag mask");
287
    return !!(mFlags & aFlags);
288
  }
289
290
  bool HasAllFlags(FlagsType aFlags) const
291
  {
292
    MOZ_ASSERT((aFlags & kWrapperFlagsMask) == 0, "Bad flag mask");
293
    return (mFlags & aFlags) == aFlags;
294
  }
295
296
  void SetFlags(FlagsType aFlagsToSet)
297
0
  {
298
0
    MOZ_ASSERT((aFlagsToSet & kWrapperFlagsMask) == 0, "Bad flag mask");
299
0
    mFlags |= aFlagsToSet;
300
0
  }
301
302
  void UnsetFlags(FlagsType aFlagsToUnset)
303
0
  {
304
0
    MOZ_ASSERT((aFlagsToUnset & kWrapperFlagsMask) == 0, "Bad flag mask");
305
0
    mFlags &= ~aFlagsToUnset;
306
0
  }
307
308
  void PreserveWrapper(nsISupports* aScriptObjectHolder)
309
  {
310
    if (PreservingWrapper()) {
311
      return;
312
    }
313
314
    nsISupports* ccISupports;
315
    aScriptObjectHolder->QueryInterface(NS_GET_IID(nsCycleCollectionISupports),
316
                                        reinterpret_cast<void**>(&ccISupports));
317
    MOZ_ASSERT(ccISupports);
318
319
    nsXPCOMCycleCollectionParticipant* participant;
320
    CallQueryInterface(ccISupports, &participant);
321
    PreserveWrapper(ccISupports, participant);
322
  }
323
324
  void PreserveWrapper(void* aScriptObjectHolder, nsScriptObjectTracer* aTracer)
325
  {
326
    if (PreservingWrapper()) {
327
      return;
328
    }
329
330
    GetWrapper(); // Read barrier for incremental GC.
331
    HoldJSObjects(aScriptObjectHolder, aTracer);
332
    SetPreservingWrapper(true);
333
#ifdef DEBUG
334
    // Make sure the cycle collector will be able to traverse to the wrapper.
335
    CheckCCWrapperTraversal(aScriptObjectHolder, aTracer);
336
#endif
337
  }
338
339
  void ReleaseWrapper(void* aScriptObjectHolder);
340
341
protected:
342
  void TraceWrapper(JSTracer* aTrc, const char* name)
343
  {
344
    if (mWrapper) {
345
      js::UnsafeTraceManuallyBarrieredEdge(aTrc, &mWrapper, name);
346
    }
347
  }
348
349
  void PoisonWrapper()
350
  {
351
    if (mWrapper) {
352
      // Set the pointer to a value that will cause a crash if it is
353
      // dereferenced.
354
      mWrapper = reinterpret_cast<JSObject*>(1);
355
    }
356
  }
357
358
private:
359
  void SetWrapperJSObject(JSObject* aWrapper);
360
361
  FlagsType GetWrapperFlags() const
362
  {
363
    return mFlags & kWrapperFlagsMask;
364
  }
365
366
  bool HasWrapperFlag(FlagsType aFlag) const
367
  {
368
    MOZ_ASSERT((aFlag & ~kWrapperFlagsMask) == 0, "Bad wrapper flag bits");
369
    return !!(mFlags & aFlag);
370
  }
371
372
  void SetWrapperFlags(FlagsType aFlagsToSet)
373
  {
374
    MOZ_ASSERT((aFlagsToSet & ~kWrapperFlagsMask) == 0, "Bad wrapper flag bits");
375
    mFlags |= aFlagsToSet;
376
  }
377
378
  void UnsetWrapperFlags(FlagsType aFlagsToUnset)
379
  {
380
    MOZ_ASSERT((aFlagsToUnset & ~kWrapperFlagsMask) == 0, "Bad wrapper flag bits");
381
    mFlags &= ~aFlagsToUnset;
382
  }
383
384
  void HoldJSObjects(void* aScriptObjectHolder,
385
                     nsScriptObjectTracer* aTracer);
386
387
#ifdef DEBUG
388
public:
389
  void CheckCCWrapperTraversal(void* aScriptObjectHolder,
390
                               nsScriptObjectTracer* aTracer);
391
private:
392
#endif // DEBUG
393
394
  /**
395
   * If this bit is set then we're preserving the wrapper, which in effect ties
396
   * the lifetime of the JS object stored in the cache to the lifetime of the
397
   * native object. We rely on the cycle collector to break the cycle that this
398
   * causes between the native object and the JS object, so it is important that
399
   * any native object that supports preserving of its wrapper
400
   * traces/traverses/unlinks the cached JS object (see
401
   * NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER and
402
   * NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER).
403
   */
404
  enum { WRAPPER_BIT_PRESERVED = 1 << 0 };
405
406
  enum { kWrapperFlagsMask = WRAPPER_BIT_PRESERVED };
407
408
  JSObject* mWrapper;
409
  FlagsType mFlags;
410
protected:
411
#ifdef BOOL_FLAGS_ON_WRAPPER_CACHE
412
  uint32_t mBoolFlags;
413
#endif
414
};
415
416
enum { WRAPPER_CACHE_FLAGS_BITS_USED = 1 };
417
418
NS_DEFINE_STATIC_IID_ACCESSOR(nsWrapperCache, NS_WRAPPERCACHE_IID)
419
420
#define NS_WRAPPERCACHE_INTERFACE_TABLE_ENTRY                                 \
421
0
  if ( aIID.Equals(NS_GET_IID(nsWrapperCache)) ) {                            \
422
0
    *aInstancePtr = static_cast<nsWrapperCache*>(this);                       \
423
0
    return NS_OK;                                                             \
424
0
  }
425
426
#define NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY                                   \
427
0
  NS_WRAPPERCACHE_INTERFACE_TABLE_ENTRY                                       \
428
0
  else
429
430
431
// Cycle collector macros for wrapper caches.
432
433
#define NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER \
434
0
  tmp->TraceWrapper(aCallbacks, aClosure);
435
436
#define NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER \
437
0
  tmp->ReleaseWrapper(p);
438
439
#define NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(_class) \
440
0
  NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(_class)              \
441
0
    NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER        \
442
0
  NS_IMPL_CYCLE_COLLECTION_TRACE_END
Unexecuted instantiation: mozilla::dom::DOMIntersectionObserverEntry::cycleCollection::Trace(void*, TraceCallbacks const&, void*)
Unexecuted instantiation: nsPluginArray::cycleCollection::Trace(void*, TraceCallbacks const&, void*)
Unexecuted instantiation: nsPluginElement::cycleCollection::Trace(void*, TraceCallbacks const&, void*)
Unexecuted instantiation: mozilla::dom::Attr::cycleCollection::Trace(void*, TraceCallbacks const&, void*)
Unexecuted instantiation: mozilla::dom::BarProp::cycleCollection::Trace(void*, TraceCallbacks const&, void*)
Unexecuted instantiation: mozilla::dom::CharacterData::cycleCollection::Trace(void*, TraceCallbacks const&, void*)
Unexecuted instantiation: mozilla::dom::Crypto::cycleCollection::Trace(void*, TraceCallbacks const&, void*)
Unexecuted instantiation: mozilla::dom::DOMError::cycleCollection::Trace(void*, TraceCallbacks const&, void*)
Unexecuted instantiation: mozilla::dom::DOMImplementation::cycleCollection::Trace(void*, TraceCallbacks const&, void*)
Unexecuted instantiation: mozilla::dom::DOMMatrixReadOnly::cycleCollection::Trace(void*, TraceCallbacks const&, void*)
Unexecuted instantiation: mozilla::dom::DOMParser::cycleCollection::Trace(void*, TraceCallbacks const&, void*)
Unexecuted instantiation: mozilla::dom::DOMPointReadOnly::cycleCollection::Trace(void*, TraceCallbacks const&, void*)
Unexecuted instantiation: mozilla::dom::DOMQuad::cycleCollection::Trace(void*, TraceCallbacks const&, void*)
Unexecuted instantiation: mozilla::dom::DOMRectReadOnly::cycleCollection::Trace(void*, TraceCallbacks const&, void*)
Unexecuted instantiation: mozilla::dom::DOMRectList::cycleCollection::Trace(void*, TraceCallbacks const&, void*)
Unexecuted instantiation: mozilla::dom::DOMStringList::cycleCollection::Trace(void*, TraceCallbacks const&, void*)
Unexecuted instantiation: nsWindowRoot::cycleCollection::Trace(void*, TraceCallbacks const&, void*)
Unexecuted instantiation: mozilla::dom::BrowserFeedWriter::cycleCollection::Trace(void*, TraceCallbacks const&, void*)
Unexecuted instantiation: mozilla::dom::PushManagerImpl::cycleCollection::Trace(void*, TraceCallbacks const&, void*)
Unexecuted instantiation: mozilla::dom::Position::cycleCollection::Trace(void*, TraceCallbacks const&, void*)
Unexecuted instantiation: mozilla::dom::Coordinates::cycleCollection::Trace(void*, TraceCallbacks const&, void*)
443
444
#define NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(_class) \
445
  NS_IMPL_CYCLE_COLLECTION_CLASS(_class)                \
446
0
  NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(_class)         \
447
0
    NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER   \
448
0
  NS_IMPL_CYCLE_COLLECTION_UNLINK_END                   \
449
0
  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_class)       \
450
0
  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END                 \
451
  NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(_class)
452
453
#define NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(_class, ...) \
454
  NS_IMPL_CYCLE_COLLECTION_CLASS(_class)                   \
455
0
  NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(_class)            \
456
0
    NS_IMPL_CYCLE_COLLECTION_UNLINK(__VA_ARGS__)           \
457
0
    NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER      \
458
0
  NS_IMPL_CYCLE_COLLECTION_UNLINK_END                      \
Unexecuted instantiation: mozilla::dom::DOMIntersectionObserverEntry::cycleCollection::Unlink(void*)
Unexecuted instantiation: nsPluginArray::cycleCollection::Unlink(void*)
Unexecuted instantiation: nsPluginElement::cycleCollection::Unlink(void*)
Unexecuted instantiation: mozilla::dom::BarProp::cycleCollection::Unlink(void*)
Unexecuted instantiation: mozilla::dom::Crypto::cycleCollection::Unlink(void*)
Unexecuted instantiation: mozilla::dom::DOMError::cycleCollection::Unlink(void*)
Unexecuted instantiation: mozilla::dom::DOMImplementation::cycleCollection::Unlink(void*)
Unexecuted instantiation: mozilla::dom::DOMMatrixReadOnly::cycleCollection::Unlink(void*)
Unexecuted instantiation: mozilla::dom::DOMParser::cycleCollection::Unlink(void*)
Unexecuted instantiation: mozilla::dom::DOMPointReadOnly::cycleCollection::Unlink(void*)
Unexecuted instantiation: mozilla::dom::DOMQuad::cycleCollection::Unlink(void*)
Unexecuted instantiation: mozilla::dom::DOMRectReadOnly::cycleCollection::Unlink(void*)
Unexecuted instantiation: mozilla::dom::DOMRectList::cycleCollection::Unlink(void*)
Unexecuted instantiation: nsWindowRoot::cycleCollection::Unlink(void*)
Unexecuted instantiation: mozilla::dom::Position::cycleCollection::Unlink(void*)
Unexecuted instantiation: mozilla::dom::Coordinates::cycleCollection::Unlink(void*)
459
0
  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_class)          \
460
0
    NS_IMPL_CYCLE_COLLECTION_TRAVERSE(__VA_ARGS__)         \
461
0
  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END                    \
Unexecuted instantiation: mozilla::dom::DOMIntersectionObserverEntry::cycleCollection::TraverseNative(void*, nsCycleCollectionTraversalCallback&)
Unexecuted instantiation: nsPluginArray::cycleCollection::TraverseNative(void*, nsCycleCollectionTraversalCallback&)
Unexecuted instantiation: nsPluginElement::cycleCollection::TraverseNative(void*, nsCycleCollectionTraversalCallback&)
Unexecuted instantiation: mozilla::dom::BarProp::cycleCollection::TraverseNative(void*, nsCycleCollectionTraversalCallback&)
Unexecuted instantiation: mozilla::dom::Crypto::cycleCollection::TraverseNative(void*, nsCycleCollectionTraversalCallback&)
Unexecuted instantiation: mozilla::dom::DOMError::cycleCollection::TraverseNative(void*, nsCycleCollectionTraversalCallback&)
Unexecuted instantiation: mozilla::dom::DOMImplementation::cycleCollection::TraverseNative(void*, nsCycleCollectionTraversalCallback&)
Unexecuted instantiation: mozilla::dom::DOMMatrixReadOnly::cycleCollection::TraverseNative(void*, nsCycleCollectionTraversalCallback&)
Unexecuted instantiation: mozilla::dom::DOMParser::cycleCollection::TraverseNative(void*, nsCycleCollectionTraversalCallback&)
Unexecuted instantiation: mozilla::dom::DOMPointReadOnly::cycleCollection::TraverseNative(void*, nsCycleCollectionTraversalCallback&)
Unexecuted instantiation: mozilla::dom::DOMQuad::cycleCollection::TraverseNative(void*, nsCycleCollectionTraversalCallback&)
Unexecuted instantiation: mozilla::dom::DOMRectReadOnly::cycleCollection::TraverseNative(void*, nsCycleCollectionTraversalCallback&)
Unexecuted instantiation: mozilla::dom::DOMRectList::cycleCollection::TraverseNative(void*, nsCycleCollectionTraversalCallback&)
Unexecuted instantiation: nsWindowRoot::cycleCollection::TraverseNative(void*, nsCycleCollectionTraversalCallback&)
Unexecuted instantiation: mozilla::dom::Position::cycleCollection::TraverseNative(void*, nsCycleCollectionTraversalCallback&)
Unexecuted instantiation: mozilla::dom::Coordinates::cycleCollection::TraverseNative(void*, nsCycleCollectionTraversalCallback&)
462
  NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(_class)
463
464
#endif /* nsWrapperCache_h___ */