Blender V4.3
implicit_sharing.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include <algorithm>
6#include <cstring>
7
8#include "MEM_guardedalloc.h"
9
11
13
15 public:
16 void *data;
17
18 MEMFreeImplicitSharing(void *data) : data(data)
19 {
20 BLI_assert(data != nullptr);
21 }
22
23 private:
24 void delete_self_with_data() override
25 {
26 MEM_freeN(data);
27 MEM_delete(this);
28 }
29};
30
32{
33 return MEM_new<MEMFreeImplicitSharing>(__func__, data);
34}
35
36namespace detail {
37
38void *make_trivial_data_mutable_impl(void *old_data,
39 const int64_t size,
40 const int64_t alignment,
41 const ImplicitSharingInfo **sharing_info)
42{
43 if (!old_data) {
44 BLI_assert(size == 0);
45 return nullptr;
46 }
47
48 BLI_assert(*sharing_info != nullptr);
49 if ((*sharing_info)->is_mutable()) {
50 (*sharing_info)->tag_ensured_mutable();
51 }
52 else {
53 void *new_data = MEM_mallocN_aligned(size, alignment, __func__);
54 memcpy(new_data, old_data, size);
55 (*sharing_info)->remove_user_and_delete_if_last();
56 *sharing_info = info_for_mem_free(new_data);
57 return new_data;
58 }
59
60 return old_data;
61}
62
63void *resize_trivial_array_impl(void *old_data,
64 const int64_t old_size,
65 const int64_t new_size,
66 const int64_t alignment,
67 const ImplicitSharingInfo **sharing_info)
68{
69 if (new_size == 0) {
70 if (*sharing_info) {
71 (*sharing_info)->remove_user_and_delete_if_last();
72 *sharing_info = nullptr;
73 }
74 return nullptr;
75 }
76
77 if (!old_data) {
78 BLI_assert(old_size == 0);
79 BLI_assert(*sharing_info == nullptr);
80 void *new_data = MEM_mallocN_aligned(new_size, alignment, __func__);
81 *sharing_info = info_for_mem_free(new_data);
82 return new_data;
83 }
84
85 BLI_assert(old_size != 0);
86 if ((*sharing_info)->is_mutable()) {
87 if (auto *info = const_cast<MEMFreeImplicitSharing *>(
88 dynamic_cast<const MEMFreeImplicitSharing *>(*sharing_info)))
89 {
90 /* If the array was allocated with the MEM allocator, we can use realloc directly, which
91 * could theoretically give better performance if the data can be reused in place. */
92 void *new_data = static_cast<int *>(MEM_reallocN(old_data, new_size));
93 info->data = new_data;
94 (*sharing_info)->tag_ensured_mutable();
95 return new_data;
96 }
97 }
98
99 void *new_data = MEM_mallocN_aligned(new_size, alignment, __func__);
100 memcpy(new_data, old_data, std::min(old_size, new_size));
101 (*sharing_info)->remove_user_and_delete_if_last();
102 *sharing_info = info_for_mem_free(new_data);
103 return new_data;
104}
105
106} // namespace detail
107
108} // namespace blender::implicit_sharing
#define BLI_assert(a)
Definition BLI_assert.h:50
Read Guarded memory(de)allocation.
#define MEM_reallocN(vmemh, len)
void * MEM_mallocN_aligned(size_t len, size_t alignment, const char *str)
Definition mallocn.cc:110
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
void * resize_trivial_array_impl(void *old_data, int64_t old_size, int64_t new_size, int64_t alignment, const ImplicitSharingInfo **sharing_info)
void * make_trivial_data_mutable_impl(void *old_data, int64_t size, int64_t alignment, const ImplicitSharingInfo **sharing_info)
const ImplicitSharingInfo * info_for_mem_free(void *data)
__int64 int64_t
Definition stdint.h:89