// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
/* Copyright (c) 2006, Google Inc.
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 * 
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

// A low-level allocator that can be used by other low-level
// modules without introducing dependency cycles.
// This allocator is slow and wasteful of memory;
// it should not be used when performance is key.

#include "base/low_level_alloc.h"
#include "base/dynamic_annotations.h"
#include "base/spinlock.h"
#include "base/logging.h"
#include "malloc_hook-inl.h"
#include <gperftools/malloc_hook.h>
#include <errno.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_MMAP
#include <sys/mman.h>
#endif
#include <new>                   // for placement-new

// On systems (like freebsd) that don't define MAP_ANONYMOUS, use the old
// form of the name instead.
#ifndef MAP_ANONYMOUS
# define MAP_ANONYMOUS MAP_ANON
#endif

// A first-fit allocator with amortized logarithmic free() time.

LowLevelAlloc::PagesAllocator::~PagesAllocator() {
}

// ---------------------------------------------------------------------------
static const int kMaxLevel = 30;

// We put this class-only struct in a namespace to avoid polluting the
// global namespace with this struct name (thus risking an ODR violation).
namespace low_level_alloc_internal {
  // This struct describes one allocated block, or one free block.
  struct AllocList {
    struct Header {
      intptr_t size;  // size of entire region, including this field. Must be
                      // first.  Valid in both allocated and unallocated blocks
      intptr_t magic; // kMagicAllocated or kMagicUnallocated xor this
      LowLevelAlloc::Arena *arena; // pointer to parent arena
      void *dummy_for_alignment;   // aligns regions to 0 mod 2*sizeof(void*)
    } header;

    // Next two fields: in unallocated blocks: freelist skiplist data
    //                  in allocated blocks: overlaps with client data
    int levels;           // levels in skiplist used
    AllocList *next[kMaxLevel];   // actually has levels elements.
                                  // The AllocList node may not have room for
                                  // all kMaxLevel entries.  See max_fit in
                                  // LLA_SkiplistLevels()
  };
}
using low_level_alloc_internal::AllocList;


// ---------------------------------------------------------------------------
// A trivial skiplist implementation.  This is used to keep the freelist
// in address order while taking only logarithmic time per insert and delete.

// An integer approximation of log2(size/base)
// Requires size >= base.
static int IntLog2(size_t size, size_t base) {
  int result = 0;
  for (size_t i = size; i > base; i >>= 1) { // i == floor(size/2**result)
    result++;
  }
  //    floor(size / 2**result) <= base < floor(size / 2**(result-1))
  // =>     log2(size/(base+1)) <= result < 1+log2(size/base)
  // => result ~= log2(size/base)
  return result;
}

// Return a random integer n:  p(n)=1/(2**n) if 1 <= n; p(n)=0 if n < 1.
static int Random() {
  static uint32 r = 1;         // no locking---it's not critical
  ANNOTATE_BENIGN_RACE(&r, "benign race, not critical.");
  int result = 1;
  while ((((r = r*1103515245 + 12345) >> 30) & 1) == 0) {
    result++;
  }
  return result;
}

// Return a number of skiplist levels for a node of size bytes, where
// base is the minimum node size.  Compute level=log2(size / base)+n
// where n is 1 if random is false and otherwise a random number generated with
// the standard distribution for a skiplist:  See Random() above.
// Bigger nodes tend to have more skiplist levels due to the log2(size / base)
// term, so first-fit searches touch fewer nodes.  "level" is clipped so
// level<kMaxLevel and next[level-1] will fit in the node.
// 0 < LLA_SkiplistLevels(x,y,false) <= LLA_SkiplistLevels(x,y,true) < kMaxLevel
static int LLA_SkiplistLevels(size_t size, size_t base, bool random) {
  // max_fit is the maximum number of levels that will fit in a node for the
  // given size.   We can't return more than max_fit, no matter what the
  // random number generator says.
  int max_fit = (size-OFFSETOF_MEMBER(AllocList, next)) / sizeof (AllocList *);
  int level = IntLog2(size, base) + (random? Random() : 1);
  if (level > max_fit)     level = max_fit;
  if (level > kMaxLevel-1) level = kMaxLevel - 1;
  RAW_CHECK(level >= 1, "block not big enough for even one level");
  return level;
}

// Return "atleast", the first element of AllocList *head s.t. *atleast >= *e.
// For 0 <= i < head->levels, set prev[i] to "no_greater", where no_greater
// points to the last element at level i in the AllocList less than *e, or is
// head if no such element exists.
static AllocList *LLA_SkiplistSearch(AllocList *head,
                                     AllocList *e, AllocList **prev) {
  AllocList *p = head;
  for (int level = head->levels - 1; level >= 0; level--) {
    for (AllocList *n; (n = p->next[level]) != 0 && n < e; p = n) {
    }
    prev[level] = p;
  }
  return (head->levels == 0) ?  0 : prev[0]->next[0];
}

// Insert element *e into AllocList *head.  Set prev[] as LLA_SkiplistSearch.
// Requires that e->levels be previously set by the caller (using
// LLA_SkiplistLevels())
static void LLA_SkiplistInsert(AllocList *head, AllocList *e,
                               AllocList **prev) {
  LLA_SkiplistSearch(head, e, prev);
  for (; head->levels < e->levels; head->levels++) { // extend prev pointers
    prev[head->levels] = head;                       // to all *e's levels
  }
  for (int i = 0; i != e->levels; i++) { // add element to list
    e->next[i] = prev[i]->next[i];
    prev[i]->next[i] = e;
  }
}

// Remove element *e from AllocList *head.  Set prev[] as LLA_SkiplistSearch().
// Requires that e->levels be previous set by the caller (using
// LLA_SkiplistLevels())
static void LLA_SkiplistDelete(AllocList *head, AllocList *e,
                               AllocList **prev) {
  AllocList *found = LLA_SkiplistSearch(head, e, prev);
  RAW_CHECK(e == found, "element not in freelist");
  for (int i = 0; i != e->levels && prev[i]->next[i] == e; i++) {
    prev[i]->next[i] = e->next[i];
  }
  while (head->levels > 0 && head->next[head->levels - 1] == 0) {
    head->levels--;   // reduce head->levels if level unused
  }
}

// ---------------------------------------------------------------------------
// Arena implementation

struct LowLevelAlloc::Arena {
  Arena() : mu(SpinLock::LINKER_INITIALIZED) {} // does nothing; for static init
  explicit Arena(int) : pagesize(0) {}  // set pagesize to zero explicitly
                                        // for non-static init

  SpinLock mu;            // protects freelist, allocation_count,
                          // pagesize, roundup, min_size
  AllocList freelist;     // head of free list; sorted by addr (under mu)
  int32 allocation_count; // count of allocated blocks (under mu)
  int32 flags;            // flags passed to NewArena (ro after init)
  size_t pagesize;        // ==getpagesize()  (init under mu, then ro)
  size_t roundup;         // lowest power of 2 >= max(16,sizeof (AllocList))
                          // (init under mu, then ro)
  size_t min_size;        // smallest allocation block size
                          // (init under mu, then ro)
  PagesAllocator *allocator;
};

// The default arena, which is used when 0 is passed instead of an Arena
// pointer.
static struct LowLevelAlloc::Arena default_arena;

// Non-malloc-hooked arenas: used only to allocate metadata for arenas that
// do not want malloc hook reporting, so that for them there's no malloc hook
// reporting even during arena creation.
static struct LowLevelAlloc::Arena unhooked_arena;
static struct LowLevelAlloc::Arena unhooked_async_sig_safe_arena;

namespace {

  class DefaultPagesAllocator : public LowLevelAlloc::PagesAllocator {
  public:
    virtual ~DefaultPagesAllocator() {};
    virtual void *MapPages(int32 flags, size_t size);
    virtual void UnMapPages(int32 flags, void *addr, size_t size);
  };

}

// magic numbers to identify allocated and unallocated blocks
static const intptr_t kMagicAllocated = 0x4c833e95;
static const intptr_t kMagicUnallocated = ~kMagicAllocated;

namespace {
  class SCOPED_LOCKABLE ArenaLock {
   public:
    explicit ArenaLock(LowLevelAlloc::Arena *arena)
        EXCLUSIVE_LOCK_FUNCTION(arena->mu)
        : left_(false), mask_valid_(false), arena_(arena) {
      if ((arena->flags & LowLevelAlloc::kAsyncSignalSafe) != 0) {
      // We've decided not to support async-signal-safe arena use until
      // there a demonstrated need.  Here's how one could do it though
      // (would need to be made more portable).
#if 0
        sigset_t all;
        sigfillset(&all);
        this->mask_valid_ =
            (pthread_sigmask(SIG_BLOCK, &all, &this->mask_) == 0);
#else
        RAW_CHECK(false, "We do not yet support async-signal-safe arena.");
#endif
      }
      this->arena_->mu.Lock();
    }
    ~ArenaLock() { RAW_CHECK(this->left_, "haven't left Arena region"); }
    void Leave() UNLOCK_FUNCTION() {
      this->arena_->mu.Unlock();
#if 0
      if (this->mask_valid_) {
        pthread_sigmask(SIG_SETMASK, &this->mask_, 0);
      }
#endif
      this->left_ = true;
    }
   private:
    bool left_;       // whether left region
    bool mask_valid_;
#if 0
    sigset_t mask_;   // old mask of blocked signals
#endif
    LowLevelAlloc::Arena *arena_;
    DISALLOW_COPY_AND_ASSIGN(ArenaLock);
  };
} // anonymous namespace

// create an appropriate magic number for an object at "ptr"
// "magic" should be kMagicAllocated or kMagicUnallocated
inline static intptr_t Magic(intptr_t magic, AllocList::Header *ptr) {
  return magic ^ reinterpret_cast<intptr_t>(ptr);
}

// Initialize the fields of an Arena
static void ArenaInit(LowLevelAlloc::Arena *arena) {
  if (arena->pagesize == 0) {
    arena->pagesize = getpagesize();
    // Round up block sizes to a power of two close to the header size.
    arena->roundup = 16;
    while (arena->roundup < sizeof (arena->freelist.header)) {
      arena->roundup += arena->roundup;
    }
    // Don't allocate blocks less than twice the roundup size to avoid tiny
    // free blocks.
    arena->min_size = 2 * arena->roundup;
    arena->freelist.header.size = 0;
    arena->freelist.header.magic =
        Magic(kMagicUnallocated, &arena->freelist.header);
    arena->freelist.header.arena = arena;
    arena->freelist.levels = 0;
    memset(arena->freelist.next, 0, sizeof (arena->freelist.next));
    arena->allocation_count = 0;
    if (arena == &default_arena) {
      // Default arena should be hooked, e.g. for heap-checker to trace
      // pointer chains through objects in the default arena.
      arena->flags = LowLevelAlloc::kCallMallocHook;
    } else if (arena == &unhooked_async_sig_safe_arena) {
      arena->flags = LowLevelAlloc::kAsyncSignalSafe;
    } else {
      arena->flags = 0;   // other arenas' flags may be overridden by client,
                          // but unhooked_arena will have 0 in 'flags'.
    }
    arena->allocator = LowLevelAlloc::GetDefaultPagesAllocator();
  }
}

// L < meta_data_arena->mu
LowLevelAlloc::Arena *LowLevelAlloc::NewArena(int32 flags,
                                              Arena *meta_data_arena) {
  return NewArenaWithCustomAlloc(flags, meta_data_arena, NULL);
}

// L < meta_data_arena->mu
LowLevelAlloc::Arena *LowLevelAlloc::NewArenaWithCustomAlloc(int32 flags,
                                                             Arena *meta_data_arena,
                                                             PagesAllocator *allocator) {
  RAW_CHECK(meta_data_arena != 0, "must pass a valid arena");
  if (meta_data_arena == &default_arena) {
    if ((flags & LowLevelAlloc::kAsyncSignalSafe) != 0) {
      meta_data_arena = &unhooked_async_sig_safe_arena;
    } else if ((flags & LowLevelAlloc::kCallMallocHook) == 0) {
      meta_data_arena = &unhooked_arena;
    }
  }
  // Arena(0) uses the constructor for non-static contexts
  Arena *result =
    new (AllocWithArena(sizeof (*result), meta_data_arena)) Arena(0);
  ArenaInit(result);
  result->flags = flags;
  if (allocator) {
    result->allocator = allocator;
  }
  return result;
}

// L < arena->mu, L < arena->arena->mu
bool LowLevelAlloc::DeleteArena(Arena *arena) {
  RAW_CHECK(arena != 0 && arena != &default_arena && arena != &unhooked_arena,
            "may not delete default arena");
  ArenaLock section(arena);
  bool empty = (arena->allocation_count == 0);
  section.Leave();
  if (empty) {
    while (arena->freelist.next[0] != 0) {
      AllocList *region = arena->freelist.next[0];
      size_t size = region->header.size;
      arena->freelist.next[0] = region->next[0];
      RAW_CHECK(region->header.magic ==
                Magic(kMagicUnallocated, &region->header),
                "bad magic number in DeleteArena()");
      RAW_CHECK(region->header.arena == arena,
                "bad arena pointer in DeleteArena()");
      RAW_CHECK(size % arena->pagesize == 0,
                "empty arena has non-page-aligned block size");
      RAW_CHECK(reinterpret_cast<intptr_t>(region) % arena->pagesize == 0,
                "empty arena has non-page-aligned block");
      int munmap_result;
      if ((arena->flags & LowLevelAlloc::kAsyncSignalSafe) == 0) {
        munmap_result = munmap(region, size);
      } else {
        munmap_result = MallocHook::UnhookedMUnmap(region, size);
      }
      RAW_CHECK(munmap_result == 0,
                "LowLevelAlloc::DeleteArena:  munmap failed address");
    }
    Free(arena);
  }
  return empty;
}

// ---------------------------------------------------------------------------

// Return value rounded up to next multiple of align.
// align must be a power of two.
static intptr_t RoundUp(intptr_t addr, intptr_t align) {
  return (addr + align - 1) & ~(align - 1);
}

// Equivalent to "return prev->next[i]" but with sanity checking
// that the freelist is in the correct order, that it
// consists of regions marked "unallocated", and that no two regions
// are adjacent in memory (they should have been coalesced).
// L < arena->mu
static AllocList *Next(int i, AllocList *prev, LowLevelAlloc::Arena *arena) {
  RAW_CHECK(i < prev->levels, "too few levels in Next()");
  AllocList *next = prev->next[i];
  if (next != 0) {
    RAW_CHECK(next->header.magic == Magic(kMagicUnallocated, &next->header),
              "bad magic number in Next()");
    RAW_CHECK(next->header.arena == arena,
              "bad arena pointer in Next()");
    if (prev != &arena->freelist) {
      RAW_CHECK(prev < next, "unordered freelist");
      RAW_CHECK(reinterpret_cast<char *>(prev) + prev->header.size <
                reinterpret_cast<char *>(next), "malformed freelist");
    }
  }
  return next;
}

// Coalesce list item "a" with its successor if they are adjacent.
static void Coalesce(AllocList *a) {
  AllocList *n = a->next[0];
  if (n != 0 && reinterpret_cast<char *>(a) + a->header.size ==
                    reinterpret_cast<char *>(n)) {
    LowLevelAlloc::Arena *arena = a->header.arena;
    a->header.size += n->header.size;
    n->header.magic = 0;
    n->header.arena = 0;
    AllocList *prev[kMaxLevel];
    LLA_SkiplistDelete(&arena->freelist, n, prev);
    LLA_SkiplistDelete(&arena->freelist, a, prev);
    a->levels = LLA_SkiplistLevels(a->header.size, arena->min_size, true);
    LLA_SkiplistInsert(&arena->freelist, a, prev);
  }
}

// Adds block at location "v" to the free list
// L >= arena->mu
static void AddToFreelist(void *v, LowLevelAlloc::Arena *arena) {
  AllocList *f = reinterpret_cast<AllocList *>(
                        reinterpret_cast<char *>(v) - sizeof (f->header));
  RAW_CHECK(f->header.magic == Magic(kMagicAllocated, &f->header),
            "bad magic number in AddToFreelist()");
  RAW_CHECK(f->header.arena == arena,
            "bad arena pointer in AddToFreelist()");
  f->levels = LLA_SkiplistLevels(f->header.size, arena->min_size, true);
  AllocList *prev[kMaxLevel];
  LLA_SkiplistInsert(&arena->freelist, f, prev);
  f->header.magic = Magic(kMagicUnallocated, &f->header);
  Coalesce(f);                  // maybe coalesce with successor
  Coalesce(prev[0]);            // maybe coalesce with predecessor
}

// Frees storage allocated by LowLevelAlloc::Alloc().
// L < arena->mu
void LowLevelAlloc::Free(void *v) {
  if (v != 0) {
    AllocList *f = reinterpret_cast<AllocList *>(
                        reinterpret_cast<char *>(v) - sizeof (f->header));
    RAW_CHECK(f->header.magic == Magic(kMagicAllocated, &f->header),
              "bad magic number in Free()");
    LowLevelAlloc::Arena *arena = f->header.arena;
    if ((arena->flags & kCallMallocHook) != 0) {
      MallocHook::InvokeDeleteHook(v);
    }
    ArenaLock section(arena);
    AddToFreelist(v, arena);
    RAW_CHECK(arena->allocation_count > 0, "nothing in arena to free");
    arena->allocation_count--;
    section.Leave();
  }
}

// allocates and returns a block of size bytes, to be freed with Free()
// L < arena->mu
static void *DoAllocWithArena(size_t request, LowLevelAlloc::Arena *arena) {
  void *result = 0;
  if (request != 0) {
    AllocList *s;       // will point to region that satisfies request
    ArenaLock section(arena);
    ArenaInit(arena);
    // round up with header
    size_t req_rnd = RoundUp(request + sizeof (s->header), arena->roundup);
    for (;;) {      // loop until we find a suitable region
      // find the minimum levels that a block of this size must have
      int i = LLA_SkiplistLevels(req_rnd, arena->min_size, false) - 1;
      if (i < arena->freelist.levels) {   // potential blocks exist
        AllocList *before = &arena->freelist;  // predecessor of s
        while ((s = Next(i, before, arena)) != 0 && s->header.size < req_rnd) {
          before = s;
        }
        if (s != 0) {       // we found a region
          break;
        }
      }
      // we unlock before mmap() both because mmap() may call a callback hook,
      // and because it may be slow.
      arena->mu.Unlock();
      // mmap generous 64K chunks to decrease
      // the chances/impact of fragmentation:
      size_t new_pages_size = RoundUp(req_rnd, arena->pagesize * 16);
      void *new_pages = arena->allocator->MapPages(arena->flags, new_pages_size);
      arena->mu.Lock();
      s = reinterpret_cast<AllocList *>(new_pages);
      s->header.size = new_pages_size;
      // Pretend the block is allocated; call AddToFreelist() to free it.
      s->header.magic = Magic(kMagicAllocated, &s->header);
      s->header.arena = arena;
      AddToFreelist(&s->levels, arena);  // insert new region into free list
    }
    AllocList *prev[kMaxLevel];
    LLA_SkiplistDelete(&arena->freelist, s, prev);    // remove from free list
    // s points to the first free region that's big enough
    if (req_rnd + arena->min_size <= s->header.size) {  // big enough to split
      AllocList *n = reinterpret_cast<AllocList *>
                        (req_rnd + reinterpret_cast<char *>(s));
      n->header.size = s->header.size - req_rnd;
      n->header.magic = Magic(kMagicAllocated, &n->header);
      n->header.arena = arena;
      s->header.size = req_rnd;
      AddToFreelist(&n->levels, arena);
    }
    s->header.magic = Magic(kMagicAllocated, &s->header);
    RAW_CHECK(s->header.arena == arena, "");
    arena->allocation_count++;
    section.Leave();
    result = &s->levels;
  }
  ANNOTATE_NEW_MEMORY(result, request);
  return result;
}

void *LowLevelAlloc::Alloc(size_t request) {
  void *result = DoAllocWithArena(request, &default_arena);
  if ((default_arena.flags & kCallMallocHook) != 0) {
    // this call must be directly in the user-called allocator function
    // for MallocHook::GetCallerStackTrace to work properly
    MallocHook::InvokeNewHook(result, request);
  }
  return result;
}

void *LowLevelAlloc::AllocWithArena(size_t request, Arena *arena) {
  RAW_CHECK(arena != 0, "must pass a valid arena");
  void *result = DoAllocWithArena(request, arena);
  if ((arena->flags & kCallMallocHook) != 0) {
    // this call must be directly in the user-called allocator function
    // for MallocHook::GetCallerStackTrace to work properly
    MallocHook::InvokeNewHook(result, request);
  }
  return result;
}

LowLevelAlloc::Arena *LowLevelAlloc::DefaultArena() {
  return &default_arena;
}

static DefaultPagesAllocator *default_pages_allocator;
static union {
  char chars[sizeof(DefaultPagesAllocator)];
  void *ptr;
} debug_pages_allocator_space;

LowLevelAlloc::PagesAllocator *LowLevelAlloc::GetDefaultPagesAllocator(void) {
  if (default_pages_allocator) {
    return default_pages_allocator;
  }
  default_pages_allocator = new (debug_pages_allocator_space.chars) DefaultPagesAllocator();
  return default_pages_allocator;
}

void *DefaultPagesAllocator::MapPages(int32 flags, size_t size) {
  void *new_pages;
  if ((flags & LowLevelAlloc::kAsyncSignalSafe) != 0) {
    new_pages = MallocHook::UnhookedMMap(0, size,
                                         PROT_WRITE|PROT_READ,
                                         MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
  } else {
    new_pages = mmap(0, size,
                     PROT_WRITE|PROT_READ,
                     MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
  }
  RAW_CHECK(new_pages != MAP_FAILED, "mmap error");

  return new_pages;
}

void DefaultPagesAllocator::UnMapPages(int32 flags, void *region, size_t size) {
  int munmap_result;
  if ((flags & LowLevelAlloc::kAsyncSignalSafe) == 0) {
    munmap_result = munmap(region, size);
  } else {
    munmap_result = MallocHook::UnhookedMUnmap(region, size);
  }
  RAW_CHECK(munmap_result == 0,
            "LowLevelAlloc::DeleteArena: munmap failed address");
}
