1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/dom/base/nsWrapperCache.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,119 @@ 1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#include "nsWrapperCacheInlines.h" 1.11 + 1.12 +#include "jsproxy.h" 1.13 +#include "mozilla/dom/DOMJSProxyHandler.h" 1.14 +#include "mozilla/HoldDropJSObjects.h" 1.15 +#include "nsCycleCollectionTraversalCallback.h" 1.16 +#include "nsCycleCollector.h" 1.17 + 1.18 +using namespace mozilla; 1.19 +using namespace mozilla::dom; 1.20 + 1.21 +/* static */ void 1.22 +nsWrapperCache::HoldJSObjects(void* aScriptObjectHolder, 1.23 + nsScriptObjectTracer* aTracer) 1.24 +{ 1.25 + cyclecollector::HoldJSObjectsImpl(aScriptObjectHolder, aTracer); 1.26 +} 1.27 + 1.28 +void 1.29 +nsWrapperCache::ReleaseWrapper(void* aScriptObjectHolder) 1.30 +{ 1.31 + if (PreservingWrapper()) { 1.32 + // PreserveWrapper puts new DOM bindings in the JS holders hash, but they 1.33 + // can also be in the DOM expando hash, so we need to try to remove them 1.34 + // from both here. 1.35 + JSObject* obj = GetWrapperPreserveColor(); 1.36 + if (IsDOMBinding() && obj && js::IsProxy(obj)) { 1.37 + DOMProxyHandler::GetAndClearExpandoObject(obj); 1.38 + } 1.39 + SetPreservingWrapper(false); 1.40 + cyclecollector::DropJSObjectsImpl(aScriptObjectHolder); 1.41 + } 1.42 +} 1.43 + 1.44 +#ifdef DEBUG 1.45 + 1.46 +class DebugWrapperTraversalCallback : public nsCycleCollectionTraversalCallback 1.47 +{ 1.48 +public: 1.49 + DebugWrapperTraversalCallback(void* aWrapper) 1.50 + : mFound(false) 1.51 + , mWrapper(aWrapper) 1.52 + { 1.53 + mFlags = WANT_ALL_TRACES; 1.54 + } 1.55 + 1.56 + NS_IMETHOD_(void) DescribeRefCountedNode(nsrefcnt aRefCount, 1.57 + const char* aObjName) 1.58 + { 1.59 + } 1.60 + NS_IMETHOD_(void) DescribeGCedNode(bool aIsMarked, 1.61 + const char* aObjName, 1.62 + uint64_t aCompartmentAddress) 1.63 + { 1.64 + } 1.65 + 1.66 + NS_IMETHOD_(void) NoteJSChild(void* aChild) 1.67 + { 1.68 + if (aChild == mWrapper) { 1.69 + mFound = true; 1.70 + } 1.71 + } 1.72 + NS_IMETHOD_(void) NoteXPCOMChild(nsISupports* aChild) 1.73 + { 1.74 + } 1.75 + NS_IMETHOD_(void) NoteNativeChild(void* aChild, 1.76 + nsCycleCollectionParticipant* aHelper) 1.77 + { 1.78 + } 1.79 + 1.80 + NS_IMETHOD_(void) NoteNextEdgeName(const char* aName) 1.81 + { 1.82 + } 1.83 + 1.84 + bool mFound; 1.85 + 1.86 +private: 1.87 + void* mWrapper; 1.88 +}; 1.89 + 1.90 +static void 1.91 +DebugWrapperTraceCallback(void* aP, const char* aName, void* aClosure) 1.92 +{ 1.93 + DebugWrapperTraversalCallback* callback = 1.94 + static_cast<DebugWrapperTraversalCallback*>(aClosure); 1.95 + callback->NoteJSChild(aP); 1.96 +} 1.97 + 1.98 +void 1.99 +nsWrapperCache::CheckCCWrapperTraversal(void* aScriptObjectHolder, 1.100 + nsScriptObjectTracer* aTracer) 1.101 +{ 1.102 + JSObject* wrapper = GetWrapper(); 1.103 + if (!wrapper) { 1.104 + return; 1.105 + } 1.106 + 1.107 + DebugWrapperTraversalCallback callback(wrapper); 1.108 + 1.109 + aTracer->Traverse(aScriptObjectHolder, callback); 1.110 + MOZ_ASSERT(callback.mFound, 1.111 + "Cycle collection participant didn't traverse to preserved " 1.112 + "wrapper! This will probably crash."); 1.113 + 1.114 + callback.mFound = false; 1.115 + aTracer->Trace(aScriptObjectHolder, 1.116 + TraceCallbackFunc(DebugWrapperTraceCallback), &callback); 1.117 + MOZ_ASSERT(callback.mFound, 1.118 + "Cycle collection participant didn't trace preserved wrapper! " 1.119 + "This will probably crash."); 1.120 +} 1.121 + 1.122 +#endif // DEBUG