/* -*- 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 gc_GCInternals_h
#define gc_GCInternals_h

#include "mozilla/ArrayUtils.h"
#include "mozilla/PodOperations.h"

#include "jscntxt.h"

#include "gc/Zone.h"
#include "vm/HelperThreads.h"
#include "vm/Runtime.h"

namespace js {
namespace gc {

void
MarkPersistentRootedChains(JSTracer* trc);

class MOZ_RAII AutoCopyFreeListToArenas
{
    JSRuntime* runtime;
    ZoneSelector selector;

  public:
    AutoCopyFreeListToArenas(JSRuntime* rt, ZoneSelector selector);
    ~AutoCopyFreeListToArenas();
};

struct MOZ_RAII AutoFinishGC
{
    explicit AutoFinishGC(JSRuntime* rt);
};

/*
 * This class should be used by any code that needs to exclusive access to the
 * heap in order to trace through it...
 */
class MOZ_RAII AutoTraceSession
{
  public:
    explicit AutoTraceSession(JSRuntime* rt, JS::HeapState state = JS::HeapState::Tracing);
    ~AutoTraceSession();

  protected:
    AutoLockForExclusiveAccess lock;
    JSRuntime* runtime;

  private:
    AutoTraceSession(const AutoTraceSession&) = delete;
    void operator=(const AutoTraceSession&) = delete;

    JS::HeapState prevState;
    AutoSPSEntry pseudoFrame;
};

struct MOZ_RAII AutoPrepareForTracing
{
    AutoFinishGC finish;
    AutoTraceSession session;
    AutoCopyFreeListToArenas copy;

    AutoPrepareForTracing(JSRuntime* rt, ZoneSelector selector);
};

class IncrementalSafety
{
    const char* reason_;

    explicit IncrementalSafety(const char* reason) : reason_(reason) {}

  public:
    static IncrementalSafety Safe() { return IncrementalSafety(nullptr); }
    static IncrementalSafety Unsafe(const char* reason) { return IncrementalSafety(reason); }

    explicit operator bool() const {
        return reason_ == nullptr;
    }

    const char* reason() {
        MOZ_ASSERT(reason_);
        return reason_;
    }
};

IncrementalSafety
IsIncrementalGCSafe(JSRuntime* rt);

class MOZ_RAII AutoStopVerifyingBarriers
{
    GCRuntime* gc;
    bool restartPreVerifier;

  public:
    AutoStopVerifyingBarriers(JSRuntime* rt, bool isShutdown)
      : gc(&rt->gc)
    {
        if (cobalt::configuration::Configuration::GetInstance()->CobaltGcZeal()) {
            restartPreVerifier = gc->endVerifyPreBarriers() && !isShutdown;
        }
    }

    ~AutoStopVerifyingBarriers() {
        if (cobalt::configuration::Configuration::GetInstance()->CobaltGcZeal()) {
            // 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::Phase outer = gc->stats.currentPhase();
            if (outer != gcstats::PHASE_NONE)
                gc->stats.endPhase(outer);
            MOZ_ASSERT((gc->stats.currentPhase() == gcstats::PHASE_NONE) ||
                       (gc->stats.currentPhase() == gcstats::PHASE_GC_BEGIN) ||
                       (gc->stats.currentPhase() == gcstats::PHASE_GC_END));

            if (restartPreVerifier)
                gc->startVerifyPreBarriers();

            if (outer != gcstats::PHASE_NONE)
                gc->stats.beginPhase(outer);
        }
    }
};

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

struct MovingTracer : JS::CallbackTracer
{
    explicit MovingTracer(JSRuntime* rt) : CallbackTracer(rt, TraceWeakMapKeysValues) {}

    void onObjectEdge(JSObject** objp) override;
    void onChild(const JS::GCCellPtr& thing) override {
        MOZ_ASSERT(!RelocationOverlay::isCellForwarded(thing.asCell()));
    }

#ifdef DEBUG
    TracerKind getTracerKind() const override { return TracerKind::Moving; }
#endif
};

class MOZ_RAII AutoMaybeStartBackgroundAllocation
{
  private:
    JSRuntime* runtime;

  public:
    AutoMaybeStartBackgroundAllocation()
      : runtime(nullptr)
    {}

    void tryToStartBackgroundAllocation(JSRuntime* rt) {
        runtime = rt;
    }

    ~AutoMaybeStartBackgroundAllocation() {
        if (runtime)
            runtime->gc.startBackgroundAllocTaskIfIdle();
    }
};

// In debug builds, set/unset the GC sweeping flag for the current thread.
struct MOZ_RAII AutoSetThreadIsSweeping
{
#ifdef DEBUG
    AutoSetThreadIsSweeping()
      : threadData_(js::TlsPerThreadData.get())
    {
        MOZ_ASSERT(!threadData_->gcSweeping);
        threadData_->gcSweeping = true;
    }

    ~AutoSetThreadIsSweeping() {
        MOZ_ASSERT(threadData_->gcSweeping);
        threadData_->gcSweeping = false;
    }

  private:
    PerThreadData* threadData_;
#else
    AutoSetThreadIsSweeping() {}
#endif
};

// Structure for counting how many times objects in a particular group have
// been tenured during a minor collection.
struct TenureCount
{
    ObjectGroup* group;
    int count;
};

// Keep rough track of how many times we tenure objects in particular groups
// during minor collections, using a fixed size hash for efficiency at the cost
// of potential collisions.
struct TenureCountCache
{
    TenureCount entries[16];

    TenureCountCache() { mozilla::PodZero(this); }

    TenureCount& findEntry(ObjectGroup* group) {
        return entries[PointerHasher<ObjectGroup*, 3>::hash(group) % mozilla::ArrayLength(entries)];
    }
};

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

#endif /* gc_GCInternals_h */
