LCOV - code coverage report
Current view: top level - dom/xbl - nsXBLMaybeCompiled.h (source / functions) Hit Total Coverage
Test: output.info Lines: 45 51 88.2 %
Date: 2017-07-14 16:53:18 Functions: 38 42 90.5 %
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             : #ifndef nsXBLMaybeCompiled_h__
       8             : #define nsXBLMaybeCompiled_h__
       9             : 
      10             : #include "js/GCAPI.h"
      11             : 
      12             : /*
      13             :  * A union containing either a pointer representing uncompiled source or a
      14             :  * JSObject* representing the compiled result.  The class is templated on the
      15             :  * source object type.
      16             :  *
      17             :  * The purpose of abstracting this as a separate class is to allow it to be
      18             :  * wrapped in a JS::Heap<T> to correctly handle post-barriering of the JSObject
      19             :  * pointer, when present.
      20             :  *
      21             :  * No implementation of rootKind() is provided, which prevents
      22             :  * Root<nsXBLMaybeCompiled<UncompiledT>> from being used.
      23             :  */
      24             : template <class UncompiledT>
      25             : class nsXBLMaybeCompiled
      26             : {
      27             : public:
      28        3867 :   nsXBLMaybeCompiled() : mUncompiled(BIT_UNCOMPILED) {}
      29             : 
      30           0 :   explicit nsXBLMaybeCompiled(UncompiledT* uncompiled)
      31           0 :     : mUncompiled(reinterpret_cast<uintptr_t>(uncompiled) | BIT_UNCOMPILED) {}
      32             : 
      33        1289 :   explicit nsXBLMaybeCompiled(JSObject* compiled) : mCompiled(compiled) {}
      34             : 
      35       14095 :   bool IsCompiled() const
      36             :   {
      37       14095 :     return !(mUncompiled & BIT_UNCOMPILED);
      38             :   }
      39             : 
      40        1289 :   UncompiledT* GetUncompiled() const
      41             :   {
      42        1289 :     MOZ_ASSERT(!IsCompiled(), "Attempt to get compiled function as uncompiled");
      43        1289 :     uintptr_t unmasked = mUncompiled & ~BIT_UNCOMPILED;
      44        1289 :     return reinterpret_cast<UncompiledT*>(unmasked);
      45             :   }
      46             : 
      47        1146 :   JSObject* GetJSFunction() const
      48             :   {
      49        1146 :     MOZ_ASSERT(IsCompiled(), "Attempt to get uncompiled function as compiled");
      50        1146 :     if (mCompiled) {
      51         968 :       JS::ExposeObjectToActiveJS(mCompiled);
      52             :     }
      53        1146 :     return mCompiled;
      54             :   }
      55             : 
      56             :   // This is appropriate for use in tracing methods, etc.
      57         579 :   JSObject* GetJSFunctionPreserveColor() const
      58             :   {
      59         579 :     MOZ_ASSERT(IsCompiled(), "Attempt to get uncompiled function as compiled");
      60         579 :     return mCompiled;
      61             :   }
      62             : 
      63             : private:
      64        2578 :   JSObject*& UnsafeGetJSFunction()
      65             :   {
      66        2578 :     MOZ_ASSERT(IsCompiled(), "Attempt to get uncompiled function as compiled");
      67        2578 :     return mCompiled;
      68             :   }
      69             : 
      70             :   enum { BIT_UNCOMPILED = 1 << 0 };
      71             : 
      72             :   union
      73             :   {
      74             :     // An pointer that represents the function before being compiled, with
      75             :     // BIT_UNCOMPILED set.
      76             :     uintptr_t mUncompiled;
      77             : 
      78             :     // The JS object for the compiled result.
      79             :     JSObject* mCompiled;
      80             :   };
      81             : 
      82             :   friend struct js::BarrierMethods<nsXBLMaybeCompiled<UncompiledT>>;
      83             : };
      84             : 
      85             : /* Add support for JS::Heap<nsXBLMaybeCompiled>. */
      86             : namespace JS {
      87             : 
      88             : template <class UncompiledT>
      89             : struct GCPolicy<nsXBLMaybeCompiled<UncompiledT>>
      90             : {
      91        2578 :   static nsXBLMaybeCompiled<UncompiledT> initial() { return nsXBLMaybeCompiled<UncompiledT>(); }
      92             : };
      93             : 
      94             : } // namespace JS
      95             : 
      96             : namespace js {
      97             : 
      98             : template <class UncompiledT>
      99             : struct BarrierMethods<nsXBLMaybeCompiled<UncompiledT>>
     100             : {
     101             :   typedef struct BarrierMethods<JSObject *> Base;
     102             : 
     103        2578 :   static void postBarrier(nsXBLMaybeCompiled<UncompiledT>* functionp,
     104             :                           nsXBLMaybeCompiled<UncompiledT> prev,
     105             :                           nsXBLMaybeCompiled<UncompiledT> next)
     106             :   {
     107        2578 :     if (next.IsCompiled()) {
     108        2578 :       Base::postBarrier(&functionp->UnsafeGetJSFunction(),
     109        1289 :                         prev.IsCompiled() ? prev.UnsafeGetJSFunction() : nullptr,
     110             :                         next.UnsafeGetJSFunction());
     111        1289 :     } else if (prev.IsCompiled()) {
     112           0 :       Base::postBarrier(&prev.UnsafeGetJSFunction(),
     113             :                         prev.UnsafeGetJSFunction(),
     114             :                         nullptr);
     115             :     }
     116        2578 :   }
     117             :   static void exposeToJS(nsXBLMaybeCompiled<UncompiledT> fun) {
     118             :     if (fun.IsCompiled()) {
     119             :       JS::ExposeObjectToActiveJS(fun.UnsafeGetJSFunction());
     120             :     }
     121             :   }
     122             : };
     123             : 
     124             : template <class T>
     125             : struct IsHeapConstructibleType<nsXBLMaybeCompiled<T>>
     126             : { // Yes, this is the exception to the rule. Sorry.
     127             :   static constexpr bool value = true;
     128             : };
     129             : 
     130             : template <class UncompiledT, class Wrapper>
     131        1289 : class HeapBase<nsXBLMaybeCompiled<UncompiledT>, Wrapper>
     132             : {
     133        5270 :   const Wrapper& wrapper() const {
     134        5270 :     return *static_cast<const Wrapper*>(this);
     135             :   }
     136             : 
     137        2380 :   Wrapper& wrapper() {
     138        2380 :     return *static_cast<Wrapper*>(this);
     139             :   }
     140             : 
     141        5270 :   const nsXBLMaybeCompiled<UncompiledT>* extract() const {
     142        5270 :     return wrapper().address();
     143             :   }
     144             : 
     145        1091 :   nsXBLMaybeCompiled<UncompiledT>* extract() {
     146        1091 :     return wrapper().unsafeGet();
     147             :   }
     148             : 
     149             : public:
     150        2256 :   bool IsCompiled() const { return extract()->IsCompiled(); }
     151        1289 :   UncompiledT* GetUncompiled() const { return extract()->GetUncompiled(); }
     152        1146 :   JSObject* GetJSFunction() const { return extract()->GetJSFunction(); }
     153         579 :   JSObject* GetJSFunctionPreserveColor() const { return extract()->GetJSFunctionPreserveColor(); }
     154             : 
     155           0 :   void SetUncompiled(UncompiledT* source) {
     156           0 :     wrapper() = nsXBLMaybeCompiled<UncompiledT>(source);
     157           0 :   }
     158             : 
     159        1289 :   void SetJSFunction(JSObject* function) {
     160        1289 :     wrapper() = nsXBLMaybeCompiled<UncompiledT>(function);
     161        1289 :   }
     162             : 
     163        1091 :   JS::Heap<JSObject*>& AsHeapObject()
     164             :   {
     165        1091 :     MOZ_ASSERT(extract()->IsCompiled());
     166        1091 :     return *reinterpret_cast<JS::Heap<JSObject*>*>(this);
     167             :   }
     168             : };
     169             : 
     170             : } /* namespace js */
     171             : 
     172             : #endif // nsXBLMaybeCompiled_h__

Generated by: LCOV version 1.13