Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/js/src/gc/   (Firefox Browser Version 153.0.1©)  Datei vom 27.6.2026 mit Größe 9 kB image not shown  

Quelle  GCInternals.h

  Sprache: C
 

/* 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/. */


/*
 * GC-internal definitions.
 */


#ifndef gc_GCInternals_h
#define gc_GCInternals_h

#include "mozilla/Maybe.h"
#include "mozilla/Range.h"
#include "mozilla/TimeStamp.h"
#include "mozilla/Vector.h"

#include "gc/Cell.h"
#include "gc/GC.h"
#include "gc/GCContext.h"
#include "gc/GCMarker.h"
#include "vm/GeckoProfiler.h"
#include "vm/HelperThreads.h"
#include "vm/JSContext.h"

namespace js {

class GCMarker;

namespace gc {

/*
 * There are a couple of classes here that serve mostly as "tokens" indicating
 * that a precondition holds. Some functions force the caller to possess such a
 * token because they require the precondition to hold, and it is better to make
 * the precondition explicit at the API entry point than to crash in an
 * assertion later on when it is relied upon.
 */


struct MOZ_RAII AutoAssertNoNurseryAlloc {
#ifdef DEBUG
  AutoAssertNoNurseryAlloc();
  ~AutoAssertNoNurseryAlloc();
#else
  AutoAssertNoNurseryAlloc() {}
#endif
};

/*
 * A class that serves as a token that the nursery in the current thread's zone
 * group is empty.
 */

class MOZ_RAII AutoAssertEmptyNursery {
 protected:
  JSContext* cx;

  mozilla::Maybe<AutoAssertNoNurseryAlloc> noAlloc;

  // Check that the nursery is empty.
  void checkCondition(JSContext* cx);

  // For subclasses that need to empty the nursery in their constructors.
  AutoAssertEmptyNursery() : cx(nullptr) {}

 public:
  explicit AutoAssertEmptyNursery(JSContext* cx) : cx(nullptr) {
    checkCondition(cx);
  }

  AutoAssertEmptyNursery(const AutoAssertEmptyNursery& other)
      : AutoAssertEmptyNursery(other.cx) {}
};

/*
 * Evict the nursery upon construction. Serves as a token indicating that the
 * nursery is empty. (See AutoAssertEmptyNursery, above.)
 */

class MOZ_RAII AutoEmptyNursery : public AutoAssertEmptyNursery {
 public:
  explicit AutoEmptyNursery(JSContext* cx);
};

class MOZ_RAII AutoGCSession : public AutoHeapSession {
 public:
  explicit AutoGCSession(GCRuntime* gc, JS::HeapState state)
      : AutoHeapSession(gc, state) {}
};

class MOZ_RAII AutoMajorGCProfilerEntry : public AutoGeckoProfilerEntry {
 public:
  explicit AutoMajorGCProfilerEntry(GCRuntime* gc);
};

// This class should be used by any code that needs exclusive access to the heap
// in order to trace through it.
//
// This version also empties the nursery after finishing any ongoing GC.
class MOZ_RAII AutoEmptyNurseryAndPrepareForTracing : private AutoFinishGC,
                                                      public AutoEmptyNursery,
                                                      public AutoTraceSession {
 public:
  explicit AutoEmptyNurseryAndPrepareForTracing(JSContext* cx)
      : AutoFinishGC(cx, JS::GCReason::PREPARE_FOR_TRACING),
        AutoEmptyNursery(cx),
        AutoTraceSession(cx->runtime()) {}
};

// Set compartments' maybeAlive flags if anything is marked while this class is
// live. This is used while marking roots.
class AutoUpdateLiveCompartments {
  GCRuntime* gc;

 public:
  explicit AutoUpdateLiveCompartments(GCRuntime* gc);
  ~AutoUpdateLiveCompartments();
};

class MOZ_RAII AutoRunParallelTask : public GCParallelTask {
  // This class takes a pointer to a member function of GCRuntime.
  using TaskFunc = JS_MEMBER_FN_PTR_TYPE(GCRuntime, void);

  TaskFunc func_;
  AutoLockHelperThreadState& lock_;

 public:
  AutoRunParallelTask(GCRuntime* gc, TaskFunc func, gcstats::PhaseKind phase,
                      GCUse use, AutoLockHelperThreadState& lock)
      : GCParallelTask(gc, phase, use), func_(func), lock_(lock) {
    gc->startTask(*this, lock_);
  }

  ~AutoRunParallelTask() { gc->joinTask(*this, lock_); }

  void run(AutoLockHelperThreadState& lock) override {
    AutoUnlockHelperThreadState unlock(lock);

    // The hazard analysis can't tell what the call to func_ will do but it's
    // not allowed to GC.
    JS::AutoSuppressGCAnalysis nogc;

    // Call pointer to member function on |gc|.
    JS_CALL_MEMBER_FN_PTR(gc, func_);
  }
};

#ifdef JS_GC_ZEAL

class MOZ_RAII AutoStopVerifyingBarriers {
  GCRuntime* gc;
  bool restartPreVerifier;

 public:
  AutoStopVerifyingBarriers(JSRuntime* rt, bool isShutdown) : gc(&rt->gc) {
    if (gc->isVerifyPreBarriersEnabled()) {
      gc->endVerifyPreBarriers();
      restartPreVerifier = !isShutdown;
    } else {
      restartPreVerifier = false;
    }
  }

  ~AutoStopVerifyingBarriers() {
    // Nasty special case: verification runs a minor GC, which *may* nest
    // inside of an outer minor GC. This is not allowed by the
    // gc::Statistics phase tree. So we pause the "real" GC, if in fact one
    // is in progress.
    gcstats::PhaseKind outer = gc->stats().currentPhaseKind();
    if (outer != gcstats::PhaseKind::NONE) {
      gc->stats().endPhase(outer);
    }
    MOZ_ASSERT(gc->stats().currentPhaseKind() == gcstats::PhaseKind::NONE);

    if (restartPreVerifier) {
      gc->startVerifyPreBarriers();
    }

    if (outer != gcstats::PhaseKind::NONE) {
      gc->stats().beginPhase(outer);
    }
  }
};
#else
struct MOZ_RAII AutoStopVerifyingBarriers {
  AutoStopVerifyingBarriers(JSRuntime*, bool) {}
};
#endif /* JS_GC_ZEAL */

class MOZ_RAII AutoPoisonFreedJitCode {
  JS::GCContext* const gcx;

 public:
  explicit AutoPoisonFreedJitCode(JS::GCContext* gcx) : gcx(gcx) {}
  ~AutoPoisonFreedJitCode() { gcx->poisonJitCode(); }
};

// Set/restore the GCContext GC use flag for the current thread.

class MOZ_RAII AutoSetThreadGCUse {
 public:
  AutoSetThreadGCUse(JS::GCContext* gcx, GCUse use)
      : gcx(gcx), prevUse(gcx->gcUse_) {
    gcx->gcUse_ = use;
  }
  explicit AutoSetThreadGCUse(GCUse use)
      : AutoSetThreadGCUse(TlsGCContext.get(), use) {}

  ~AutoSetThreadGCUse() { gcx->gcUse_ = prevUse; }

 protected:
  JS::GCContext* gcx;
  GCUse prevUse;
};

template <GCUse Use>
class AutoSetThreadGCUseT : public AutoSetThreadGCUse {
 public:
  explicit AutoSetThreadGCUseT(JS::GCContext* gcx)
      : AutoSetThreadGCUse(gcx, Use) {}
  AutoSetThreadGCUseT() : AutoSetThreadGCUseT(TlsGCContext.get()) {}
};

using AutoSetThreadIsPerformingGC = AutoSetThreadGCUseT<GCUse::Unspecified>;
using AutoSetThreadIsMarking = AutoSetThreadGCUseT<GCUse::Marking>;
using AutoSetThreadIsFinalizing = AutoSetThreadGCUseT<GCUse::Finalizing>;

class AutoSetThreadIsSweeping : public AutoSetThreadGCUseT<GCUse::Sweeping> {
 public:
  explicit AutoSetThreadIsSweeping(JS::GCContext* gcx,
                                   JS::Zone* sweepZone = nullptr)
      : AutoSetThreadGCUseT(gcx) {
#ifdef DEBUG
    prevZone = gcx->gcSweepZone_;
    gcx->gcSweepZone_ = sweepZone;
#endif
  }
  explicit AutoSetThreadIsSweeping(JS::Zone* sweepZone = nullptr)
      : AutoSetThreadIsSweeping(TlsGCContext.get(), sweepZone) {}

