LCOV - code coverage report
Current view: top level - js/public - GCPolicyAPI.h (source / functions) Hit Total Coverage
Test: output.info Lines: 12 29 41.4 %
Date: 2017-07-14 16:53:18 Functions: 34 133 25.6 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
       2             :  * vim: set ts=8 sts=4 et sw=4 tw=99:
       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             : // GC Policy Mechanism
       8             : 
       9             : // A GCPolicy controls how the GC interacts with both direct pointers to GC
      10             : // things (e.g. JSObject* or JSString*), tagged and/or optional pointers to GC
      11             : // things (e.g.  Value or jsid), and C++ container types (e.g.
      12             : // JSPropertyDescriptor or GCHashMap).
      13             : //
      14             : // The GCPolicy provides at a minimum:
      15             : //
      16             : //   static T initial()
      17             : //       - Construct and return an empty T.
      18             : //
      19             : //   static void trace(JSTracer, T* tp, const char* name)
      20             : //       - Trace the edge |*tp|, calling the edge |name|. Containers like
      21             : //         GCHashMap and GCHashSet use this method to trace their children.
      22             : //
      23             : //   static bool needsSweep(T* tp)
      24             : //       - Return true if |*tp| is about to be finalized. Otherwise, update the
      25             : //         edge for moving GC, and return false. Containers like GCHashMap and
      26             : //         GCHashSet use this method to decide when to remove an entry: if this
      27             : //         function returns true on a key/value/member/etc, its entry is dropped
      28             : //         from the container. Specializing this method is the standard way to
      29             : //         get custom weak behavior from a container type.
      30             : //
      31             : // The default GCPolicy<T> assumes that T has a default constructor and |trace|
      32             : // and |needsSweep| methods, and forwards to them. GCPolicy has appropriate
      33             : // specializations for pointers to GC things and pointer-like types like
      34             : // JS::Heap<T> and mozilla::UniquePtr<T>.
      35             : //
      36             : // There are some stock structs your specializations can inherit from.
      37             : // IgnoreGCPolicy<T> does nothing. StructGCPolicy<T> forwards the methods to the
      38             : // referent type T.
      39             : 
      40             : #ifndef GCPolicyAPI_h
      41             : #define GCPolicyAPI_h
      42             : 
      43             : #include "mozilla/Maybe.h"
      44             : #include "mozilla/UniquePtr.h"
      45             : 
      46             : #include "js/TraceKind.h"
      47             : #include "js/TracingAPI.h"
      48             : 
      49             : // Expand the given macro D for each public GC pointer.
      50             : #define FOR_EACH_PUBLIC_GC_POINTER_TYPE(D) \
      51             :     D(JS::Symbol*) \
      52             :     D(JSAtom*) \
      53             :     D(JSFunction*) \
      54             :     D(JSObject*) \
      55             :     D(JSScript*) \
      56             :     D(JSString*)
      57             : 
      58             : // Expand the given macro D for each public tagged GC pointer type.
      59             : #define FOR_EACH_PUBLIC_TAGGED_GC_POINTER_TYPE(D) \
      60             :     D(JS::Value) \
      61             :     D(jsid)
      62             : 
      63             : #define FOR_EACH_PUBLIC_AGGREGATE_GC_POINTER_TYPE(D) \
      64             :     D(JSPropertyDescriptor)
      65             : 
      66             : class JSAtom;
      67             : class JSFunction;
      68             : class JSObject;
      69             : class JSScript;
      70             : class JSString;
      71             : namespace JS {
      72             : class Symbol;
      73             : }
      74             : 
      75             : namespace JS {
      76             : 
      77             : // Defines a policy for container types with non-GC, i.e. C storage. This
      78             : // policy dispatches to the underlying struct for GC interactions.
      79             : template <typename T>
      80             : struct StructGCPolicy
      81             : {
      82      555937 :     static T initial() {
      83      555937 :         return T();
      84             :     }
      85             : 
      86         297 :     static void trace(JSTracer* trc, T* tp, const char* name) {
      87         297 :         tp->trace(trc);
      88         297 :     }
      89             : 
      90           0 :     static void sweep(T* tp) {
      91           0 :         return tp->sweep();
      92             :     }
      93             : 
      94        2101 :     static bool needsSweep(T* tp) {
      95        2101 :         return tp->needsSweep();
      96             :     }
      97             : };
      98             : 
      99             : // The default GC policy attempts to defer to methods on the underlying type.
     100             : // Most C++ structures that contain a default constructor, a trace function and
     101             : // a sweep function will work out of the box with Rooted, Handle, GCVector,
     102             : // and GCHash{Set,Map}.
     103             : template <typename T> struct GCPolicy : public StructGCPolicy<T> {};
     104             : 
     105             : // This policy ignores any GC interaction, e.g. for non-GC types.
     106             : template <typename T>
     107             : struct IgnoreGCPolicy {
     108             :     static T initial() { return T(); }
     109           0 :     static void trace(JSTracer* trc, T* t, const char* name) {}
     110           0 :     static bool needsSweep(T* v) { return false; }
     111             : };
     112             : template <> struct GCPolicy<uint32_t> : public IgnoreGCPolicy<uint32_t> {};
     113             : template <> struct GCPolicy<uint64_t> : public IgnoreGCPolicy<uint64_t> {};
     114             : 
     115             : template <typename T>
     116             : struct GCPointerPolicy
     117             : {
     118     1642563 :     static T initial() { return nullptr; }
     119           8 :     static void trace(JSTracer* trc, T* vp, const char* name) {
     120           8 :         if (*vp)
     121           8 :             js::UnsafeTraceManuallyBarrieredEdge(trc, vp, name);
     122           8 :     }
     123           0 :     static bool needsSweep(T* vp) {
     124           0 :         if (*vp)
     125           0 :             return js::gc::IsAboutToBeFinalizedUnbarriered(vp);
     126           0 :         return false;
     127             :     }
     128             : };
     129             : template <> struct GCPolicy<JS::Symbol*> : public GCPointerPolicy<JS::Symbol*> {};
     130             : template <> struct GCPolicy<JSAtom*> : public GCPointerPolicy<JSAtom*> {};
     131             : template <> struct GCPolicy<JSFunction*> : public GCPointerPolicy<JSFunction*> {};
     132             : template <> struct GCPolicy<JSObject*> : public GCPointerPolicy<JSObject*> {};
     133             : template <> struct GCPolicy<JSScript*> : public GCPointerPolicy<JSScript*> {};
     134             : template <> struct GCPolicy<JSString*> : public GCPointerPolicy<JSString*> {};
     135             : 
     136             : template <typename T>
     137             : struct GCPolicy<JS::Heap<T>>
     138             : {
     139           0 :     static void trace(JSTracer* trc, JS::Heap<T>* thingp, const char* name) {
     140           0 :         TraceEdge(trc, thingp, name);
     141           0 :     }
     142           0 :     static bool needsSweep(JS::Heap<T>* thingp) {
     143           0 :         return *thingp && js::gc::EdgeNeedsSweep(thingp);
     144             :     }
     145             : };
     146             : 
     147             : // GCPolicy<UniquePtr<T>> forwards the contained pointer to GCPolicy<T>.
     148             : template <typename T, typename D>
     149             : struct GCPolicy<mozilla::UniquePtr<T, D>>
     150             : {
     151             :     static mozilla::UniquePtr<T,D> initial() { return mozilla::UniquePtr<T,D>(); }
     152           0 :     static void trace(JSTracer* trc, mozilla::UniquePtr<T,D>* tp, const char* name) {
     153           0 :         if (tp->get())
     154           0 :             GCPolicy<T>::trace(trc, tp->get(), name);
     155           0 :     }
     156             :     static bool needsSweep(mozilla::UniquePtr<T,D>* tp) {
     157             :         if (tp->get())
     158             :             return GCPolicy<T>::needsSweep(tp->get());
     159             :         return false;
     160             :     }
     161             : };
     162             : 
     163             : // GCPolicy<Maybe<T>> forwards tracing/sweeping to GCPolicy<T*> if
     164             : // when the Maybe<T> is full.
     165             : template <typename T>
     166             : struct GCPolicy<mozilla::Maybe<T>>
     167             : {
     168             :     static mozilla::Maybe<T> initial() { return mozilla::Maybe<T>(); }
     169             :     static void trace(JSTracer* trc, mozilla::Maybe<T>* tp, const char* name) {
     170             :         if (tp->isSome())
     171             :             GCPolicy<T>::trace(trc, tp->ptr(), name);
     172             :     }
     173             :     static bool needsSweep(mozilla::Maybe<T>* tp) {
     174             :         if (tp->isSome())
     175             :             return GCPolicy<T>::needsSweep(tp->ptr());
     176             :         return false;
     177             :     }
     178             : };
     179             : 
     180             : } // namespace JS
     181             : 
     182             : #endif // GCPolicyAPI_h

Generated by: LCOV version 1.13