1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
|
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "build/rust/allocator/allocator_impls.h"
#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/390223051): Remove C-library calls to fix the errors.
#pragma allow_unsafe_libc_calls
#endif
#include <cstddef>
#include <cstring>
#include "build/build_config.h"
#include "build/rust/allocator/buildflags.h"
#if BUILDFLAG(RUST_ALLOCATOR_USES_PARTITION_ALLOC)
#include "partition_alloc/partition_alloc_constants.h" // nogncheck
#include "partition_alloc/shim/allocator_shim.h" // nogncheck
#elif BUILDFLAG(RUST_ALLOCATOR_USES_ALIGNED_MALLOC)
#include <cstdlib>
#endif
namespace rust_allocator_internal {
unsigned char* alloc(size_t size, size_t align) {
#if BUILDFLAG(RUST_ALLOCATOR_USES_PARTITION_ALLOC)
// PartitionAlloc will crash if given an alignment larger than this.
if (align > partition_alloc::internal::kMaxSupportedAlignment) {
return nullptr;
}
// We use unchecked allocation paths in PartitionAlloc rather than going
// through its shims in `malloc()` etc so that we can support fallible
// allocation paths such as Vec::try_reserve without crashing on allocation
// failure.
if (align <= alignof(std::max_align_t)) {
return static_cast<unsigned char*>(allocator_shim::UncheckedAlloc(size));
} else {
return static_cast<unsigned char*>(
allocator_shim::UncheckedAlignedAlloc(size, align));
}
#elif BUILDFLAG(RUST_ALLOCATOR_USES_ALIGNED_MALLOC)
return static_cast<unsigned char*>(_aligned_malloc(size, align));
#else
#error This configuration is not supported.
#endif
}
void dealloc(unsigned char* p, size_t size, size_t align) {
#if BUILDFLAG(RUST_ALLOCATOR_USES_PARTITION_ALLOC)
if (align <= alignof(std::max_align_t)) {
allocator_shim::UncheckedFree(p);
} else {
allocator_shim::UncheckedAlignedFree(p);
}
#elif BUILDFLAG(RUST_ALLOCATOR_USES_ALIGNED_MALLOC)
return _aligned_free(p);
#else
#error This configuration is not supported.
#endif
}
unsigned char* realloc(unsigned char* p,
size_t old_size,
size_t align,
size_t new_size) {
#if BUILDFLAG(RUST_ALLOCATOR_USES_PARTITION_ALLOC)
// We use unchecked allocation paths in PartitionAlloc rather than going
// through its shims in `malloc()` etc so that we can support fallible
// allocation paths such as Vec::try_reserve without crashing on allocation
// failure.
if (align <= alignof(std::max_align_t)) {
return static_cast<unsigned char*>(
allocator_shim::UncheckedRealloc(p, new_size));
} else {
return static_cast<unsigned char*>(
allocator_shim::UncheckedAlignedRealloc(p, new_size, align));
}
#elif BUILDFLAG(RUST_ALLOCATOR_USES_ALIGNED_MALLOC)
return static_cast<unsigned char*>(_aligned_realloc(p, new_size, align));
#else
#error This configuration is not supported.
#endif
}
unsigned char* alloc_zeroed(size_t size, size_t align) {
#if BUILDFLAG(RUST_ALLOCATOR_USES_PARTITION_ALLOC) || \
BUILDFLAG(RUST_ALLOCATOR_USES_ALIGNED_MALLOC)
// TODO(danakj): When RUST_ALLOCATOR_USES_PARTITION_ALLOC is true, it's
// possible that a partition_alloc::UncheckedAllocZeroed() call would perform
// better than partition_alloc::UncheckedAlloc() + memset. But there is no
// such API today. See b/342251590.
unsigned char* p = alloc(size, align);
if (p) {
memset(p, 0, size);
}
return p;
#else
#error This configuration is not supported.
#endif
}
} // namespace rust_allocator_internal
|