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

#include "gc/GCInternals.h"
#include "gc/Zone.h"

#include "jsapi-tests/tests.h"

static void
MinimizeHeap(JSRuntime* rt)
{
    // The second collection is to force us to wait for the background
    // sweeping that the first GC started to finish.
    JS_GC(rt);
    JS_GC(rt);
    js::gc::AutoFinishGC finish(rt);
}

BEGIN_TEST(testGCUID)
{
  if (configuration::Configuration::GetInstance()->CobaltGcZeal()) {
    AutoLeaveZeal nozeal(cx);
  }

  uint64_t uid = 0;
  uint64_t tmp = 0;

  // Ensure the heap is as minimal as it can get.
  MinimizeHeap(rt);

  JS::RootedObject obj(cx, JS_NewPlainObject(cx));
  uintptr_t nurseryAddr = uintptr_t(obj.get());
  CHECK(obj);
  CHECK(js::gc::IsInsideNursery(obj));

  // Do not start with an ID.
  CHECK(!obj->zone()->hasUniqueId(obj));

  // Ensure we can get a new UID.
  CHECK(obj->zone()->getUniqueId(obj, &uid));
  CHECK(uid > js::gc::LargestTaggedNullCellPointer);

  // We should now have an id.
  CHECK(obj->zone()->hasUniqueId(obj));

  // Calling again should get us the same thing.
  CHECK(obj->zone()->getUniqueId(obj, &tmp));
  CHECK(uid == tmp);

  // Tenure the thing and check that the UID moved with it.
  MinimizeHeap(rt);
  uintptr_t tenuredAddr = uintptr_t(obj.get());
  CHECK(tenuredAddr != nurseryAddr);
  CHECK(!js::gc::IsInsideNursery(obj));
  CHECK(obj->zone()->hasUniqueId(obj));
  CHECK(obj->zone()->getUniqueId(obj, &tmp));
  CHECK(uid == tmp);

  // Allocate a new nursery thing in the same location and check that we
  // removed the prior uid that was attached to the location.
  obj = JS_NewPlainObject(cx);
  CHECK(obj);
  CHECK(uintptr_t(obj.get()) == nurseryAddr);
  CHECK(!obj->zone()->hasUniqueId(obj));

  // Try to get another tenured object in the same location and check that
  // the uid was removed correctly.
  obj = nullptr;
  MinimizeHeap(rt);
  obj = JS_NewPlainObject(cx);
  MinimizeHeap(rt);
  CHECK(uintptr_t(obj.get()) == tenuredAddr);
  CHECK(!obj->zone()->hasUniqueId(obj));
  CHECK(obj->zone()->getUniqueId(obj, &tmp));
  CHECK(uid != tmp);
  uid = tmp;

  // Allocate a few arenas worth of objects to ensure we get some compaction.
  const static size_t N = 2049;
  using ObjectVector = js::TraceableVector<JSObject*>;
  JS::Rooted<ObjectVector> vec(cx, ObjectVector(cx));
  for (size_t i = 0; i < N; ++i) {
    obj = JS_NewPlainObject(cx);
    CHECK(obj);
    CHECK(vec.append(obj));
    }

    // Transfer our vector to tenured if it isn't there already.
    MinimizeHeap(rt);

    // Tear holes in the heap by unrooting the even objects and collecting.
    JS::Rooted<ObjectVector> vec2(cx, ObjectVector(cx));
    for (size_t i = 0; i < N; ++i) {
        if (i % 2 == 1)
            vec2.append(vec[i]);
    }
    vec.clear();
    MinimizeHeap(rt);

    // Grab the last object in the vector as our object of interest.
    obj = vec2.back();
    CHECK(obj);
    tenuredAddr = uintptr_t(obj.get());
    CHECK(obj->zone()->getUniqueId(obj, &uid));

    // Force a compaction to move the object and check that the uid moved to
    // the new tenured heap location.
    JS::PrepareForFullGC(rt);
    JS::GCForReason(rt, GC_SHRINK, JS::gcreason::API);
    MinimizeHeap(rt);
    CHECK(uintptr_t(obj.get()) != tenuredAddr);
    CHECK(obj->zone()->hasUniqueId(obj));
    CHECK(obj->zone()->getUniqueId(obj, &tmp));
    CHECK(uid == tmp);

    return true;
}
END_TEST(testGCUID)
