/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- * vim: set ts=8 sts=2 et sw=2 tw=80: * 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/. */ /* * Marking and sweeping APIs for use by implementations of different GC cell * kinds. */ #ifndef gc_Marking_h #define gc_Marking_h #include "js/TypeDecls.h" #include "vm/TaggedProto.h" class JSLinearString; class JSRope; class JSTracer; struct JSClass; namespace js { class BaseShape; class GCMarker; class NativeObject; class ObjectGroup; class Shape; class WeakMapBase; namespace jit { class JitCode; } // namespace jit namespace gc { struct Cell; class TenuredCell; /*** Liveness ***/ // The IsMarkedInternal and IsAboutToBeFinalizedInternal function templates are // used to implement the IsMarked and IsAboutToBeFinalized set of functions. // These internal functions are instantiated for the base GC types and should // not be called directly. // // Note that there are two function templates declared for each, not one // template and a specialization. This is necessary so that pointer arguments // (e.g. JSObject**) and tagged value arguments (e.g. JS::Value*) are routed to // separate implementations. template bool IsMarkedInternal(JSRuntime* rt, T** thing); template bool IsAboutToBeFinalizedInternal(T* thingp); template bool IsAboutToBeFinalizedInternal(T** thingp); // Report whether a GC thing has been marked with any color. Things which are in // zones that are not currently being collected or are owned by another runtime // are always reported as being marked. template inline bool IsMarkedUnbarriered(JSRuntime* rt, T* thingp) { return IsMarkedInternal(rt, ConvertToBase(thingp)); } // Report whether a GC thing has been marked with any color. Things which are in // zones that are not currently being collected or are owned by another runtime // are always reported as being marked. template inline bool IsMarked(JSRuntime* rt, BarrieredBase* thingp) { return IsMarkedInternal(rt, ConvertToBase(thingp->unbarrieredAddress())); } template inline bool IsAboutToBeFinalizedUnbarriered(T* thingp) { return IsAboutToBeFinalizedInternal(ConvertToBase(thingp)); } template inline bool IsAboutToBeFinalized(const BarrieredBase* thingp) { return IsAboutToBeFinalizedInternal( ConvertToBase(thingp->unbarrieredAddress())); } inline bool IsAboutToBeFinalizedDuringMinorSweep(Cell* cell); inline Cell* ToMarkable(const Value& v) { if (v.isGCThing()) { return (Cell*)v.toGCThing(); } return nullptr; } inline Cell* ToMarkable(Cell* cell) { return cell; } bool UnmarkGrayGCThingUnchecked(JSRuntime* rt, JS::GCCellPtr thing); } /* namespace gc */ // The return value indicates if anything was unmarked. bool UnmarkGrayShapeRecursively(Shape* shape); namespace gc { // Functions for checking and updating GC thing pointers that might have been // moved by compacting GC. Overloads are also provided that work with Values. // // IsForwarded - check whether a pointer refers to an GC thing that has been // moved. // // Forwarded - return a pointer to the new location of a GC thing given a // pointer to old location. // // MaybeForwarded - used before dereferencing a pointer that may refer to a // moved GC thing without updating it. For JSObjects this will // also update the object's shape pointer if it has been moved // to allow slots to be accessed. template inline bool IsForwarded(const T* t); template inline T* Forwarded(const T* t); inline Value Forwarded(const JS::Value& value); template inline T MaybeForwarded(T t); // Helper functions for use in situations where the object's group might be // forwarded, for example while marking. inline const JSClass* MaybeForwardedObjectClass(const JSObject* obj); template inline bool MaybeForwardedObjectIs(JSObject* obj); template inline T& MaybeForwardedObjectAs(JSObject* obj); // Trace TypedObject trace lists with specialised paths for GCMarker and // TenuringTracer. void VisitTraceList(JSTracer* trc, JSObject* obj, const uint32_t* traceList, uint8_t* memory); #ifdef JSGC_HASH_TABLE_CHECKS template inline bool IsGCThingValidAfterMovingGC(T* t); template inline void CheckGCThingAfterMovingGC(T* t); template inline void CheckGCThingAfterMovingGC(const WeakHeapPtr& t); #endif // JSGC_HASH_TABLE_CHECKS } /* namespace gc */ // Debugging functions to check tracing invariants. #ifdef DEBUG template void CheckTracedThing(JSTracer* trc, T* thing); template void CheckTracedThing(JSTracer* trc, const T& thing); #else template inline void CheckTracedThing(JSTracer* trc, T* thing) {} template inline void CheckTracedThing(JSTracer* trc, const T& thing) {} #endif } /* namespace js */ #endif /* gc_Marking_h */