]> git.saurik.com Git - apple/icu.git/blame - icuSources/common/cmemory.cpp
ICU-59173.0.1.tar.gz
[apple/icu.git] / icuSources / common / cmemory.cpp
CommitLineData
f3c0d7a5
A
1// © 2016 and later: Unicode, Inc. and others.
2// License & terms of use: http://www.unicode.org/copyright.html
b75a7d8f
A
3/*
4******************************************************************************
5*
b331163b 6* Copyright (C) 2002-2015, International Business Machines
b75a7d8f
A
7* Corporation and others. All Rights Reserved.
8*
9******************************************************************************
10*
11* File cmemory.c ICU Heap allocation.
12* All ICU heap allocation, both for C and C++ new of ICU
13* class types, comes through these functions.
14*
15* If you have a need to replace ICU allocation, this is the
16* place to do it.
17*
18* Note that uprv_malloc(0) returns a non-NULL pointer, and
19* that a subsequent free of that pointer value is a NOP.
20*
21******************************************************************************
22*/
374ca955 23#include "unicode/uclean.h"
73c04bcf 24#include "cmemory.h"
4388f060 25#include "putilimp.h"
51004dcb 26#include "uassert.h"
73c04bcf 27#include <stdlib.h>
b75a7d8f 28
51004dcb 29/* uprv_malloc(0) returns a pointer to this read-only data. */
b75a7d8f
A
30static const int32_t zeroMem[] = {0, 0, 0, 0, 0, 0};
31
374ca955
A
32/* Function Pointers for user-supplied heap functions */
33static const void *pContext;
34static UMemAllocFn *pAlloc;
35static UMemReallocFn *pRealloc;
36static UMemFreeFn *pFree;
37
51004dcb
A
38#if U_DEBUG && defined(UPRV_MALLOC_COUNT)
39#include <stdio.h>
40static int n=0;
41static long b=0;
42#endif
43
44#if U_DEBUG
45
46static char gValidMemorySink = 0;
47
48U_CAPI void uprv_checkValidMemory(const void *p, size_t n) {
49 /*
50 * Access the memory to ensure that it's all valid.
51 * Load and save a computed value to try to ensure that the compiler
52 * does not throw away the whole loop.
53 * A thread analyzer might complain about un-mutexed access to gValidMemorySink
54 * which is true but harmless because no one ever uses the value in gValidMemorySink.
55 */
56 const char *s = (const char *)p;
57 char c = gValidMemorySink;
58 size_t i;
59 U_ASSERT(p != NULL);
60 for(i = 0; i < n; ++i) {
61 c ^= s[i];
62 }
63 gValidMemorySink = c;
64}
65
66#endif /* U_DEBUG */
67
b75a7d8f
A
68U_CAPI void * U_EXPORT2
69uprv_malloc(size_t s) {
51004dcb
A
70#if U_DEBUG && defined(UPRV_MALLOC_COUNT)
71#if 1
72 putchar('>');
73 fflush(stdout);
74#else
75 fprintf(stderr,"MALLOC\t#%d\t%ul bytes\t%ul total\n", ++n,s,(b+=s)); fflush(stderr);
76#endif
77#endif
b75a7d8f 78 if (s > 0) {
374ca955
A
79 if (pAlloc) {
80 return (*pAlloc)(pContext, s);
81 } else {
4388f060 82 return uprv_default_malloc(s);
374ca955 83 }
b75a7d8f
A
84 } else {
85 return (void *)zeroMem;
86 }
87}
88
89U_CAPI void * U_EXPORT2
90uprv_realloc(void * buffer, size_t size) {
51004dcb
A
91#if U_DEBUG && defined(UPRV_MALLOC_COUNT)
92 putchar('~');
93 fflush(stdout);
94#endif
b75a7d8f
A
95 if (buffer == zeroMem) {
96 return uprv_malloc(size);
97 } else if (size == 0) {
374ca955
A
98 if (pFree) {
99 (*pFree)(pContext, buffer);
100 } else {
4388f060 101 uprv_default_free(buffer);
374ca955 102 }
b75a7d8f
A
103 return (void *)zeroMem;
104 } else {
374ca955
A
105 if (pRealloc) {
106 return (*pRealloc)(pContext, buffer, size);
107 } else {
4388f060 108 return uprv_default_realloc(buffer, size);
374ca955 109 }
b75a7d8f
A
110 }
111}
112
113U_CAPI void U_EXPORT2
114uprv_free(void *buffer) {
51004dcb
A
115#if U_DEBUG && defined(UPRV_MALLOC_COUNT)
116 putchar('<');
117 fflush(stdout);
118#endif
b75a7d8f 119 if (buffer != zeroMem) {
374ca955
A
120 if (pFree) {
121 (*pFree)(pContext, buffer);
122 } else {
4388f060 123 uprv_default_free(buffer);
374ca955
A
124 }
125 }
126}
127
4388f060
A
128U_CAPI void * U_EXPORT2
129uprv_calloc(size_t num, size_t size) {
130 void *mem = NULL;
131 size *= num;
132 mem = uprv_malloc(size);
133 if (mem) {
134 uprv_memset(mem, 0, size);
135 }
136 return mem;
137}
138
374ca955
A
139U_CAPI void U_EXPORT2
140u_setMemoryFunctions(const void *context, UMemAllocFn *a, UMemReallocFn *r, UMemFreeFn *f, UErrorCode *status)
141{
142 if (U_FAILURE(*status)) {
143 return;
144 }
145 if (a==NULL || r==NULL || f==NULL) {
146 *status = U_ILLEGAL_ARGUMENT_ERROR;
147 return;
148 }
374ca955
A
149 pContext = context;
150 pAlloc = a;
151 pRealloc = r;
152 pFree = f;
153}
154
155
156U_CFUNC UBool cmemory_cleanup(void) {
157 pContext = NULL;
158 pAlloc = NULL;
159 pRealloc = NULL;
160 pFree = NULL;
374ca955
A
161 return TRUE;
162}