Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  GCContext.h   Sprache: C

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


#ifndef gc_GCContext_h
#define gc_GCContext_h

#include "mozilla/Assertions.h"  // MOZ_ASSERT
#include "mozilla/ThreadLocal.h"

#include "jspubtd.h"
#include "jstypes.h"                  // JS_PUBLIC_API
#include "gc/GCEnum.h"                // js::MemoryUse
#include "jit/ExecutableAllocator.h"  // jit::JitPoisonRangeVector
#include "js/Utility.h"               // js_free

struct JS_PUBLIC_API JSRuntime;

namespace js {

class AutoTouchingGrayThings;

namespace gc {

class AutoSetThreadGCUse;
class AutoSetThreadIsSweeping;

enum class GCUse {
  // This thread is not running in the garbage collector.
  None,

  // This thread is currently collecting. Used when no finer detail is known.
  Unspecified,

  // This thread is currently marking GC things. This thread could be the main
  // thread or a helper thread doing sweep-marking.
  Marking,

  // This thread is currently sweeping GC things. This thread could be the
  // main thread or a helper thread while the main thread is running the
  // mutator.
  Sweeping,

  // Whether this thread is currently finalizing GC things. This thread could
  // be the main thread or a helper thread doing finalization while the main
  // thread is running the mutator.
  Finalizing
};

}  // namespace gc
}  // namespace js

namespace JS {

/*
 * GCContext is by GC operations that can run on or off the main thread.
 *
 * Its main function is to provide methods to free memory and update memory
 * accounting. For convenience, it also has delete_ convenience methods that
 * also call destructors.
 *
 * It is passed to finalizers and other sweep-phase hooks as JSContext is not
 * available off the main thread.
 */

class GCContext {
  using Cell = js::gc::Cell;
  using MemoryUse = js::MemoryUse;

  JSRuntime* const runtime_;

  js::jit::JitPoisonRangeVector jitPoisonRanges;

  // Which part of the garbage collector this context is running at the moment.
  js::gc::GCUse gcUse_ = js::gc::GCUse::None;
  friend class js::gc::AutoSetThreadGCUse;
  friend class js::gc::AutoSetThreadIsSweeping;

#ifdef DEBUG
  // The specific zone currently being swept, if any.
  Zone* gcSweepZone_ = nullptr;

  // Whether this thread is currently manipulating possibly-gray GC things.
  size_t isTouchingGrayThings_ = false;
  friend class js::AutoTouchingGrayThings;
#endif

 public:
  explicit GCContext(JSRuntime* maybeRuntime);
  ~GCContext();

  JSRuntime* runtime() const {
    MOZ_ASSERT(onMainThread());
    return runtimeFromAnyThread();
  }
  JSRuntime* runtimeFromAnyThread() const {
    MOZ_ASSERT(runtime_);
    return runtime_;
  }

  js::gc::GCUse gcUse() const { return gcUse_; }
  bool isCollecting() const { return gcUse() != js::gc::GCUse::None; }
  bool isFinalizing() const { return gcUse_ == js::gc::GCUse::Finalizing; }

#ifdef DEBUG
  bool onMainThread() const {
    return js::CurrentThreadCanAccessRuntime(runtime_);
  }

  Zone* gcSweepZone() const { return gcSweepZone_; }
  bool isTouchingGrayThings() const { return isTouchingGrayThings_; }
#endif

  // Deprecated. Where possible, memory should be tracked against the owning GC
  // thing by calling js::AddCellMemory and the memory freed with free_() below.
  void freeUntracked(void* p) { js_free(p); }

  // Free memory associated with a GC thing and update the memory accounting.
  //
  // The memory should have been associated with the GC thing using
  // js::InitReservedSlot or js::InitObjectPrivate, or possibly
  // js::AddCellMemory.
  void free_(Cell* cell, void* p, size_t nbytes, MemoryUse use);

  bool appendJitPoisonRange(const js::jit::JitPoisonRange& range) {
    return jitPoisonRanges.append(range);
  }
  bool hasJitCodeToPoison() const { return !jitPoisonRanges.empty(); }
  void poisonJitCode();