  ~AutoSetThreadIsSweeping() {
#ifdef DEBUG
    MOZ_ASSERT_IF(prevUse == GCUse::None, !prevZone);
    gcx->gcSweepZone_ = prevZone;
#endif
  }

 private:
#ifdef DEBUG
  JS::Zone* prevZone;
#endif
};

class MOZ_RAII AutoDisallowPreWriteBarrier {
 public:
  explicit AutoDisallowPreWriteBarrier(JS::GCContext* gcx) {
#ifdef DEBUG
    gcx_ = gcx;
    MOZ_ASSERT(gcx->preWriteBarrierAllowed_);
    gcx->preWriteBarrierAllowed_ = false;
#endif
  }
  ~AutoDisallowPreWriteBarrier() {
#ifdef DEBUG
    MOZ_ASSERT(!gcx_->preWriteBarrierAllowed_);
    gcx_->preWriteBarrierAllowed_ = true;
#endif
  }

 private:
#ifdef DEBUG
  JS::GCContext* gcx_;
#endif
};

#ifdef JSGC_HASH_TABLE_CHECKS
void CheckHashTablesAfterMovingGC(JSRuntime* rt);
void CheckHeapAfterGC(JSRuntime* rt);
#endif

struct MovingTracer final : public GenericTracerImpl<MovingTracer> {
  explicit MovingTracer(JSRuntime* rt);

 private:
  template <typename T>
  bool onEdge(T** thingp, const char* name);
  friend class GenericTracerImpl<MovingTracer>;
};

struct MinorSweepingTracer final
    : public GenericTracerImpl<MinorSweepingTracer> {
  explicit MinorSweepingTracer(JSRuntime* rt);

 private:
  template <typename T>
  bool onEdge(T** thingp, const char* name);
  friend class GenericTracerImpl<MinorSweepingTracer>;
};

class MOZ_RAII AutoUpdateMarkStackRanges {
  GCMarker& marker_;

 public:
  explicit AutoUpdateMarkStackRanges(GCMarker& marker) : marker_(marker) {
    marker_.updateRangesAtStartOfSlice();
  }
  ~AutoUpdateMarkStackRanges() { marker_.updateRangesAtEndOfSlice(); }
};

extern void DelayCrossCompartmentGrayMarking(GCMarker* maybeMarker,
                                             JSObject* src);

inline bool IsOOMReason(JS::GCReason reason) {
  return reason == JS::GCReason::LAST_DITCH ||
         reason == JS::GCReason::MEM_PRESSURE;
}

void* AllocateTenuredCellInGC(JS::Zone* zone, AllocKind thingKind);

void ReadProfileEnv(const char* envName, const char* helpText, bool* enableOut,
                    bool* workersOut, mozilla::TimeDuration* thresholdOut);

bool ShouldPrintProfile(JSRuntime* runtime, bool enable, bool workers,
                        mozilla::TimeDuration threshold,
                        mozilla::TimeDuration duration);

using CharRange = mozilla::Range<const char>;
using CharRangeVector = Vector<CharRange, 0, SystemAllocPolicy>;

// Split a string on a given character and produce a vector of CharRanges that
// reference the input string.
extern bool SplitStringBy(const char* string, char delimiter,
                          CharRangeVector* resultOut);
extern bool SplitStringBy(const CharRange& string, char delimiter,
                          CharRangeVector* resultOut);

/* namespace gc */
/* namespace js */

#endif /* gc_GCInternals_h */

Messung V0.5 in Prozent
C=90 H=58 G=75

¤ Dauer der Verarbeitung: 0.4 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.