From 49ad697403f7031f292924096851b498f788bbfd Mon Sep 17 00:00:00 2001 From: Javier Fernandez Date: Mon, 7 Mar 2016 15:05:43 +0100 Subject: Breaking several cyclic references between SVG animated properties. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Based on upstream fix by sabouhallawa@apple.com at http://trac.webkit.org/changeset/196268 The leak happens because of cyclic reference between SVGListPropertyTearOff and SVGAnimatedListPropertyTearOff which is derived from SVGAnimatedProperty. There is also cyclic reference between SVGAnimatedProperty and SVGElement and this causes the whole document to be leaked. So if the JS requests, for example, an instance of SVGPolylineElement.points, the whole document will be leaked. The fix depends on having the cyclic reference as is since the owning and the owned classes have to live together if any of them is referenced. But the owning class caches a raw 'ref-counted' pointer of the owned class. If it is requested for an instance of the owned class it returned a RefPtr<> of it. Once the owned class is not used, it can delete itself. The only thing needed here is to notify the owner class of the deletion so it cleans its caches and be able to create a new pointer if it is requested for an instance of the owned class later. Revert the change of r181345 in SVGAnimatedProperty::lookupOrCreateWrapper() to break the cyclic reference between SVGElement and SVGAnimatedProperty. Also apply the same approach in SVGAnimatedListPropertyTearOff::baseVal() and animVal() to break cyclic reference between SVGListPropertyTearOff and SVGAnimatedListPropertyTearOff. Change-Id: Ied6a077299e47855feb235a1c9310f1a58aad91b Reviewed-by: Konstantin Tokarev Reviewed-by: Michael BrĂ¼ning --- Source/WebCore/svg/SVGViewSpec.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'Source/WebCore/svg/SVGViewSpec.cpp') diff --git a/Source/WebCore/svg/SVGViewSpec.cpp b/Source/WebCore/svg/SVGViewSpec.cpp index 253c082fb..5ac02dbdd 100644 --- a/Source/WebCore/svg/SVGViewSpec.cpp +++ b/Source/WebCore/svg/SVGViewSpec.cpp @@ -117,8 +117,8 @@ void SVGViewSpec::setTransformString(const String& transform) SVGTransformList newList; newList.parse(transform); - if (SVGAnimatedProperty* wrapper = SVGAnimatedProperty::lookupWrapper(m_contextElement, transformPropertyInfo())) - static_cast(wrapper)->detachListWrappers(newList.size()); + if (RefPtr wrapper = SVGAnimatedProperty::lookupWrapper(m_contextElement, transformPropertyInfo())) + static_pointer_cast(wrapper)->detachListWrappers(newList.size()); m_transform = newList; } @@ -148,12 +148,12 @@ SVGElement* SVGViewSpec::viewTarget() const return toSVGElement(element); } -SVGTransformListPropertyTearOff* SVGViewSpec::transform() +RefPtr SVGViewSpec::transform() { if (!m_contextElement) return 0; // Return the animVal here, as its readonly by default - which is exactly what we want here. - return static_cast(static_pointer_cast(lookupOrCreateTransformWrapper(this))->animVal()); + return static_cast(static_pointer_cast(lookupOrCreateTransformWrapper(this))->animVal().get()); } PassRefPtr SVGViewSpec::viewBoxAnimated() -- cgit v1.2.1