From 5f8de423f190bbb79a62f804151bc24824fa32d8 Mon Sep 17 00:00:00 2001 From: "Matt A. Tobin" Date: Fri, 2 Feb 2018 04:16:08 -0500 Subject: Add m-esr52 at 52.6.0 --- js/public/GCPolicyAPI.h | 164 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 js/public/GCPolicyAPI.h (limited to 'js/public/GCPolicyAPI.h') diff --git a/js/public/GCPolicyAPI.h b/js/public/GCPolicyAPI.h new file mode 100644 index 000000000..054e397af --- /dev/null +++ b/js/public/GCPolicyAPI.h @@ -0,0 +1,164 @@ +/* -*- 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++ container types (e.g. +// JSPropertyDescriptor or GCHashMap). +// +// The GCPolicy provides at a minimum: +// +// static T initial() +// - Construct and return an empty T. +// +// static void trace(JSTracer, T* tp, const char* name) +// - Trace the edge |*tp|, calling the edge |name|. Containers like +// GCHashMap and GCHashSet use this method to trace their children. +// +// static bool needsSweep(T* tp) +// - Return true if |*tp| is about to be finalized. Otherwise, update the +// edge for moving GC, and return false. Containers like GCHashMap and +// GCHashSet use this method to decide when to remove an entry: if this +// function returns true on a key/value/member/etc, its entry is dropped +// from the container. Specializing this method is the standard way to +// get custom weak behavior from a container type. +// +// The default GCPolicy assumes that T has a default constructor and |trace| +// and |needsSweep| methods, and forwards to them. GCPolicy has appropriate +// specializations for pointers to GC things and pointer-like types like +// JS::Heap and mozilla::UniquePtr. +// +// There are some stock structs your specializations can inherit from. +// IgnoreGCPolicy does nothing. StructGCPolicy forwards the methods to the +// referent type T. + +#ifndef GCPolicyAPI_h +#define GCPolicyAPI_h + +#include "mozilla/UniquePtr.h" + +#include "js/TraceKind.h" +#include "js/TracingAPI.h" + +// Expand the given macro D for each public GC pointer. +#define FOR_EACH_PUBLIC_GC_POINTER_TYPE(D) \ + D(JS::Symbol*) \ + D(JSAtom*) \ + D(JSFunction*) \ + D(JSObject*) \ + D(JSScript*) \ + D(JSString*) + +// Expand the given macro D for each public tagged GC pointer type. +#define FOR_EACH_PUBLIC_TAGGED_GC_POINTER_TYPE(D) \ + D(JS::Value) \ + D(jsid) + +#define FOR_EACH_PUBLIC_AGGREGATE_GC_POINTER_TYPE(D) \ + D(JSPropertyDescriptor) + +class JSAtom; +class JSFunction; +class JSObject; +class JSScript; +class JSString; +namespace JS { +class Symbol; +} + +namespace JS { + +// Defines a policy for container types with non-GC, i.e. C storage. This +// policy dispatches to the underlying struct 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 void sweep(T* tp) { + return tp->sweep(); + } + + 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 bool needsSweep(T* vp) { + if (*vp) + return js::gc::IsAboutToBeFinalizedUnbarriered(vp); + return false; + } +}; +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) { + TraceEdge(trc, thingp, name); + } + static bool needsSweep(JS::Heap* thingp) { + return js::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) { + if (tp->get()) + GCPolicy::trace(trc, tp->get(), name); + } + static bool needsSweep(mozilla::UniquePtr* tp) { + if (tp->get()) + return GCPolicy::needsSweep(tp->get()); + return false; + } +}; + +} // namespace JS + +#endif // GCPolicyAPI_h -- cgit v1.2.3