/* -*- 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 struct InternalGCPointerPolicy { using Type = typename mozilla::RemovePointer::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 : public js::InternalGCPointerPolicy {}; FOR_EACH_INTERNAL_GC_POINTER_TYPE(DEFINE_INTERNAL_GC_POLICY) #undef DEFINE_INTERNAL_GC_POLICY template struct GCPolicy> { static void trace(JSTracer* trc, js::HeapPtr* thingp, const char* name) { js::TraceEdge(trc, thingp, name); } static bool needsSweep(js::HeapPtr* thingp) { return js::gc::IsAboutToBeFinalized(thingp); } }; template struct GCPolicy> { static void trace(JSTracer* trc, js::ReadBarriered* thingp, const char* name) { js::TraceEdge(trc, thingp, name); } static bool needsSweep(js::ReadBarriered* thingp) { return js::gc::IsAboutToBeFinalized(thingp); } }; } // namespace JS #endif // gc_Policy_h