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