/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * vim: set ts=8 sts=4 et sw=4 tw=99: * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ // GC Policy Mechanism // A GCPolicy controls how the GC interacts with both direct pointers to GC // things (e.g. JSObject* or JSString*), tagged and/or optional pointers to GC // things (e.g. Value or jsid), and C++ aggregate types (e.g. // JSPropertyDescriptor or GCHashMap). // // The GCPolicy provides at a minimum: // // static T initial() // - Tells the GC how to construct an empty T. // // static void trace(JSTracer, T* tp, const char* name) // - Tells the GC how to traverse the edge. In the case of an aggregate, // describe how to trace the children. // // static bool needsSweep(T* tp) // - Tells the GC how to determine if an edge is about to be finalized, // and potentially updates the edge for moving GC if not. For // aggregates, it determines the weakness semantics of storing the // aggregate inside a weak container of some sort. For example, you // might specialize a weak table's key type GCPolicy to describe // when an entry should be kept during sweeping. This is the primary // reason that GC-supporting weak containers can override the [sweep?] // policy on a per-container basis. #ifndef GCPolicyAPI_h #define GCPolicyAPI_h #include "mozilla/UniquePtr.h" #include "js/TraceKind.h" #include "js/TracingAPI.h" class JSAtom; class JSFunction; class JSObject; class JSScript; class JSString; namespace JS { class Symbol; } namespace js { // Defines a policy for aggregate types with non-GC, i.e. C storage. This // policy dispatches to the underlying aggregate for GC interactions. template struct StructGCPolicy { static T initial() { return T(); } static void trace(JSTracer* trc, T* tp, const char* name) { tp->trace(trc); } static bool needsSweep(T* tp) { return tp->needsSweep(); } }; // The default GC policy attempts to defer to methods on the underlying type. // Most C++ structures that contain a default constructor, a trace function and // a sweep function will work out of the box with Rooted, Handle, GCVector, // and GCHash{Set,Map}. template struct GCPolicy : public StructGCPolicy {}; // This policy ignores any GC interaction, e.g. for non-GC types. template struct IgnoreGCPolicy { static T initial() { return T(); } static void trace(JSTracer* trc, T* t, const char* name) {} static bool needsSweep(T* v) { return false; } }; template <> struct GCPolicy : public IgnoreGCPolicy {}; template <> struct GCPolicy : public IgnoreGCPolicy {}; template struct GCPointerPolicy { static T initial() { return nullptr; } static void trace(JSTracer* trc, T* vp, const char* name) { if (*vp) js::UnsafeTraceManuallyBarrieredEdge(trc, vp, name); } static void needsSweep(T* vp) { return js::gc::EdgeNeedsSweep(vp); } }; template <> struct GCPolicy : public GCPointerPolicy {}; template <> struct GCPolicy : public GCPointerPolicy {}; template <> struct GCPolicy : public GCPointerPolicy {}; template <> struct GCPolicy : public GCPointerPolicy {}; template <> struct GCPolicy : public GCPointerPolicy {}; template <> struct GCPolicy : public GCPointerPolicy {}; template struct GCPolicy> { static void trace(JSTracer* trc, JS::Heap* thingp, const char* name) { JS::TraceEdge(trc, thingp, name); } static bool needsSweep(JS::Heap* thingp) { return gc::EdgeNeedsSweep(thingp); } }; // GCPolicy> forwards the contained pointer to GCPolicy. template struct GCPolicy> { static mozilla::UniquePtr initial() { return mozilla::UniquePtr(); } static void trace(JSTracer* trc, mozilla::UniquePtr* tp, const char* name) { GCPolicy::trace(trc, tp->get(), name); } static bool needsSweep(mozilla::UniquePtr* tp) { return GCPolicy::needsSweep(tp->get()); } }; } // namespace js #endif // GCPolicyAPI_h