// Copyright 2015 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Module Overview: Starboard Memory module
//
// Defines functions for memory allocation, alignment, copying, and comparing.
//
// # Porters
//
// All of the "Unchecked" and "Free" functions must be implemented, but they
// should not be called directly. The Starboard platform wraps them with extra
// accounting under certain circumstances.
//
// # Porters and Application Developers
//
// Nobody should call the "Checked", "Unchecked" or "Free" functions directly
// because that evades Starboard's memory tracking. In both port
// implementations and Starboard client application code, you should always
// call SbMemoryAllocate and SbMemoryDeallocate rather than
// SbMemoryAllocateUnchecked and SbMemoryFree.
//
// - The "checked" functions are SbMemoryAllocateChecked(),
//   SbMemoryReallocateChecked(), and SbMemoryAllocateAlignedChecked().
// - The "unchecked" functions are SbMemoryAllocateUnchecked(),
//   SbMemoryReallocateUnchecked(), and SbMemoryAllocateAlignedUnchecked().
// - The "free" functions are SbMemoryFree() and SbMemoryFreeAligned().

#ifndef STARBOARD_MEMORY_H_
#define STARBOARD_MEMORY_H_

#include "starboard/configuration.h"
#include "starboard/export.h"
#include "starboard/system.h"
#include "starboard/types.h"

