codegen: use gen_frame_decompress_slot in gen_option_ord
[ajla.git] / mem_al.h
blob3bdd9e9a8fc8b15a4c42429cde0944cc644eacf4
1 /*
2 * Copyright (C) 2024 Mikulas Patocka
4 * This file is part of Ajla.
6 * Ajla is free software: you can redistribute it and/or modify it under the
7 * terms of the GNU General Public License as published by the Free Software
8 * Foundation, either version 3 of the License, or (at your option) any later
9 * version.
11 * Ajla is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
13 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along with
16 * Ajla. If not, see <https://www.gnu.org/licenses/>.
19 #ifndef AJLA_MEM_AL_H
20 #define AJLA_MEM_AL_H
22 #if defined(USE_AMALLOC)
23 extern uchar_efficient_t amalloc_enabled;
24 #else
25 #define amalloc_enabled 0
26 #endif
28 void * attr_fastcall mem_alloc_position(size_t size, ajla_error_t *mayfail argument_position);
29 void * attr_fastcall mem_calloc_position(size_t size, ajla_error_t *mayfail argument_position);
30 void * attr_fastcall mem_align_position(size_t size, size_t alignment, ajla_error_t *mayfail argument_position);
31 void * attr_fastcall mem_calign_position(size_t size, size_t alignment, ajla_error_t *mayfail argument_position);
32 void * attr_fastcall mem_realloc_position(void *ptr, size_t size, ajla_error_t *mayfail argument_position);
33 void attr_fastcall mem_free_position(const void *ptr argument_position);
34 void attr_fastcall mem_free_aligned_position(const void *ptr argument_position);
36 #define mem_alloc_fn(x, y) mem_alloc_position(x, y pass_file_line)
37 #define mem_calloc_fn(x, y) mem_calloc_position(x, y pass_file_line)
38 #define mem_align_fn(x, y, z) mem_align_position(x, y, z pass_file_line)
39 #define mem_calign_fn(x, y, z) mem_calign_position(x, y, z pass_file_line)
40 #define mem_realloc_fn(x, y, z) mem_realloc_position(x, y, z pass_file_line)
41 #define mem_free(x) mem_free_position(x pass_file_line)
42 #define mem_free_aligned(x) mem_free_aligned_position(x pass_file_line)
44 #define mem_alloc_mayfail(t, x, y) cast_ptr(t, mem_alloc_fn(x, y))
45 #define mem_calloc_mayfail(t, x, y) cast_ptr(t, mem_calloc_fn(x, y))
46 #define mem_align_mayfail(t, x, y, z) cast_ptr(t, mem_align_fn(x, y, z))
47 #define mem_calign_mayfail(t, x, y, z) cast_ptr(t, mem_calign_fn(x, y, z))
48 #define mem_realloc_mayfail(t, x, y, z) cast_ptr(t, mem_realloc_fn(x, y, z))
50 #define mem_alloc(t, x) mem_alloc_mayfail(t, x, NULL)
51 #define mem_calloc(t, x) mem_calloc_mayfail(t, x, NULL)
52 #define mem_align(t, x, y) mem_align_mayfail(t, x, y, NULL)
53 #define mem_calign(t, x, y) mem_calign_mayfail(t, x, y, NULL)
54 #define mem_realloc(t, x, y) mem_realloc_mayfail(t, x, y, NULL)
56 #ifdef DEBUG_MEMORY_POSSIBLE
57 void attr_fastcall mem_set_position(const void *ptr argument_position);
58 const char * attr_fastcall mem_get_position(const void *ptr argument_position);
59 void attr_fastcall mem_verify_position(const void attr_unused *ptr argument_position);
60 void attr_fastcall mem_verify_aligned_position(const void attr_unused *ptr argument_position);
61 #else
62 static inline void mem_set_position(const void attr_unused *ptr argument_position) { }
63 static inline const char *mem_get_position(const void attr_unused *ptr argument_position) { return "unknown position"; }
64 static inline void mem_verify_position(const void attr_unused *ptr argument_position) { }
65 static inline void mem_verify_aligned_position(const void attr_unused *ptr argument_position) { }
66 #endif
68 #define mem_get_pos(x) mem_get_position(x pass_file_line)
69 #define mem_verify(x) mem_verify_position(x pass_file_line)
70 #define mem_verify_aligned(x) mem_verify_aligned_position(x pass_file_line)
72 bool mem_trim_cache(void);
74 #define MR_SUMMARY 0
75 #define MR_MOST_ALLOCATED 1
76 #define MR_LARGEST_BLOCKS 2
77 #ifdef DEBUG_MEMORY_POSSIBLE
78 void mem_report_usage(int mode, const char *string);
79 #else
80 static inline void mem_report_usage(int attr_unused mode, const char attr_unused *string) { }
81 #endif
83 bool mem_enable_debugging_option(const char *option, size_t l);
84 bool mem_al_enable_profile(const char *option, size_t l);
85 void mem_al_set_ptrcomp(const char *str);
86 void mem_al_set_system_malloc(const char attr_unused *str);
87 void mem_init(void);
88 void mem_init_multithreaded(void);
89 void mem_done_multithreaded(void);
90 void mem_done(void);
92 static inline bool mem_check_overflow(size_t prefix, size_t n_elements, size_t el_size, ajla_error_t *err)
94 if (unlikely(n_elements > (size_t_limit - prefix) / el_size)) {
95 fatal_mayfail(error_ajla(EC_SYNC, AJLA_ERROR_SIZE_OVERFLOW), err, "allocation size overflow: %" PRIuMAX " + %" PRIuMAX " * %" PRIuMAX "", (uintmax_t)prefix, (uintmax_t)n_elements, (uintmax_t)el_size);
96 return false;
98 return true;
101 #define struct_check_overflow(full, part, n_elements, err) mem_check_overflow(offsetof(full, part), n_elements, sizeof(((full *)NULL)->part[0]), err)
103 #define mem_alloc_array_mayfail(alloc, type, minimum, prefix, n_elements, el_size, err)\
104 (unlikely(!mem_check_overflow(prefix, n_elements, el_size, err)) ? cast_ptr(type, NULL) : alloc(type, maximum_maybe0((size_t)(prefix) + (size_t)(n_elements) * (size_t)(el_size), (size_t)(minimum)), err))
106 #define struct_alloc_array_mayfail(alloc, full, part, n_elements, err)\
107 mem_alloc_array_mayfail(alloc, full *, partial_sizeof_lower_bound(full), offsetof(full, part), n_elements, sizeof(((full *)NULL)->part[0]), err)
109 #endif