/src/skia/src/ports/SkMemory_malloc.cpp
Line | Count | Source (jump to first uncovered line) |
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 | | |
8 | | #include "include/private/base/SkAssert.h" |
9 | | #include "include/private/base/SkDebug.h" |
10 | | #include "include/private/base/SkFeatures.h" |
11 | | #include "include/private/base/SkMalloc.h" |
12 | | |
13 | | #include <algorithm> |
14 | | #include <cstdlib> |
15 | | |
16 | | #if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS) |
17 | | #include <malloc/malloc.h> |
18 | | #elif defined(SK_BUILD_FOR_ANDROID) || defined(SK_BUILD_FOR_UNIX) |
19 | | #include <malloc.h> |
20 | | #elif defined(SK_BUILD_FOR_WIN) |
21 | | #include <malloc.h> |
22 | | #endif |
23 | | |
24 | | #if defined(SK_DEBUG) && defined(SK_BUILD_FOR_WIN) |
25 | | #include <intrin.h> |
26 | | // This is a super stable value and setting it here avoids pulling in all of windows.h. |
27 | | #ifndef FAST_FAIL_FATAL_APP_EXIT |
28 | | #define FAST_FAIL_FATAL_APP_EXIT 7 |
29 | | #endif |
30 | | #endif |
31 | | |
32 | | #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK |
33 | | #define SK_DEBUGFAILF(fmt, ...) SK_ABORT(fmt"\n", __VA_ARGS__) |
34 | | #else |
35 | 0 | #define SK_DEBUGFAILF(fmt, ...) SkASSERT((SkDebugf(fmt"\n", __VA_ARGS__), false)) |
36 | | #endif |
37 | | |
38 | 0 | static inline void sk_out_of_memory(size_t size) { |
39 | 0 | SK_DEBUGFAILF("sk_out_of_memory (asked for %zu bytes)", |
40 | 0 | size); |
41 | | #if defined(SK_BUILD_FOR_AFL_FUZZ) |
42 | | exit(1); |
43 | | #else |
44 | 0 | abort(); |
45 | 0 | #endif |
46 | 0 | } Unexecuted instantiation: SkMemory_malloc.cpp:sk_out_of_memory(unsigned long) Unexecuted instantiation: SkMemory_malloc.cpp:sk_out_of_memory(unsigned long) |
47 | | |
48 | 112M | static inline void* throw_on_failure(size_t size, void* p) { |
49 | 112M | if (size > 0 && p == nullptr) { |
50 | | // If we've got a nullptr here, the only reason we should have failed is running out of RAM. |
51 | 0 | sk_out_of_memory(size); |
52 | 0 | } |
53 | 112M | return p; |
54 | 112M | } |
55 | | |
56 | 0 | void sk_abort_no_print() { |
57 | | #if defined(SK_DEBUG) && defined(SK_BUILD_FOR_WIN) |
58 | | __fastfail(FAST_FAIL_FATAL_APP_EXIT); |
59 | | #elif defined(__clang__) |
60 | | __builtin_trap(); |
61 | | #else |
62 | | abort(); |
63 | | #endif |
64 | 0 | } |
65 | | |
66 | 0 | void sk_out_of_memory(void) { |
67 | 0 | SkDEBUGFAIL("sk_out_of_memory"); |
68 | | #if defined(SK_BUILD_FOR_AFL_FUZZ) |
69 | | exit(1); |
70 | | #else |
71 | 0 | abort(); |
72 | 0 | #endif |
73 | 0 | } Unexecuted instantiation: sk_out_of_memory() Unexecuted instantiation: sk_out_of_memory() |
74 | | |
75 | 14.6M | void* sk_realloc_throw(void* addr, size_t size) { |
76 | 14.6M | if (size == 0) { |
77 | 0 | sk_free(addr); |
78 | 0 | return nullptr; |
79 | 0 | } |
80 | 14.6M | return throw_on_failure(size, realloc(addr, size)); |
81 | 14.6M | } |
82 | | |
83 | 224M | void sk_free(void* p) { |
84 | | // The guard here produces a performance improvement across many tests, and many platforms. |
85 | | // Removing the check was tried in skia cl 588037. |
86 | 224M | if (p != nullptr) { |
87 | 123M | free(p); |
88 | 123M | } |
89 | 224M | } |
90 | | |
91 | 116M | void* sk_malloc_flags(size_t size, unsigned flags) { |
92 | 116M | void* p; |
93 | 116M | if (flags & SK_MALLOC_ZERO_INITIALIZE) { |
94 | 371k | p = calloc(size, 1); |
95 | 115M | } else { |
96 | | #if defined(SK_BUILD_FOR_ANDROID_FRAMEWORK) && defined(__BIONIC__) |
97 | | /* TODO: After b/169449588 is fixed, we will want to change this to restore |
98 | | * original behavior instead of always disabling the flag. |
99 | | * TODO: After b/158870657 is fixed and scudo is used globally, we can assert when an |
100 | | * an error is returned. |
101 | | */ |
102 | | // malloc() generally doesn't initialize its memory and that's a huge security hole, |
103 | | // so Android has replaced its malloc() with one that zeros memory, |
104 | | // but that's a huge performance hit for HWUI, so turn it back off again. |
105 | | (void)mallopt(M_THREAD_DISABLE_MEM_INIT, 1); |
106 | | #endif |
107 | 115M | p = malloc(size); |
108 | | #if defined(SK_BUILD_FOR_ANDROID_FRAMEWORK) && defined(__BIONIC__) |
109 | | (void)mallopt(M_THREAD_DISABLE_MEM_INIT, 0); |
110 | | #endif |
111 | 115M | } |
112 | 116M | if (flags & SK_MALLOC_THROW) { |
113 | 97.9M | return throw_on_failure(size, p); |
114 | 97.9M | } else { |
115 | 18.2M | return p; |
116 | 18.2M | } |
117 | 116M | } |
118 | | |
119 | 63.6M | size_t sk_malloc_size(void* addr, size_t size) { |
120 | 63.6M | size_t completeSize = size; |
121 | | |
122 | | // Use the OS specific calls to find the actual capacity. |
123 | | #if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS) |
124 | | // TODO: remove the max, when the chrome implementation of malloc_size doesn't return 0. |
125 | | completeSize = std::max(malloc_size(addr), size); |
126 | | #elif defined(SK_BUILD_FOR_ANDROID) && __ANDROID_API__ >= 17 |
127 | | completeSize = malloc_usable_size(addr); |
128 | | SkASSERT(completeSize >= size); |
129 | | #elif defined(SK_BUILD_FOR_UNIX) |
130 | | completeSize = malloc_usable_size(addr); |
131 | 63.6M | SkASSERT(completeSize >= size); |
132 | | #elif defined(SK_BUILD_FOR_WIN) |
133 | | completeSize = _msize(addr); |
134 | | SkASSERT(completeSize >= size); |
135 | | #endif |
136 | | |
137 | 63.6M | return completeSize; |
138 | 63.6M | } sk_malloc_size(void*, unsigned long) Line | Count | Source | 119 | 63.6M | size_t sk_malloc_size(void* addr, size_t size) { | 120 | 63.6M | size_t completeSize = size; | 121 | | | 122 | | // Use the OS specific calls to find the actual capacity. | 123 | | #if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS) | 124 | | // TODO: remove the max, when the chrome implementation of malloc_size doesn't return 0. | 125 | | completeSize = std::max(malloc_size(addr), size); | 126 | | #elif defined(SK_BUILD_FOR_ANDROID) && __ANDROID_API__ >= 17 | 127 | | completeSize = malloc_usable_size(addr); | 128 | | SkASSERT(completeSize >= size); | 129 | | #elif defined(SK_BUILD_FOR_UNIX) | 130 | | completeSize = malloc_usable_size(addr); | 131 | 63.6M | SkASSERT(completeSize >= size); | 132 | | #elif defined(SK_BUILD_FOR_WIN) | 133 | | completeSize = _msize(addr); | 134 | | SkASSERT(completeSize >= size); | 135 | | #endif | 136 | | | 137 | 63.6M | return completeSize; | 138 | 63.6M | } |
sk_malloc_size(void*, unsigned long) Line | Count | Source | 119 | 20 | size_t sk_malloc_size(void* addr, size_t size) { | 120 | 20 | size_t completeSize = size; | 121 | | | 122 | | // Use the OS specific calls to find the actual capacity. | 123 | | #if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS) | 124 | | // TODO: remove the max, when the chrome implementation of malloc_size doesn't return 0. | 125 | | completeSize = std::max(malloc_size(addr), size); | 126 | | #elif defined(SK_BUILD_FOR_ANDROID) && __ANDROID_API__ >= 17 | 127 | | completeSize = malloc_usable_size(addr); | 128 | | SkASSERT(completeSize >= size); | 129 | | #elif defined(SK_BUILD_FOR_UNIX) | 130 | | completeSize = malloc_usable_size(addr); | 131 | 20 | SkASSERT(completeSize >= size); | 132 | | #elif defined(SK_BUILD_FOR_WIN) | 133 | | completeSize = _msize(addr); | 134 | | SkASSERT(completeSize >= size); | 135 | | #endif | 136 | | | 137 | 20 | return completeSize; | 138 | 20 | } |
|