#ifdef __cplusplus
extern "C" {
#endif

#define SB_MEMORY_MAP_FAILED ((void*)-1)  // NOLINT(readability/casting)

// The bitwise OR of these flags should be passed to SbMemoryMap to indicate
// how the mapped memory can be used.
typedef enum SbMemoryMapFlags {
// No flags set: Reserves virtual address space. SbMemoryProtect() can later
// make it accessible.
#if SB_API_VERSION >= 10
  kSbMemoryMapProtectReserved = 0,
#endif
  kSbMemoryMapProtectRead = 1 << 0,   // Mapped memory can be read.
  kSbMemoryMapProtectWrite = 1 << 1,  // Mapped memory can be written to.
#if SB_CAN(MAP_EXECUTABLE_MEMORY)
  kSbMemoryMapProtectExec = 1 << 2,  // Mapped memory can be executed.
#endif
  kSbMemoryMapProtectReadWrite =
      kSbMemoryMapProtectRead | kSbMemoryMapProtectWrite,
} SbMemoryMapFlags;

// Checks whether |memory| is aligned to |alignment| bytes.
static SB_C_FORCE_INLINE bool SbMemoryIsAligned(const void* memory,
                                                size_t alignment) {
  return ((uintptr_t)memory) % alignment == 0;
}

// Rounds |size| up to SB_MEMORY_PAGE_SIZE.
static SB_C_FORCE_INLINE size_t SbMemoryAlignToPageSize(size_t size) {
  return (size + SB_MEMORY_PAGE_SIZE - 1) & ~(SB_MEMORY_PAGE_SIZE - 1);
}

static SB_C_FORCE_INLINE void SbAbortIfAllocationFailed(size_t requested_bytes,
                                                        void* address) {
  if (SB_UNLIKELY(requested_bytes > 0 && address == NULL)) {
    // Will abort the program if no debugger is attached.
    SbSystemBreakIntoDebugger();
  }
}

// Allocates and returns a chunk of memory of at least |size| bytes. This
// function should be called from the client codebase. It is intended to be a
// drop-in replacement for |malloc|.
//
// Note that this function returns |NULL| if it is unable to allocate the
// memory.
//
// |size|: The amount of memory to be allocated. If |size| is 0, the function
//   may return |NULL| or it may return a unique pointer value that can be
//   passed to SbMemoryDeallocate.
SB_EXPORT void* SbMemoryAllocate(size_t size);

// Same as SbMemoryAllocate() but will not report memory to the tracker. Avoid
// using this unless absolutely necessary.
SB_EXPORT void* SbMemoryAllocateNoReport(size_t size);

// Attempts to resize |memory| to be at least |size| bytes, without touching
// the contents of memory.
// - If the function cannot perform the fast resize, it allocates a new chunk
//   of memory, copies the contents over, and frees the previous chunk,
//   returning a pointer to the new chunk.
// - If the function cannot perform the slow resize, it returns |NULL|,
//   leaving the given memory chunk unchanged.
//
// This function should be called from the client codebase. It is meant to be a
// drop-in replacement for |realloc|.
//
// |memory|: The chunk of memory to be resized. |memory| may be NULL, in which
//   case it behaves exactly like SbMemoryAllocateUnchecked.
// |size|: The size to which |memory| will be resized. If |size| is |0|,
//   the function may return |NULL| or it may return a unique pointer value
//   that can be passed to SbMemoryDeallocate.
SB_EXPORT void* SbMemoryReallocate(void* memory, size_t size);

// Allocates and returns a chunk of memory of at least |size| bytes, aligned to
// |alignment|. This function should be called from the client codebase. It is
// meant to be a drop-in replacement for |memalign|.
//
// The function returns |NULL| if it cannot allocate the memory. In addition,
// the function's behavior is undefined if |alignment| is not a power of two.
//
// |alignment|: The way that data is arranged and accessed in memory. The value
//   must be a power of two.
// |size|: The size of the memory to be allocated. If |size| is |0|, the
//   function may return |NULL| or it may return a unique aligned pointer value
//   that can be passed to SbMemoryDeallocateAligned.
SB_EXPORT void* SbMemoryAllocateAligned(size_t alignment, size_t size);

// Frees a previously allocated chunk of memory. If |memory| is NULL, then the
// operation is a no-op. This function should be called from the client
// codebase. It is meant to be a drop-in replacement for |free|.
//
// |memory|: The chunk of memory to be freed.
SB_EXPORT void SbMemoryDeallocate(void* memory);

// Same as SbMemoryDeallocate() but will not report memory deallocation to the
// tracker. This function must be matched with SbMemoryAllocateNoReport().
SB_EXPORT void SbMemoryDeallocateNoReport(void* memory);

// Frees a previously allocated chunk of aligned memory. This function should
// be called from the client codebase. It is meant to be a drop-in replacement
// for |_aligned_free|.

// |memory|: The chunk of memory to be freed. If |memory| is NULL, then the
//   function is a no-op.
SB_EXPORT void SbMemoryDeallocateAligned(void* memory);

/////////////////////////////////////////////////////////////////
// The following functions must be provided by Starboard ports.
/////////////////////////////////////////////////////////////////

// This is the implementation of SbMemoryAllocate that must be
// provided by Starboard ports.
//
// DO NOT CALL. Call SbMemoryAllocate(...) instead.
SB_DEPRECATED_EXTERNAL(
    SB_EXPORT void* SbMemoryAllocateUnchecked(size_t size));

// This is the implementation of SbMemoryReallocate that must be
// provided by Starboard ports.
//
// DO NOT CALL. Call SbMemoryReallocate(...) instead.
SB_DEPRECATED_EXTERNAL(
    SB_EXPORT void* SbMemoryReallocateUnchecked(void* memory, size_t size));

// This is the implementation of SbMemoryAllocateAligned that must be
// provided by Starboard ports.
//
// DO NOT CALL. Call SbMemoryAllocateAligned(...) instead.
SB_DEPRECATED_EXTERNAL(
    SB_EXPORT void* SbMemoryAllocateAlignedUnchecked(size_t alignment,
                                                     size_t size));

// This is the implementation of SbMemoryDeallocate that must be provided by
// Starboard ports.
//
// DO NOT CALL. Call SbMemoryDeallocate(...) instead.
SB_DEPRECATED_EXTERNAL(
    SB_EXPORT void SbMemoryFree(void* memory));

// This is the implementation of SbMemoryFreeAligned that must be provided by
// Starboard ports.
//
// DO NOT CALL. Call SbMemoryDeallocateAligned(...) instead.
SB_DEPRECATED_EXTERNAL(
    SB_EXPORT void SbMemoryFreeAligned(void* memory));

#if SB_API_VERSION >= SB_MMAP_REQUIRED_VERSION || SB_HAS(MMAP)
// Allocates |size_bytes| worth of physical memory pages and maps them into
// an available virtual region. This function returns |SB_MEMORY_MAP_FAILED|
// on failure. |NULL| is a valid return value.
//
// |size_bytes|: The amount of physical memory pages to be allocated.
// |flags|: The bitwise OR of the protection flags for the mapped memory
//   as specified in |SbMemoryMapFlags|. Allocating executable memory is not
//   allowed and will fail. If executable memory is needed, map non-executable
//   memory first and then switch access to executable using SbMemoryProtect.
//   When kSbMemoryMapProtectReserved is used, the address space will not be
//   accessible and, if possible, the platform should not count it against any
//   memory budget.
// |name|: A value that appears in the debugger on some platforms. The value
//   can be up to 32 bytes.
SB_EXPORT void* SbMemoryMap(int64_t size_bytes, int flags, const char* name);

// Unmap |size_bytes| of physical pages starting from |virtual_address|,
// returning |true| on success. After this function completes,
// [virtual_address, virtual_address + size_bytes) will not be read/writable.
// This function can unmap multiple contiguous regions that were mapped with
// separate calls to SbMemoryMap(). For example, if one call to
// |SbMemoryMap(0x1000)| returns |(void*)0xA000|, and another call to
// |SbMemoryMap(0x1000)| returns |(void*)0xB000|,
// |SbMemoryUnmap(0xA000, 0x2000)| should free both regions.
SB_EXPORT bool SbMemoryUnmap(void* virtual_address, int64_t size_bytes);

#if SB_API_VERSION >= 10
// Change the protection of |size_bytes| of memory regions, starting from
// |virtual_address|, to |flags|, returning |true| on success.
SB_EXPORT bool SbMemoryProtect(void* virtual_address,
                               int64_t size_bytes,
                               int flags);
#endif

#if SB_CAN(MAP_EXECUTABLE_MEMORY)
// Flushes any data in the given virtual address range that is cached locally in
// the current processor core to physical memory, ensuring that data and
// instruction caches are cleared. This is required to be called on executable
// memory that has been written to and might be executed in the future.
SB_EXPORT void SbMemoryFlush(void* virtual_address, int64_t size_bytes);
#endif
#endif  // SB_API_VERSION >= SB_MMAP_REQUIRED_VERSION || SB_HAS(MMAP)

// Gets the stack bounds for the current thread.
//
// |out_high|: The highest addressable byte + 1 for the current thread.
// |out_low|: The lowest addressable byte for the current thread.
SB_EXPORT void SbMemoryGetStackBounds(void** out_high, void** out_low);

// Copies |count| sequential bytes from |source| to |destination|, without
// support for the |source| and |destination| regions overlapping. This
// function is meant to be a drop-in replacement for |memcpy|.
//
// The function's behavior is undefined if |destination| or |source| are NULL,
// and the function is a no-op if |count| is 0. The return value is
// |destination|.
//
// |destination|: The destination of the copied memory.
// |source|: The source of the copied memory.
// |count|: The number of sequential bytes to be copied.
SB_EXPORT void* SbMemoryCopy(void* destination,
                             const void* source,
                             size_t count);

// Copies |count| sequential bytes from |source| to |destination|, with support
// for the |source| and |destination| regions overlapping. This function is
// meant to be a drop-in replacement for |memmove|.
//
// The function's behavior is undefined if |destination| or |source| are NULL,
// and the function is a no-op if |count| is 0. The return value is
// |destination|.
//
// |destination|: The destination of the copied memory.
// |source|: The source of the copied memory.
// |count|: The number of sequential bytes to be copied.
SB_EXPORT void* SbMemoryMove(void* destination,
                             const void* source,
                             size_t count);

// Fills |count| sequential bytes starting at |destination|, with the unsigned
// char coercion of |byte_value|. This function is meant to be a drop-in
// replacement for |memset|.
//
// The function's behavior is undefined if |destination| is NULL, and the
// function is a no-op if |count| is 0. The return value is |destination|.
//
// |destination|: The destination of the copied memory.
// |count|: The number of sequential bytes to be set.
SB_EXPORT void* SbMemorySet(void* destination, int byte_value, size_t count);

// Compares the contents of the first |count| bytes of |buffer1| and |buffer2|.
// This function returns:
// - |-1| if |buffer1| is "less-than" |buffer2|
// - |0| if |buffer1| and |buffer2| are equal
// - |1| if |buffer1| is "greater-than" |buffer2|.
//
// This function is meant to be a drop-in replacement for |memcmp|.
//
// |buffer1|: The first buffer to be compared.
// |buffer2|: The second buffer to be compared.
// |count|: The number of bytes to be compared.
SB_EXPORT int SbMemoryCompare(const void* buffer1,
                              const void* buffer2,
                              size_t count);

// Finds the lower 8-bits of |value| in the first |count| bytes of |buffer|
// and returns either a pointer to the first found occurrence or |NULL| if
// the value is not found. This function is meant to be a drop-in replacement
// for |memchr|.
SB_EXPORT const void* SbMemoryFindByte(const void* buffer,
                                       int value,
                                       size_t count);

// A wrapper that implements a drop-in replacement for |calloc|, which is used
// in some packages.
static SB_C_INLINE void* SbMemoryCalloc(size_t count, size_t size) {
  size_t total = count * size;
  void* result = SbMemoryAllocate(total);
  if (result) {
    SbMemorySet(result, 0, total);
  }
  return result;
}

// Returns true if the first |count| bytes of |buffer| are set to zero.
static SB_C_INLINE bool SbMemoryIsZero(const void* buffer, size_t count) {
  if (count == 0) {
    return true;
  }
  const char* char_buffer = (const char*)(buffer);
  return char_buffer[0] == 0 &&
         SbMemoryCompare(char_buffer, char_buffer + 1, count - 1) == 0;
}

/////////////////////////////////////////////////////////////////
// Deprecated. Do not use.
/////////////////////////////////////////////////////////////////

// Same as SbMemoryAllocateUnchecked, but will abort() in the case of an
// allocation failure.
//
// DO NOT CALL. Call SbMemoryAllocate(...) instead.
SB_DEPRECATED_EXTERNAL(
    SB_EXPORT void* SbMemoryAllocateChecked(size_t size));

// Same as SbMemoryReallocateUnchecked, but will abort() in the case of an
// allocation failure.
//
// DO NOT CALL. Call SbMemoryReallocate(...) instead.
SB_DEPRECATED_EXTERNAL(
    SB_EXPORT void* SbMemoryReallocateChecked(void* memory, size_t size));

// Same as SbMemoryAllocateAlignedUnchecked, but will abort() in the case of an
// allocation failure.
//
// DO NOT CALL. Call SbMemoryAllocateAligned(...) instead.
SB_DEPRECATED_EXTERNAL(
    SB_EXPORT void* SbMemoryAllocateAlignedChecked(size_t alignment,
                                                   size_t size));

#ifdef __cplusplus
}  // extern "C"
#endif

#endif  // STARBOARD_MEMORY_H_
