1 /*
2 * Copyright 2011 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7 #include "SkMalloc.h"
8
9 #include "SkTypes.h"
10
11 #include <cstdlib>
12
13 #define SK_DEBUGFAILF(fmt, ...) \
14 SkASSERT((SkDebugf(fmt"\n", __VA_ARGS__), false))
15
sk_out_of_memory(size_t size)16 static inline void sk_out_of_memory(size_t size) {
17 SK_DEBUGFAILF("sk_out_of_memory (asked for " SK_SIZE_T_SPECIFIER " bytes)",
18 size);
19 #if defined(IS_FUZZING)
20 exit(1);
21 #else
22 abort();
23 #endif
24 }
25
throw_on_failure(size_t size,void * p)26 static inline void* throw_on_failure(size_t size, void* p) {
27 if (size > 0 && p == nullptr) {
28 // If we've got a nullptr here, the only reason we should have failed is running out of RAM.
29 sk_out_of_memory(size);
30 }
31 return p;
32 }
33
sk_abort_no_print()34 void sk_abort_no_print() {
35 #if defined(SK_BUILD_FOR_WIN) && defined(SK_IS_BOT)
36 // do not display a system dialog before aborting the process
37 _set_abort_behavior(0, _WRITE_ABORT_MSG);
38 #endif
39 #if defined(SK_DEBUG) && defined(SK_BUILD_FOR_WIN)
40 __debugbreak();
41 #endif
42 #if defined(IS_FUZZING)
43 exit(1);
44 #else
45 abort();
46 #endif
47 }
48
sk_out_of_memory(void)49 void sk_out_of_memory(void) {
50 SkDEBUGFAIL("sk_out_of_memory");
51 #if defined(IS_FUZZING)
52 exit(1);
53 #else
54 abort();
55 #endif
56 }
57
sk_malloc_throw(size_t size)58 void* sk_malloc_throw(size_t size) {
59 return sk_malloc_flags(size, SK_MALLOC_THROW);
60 }
61
sk_realloc_throw(void * addr,size_t size)62 void* sk_realloc_throw(void* addr, size_t size) {
63 return throw_on_failure(size, realloc(addr, size));
64 }
65
sk_free(void * p)66 void sk_free(void* p) {
67 if (p) {
68 free(p);
69 }
70 }
71
sk_malloc_flags(size_t size,unsigned flags)72 void* sk_malloc_flags(size_t size, unsigned flags) {
73 void* p = malloc(size);
74 if (flags & SK_MALLOC_THROW) {
75 return throw_on_failure(size, p);
76 } else {
77 return p;
78 }
79 }
80
sk_calloc(size_t size)81 void* sk_calloc(size_t size) {
82 return calloc(size, 1);
83 }
84
sk_calloc_throw(size_t size)85 void* sk_calloc_throw(size_t size) {
86 return throw_on_failure(size, sk_calloc(size));
87 }
88