  // Deprecated. Where possible, memory should be tracked against the owning GC
  // thing by calling js::AddCellMemory and the memory freed with delete_()
  // below.
  template <class T>
  void deleteUntracked(T* p) {
    if (p) {
      p->~T();
      js_free(p);
    }
  }

  // Delete a C++ object that was associated with a GC thing and update the
  // memory accounting. The size is determined by the type T.
  //
  // The memory should have been associated with the GC thing using
  // js::InitReservedSlot or js::InitObjectPrivate, or possibly
  // js::AddCellMemory.
  template <class T>
  void delete_(Cell* cell, T* p, MemoryUse use) {
    delete_(cell, p, sizeof(T), use);
  }

  // Delete a C++ object that was associated with a GC thing and update the
  // memory accounting.
  //
  // The memory should have been associated with the GC thing using
  // js::InitReservedSlot or js::InitObjectPrivate, or possibly
  // js::AddCellMemory.
  template <class T>
  void delete_(Cell* cell, T* p, size_t nbytes, MemoryUse use) {
    if (p) {
      p->~T();
      free_(cell, p, nbytes, use);
    }
  }

  // Release a RefCounted object that was associated with a GC thing and update
  // the memory accounting.
  //
  // The memory should have been associated with the GC thing using
  // js::InitReservedSlot or js::InitObjectPrivate, or possibly
  // js::AddCellMemory.
  //
  // This counts the memory once per association with a GC thing. It's not
  // expected that the same object is associated with more than one GC thing in
  // each zone. If this is the case then some other form of accounting would be
  // more appropriate.
  template <class T>
  void release(Cell* cell, T* p, MemoryUse use) {
    release(cell, p, sizeof(T), use);
  }

  // Release a RefCounted object and that was associated with a GC thing and
  // update the memory accounting.
  //
  // The memory should have been associated with the GC thing using
  // js::InitReservedSlot or js::InitObjectPrivate, or possibly
  // js::AddCellMemory.
  template <class T>
  void release(Cell* cell, T* p, size_t nbytes, MemoryUse use);

  // Update the memory accounting for a GC for memory freed by some other
  // method.
  void removeCellMemory(Cell* cell, size_t nbytes, MemoryUse use);
};

}  // namespace JS

namespace js {

/* Thread Local Storage for storing the GCContext for a thread. */
extern MOZ_THREAD_LOCAL(JS::GCContext*) TlsGCContext;

inline JS::GCContext* MaybeGetGCContext() {
  if (!TlsGCContext.init()) {
    return nullptr;
  }
  return TlsGCContext.get();
}

class MOZ_RAII AutoTouchingGrayThings {
 public:
#ifdef DEBUG
  AutoTouchingGrayThings() { TlsGCContext.get()->isTouchingGrayThings_++; }
  ~AutoTouchingGrayThings() {
    JS::GCContext* gcx = TlsGCContext.get();
    MOZ_ASSERT(gcx->isTouchingGrayThings_);
    gcx->isTouchingGrayThings_--;
  }
#else
  AutoTouchingGrayThings() {}
#endif
};

#ifdef DEBUG

inline bool CurrentThreadIsGCMarking() {
  JS::GCContext* gcx = MaybeGetGCContext();
  return gcx && gcx->gcUse() == gc::GCUse::Marking;
}

inline bool CurrentThreadIsGCSweeping() {
  JS::GCContext* gcx = MaybeGetGCContext();
  return gcx && gcx->gcUse() == gc::GCUse::Sweeping;
}

inline bool CurrentThreadIsGCFinalizing() {
  JS::GCContext* gcx = MaybeGetGCContext();
  return gcx && gcx->gcUse() == gc::GCUse::Finalizing;
}

inline bool CurrentThreadIsTouchingGrayThings() {
  JS::GCContext* gcx = MaybeGetGCContext();
  return gcx && gcx->isTouchingGrayThings();
}

inline bool CurrentThreadIsPerformingGC() {
  JS::GCContext* gcx = MaybeGetGCContext();
  return gcx && gcx->isCollecting();
}

#endif

}  // namespace js

#endif  // gc_GCContext_h

Messung V0.5
C=85 H=100 G=92

¤ Dauer der Verarbeitung: 0.11 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

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.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge