DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Implementation

Mercurial (b6d82b1a6b02)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202
/* -*- 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/. */

/*
 * JS engine garbage collector API.
 */

#ifndef gc_GC_h
#define gc_GC_h

#include "jsapi.h"

#include "gc/AllocKind.h"
#include "gc/GCEnum.h"
#include "js/TraceKind.h"

class JSExternalString;
class JSFatInlineString;
class JSTracer;

namespace js {

class AccessorShape;
class FatInlineAtom;
class NormalAtom;

class Nursery;

namespace gc {

class Arena;
struct Chunk;
struct Cell;

/*
 * Map from C++ type to alloc kind for non-object types. JSObject does not have
 * a 1:1 mapping, so must use Arena::thingSize.
 *
 * The AllocKind is available as MapTypeToFinalizeKind<SomeType>::kind.
 */
template <typename T>
struct MapTypeToFinalizeKind {};
#define EXPAND_MAPTYPETOFINALIZEKIND(allocKind, traceKind, type, sizedType, \
                                     bgFinal, nursery, compact)             \
  template <>                                                               \
  struct MapTypeToFinalizeKind<type> {                                      \
    static const AllocKind kind = AllocKind::allocKind;                     \
  };
FOR_EACH_NONOBJECT_ALLOCKIND(EXPAND_MAPTYPETOFINALIZEKIND)
#undef EXPAND_MAPTYPETOFINALIZEKIND

} /* namespace gc */

extern void TraceRuntime(JSTracer* trc);

extern void ReleaseAllJITCode(JSFreeOp* op);

extern void PrepareForDebugGC(JSRuntime* rt);

/* Functions for managing cross compartment gray pointers. */

extern void NotifyGCNukeWrapper(JSObject* o);

extern unsigned NotifyGCPreSwap(JSObject* a, JSObject* b);

extern void NotifyGCPostSwap(JSObject* a, JSObject* b, unsigned preResult);

typedef void (*IterateChunkCallback)(JSRuntime* rt, void* data,
                                     gc::Chunk* chunk);
typedef void (*IterateZoneCallback)(JSRuntime* rt, void* data, JS::Zone* zone);
typedef void (*IterateArenaCallback)(JSRuntime* rt, void* data,
                                     gc::Arena* arena, JS::TraceKind traceKind,
                                     size_t thingSize);
typedef void (*IterateCellCallback)(JSRuntime* rt, void* data, void* thing,
                                    JS::TraceKind traceKind, size_t thingSize);

/*
 * This function calls |zoneCallback| on every zone, |realmCallback| on
 * every realm, |arenaCallback| on every in-use arena, and |cellCallback|
 * on every in-use cell in the GC heap.
 *
 * Note that no read barrier is triggered on the cells passed to cellCallback,
 * so no these pointers must not escape the callback.
 */
extern void IterateHeapUnbarriered(JSContext* cx, void* data,
                                   IterateZoneCallback zoneCallback,
                                   JS::IterateRealmCallback realmCallback,
                                   IterateArenaCallback arenaCallback,
                                   IterateCellCallback cellCallback);

/*
 * This function is like IterateHeapUnbarriered, but does it for a single zone.
 */
extern void IterateHeapUnbarrieredForZone(
    JSContext* cx, JS::Zone* zone, void* data, IterateZoneCallback zoneCallback,
    JS::IterateRealmCallback realmCallback, IterateArenaCallback arenaCallback,
    IterateCellCallback cellCallback);

/*
 * Invoke chunkCallback on every in-use chunk.
 */
extern void IterateChunks(JSContext* cx, void* data,
                          IterateChunkCallback chunkCallback);

typedef void (*IterateScriptCallback)(JSRuntime* rt, void* data,
                                      JSScript* script,
                                      const JS::AutoRequireNoGC& nogc);
typedef void (*IterateLazyScriptCallback)(JSRuntime* rt, void* data,
                                          LazyScript* lazyScript,
                                          const JS::AutoRequireNoGC& nogc);

/*
 * Invoke scriptCallback on every in-use script for the given realm or for all
 * realms if it is null.
 */
extern void IterateScripts(JSContext* cx, JS::Realm* realm, void* data,
                           IterateScriptCallback scriptCallback);
extern void IterateLazyScripts(JSContext* cx, JS::Realm* realm, void* data,
                               IterateLazyScriptCallback lazyScriptCallback);

JS::Realm* NewRealm(JSContext* cx, JSPrincipals* principals,
                    const JS::RealmOptions& options);

namespace gc {

void FinishGC(JSContext* cx, JS::GCReason = JS::GCReason::FINISH_GC);

/*
 * Merge all contents of source into target. This can only be used if source is
 * the only realm in its zone.
 */
void MergeRealms(JS::Realm* source, JS::Realm* target);

enum VerifierType { PreBarrierVerifier };

#ifdef JS_GC_ZEAL

extern const char ZealModeHelpText[];

/* Check that write barriers have been used correctly. See gc/Verifier.cpp. */
void VerifyBarriers(JSRuntime* rt, VerifierType type);

void MaybeVerifyBarriers(JSContext* cx, bool always = false);

void DumpArenaInfo();

#else

static inline void VerifyBarriers(JSRuntime* rt, VerifierType type) {}

static inline void MaybeVerifyBarriers(JSContext* cx, bool always = false) {}

#endif

/*
 * Instances of this class prevent GC while they are live by updating the
 * |JSContext::suppressGC| counter. Use of this class is highly
 * discouraged. Please carefully read the comment in vm/JSContext.h above
 * |suppressGC| and take all appropriate precautions before instantiating this
 * class.
 */
class MOZ_RAII JS_HAZ_GC_SUPPRESSED AutoSuppressGC {
  int32_t& suppressGC_;

 public:
  explicit AutoSuppressGC(JSContext* cx);

  ~AutoSuppressGC() { suppressGC_--; }
};

const char* StateName(State state);

} /* namespace gc */

/* Use this to avoid assertions when manipulating the wrapper map. */
class MOZ_RAII AutoDisableProxyCheck {
 public:
#ifdef DEBUG
  AutoDisableProxyCheck();
  ~AutoDisableProxyCheck();
#else
  AutoDisableProxyCheck() {}
#endif
};

struct MOZ_RAII AutoDisableCompactingGC {
  explicit AutoDisableCompactingGC(JSContext* cx);
  ~AutoDisableCompactingGC();

 private:
  JSContext* cx;
};

// This is the same as IsInsideNursery, but not inlined.
bool UninlinedIsInsideNursery(const gc::Cell* cell);

} /* namespace js */

#endif /* gc_GC_h */