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

#include "gc/GCInternals.h"
#include "gc/Memory.h"
#include "jsapi-tests/tests.h"

#if defined(XP_WIN)
#include "jswin.h"
#include <psapi.h>
#elif defined(SOLARIS)
// This test doesn't apply to Solaris.
#elif defined(XP_UNIX)
#include <algorithm>
#include <errno.h>
#include <sys/mman.h>
#include <sys/resource.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#else
#error "Memory mapping functions are not defined for your OS."
#endif

BEGIN_TEST(testGCAllocator)
{
    size_t PageSize = 0;
#if defined(XP_WIN)
#  if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
    SYSTEM_INFO sysinfo;
    GetSystemInfo(&sysinfo);
    PageSize = sysinfo.dwPageSize;
#  else // Various APIs are unavailable. This test is disabled.
    return true;
#  endif
#elif defined(SOLARIS)
    return true;
#elif defined(XP_UNIX)
    PageSize = size_t(sysconf(_SC_PAGESIZE));
#else
    return true;
#endif

    /* Finish any ongoing background free activity. */
    js::gc::AutoFinishGC finishGC(rt);

    bool growUp;
    CHECK(addressesGrowUp(&growUp));

    if (growUp)
        return testGCAllocatorUp(PageSize);
    return testGCAllocatorDown(PageSize);
}

static const size_t Chunk = 512 * 1024;
static const size_t Alignment = 2 * Chunk;
static const int MaxTempChunks = 4096;
static const size_t StagingSize = 16 * Chunk;

bool
addressesGrowUp(bool* resultOut)
{
    /*
     * Try to detect whether the OS allocates memory in increasing or decreasing
     * address order by making several allocations and comparing the addresses.
     */

    static const unsigned ChunksToTest = 20;
    static const int ThresholdCount = 15;

    void* chunks[ChunksToTest];
    for (unsigned i = 0; i < ChunksToTest; i++) {
        chunks[i] = mapMemory(2 * Chunk);
        CHECK(chunks[i]);
    }

    int upCount = 0;
    int downCount = 0;

    for (unsigned i = 0; i < ChunksToTest - 1; i++) {
        if (chunks[i] < chunks[i + 1])
            upCount++;
        else
            downCount++;
    }

    for (unsigned i = 0; i < ChunksToTest; i++)
        unmapPages(chunks[i], 2 * Chunk);

    /* Check results were mostly consistent. */
    CHECK(abs(upCount - downCount) >= ThresholdCount);

    *resultOut = upCount > downCount;

    return true;
}

size_t
offsetFromAligned(void* p)
{
    return uintptr_t(p) % Alignment;
}

enum AllocType {
   UseNormalAllocator,
   UseLastDitchAllocator
};

bool
testGCAllocatorUp(const size_t PageSize)
{
    const size_t UnalignedSize = StagingSize + Alignment - PageSize;
    void* chunkPool[MaxTempChunks];
    // Allocate a contiguous chunk that we can partition for testing.
    void* stagingArea = mapMemory(UnalignedSize);
    if (!stagingArea)
        return false;
    // Ensure that the staging area is aligned.
    unmapPages(stagingArea, UnalignedSize);
    if (offsetFromAligned(stagingArea)) {
        const size_t Offset = offsetFromAligned(stagingArea);
        // Place the area at the lowest aligned address.
        stagingArea = (void*)(uintptr_t(stagingArea) + (Alignment - Offset));
    }
    mapMemoryAt(stagingArea, StagingSize);
    // Make sure there are no available chunks below the staging area.
    int tempChunks;
    if (!fillSpaceBeforeStagingArea(tempChunks, stagingArea, chunkPool, false))
        return false;
    // Unmap the staging area so we can set it up for testing.
    unmapPages(stagingArea, StagingSize);
    // Check that the first chunk is used if it is aligned.
    CHECK(positionIsCorrect("xxooxxx---------", stagingArea, chunkPool, tempChunks));
    // Check that the first chunk is used if it can be aligned.
    CHECK(positionIsCorrect("x-ooxxx---------", stagingArea, chunkPool, tempChunks));
    // Check that an aligned chunk after a single unalignable chunk is used.
    CHECK(positionIsCorrect("x--xooxxx-------", stagingArea, chunkPool, tempChunks));
    // Check that we fall back to the slow path after two unalignable chunks.
    CHECK(positionIsCorrect("x--xx--xoo--xxx-", stagingArea, chunkPool, tempChunks));
    // Check that we also fall back after an unalignable and an alignable chunk.
    CHECK(positionIsCorrect("x--xx---x-oo--x-", stagingArea, chunkPool, tempChunks));
    // Check that the last ditch allocator works as expected.
    CHECK(positionIsCorrect("x--xx--xx-oox---", stagingArea, chunkPool, tempChunks,
                            UseLastDitchAllocator));

    // Clean up.
    while (--tempChunks >= 0)
        unmapPages(chunkPool[tempChunks], 2 * Chunk);
    return true;
}

