mirror of
https://github.com/classilla/tenfourfox.git
synced 2024-09-25 17:55:23 +00:00
151 lines
5.8 KiB
C++
151 lines
5.8 KiB
C++
/* -*- 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/. */
|
|
|
|
#ifndef js_Tracer_h
|
|
#define js_Tracer_h
|
|
|
|
#include "jsfriendapi.h"
|
|
|
|
#include "gc/Barrier.h"
|
|
#include "js/GCHashTable.h"
|
|
|
|
namespace js {
|
|
|
|
// Internal Tracing API
|
|
//
|
|
// Tracing is an abstract visitation of each edge in a JS heap graph.[1] The
|
|
// most common (and performance sensitive) use of this infrastructure is for GC
|
|
// "marking" as part of the mark-and-sweep collector; however, this
|
|
// infrastructure is much more general than that and is used for many other
|
|
// purposes as well.
|
|
//
|
|
// One commonly misunderstood subtlety of the tracing architecture is the role
|
|
// of graph vertices versus graph edges. Graph vertices are the heap
|
|
// allocations -- GC things -- that are returned by Allocate. Graph edges are
|
|
// pointers -- including tagged pointers like Value and jsid -- that link the
|
|
// allocations into a complex heap. The tracing API deals *only* with edges.
|
|
// Any action taken on the target of a graph edge is independent of the tracing
|
|
// itself.
|
|
//
|
|
// Another common misunderstanding relates to the role of the JSTracer. The
|
|
// JSTracer instance determines what tracing does when visiting an edge; it
|
|
// does not itself participate in the tracing process, other than to be passed
|
|
// through as opaque data. It works like a closure in that respect.
|
|
//
|
|
// Tracing implementations internal to SpiderMonkey should use these interfaces
|
|
// instead of the public interfaces in js/TracingAPI.h. Unlike the public
|
|
// tracing methods, these work on internal types and avoid an external call.
|
|
//
|
|
// Note that the implementations for these methods are, surprisingly, in
|
|
// js/src/gc/Marking.cpp. This is so that the compiler can inline as much as
|
|
// possible in the common, marking pathways. Conceptually, however, they remain
|
|
// as part of the generic "tracing" architecture, rather than the more specific
|
|
// marking implementation of tracing.
|
|
//
|
|
// 1 - In SpiderMonkey, we call this concept tracing rather than visiting
|
|
// because "visiting" is already used by the compiler. Also, it's been
|
|
// called "tracing" forever and changing it would be extremely difficult at
|
|
// this point.
|
|
|
|
// Trace through an edge in the live object graph on behalf of tracing. The
|
|
// effect of tracing the edge depends on the JSTracer being used.
|
|
template <typename T>
|
|
void
|
|
TraceEdge(JSTracer* trc, WriteBarrieredBase<T>* thingp, const char* name);
|
|
|
|
// Trace through a "root" edge. These edges are the initial edges in the object
|
|
// graph traversal. Root edges are asserted to only be traversed in the initial
|
|
// phase of a GC.
|
|
template <typename T>
|
|
void
|
|
TraceRoot(JSTracer* trc, T* thingp, const char* name);
|
|
|
|
template <typename T>
|
|
void
|
|
TraceRoot(JSTracer* trc, ReadBarriered<T>* thingp, const char* name);
|
|
|
|
// Idential to TraceRoot, except that this variant will not crash if |*thingp|
|
|
// is null.
|
|
template <typename T>
|
|
void
|
|
TraceNullableRoot(JSTracer* trc, T* thingp, const char* name);
|
|
|
|
template <typename T>
|
|
void
|
|
TraceNullableRoot(JSTracer* trc, ReadBarriered<T>* thingp, const char* name);
|
|
|
|
// Like TraceEdge, but for edges that do not use one of the automatic barrier
|
|
// classes and, thus, must be treated specially for moving GC. This method is
|
|
// separate from TraceEdge to make accidental use of such edges more obvious.
|
|
template <typename T>
|
|
void
|
|
TraceManuallyBarrieredEdge(JSTracer* trc, T* thingp, const char* name);
|
|
|
|
// Visits a WeakRef, but does not trace its referents. If *thingp is not marked
|
|
// at the end of marking, it is replaced by nullptr. This method records
|
|
// thingp, so the edge location must not change after this function is called.
|
|
template <typename T>
|
|
void
|
|
TraceWeakEdge(JSTracer* trc, WeakRef<T>* thingp, const char* name);
|
|
|
|
// Trace all edges contained in the given array.
|
|
template <typename T>
|
|
void
|
|
TraceRange(JSTracer* trc, size_t len, WriteBarrieredBase<T>* vec, const char* name);
|
|
|
|
// Trace all root edges in the given array.
|
|
template <typename T>
|
|
void
|
|
TraceRootRange(JSTracer* trc, size_t len, T* vec, const char* name);
|
|
|
|
// Trace an edge that crosses compartment boundaries. If the compartment of the
|
|
// destination thing is not being GC'd, then the edge will not be traced.
|
|
template <typename T>
|
|
void
|
|
TraceCrossCompartmentEdge(JSTracer* trc, JSObject* src, WriteBarrieredBase<T>* dst,
|
|
const char* name);
|
|
|
|
// As above but with manual barriers.
|
|
template <typename T>
|
|
void
|
|
TraceManuallyBarrieredCrossCompartmentEdge(JSTracer* trc, JSObject* src, T* dst,
|
|
const char* name);
|
|
|
|
// Permanent atoms and well-known symbols are shared between runtimes and must
|
|
// use a separate marking path so that we can filter them out of normal heap
|
|
// tracing.
|
|
template <typename T>
|
|
void
|
|
TraceProcessGlobalRoot(JSTracer* trc, T* thing, const char* name);
|
|
|
|
// Trace a root edge that uses the base GC thing type, instead of a more
|
|
// specific type.
|
|
void
|
|
TraceGenericPointerRoot(JSTracer* trc, gc::Cell** thingp, const char* name);
|
|
|
|
// Trace a non-root edge that uses the base GC thing type, instead of a more
|
|
// specific type.
|
|
void
|
|
TraceManuallyBarrieredGenericPointerEdge(JSTracer* trc, gc::Cell** thingp, const char* name);
|
|
|
|
// Deprecated. Please use one of the strongly typed variants above.
|
|
void
|
|
TraceChildren(JSTracer* trc, void* thing, JS::TraceKind kind);
|
|
|
|
namespace gc {
|
|
|
|
// Trace through a shape or group iteratively during cycle collection to avoid
|
|
// deep or infinite recursion.
|
|
void
|
|
TraceCycleCollectorChildren(JS::CallbackTracer* trc, Shape* shape);
|
|
void
|
|
TraceCycleCollectorChildren(JS::CallbackTracer* trc, ObjectGroup* group);
|
|
|
|
} // namespace gc
|
|
} // namespace js
|
|
|
|
#endif /* js_Tracer_h */
|