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

#include "jsapi-tests/tests.h"

static const unsigned BufferSize = 20;
static unsigned FinalizeCalls = 0;
static JSFinalizeStatus StatusBuffer[BufferSize];
static bool IsCompartmentGCBuffer[BufferSize];

BEGIN_TEST(testGCFinalizeCallback)
{
    JS_SetGCParameter(rt, JSGC_MODE, JSGC_MODE_INCREMENTAL);

    /* Full GC, non-incremental. */
    FinalizeCalls = 0;
    JS_GC(rt);
    CHECK(rt->gc.isFullGc());
    CHECK(checkSingleGroup());
    CHECK(checkFinalizeStatus());
    CHECK(checkFinalizeIsCompartmentGC(false));

    /* Full GC, incremental. */
    FinalizeCalls = 0;
    JS::PrepareForFullGC(rt);
    JS::StartIncrementalGC(rt, GC_NORMAL, JS::gcreason::API, 1000000);
    CHECK(!rt->gc.isIncrementalGCInProgress());
    CHECK(rt->gc.isFullGc());
    CHECK(checkMultipleGroups());
    CHECK(checkFinalizeStatus());
    CHECK(checkFinalizeIsCompartmentGC(false));

    JS::RootedObject global1(cx, createTestGlobal());
    JS::RootedObject global2(cx, createTestGlobal());
    JS::RootedObject global3(cx, createTestGlobal());
    CHECK(global1);
    CHECK(global2);
    CHECK(global3);

    /* Compartment GC, non-incremental, single compartment. */
    FinalizeCalls = 0;
    JS::PrepareZoneForGC(global1->zone());
    JS::GCForReason(rt, GC_NORMAL, JS::gcreason::API);
    CHECK(!rt->gc.isFullGc());
    CHECK(checkSingleGroup());
    CHECK(checkFinalizeStatus());
    CHECK(checkFinalizeIsCompartmentGC(true));

    /* Compartment GC, non-incremental, multiple compartments. */
    FinalizeCalls = 0;
    JS::PrepareZoneForGC(global1->zone());
    JS::PrepareZoneForGC(global2->zone());
    JS::PrepareZoneForGC(global3->zone());
    JS::GCForReason(rt, GC_NORMAL, JS::gcreason::API);
    CHECK(!rt->gc.isFullGc());
    CHECK(checkSingleGroup());
    CHECK(checkFinalizeStatus());
    CHECK(checkFinalizeIsCompartmentGC(true));

    /* Compartment GC, incremental, single compartment. */
    FinalizeCalls = 0;
    JS::PrepareZoneForGC(global1->zone());
    JS::StartIncrementalGC(rt, GC_NORMAL, JS::gcreason::API, 1000000);
    CHECK(!rt->gc.isIncrementalGCInProgress());
    CHECK(!rt->gc.isFullGc());
    CHECK(checkSingleGroup());
    CHECK(checkFinalizeStatus());
    CHECK(checkFinalizeIsCompartmentGC(true));

    /* Compartment GC, incremental, multiple compartments. */
    FinalizeCalls = 0;
    JS::PrepareZoneForGC(global1->zone());
    JS::PrepareZoneForGC(global2->zone());
    JS::PrepareZoneForGC(global3->zone());
    JS::StartIncrementalGC(rt, GC_NORMAL, JS::gcreason::API, 1000000);
    CHECK(!rt->gc.isIncrementalGCInProgress());
    CHECK(!rt->gc.isFullGc());
    CHECK(checkMultipleGroups());
    CHECK(checkFinalizeStatus());
    CHECK(checkFinalizeIsCompartmentGC(true));

    if (configuration::Configuration::GetInstance()->CobaltGcZeal()) {
      /* Full GC with reset due to new compartment, becoming compartment GC. */

      FinalizeCalls = 0;
      JS_SetGCZeal(cx, 9, 1000000);
      JS::PrepareForFullGC(rt);
      js::SliceBudget budget(js::WorkBudget(1));
      rt->gc.startDebugGC(GC_NORMAL, budget);
      CHECK(rt->gc.state() == js::gc::MARK);
      CHECK(rt->gc.isFullGc());

      JS::RootedObject global4(cx, createTestGlobal());
      budget = js::SliceBudget(js::WorkBudget(1));
      rt->gc.debugGCSlice(budget);
      CHECK(!rt->gc.isIncrementalGCInProgress());
      CHECK(!rt->gc.isFullGc());
      CHECK(checkMultipleGroups());
      CHECK(checkFinalizeStatus());

      for (unsigned i = 0; i < FinalizeCalls - 1; ++i)
        CHECK(!IsCompartmentGCBuffer[i]);
      CHECK(IsCompartmentGCBuffer[FinalizeCalls - 1]);

      JS_SetGCZeal(cx, 0, 0);
    }

    /*
     * Make some use of the globals here to ensure the compiler doesn't optimize
     * them away in release builds, causing the compartments to be collected and
     * the test to fail.
     */
    CHECK(JS_IsGlobalObject(global1));
    CHECK(JS_IsGlobalObject(global2));
    CHECK(JS_IsGlobalObject(global3));

    return true;
}

JSObject* createTestGlobal()
{
    JS::CompartmentOptions options;
    options.setVersion(JSVERSION_LATEST);
    return JS_NewGlobalObject(cx, getGlobalClass(), nullptr, JS::FireOnNewGlobalHook, options);
}

virtual bool init() override
{
    if (!JSAPITest::init())
        return false;

    JS_AddFinalizeCallback(rt, FinalizeCallback, nullptr);
    return true;
}

virtual void uninit() override
{
    JS_RemoveFinalizeCallback(rt, FinalizeCallback);
    JSAPITest::uninit();
}

bool checkSingleGroup()
{
    CHECK(FinalizeCalls < BufferSize);
    CHECK(FinalizeCalls == 3);
    return true;
}

bool checkMultipleGroups()
{
    CHECK(FinalizeCalls < BufferSize);
    CHECK(FinalizeCalls % 2 == 1);
    CHECK((FinalizeCalls - 1) / 2 > 1);
    return true;
}

bool checkFinalizeStatus()
{
    /*
     * The finalize callback should be called twice for each compartment group
     * finalized, with status JSFINALIZE_GROUP_START and JSFINALIZE_GROUP_END,
     * and then once more with JSFINALIZE_COLLECTION_END.
     */

    for (unsigned i = 0; i < FinalizeCalls - 1; i += 2) {
        CHECK(StatusBuffer[i] == JSFINALIZE_GROUP_START);
        CHECK(StatusBuffer[i + 1] == JSFINALIZE_GROUP_END);
    }

    CHECK(StatusBuffer[FinalizeCalls - 1] == JSFINALIZE_COLLECTION_END);

    return true;
}

bool checkFinalizeIsCompartmentGC(bool isCompartmentGC)
{
    for (unsigned i = 0; i < FinalizeCalls; ++i)
        CHECK(IsCompartmentGCBuffer[i] == isCompartmentGC);

    return true;
}

static void
FinalizeCallback(JSFreeOp* fop, JSFinalizeStatus status, bool isCompartmentGC, void* data)
{
    if (FinalizeCalls < BufferSize) {
        StatusBuffer[FinalizeCalls] = status;
        IsCompartmentGCBuffer[FinalizeCalls] = isCompartmentGC;
    }
    ++FinalizeCalls;
}
END_TEST(testGCFinalizeCallback)
