
/*
 * Copyright 2006 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */


#include "SkTypes.h"
#include <stdio.h>
#include <stdlib.h>

#ifdef SK_DEBUG
    #define SK_TAG_BLOCKS
    // #define SK_TRACK_ALLOC  // enable to see a printf for every alloc/free
    // #define SK_CHECK_TAGS   // enable to double-check debugging link list
#endif

#ifdef SK_TAG_BLOCKS

#include "SkThread.h"

// size this (as a multiple of 4) so that the total offset to the internal data
// is at least a multiple of 8 (since some clients of our malloc may require
// that.
static const char kBlockHeaderTag[] = { 's', 'k', 'i', 'a', '1', '2', '3', '4' };
static const char kBlockTrailerTag[] = { 'a', 'i', 'k', 's' };
#define kByteFill 0xCD
#define kDeleteFill 0xEF

static SkBaseMutex& get_block_mutex() {
    static SkMutex* gBlockMutex;
    if (NULL == gBlockMutex) {
        gBlockMutex = new SkMutex;
    }
    return *gBlockMutex;
}

static struct SkBlockHeader* gHeader;

struct SkBlockHeader {
    SkBlockHeader* fNext;
#ifdef SK_CHECK_TAGS
    SkBlockHeader** fTop; // set to verify in debugger that block was alloc'd / freed with same gHeader
    SkBlockHeader* fPrevious; // set to see in debugger previous block when corruption happens
#endif
    size_t fSize;
    char fHeader[sizeof(kBlockHeaderTag)];
    // data goes here. The offset to this point must be a multiple of 8
    char fTrailer[sizeof(kBlockTrailerTag)];

    void* add(size_t realSize)
    {
        SkAutoMutexAcquire  ac(get_block_mutex());
        InMutexValidate();
        fNext = gHeader;
#ifdef SK_CHECK_TAGS
        fTop = &gHeader;
        fPrevious = NULL;
        if (fNext != NULL)
            fNext->fPrevious = this;
#endif
        gHeader = this;
        fSize = realSize;
        memcpy(fHeader, kBlockHeaderTag, sizeof(kBlockHeaderTag));
        void* result = fTrailer;
        void* trailer = (char*)result + realSize;
        memcpy(trailer, kBlockTrailerTag, sizeof(kBlockTrailerTag));
        return result;
    }

    static void Dump()
    {
        SkAutoMutexAcquire  ac(get_block_mutex());
        InMutexValidate();
        SkBlockHeader* header = gHeader;
        int count = 0;
        size_t size = 0;
        while (header != NULL) {
            char scratch[256];
            char* pos = scratch;
            size_t size = header->fSize;
            int* data = (int*)(void*)header->fTrailer;
            pos += sprintf(pos, "%p 0x%08zx (%7zd)  ",
                data, size, size);
            size >>= 2;
            size_t ints = size > 4 ? 4 : size;
            size_t index;
            for (index = 0; index < ints; index++)
                pos += sprintf(pos, "0x%08x ", data[index]);
            pos += sprintf(pos, " (");
            for (index = 0; index < ints; index++)
                pos += sprintf(pos, "%g ", data[index] / 65536.0f);
            if (ints > 0)
                --pos;
            pos += sprintf(pos, ") \"");
            size_t chars = size > 16 ? 16 : size;
            char* chPtr = (char*) data;
            for (index = 0; index < chars; index++) {
                char ch = chPtr[index];
                pos += sprintf(pos, "%c", ch >= ' ' && ch < 0x7f ? ch : '?');
            }
            pos += sprintf(pos, "\"");
            SkDebugf("%s\n", scratch);
            count++;
            size += header->fSize;
            header = header->fNext;
        }
        SkDebugf("--- count %d  size 0x%08x (%zd) ---\n", count, size, size);
    }