bool
testGCAllocatorDown(const size_t PageSize)
{
    const size_t UnalignedSize = StagingSize + Alignment - PageSize;
    void* chunkPool[MaxTempChunks];
    // Allocate a contiguous chunk that we can partition for testing.
    void* stagingArea = mapMemory(UnalignedSize);
    if (!stagingArea)
        return false;
    // Ensure that the staging area is aligned.
    unmapPages(stagingArea, UnalignedSize);
    if (offsetFromAligned(stagingArea)) {
        void* stagingEnd = (void*)(uintptr_t(stagingArea) + UnalignedSize);
        const size_t Offset = offsetFromAligned(stagingEnd);
        // Place the area at the highest aligned address.
        stagingArea = (void*)(uintptr_t(stagingEnd) - Offset - StagingSize);
    }
    mapMemoryAt(stagingArea, StagingSize);
    // Make sure there are no available chunks above the staging area.
    int tempChunks;
    if (!fillSpaceBeforeStagingArea(tempChunks, stagingArea, chunkPool, true))
        return false;
    // Unmap the staging area so we can set it up for testing.
    unmapPages(stagingArea, StagingSize);
    // Check that the first chunk is used if it is aligned.
    CHECK(positionIsCorrect("---------xxxooxx", stagingArea, chunkPool, tempChunks));
    // Check that the first chunk is used if it can be aligned.
    CHECK(positionIsCorrect("---------xxxoo-x", stagingArea, chunkPool, tempChunks));
    // Check that an aligned chunk after a single unalignable chunk is used.
    CHECK(positionIsCorrect("-------xxxoox--x", stagingArea, chunkPool, tempChunks));
    // Check that we fall back to the slow path after two unalignable chunks.
    CHECK(positionIsCorrect("-xxx--oox--xx--x", stagingArea, chunkPool, tempChunks));
    // Check that we also fall back after an unalignable and an alignable chunk.
    CHECK(positionIsCorrect("-x--oo-x---xx--x", stagingArea, chunkPool, tempChunks));
    // Check that the last ditch allocator works as expected.
    CHECK(positionIsCorrect("---xoo-xx--xx--x", stagingArea, chunkPool, tempChunks,
                            UseLastDitchAllocator));

    // Clean up.
    while (--tempChunks >= 0)
        unmapPages(chunkPool[tempChunks], 2 * Chunk);
    return true;
}

bool
fillSpaceBeforeStagingArea(int& tempChunks, void* stagingArea,
                           void** chunkPool, bool addressesGrowDown)
{
    // Make sure there are no available chunks before the staging area.
    tempChunks = 0;
    chunkPool[tempChunks++] = mapMemory(2 * Chunk);
    while (tempChunks < MaxTempChunks && chunkPool[tempChunks - 1] &&
           (chunkPool[tempChunks - 1] < stagingArea) ^ addressesGrowDown) {
        chunkPool[tempChunks++] = mapMemory(2 * Chunk);
        if (!chunkPool[tempChunks - 1])
            break; // We already have our staging area, so OOM here is okay.
        if ((chunkPool[tempChunks - 1] < chunkPool[tempChunks - 2]) ^ addressesGrowDown)
            break; // The address growth direction is inconsistent!
    }
    // OOM also means success in this case.
    if (!chunkPool[tempChunks - 1]) {
        --tempChunks;
        return true;
    }
    // Bail if we can't guarantee the right address space layout.
    if ((chunkPool[tempChunks - 1] < stagingArea) ^ addressesGrowDown || (tempChunks > 1 &&
            (chunkPool[tempChunks - 1] < chunkPool[tempChunks - 2]) ^ addressesGrowDown))
    {
        while (--tempChunks >= 0)
            unmapPages(chunkPool[tempChunks], 2 * Chunk);
        unmapPages(stagingArea, StagingSize);
        return false;
    }
    return true;
}

bool
positionIsCorrect(const char* str, void* base, void** chunkPool, int tempChunks,
                  AllocType allocator = UseNormalAllocator)
{
    // str represents a region of memory, with each character representing a
    // region of Chunk bytes. str should contain only x, o and -, where
    // x = mapped by the test to set up the initial conditions,
    // o = mapped by the GC allocator, and
    // - = unmapped.
    // base should point to a region of contiguous free memory
    // large enough to hold strlen(str) chunks of Chunk bytes.
    int len = strlen(str);
    int i;
    // Find the index of the desired address.
    for (i = 0; i < len && str[i] != 'o'; ++i);
    void* desired = (void*)(uintptr_t(base) + i * Chunk);
    // Map the regions indicated by str.
    for (i = 0; i < len; ++i) {
        if (str[i] == 'x')
            mapMemoryAt((void*)(uintptr_t(base) +  i * Chunk), Chunk);
    }
    // Allocate using the GC's allocator.
    void* result;
    if (allocator == UseNormalAllocator)
        result = js::gc::MapAlignedPages(2 * Chunk, Alignment);
    else
        result = js::gc::TestMapAlignedPagesLastDitch(2 * Chunk, Alignment);
    // Clean up the mapped regions.
    if (result)
        js::gc::UnmapPages(result, 2 * Chunk);
    for (--i; i >= 0; --i) {
        if (str[i] == 'x')
            js::gc::UnmapPages((void*)(uintptr_t(base) +  i * Chunk), Chunk);
    }
    // CHECK returns, so clean up on failure.
    if (result != desired) {
        while (--tempChunks >= 0)
            js::gc::UnmapPages(chunkPool[tempChunks], 2 * Chunk);
    }
    return result == desired;
}

#if defined(XP_WIN)
#  if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)

void*
mapMemoryAt(void* desired, size_t length)
{
    return VirtualAlloc(desired, length, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
}

void*
mapMemory(size_t length)
{
    return VirtualAlloc(nullptr, length, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
}

void
unmapPages(void* p, size_t size)
{
    MOZ_ALWAYS_TRUE(VirtualFree(p, 0, MEM_RELEASE));
}

#  else // Various APIs are unavailable. This test is disabled.

void* mapMemoryAt(void* desired, size_t length) { return nullptr; }
void* mapMemory(size_t length) { return nullptr; }
void unmapPages(void* p, size_t size) { }

#  endif
#elif defined(SOLARIS) // This test doesn't apply to Solaris.

void* mapMemoryAt(void* desired, size_t length) { return nullptr; }
void* mapMemory(size_t length) { return nullptr; }
void unmapPages(void* p, size_t size) { }

#elif defined(XP_UNIX)

void*
mapMemoryAt(void* desired, size_t length)
{
#if defined(__ia64__) || (defined(__sparc64__) && defined(__NetBSD__))
    MOZ_RELEASE_ASSERT(0xffff800000000000ULL & (uintptr_t(desired) + length - 1) == 0);
#endif
    void* region = mmap(desired, length, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
    if (region == MAP_FAILED)
        return nullptr;
    if (region != desired) {
        if (munmap(region, length))
            MOZ_RELEASE_ASSERT(errno == ENOMEM);
        return nullptr;
    }
    return region;
}

void*
mapMemory(size_t length)
{
    void* hint = nullptr;
#if defined(__ia64__) || (defined(__sparc64__) && defined(__NetBSD__))
    hint = (void*)0x0000070000000000ULL;
#endif
    void* region = mmap(hint, length, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
    if (region == MAP_FAILED)
        return nullptr;
#if defined(__ia64__) || (defined(__sparc64__) && defined(__NetBSD__))
    if ((uintptr_t(region) + (length - 1)) & 0xffff800000000000ULL) {
        if (munmap(region, length))
            MOZ_RELEASE_ASSERT(errno == ENOMEM);
        return nullptr;
    }
#endif
    return region;
}

void
unmapPages(void* p, size_t size)
{
    if (munmap(p, size))
        MOZ_RELEASE_ASSERT(errno == ENOMEM);
}

#else // !defined(XP_WIN) && !defined(SOLARIS) && !defined(XP_UNIX)
#error "Memory mapping functions are not defined for your OS."
#endif
END_TEST(testGCAllocator)
