diff options
Diffstat (limited to 'js/src/gc/Policy.h')
-rw-r--r-- | js/src/gc/Policy.h | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/js/src/gc/Policy.h b/js/src/gc/Policy.h new file mode 100644 index 000000000..74b34d9c8 --- /dev/null +++ b/js/src/gc/Policy.h @@ -0,0 +1,159 @@ +/* -*- 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/. */ + +/* JS Garbage Collector. */ + +#ifndef gc_Policy_h +#define gc_Policy_h + +#include "mozilla/TypeTraits.h" +#include "gc/Barrier.h" +#include "gc/Marking.h" +#include "js/GCPolicyAPI.h" + +// Forward declare the types we're defining policies for. This file is +// included in all places that define GC things, so the real definitions +// will be available when we do template expansion, allowing for use of +// static members in the underlying types. We cannot, however, use +// static_assert to verify relations between types. +class JSLinearString; +namespace js { +class AccessorShape; +class ArgumentsObject; +class ArrayBufferObject; +class ArrayBufferObjectMaybeShared; +class ArrayBufferViewObject; +class ArrayObject; +class BaseShape; +class DebugEnvironmentProxy; +class DebuggerFrame; +class ExportEntryObject; +class EnvironmentObject; +class GlobalObject; +class ImportEntryObject; +class LazyScript; +class LexicalEnvironmentObject; +class ModuleEnvironmentObject; +class ModuleNamespaceObject; +class ModuleObject; +class NativeObject; +class ObjectGroup; +class PlainObject; +class PropertyName; +class RegExpObject; +class SavedFrame; +class Scope; +class EnvironmentObject; +class ScriptSourceObject; +class Shape; +class SharedArrayBufferObject; +class StructTypeDescr; +class UnownedBaseShape; +class WasmMemoryObject; +namespace jit { +class JitCode; +} // namespace jit +} // namespace js + +// Expand the given macro D for each valid GC reference type. +#define FOR_EACH_INTERNAL_GC_POINTER_TYPE(D) \ + D(JSFlatString*) \ + D(JSLinearString*) \ + D(js::AccessorShape*) \ + D(js::ArgumentsObject*) \ + D(js::ArrayBufferObject*) \ + D(js::ArrayBufferObjectMaybeShared*) \ + D(js::ArrayBufferViewObject*) \ + D(js::ArrayObject*) \ + D(js::BaseShape*) \ + D(js::DebugEnvironmentProxy*) \ + D(js::DebuggerFrame*) \ + D(js::ExportEntryObject*) \ + D(js::EnvironmentObject*) \ + D(js::GlobalObject*) \ + D(js::ImportEntryObject*) \ + D(js::LazyScript*) \ + D(js::LexicalEnvironmentObject*) \ + D(js::ModuleEnvironmentObject*) \ + D(js::ModuleNamespaceObject*) \ + D(js::ModuleObject*) \ + D(js::NativeObject*) \ + D(js::ObjectGroup*) \ + D(js::PlainObject*) \ + D(js::PropertyName*) \ + D(js::RegExpObject*) \ + D(js::SavedFrame*) \ + D(js::Scope*) \ + D(js::ScriptSourceObject*) \ + D(js::Shape*) \ + D(js::SharedArrayBufferObject*) \ + D(js::StructTypeDescr*) \ + D(js::UnownedBaseShape*) \ + D(js::WasmInstanceObject*) \ + D(js::WasmMemoryObject*) \ + D(js::WasmTableObject*) \ + D(js::jit::JitCode*) + +// Expand the given macro D for each internal tagged GC pointer type. +#define FOR_EACH_INTERNAL_TAGGED_GC_POINTER_TYPE(D) \ + D(js::TaggedProto) + +// Expand the macro D for every GC reference type that we know about. +#define FOR_EACH_GC_POINTER_TYPE(D) \ + FOR_EACH_PUBLIC_GC_POINTER_TYPE(D) \ + FOR_EACH_PUBLIC_TAGGED_GC_POINTER_TYPE(D) \ + FOR_EACH_INTERNAL_GC_POINTER_TYPE(D) \ + FOR_EACH_INTERNAL_TAGGED_GC_POINTER_TYPE(D) + +namespace js { + +// Define the GCPolicy for all internal pointers. +template <typename T> +struct InternalGCPointerPolicy { + using Type = typename mozilla::RemovePointer<T>::Type; + static T initial() { return nullptr; } + static void preBarrier(T v) { Type::writeBarrierPre(v); } + static void postBarrier(T* vp, T prev, T next) { Type::writeBarrierPost(vp, prev, next); } + static void readBarrier(T v) { Type::readBarrier(v); } + static void trace(JSTracer* trc, T* vp, const char* name) { + TraceManuallyBarrieredEdge(trc, vp, name); + } +}; + +} // namespace js + +namespace JS { + +#define DEFINE_INTERNAL_GC_POLICY(type) \ + template <> struct GCPolicy<type> : public js::InternalGCPointerPolicy<type> {}; +FOR_EACH_INTERNAL_GC_POINTER_TYPE(DEFINE_INTERNAL_GC_POLICY) +#undef DEFINE_INTERNAL_GC_POLICY + +template <typename T> +struct GCPolicy<js::HeapPtr<T>> +{ + static void trace(JSTracer* trc, js::HeapPtr<T>* thingp, const char* name) { + js::TraceEdge(trc, thingp, name); + } + static bool needsSweep(js::HeapPtr<T>* thingp) { + return js::gc::IsAboutToBeFinalized(thingp); + } +}; + +template <typename T> +struct GCPolicy<js::ReadBarriered<T>> +{ + static void trace(JSTracer* trc, js::ReadBarriered<T>* thingp, const char* name) { + js::TraceEdge(trc, thingp, name); + } + static bool needsSweep(js::ReadBarriered<T>* thingp) { + return js::gc::IsAboutToBeFinalized(thingp); + } +}; + +} // namespace JS + +#endif // gc_Policy_h |