    void remove() const
    {
        SkAutoMutexAcquire  ac(get_block_mutex());
        SkBlockHeader** findPtr = &gHeader;
        do {
            SkBlockHeader* find = *findPtr;
            SkASSERT(find != NULL);
            if (find == this) {
                *findPtr = fNext;
                break;
            }
            findPtr = &find->fNext;
        } while (true);
        InMutexValidate();
        SkASSERT(memcmp(fHeader, kBlockHeaderTag, sizeof(kBlockHeaderTag)) == 0);
        const char* trailer = fTrailer + fSize;
        SkASSERT(memcmp(trailer, kBlockTrailerTag, sizeof(kBlockTrailerTag)) == 0);
    }

    static void Validate()
    {
        SkAutoMutexAcquire  ac(get_block_mutex());
        InMutexValidate();
    }

private:
    static void InMutexValidate()
    {
        SkBlockHeader* header = gHeader;
        while (header != NULL) {
            SkASSERT(memcmp(header->fHeader, kBlockHeaderTag, sizeof(kBlockHeaderTag)) == 0);
            char* trailer = header->fTrailer + header->fSize;
            SkASSERT(memcmp(trailer, kBlockTrailerTag, sizeof(kBlockTrailerTag)) == 0);
            header = header->fNext;
        }
    }
};

void ValidateHeap();
void ValidateHeap()
{
    SkBlockHeader::Validate();
}
#else
void ValidateHeap() {}
#endif

void sk_throw()
{
    SkDEBUGFAIL("sk_throw");
    abort();
}

void sk_out_of_memory(void)
{
    SkDEBUGFAIL("sk_out_of_memory");
    abort();
}

void* sk_malloc_throw(size_t size)
{
    return sk_malloc_flags(size, SK_MALLOC_THROW);
}

void* sk_realloc_throw(void* addr, size_t size)
{
#ifdef SK_TAG_BLOCKS
    ValidateHeap();
    if (addr != NULL) {
        SkBlockHeader* header = (SkBlockHeader*)
            ((char*)addr - SK_OFFSETOF(SkBlockHeader, fTrailer));
        header->remove();
#ifdef SK_TRACK_ALLOC
        printf("sk_realloc_throw %p oldSize=%zd\n", addr, header->fSize);
#endif
        addr = header;
    }
    size_t realSize = size;
    if (size)
        size += sizeof(SkBlockHeader);
#endif

    void* p = realloc(addr, size);
    if (size == 0)
    {
        ValidateHeap();
        return p;
    }

    if (p == NULL)
        sk_throw();
#ifdef SK_TAG_BLOCKS
    else
    {
        SkBlockHeader* header = (SkBlockHeader*) p;
        p = header->add(realSize);
#ifdef SK_TRACK_ALLOC
        printf("sk_realloc_throw %p size=%zd\n", p, realSize);
#endif
    }
#endif
    ValidateHeap();
    return p;
}

void sk_free(void* p)
{
    if (p)
    {
        ValidateHeap();
#ifdef SK_TAG_BLOCKS
        SkBlockHeader* header = (SkBlockHeader*)
            ((char*)p - SK_OFFSETOF(SkBlockHeader, fTrailer));
        header->remove();
#ifdef SK_TRACK_ALLOC
        printf("sk_free %p size=%zd\n", p, header->fSize);
#endif
        size_t size = header->fSize + sizeof(SkBlockHeader);
        memset(header, kDeleteFill, size);
        p = header;
#endif
        ValidateHeap();
        free(p);
        ValidateHeap();
    }
}

void* sk_malloc_flags(size_t size, unsigned flags)
{
    ValidateHeap();
#ifdef SK_TAG_BLOCKS
    size_t realSize = size;
    size += sizeof(SkBlockHeader);
#endif

    void* p = malloc(size);
    if (p == NULL)
    {
        if (flags & SK_MALLOC_THROW)
            sk_throw();
    }
#ifdef SK_TAG_BLOCKS
    else
    {
        SkBlockHeader* header = (SkBlockHeader*) p;
        p = header->add(realSize);
        memset(p, kByteFill, realSize);
#ifdef SK_TRACK_ALLOC
        printf("sk_malloc_flags %p size=%zd\n", p, realSize);
#endif
    }
#endif
    ValidateHeap();
    return p;
}
