%PDF- %PDF-
| Direktori : /home2/vacivi36/vittasync.vacivitta.com.br/vittasync/node/deps/v8/src/base/platform/ |
| Current File : //home2/vacivi36/vittasync.vacivitta.com.br/vittasync/node/deps/v8/src/base/platform/memory.h |
// Copyright 2022 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_BASE_PLATFORM_MEMORY_H_
#define V8_BASE_PLATFORM_MEMORY_H_
#include <cstddef>
#include <cstdlib>
#include "include/v8config.h"
#include "src/base/bits.h"
#include "src/base/logging.h"
#include "src/base/macros.h"
#if V8_OS_STARBOARD
#include "starboard/memory.h"
#endif // V8_OS_STARBOARD
#if V8_OS_DARWIN
#include <malloc/malloc.h>
#else // !V8_OS_DARWIN
#include <malloc.h>
#endif // !V8_OS_DARWIN
#if (V8_OS_POSIX && !V8_OS_AIX && !V8_OS_SOLARIS) || V8_OS_WIN
#define V8_HAS_MALLOC_USABLE_SIZE 1
#endif // (V8_OS_POSIX && !V8_OS_AIX && !V8_OS_SOLARIS) || V8_OS_WIN
namespace v8::base {
inline void* Malloc(size_t size) {
#if V8_OS_STARBOARD
return SbMemoryAllocate(size);
#elif V8_OS_AIX && _LINUX_SOURCE_COMPAT
// Work around for GCC bug on AIX.
// See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79839
return __linux_malloc(size);
#else
return malloc(size);
#endif
}
inline void* Realloc(void* memory, size_t size) {
#if V8_OS_STARBOARD
return SbMemoryReallocate(memory, size);
#elif V8_OS_AIX && _LINUX_SOURCE_COMPAT
// Work around for GCC bug on AIX, see Malloc().
// See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79839
return __linux_realloc(memory, size);
#else
return realloc(memory, size);
#endif
}
inline void Free(void* memory) {
#if V8_OS_STARBOARD
return SbMemoryDeallocate(memory);
#else // !V8_OS_STARBOARD
return free(memory);
#endif // !V8_OS_STARBOARD
}
inline void* Calloc(size_t count, size_t size) {
#if V8_OS_STARBOARD
return SbMemoryCalloc(count, size);
#elif V8_OS_AIX && _LINUX_SOURCE_COMPAT
// Work around for GCC bug on AIX, see Malloc().
return __linux_calloc(count, size);
#else
return calloc(count, size);
#endif
}
// Aligned allocation. Memory must be freed with `AlignedFree()` as not all
// platforms support using general free for aligned allocations.
inline void* AlignedAlloc(size_t size, size_t alignment) {
DCHECK_LE(alignof(void*), alignment);
DCHECK(base::bits::IsPowerOfTwo(alignment));
#if V8_OS_WIN
return _aligned_malloc(size, alignment);
#elif V8_LIBC_BIONIC
// posix_memalign is not exposed in some Android versions, so we fall back to
// memalign. See http://code.google.com/p/android/issues/detail?id=35391.
return memalign(alignment, size);
#elif V8_OS_STARBOARD
return SbMemoryAllocateAligned(alignment, size);
#else // POSIX
void* ptr;
if (posix_memalign(&ptr, alignment, size)) ptr = nullptr;
return ptr;
#endif // POSIX
}
inline void AlignedFree(void* ptr) {
#if V8_OS_WIN
_aligned_free(ptr);
#elif V8_OS_STARBOARD
SbMemoryFreeAligned(ptr);
#else
// Using regular Free() is not correct in general. For most platforms,
// including V8_LIBC_BIONIC, it is though.
base::Free(ptr);
#endif
}
#if V8_HAS_MALLOC_USABLE_SIZE
// Note that the use of additional bytes that deviate from the original
// `Malloc()` request returned by `MallocUsableSize()` is not UBSan-safe. Use
// `AllocateAtLeast()` for a safe version.
inline size_t MallocUsableSize(void* ptr) {
#if V8_OS_WIN
// |_msize| cannot handle a null pointer.
if (!ptr) return 0;
return _msize(ptr);
#elif V8_OS_DARWIN
return malloc_size(ptr);
#else // POSIX.
return malloc_usable_size(ptr);
#endif // POSIX.
}
#endif // V8_HAS_MALLOC_USABLE_SIZE
// Mimics C++23 `allocation_result`.
template <class Pointer>
struct AllocationResult {
Pointer ptr = nullptr;
size_t count = 0;
};
// Allocates at least `n * sizeof(T)` uninitialized storage but may allocate
// more which is indicated by the return value. Mimics C++23
// `allocate_at_least()`.
template <typename T>
V8_NODISCARD AllocationResult<T*> AllocateAtLeast(size_t n) {
const size_t min_wanted_size = n * sizeof(T);
auto* memory = static_cast<T*>(Malloc(min_wanted_size));
#if !V8_HAS_MALLOC_USABLE_SIZE
return {memory, min_wanted_size};
#else // V8_HAS_MALLOC_USABLE_SIZE
const size_t usable_size = MallocUsableSize(memory);
#if V8_USE_UNDEFINED_BEHAVIOR_SANITIZER
if (memory == nullptr)
return {nullptr, 0};
// UBSan (specifically, -fsanitize=bounds) assumes that any access outside
// of the requested size for malloc is UB and will trap in ud2 instructions.
// This can be worked around by using `Realloc()` on the specific memory
// region.
if (usable_size != min_wanted_size) {
memory = static_cast<T*>(Realloc(memory, usable_size));
}
#endif // V8_USE_UNDEFINED_BEHAVIOR_SANITIZER
return {memory, usable_size};
#endif // V8_HAS_MALLOC_USABLE_SIZE
}
} // namespace v8::base
#undef V8_HAS_MALLOC_USABLE_SIZE
#endif // V8_BASE_PLATFORM_MEMORY_H_