LCOV - code coverage report
Current view: top level - dom/base - nsWrapperCache.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 45 53 84.9 %
Date: 2017-07-14 16:53:18 Functions: 11 13 84.6 %
Legend: Lines: hit not hit

          Line data    Source code
       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 "js/Class.h"
      10             : #include "js/Proxy.h"
      11             : #include "mozilla/CycleCollectedJSRuntime.h"
      12             : #include "mozilla/HoldDropJSObjects.h"
      13             : #include "nsCycleCollectionTraversalCallback.h"
      14             : #include "nsCycleCollector.h"
      15             : 
      16             : using namespace mozilla;
      17             : using namespace mozilla::dom;
      18             : 
      19             : #ifdef DEBUG
      20             : /* static */ bool
      21        2598 : nsWrapperCache::HasJSObjectMovedOp(JSObject* aWrapper)
      22             : {
      23        2598 :     return js::HasObjectMovedOp(aWrapper);
      24             : }
      25             : #endif
      26             : 
      27             : void
      28         259 : nsWrapperCache::HoldJSObjects(void* aScriptObjectHolder,
      29             :                               nsScriptObjectTracer* aTracer)
      30             : {
      31         259 :   cyclecollector::HoldJSObjectsImpl(aScriptObjectHolder, aTracer);
      32         259 :   if (mWrapper && !JS::ObjectIsTenured(mWrapper)) {
      33           0 :     CycleCollectedJSRuntime::Get()->NurseryWrapperPreserved(mWrapper);
      34             :   }
      35         259 : }
      36             : 
      37             : void
      38        2656 : nsWrapperCache::SetWrapperJSObject(JSObject* aWrapper)
      39             : {
      40        2656 :   mWrapper = aWrapper;
      41        2656 :   UnsetWrapperFlags(kWrapperFlagsMask & ~WRAPPER_IS_NOT_DOM_BINDING);
      42             : 
      43        2656 :   if (aWrapper && !JS::ObjectIsTenured(aWrapper)) {
      44          77 :     CycleCollectedJSRuntime::Get()->NurseryWrapperAdded(this);
      45             :   }
      46        2656 : }
      47             : 
      48             : void
      49          47 : nsWrapperCache::ReleaseWrapper(void* aScriptObjectHolder)
      50             : {
      51          47 :   if (PreservingWrapper()) {
      52           0 :     SetPreservingWrapper(false);
      53           0 :     cyclecollector::DropJSObjectsImpl(aScriptObjectHolder);
      54             :   }
      55          47 : }
      56             : 
      57             : #ifdef DEBUG
      58             : 
      59             : class DebugWrapperTraversalCallback : public nsCycleCollectionTraversalCallback
      60             : {
      61             : public:
      62        2572 :   explicit DebugWrapperTraversalCallback(JSObject* aWrapper)
      63        2572 :     : mFound(false)
      64        2572 :     , mWrapper(JS::GCCellPtr(aWrapper))
      65             :   {
      66        2572 :     mFlags = WANT_ALL_TRACES;
      67        2572 :   }
      68             : 
      69        2572 :   NS_IMETHOD_(void) DescribeRefCountedNode(nsrefcnt aRefCount,
      70             :                                            const char* aObjName)
      71             :   {
      72        2572 :   }
      73           0 :   NS_IMETHOD_(void) DescribeGCedNode(bool aIsMarked,
      74             :                                      const char* aObjName,
      75             :                                      uint64_t aCompartmentAddress)
      76             :   {
      77           0 :   }
      78             : 
      79        5184 :   NS_IMETHOD_(void) NoteJSChild(const JS::GCCellPtr& aChild)
      80             :   {
      81        5184 :     if (aChild == mWrapper) {
      82        5144 :       mFound = true;
      83             :     }
      84        5184 :   }
      85        9877 :   NS_IMETHOD_(void) NoteXPCOMChild(nsISupports* aChild)
      86             :   {
      87        9877 :   }
      88        1071 :   NS_IMETHOD_(void) NoteNativeChild(void* aChild,
      89             :                                     nsCycleCollectionParticipant* aHelper)
      90             :   {
      91        1071 :   }
      92             : 
      93           0 :   NS_IMETHOD_(void) NoteNextEdgeName(const char* aName)
      94             :   {
      95           0 :   }
      96             : 
      97             :   bool mFound;
      98             : 
      99             : private:
     100             :   JS::GCCellPtr mWrapper;
     101             : };
     102             : 
     103             : static void
     104        2592 : DebugWrapperTraceCallback(JS::GCCellPtr aPtr, const char* aName, void* aClosure)
     105             : {
     106             :   DebugWrapperTraversalCallback* callback =
     107        2592 :     static_cast<DebugWrapperTraversalCallback*>(aClosure);
     108        2592 :   if (aPtr.is<JSObject>()) {
     109        2592 :     callback->NoteJSChild(aPtr);
     110             :   }
     111        2592 : }
     112             : 
     113             : void
     114        2572 : nsWrapperCache::CheckCCWrapperTraversal(void* aScriptObjectHolder,
     115             :                                         nsScriptObjectTracer* aTracer)
     116             : {
     117        2572 :   JSObject* wrapper = GetWrapper();
     118        2572 :   if (!wrapper) {
     119           0 :     return;
     120             :   }
     121             : 
     122        2572 :   DebugWrapperTraversalCallback callback(wrapper);
     123             : 
     124             :   // The CC traversal machinery cannot trigger GC; however, the analysis cannot
     125             :   // see through the COM layer, so we use a suppression to help it.
     126        5144 :   JS::AutoSuppressGCAnalysis suppress;
     127             : 
     128        2572 :   aTracer->TraverseNativeAndJS(aScriptObjectHolder, callback);
     129        2572 :   MOZ_ASSERT(callback.mFound,
     130             :              "Cycle collection participant didn't traverse to preserved "
     131             :              "wrapper! This will probably crash.");
     132             : 
     133        2572 :   callback.mFound = false;
     134             :   aTracer->Trace(aScriptObjectHolder,
     135        2572 :                  TraceCallbackFunc(DebugWrapperTraceCallback), &callback);
     136        2572 :   MOZ_ASSERT(callback.mFound,
     137             :              "Cycle collection participant didn't trace preserved wrapper! "
     138             :              "This will probably crash.");
     139             : }
     140             : 
     141             : #endif // DEBUG

Generated by: LCOV version 1.13