dom/base/nsWrapperCache.cpp

branch
TOR_BUG_9701
changeset 15
b8a032363ba2
equal deleted inserted replaced
-1:000000000000 0:f48327c7799d
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 #include "nsWrapperCacheInlines.h"
8
9 #include "jsproxy.h"
10 #include "mozilla/dom/DOMJSProxyHandler.h"
11 #include "mozilla/HoldDropJSObjects.h"
12 #include "nsCycleCollectionTraversalCallback.h"
13 #include "nsCycleCollector.h"
14
15 using namespace mozilla;
16 using namespace mozilla::dom;
17
18 /* static */ void
19 nsWrapperCache::HoldJSObjects(void* aScriptObjectHolder,
20 nsScriptObjectTracer* aTracer)
21 {
22 cyclecollector::HoldJSObjectsImpl(aScriptObjectHolder, aTracer);
23 }
24
25 void
26 nsWrapperCache::ReleaseWrapper(void* aScriptObjectHolder)
27 {
28 if (PreservingWrapper()) {
29 // PreserveWrapper puts new DOM bindings in the JS holders hash, but they
30 // can also be in the DOM expando hash, so we need to try to remove them
31 // from both here.
32 JSObject* obj = GetWrapperPreserveColor();
33 if (IsDOMBinding() && obj && js::IsProxy(obj)) {
34 DOMProxyHandler::GetAndClearExpandoObject(obj);
35 }
36 SetPreservingWrapper(false);
37 cyclecollector::DropJSObjectsImpl(aScriptObjectHolder);
38 }
39 }
40
41 #ifdef DEBUG
42
43 class DebugWrapperTraversalCallback : public nsCycleCollectionTraversalCallback
44 {
45 public:
46 DebugWrapperTraversalCallback(void* aWrapper)
47 : mFound(false)
48 , mWrapper(aWrapper)
49 {
50 mFlags = WANT_ALL_TRACES;
51 }
52
53 NS_IMETHOD_(void) DescribeRefCountedNode(nsrefcnt aRefCount,
54 const char* aObjName)
55 {
56 }
57 NS_IMETHOD_(void) DescribeGCedNode(bool aIsMarked,
58 const char* aObjName,
59 uint64_t aCompartmentAddress)
60 {
61 }
62
63 NS_IMETHOD_(void) NoteJSChild(void* aChild)
64 {
65 if (aChild == mWrapper) {
66 mFound = true;
67 }
68 }
69 NS_IMETHOD_(void) NoteXPCOMChild(nsISupports* aChild)
70 {
71 }
72 NS_IMETHOD_(void) NoteNativeChild(void* aChild,
73 nsCycleCollectionParticipant* aHelper)
74 {
75 }
76
77 NS_IMETHOD_(void) NoteNextEdgeName(const char* aName)
78 {
79 }
80
81 bool mFound;
82
83 private:
84 void* mWrapper;
85 };
86
87 static void
88 DebugWrapperTraceCallback(void* aP, const char* aName, void* aClosure)
89 {
90 DebugWrapperTraversalCallback* callback =
91 static_cast<DebugWrapperTraversalCallback*>(aClosure);
92 callback->NoteJSChild(aP);
93 }
94
95 void
96 nsWrapperCache::CheckCCWrapperTraversal(void* aScriptObjectHolder,
97 nsScriptObjectTracer* aTracer)
98 {
99 JSObject* wrapper = GetWrapper();
100 if (!wrapper) {
101 return;
102 }
103
104 DebugWrapperTraversalCallback callback(wrapper);
105
106 aTracer->Traverse(aScriptObjectHolder, callback);
107 MOZ_ASSERT(callback.mFound,
108 "Cycle collection participant didn't traverse to preserved "
109 "wrapper! This will probably crash.");
110
111 callback.mFound = false;
112 aTracer->Trace(aScriptObjectHolder,
113 TraceCallbackFunc(DebugWrapperTraceCallback), &callback);
114 MOZ_ASSERT(callback.mFound,
115 "Cycle collection participant didn't trace preserved wrapper! "
116 "This will probably crash.");
117 }
118
119 #endif // DEBUG

mercurial