1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc.
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */
7f20488b4f2139e6ca09fee7e39b731dd8ab467dbbungeman
87edde238f741b7954a18797e88dcd04b59d79d2fMike Reed#include "SkMalloc.h"
9f20488b4f2139e6ca09fee7e39b731dd8ab467dbbungeman
10d7b34a5ca0a9183e70737125c688d2a8b5310d81Herb Derby#include <cstdlib>
117a561082645315215949fb7ad9c80c883ffd89adreed@android.com
1261b1436c224482611b864bff354b2664772b1b62halcanary#define SK_DEBUGFAILF(fmt, ...) \
1361b1436c224482611b864bff354b2664772b1b62halcanary    SkASSERT((SkDebugf(fmt"\n", __VA_ARGS__), false))
1461b1436c224482611b864bff354b2664772b1b62halcanary
1561b1436c224482611b864bff354b2664772b1b62halcanarystatic inline void sk_out_of_memory(size_t size) {
1661b1436c224482611b864bff354b2664772b1b62halcanary    SK_DEBUGFAILF("sk_out_of_memory (asked for " SK_SIZE_T_SPECIFIER " bytes)",
1761b1436c224482611b864bff354b2664772b1b62halcanary                  size);
182416f968a69ff71f83eb17e97d1cb6448c916a69Kevin Lubick#if defined(IS_FUZZING_WITH_AFL)
19edee1ae9e3b87983ed0ff0ea55b3c49892901260Kevin Lubick    exit(1);
20edee1ae9e3b87983ed0ff0ea55b3c49892901260Kevin Lubick#else
2161b1436c224482611b864bff354b2664772b1b62halcanary    abort();
22edee1ae9e3b87983ed0ff0ea55b3c49892901260Kevin Lubick#endif
2361b1436c224482611b864bff354b2664772b1b62halcanary}
2461b1436c224482611b864bff354b2664772b1b62halcanary
25dd6cde5235d5d36607f4f1df66057d807b432b99commit-bot@chromium.orgstatic inline void* throw_on_failure(size_t size, void* p) {
2696fcdcc219d2a0d3579719b84b28bede76efba64halcanary    if (size > 0 && p == nullptr) {
2796fcdcc219d2a0d3579719b84b28bede76efba64halcanary        // If we've got a nullptr here, the only reason we should have failed is running out of RAM.
2861b1436c224482611b864bff354b2664772b1b62halcanary        sk_out_of_memory(size);
29519f9677a41239808f41a7c13ef1f6e05eb1ed50mtklein@google.com    }
30519f9677a41239808f41a7c13ef1f6e05eb1ed50mtklein@google.com    return p;
31519f9677a41239808f41a7c13ef1f6e05eb1ed50mtklein@google.com}
32519f9677a41239808f41a7c13ef1f6e05eb1ed50mtklein@google.com
33f2b340fc885ad2a12d2d73974eff9c8f4c94192cdjsollenvoid sk_abort_no_print() {
34ad514d00e5a65dadf9040d0cde4b897f565b5c19bsalomon#if defined(SK_BUILD_FOR_WIN) && defined(SK_IS_BOT)
356b48984333029f2ad94a06339b2329bda8ee09badjsollen    // do not display a system dialog before aborting the process
366b48984333029f2ad94a06339b2329bda8ee09badjsollen    _set_abort_behavior(0, _WRITE_ABORT_MSG);
376b48984333029f2ad94a06339b2329bda8ee09badjsollen#endif
381f790aaeef47b02fe72b9b62d1e8c7ead85ae442bungeman#if defined(SK_DEBUG) && defined(SK_BUILD_FOR_WIN)
391f790aaeef47b02fe72b9b62d1e8c7ead85ae442bungeman    __debugbreak();
401f790aaeef47b02fe72b9b62d1e8c7ead85ae442bungeman#else
417a561082645315215949fb7ad9c80c883ffd89adreed@android.com    abort();
421f790aaeef47b02fe72b9b62d1e8c7ead85ae442bungeman#endif
437a561082645315215949fb7ad9c80c883ffd89adreed@android.com}
447a561082645315215949fb7ad9c80c883ffd89adreed@android.com
457a561082645315215949fb7ad9c80c883ffd89adreed@android.comvoid sk_out_of_memory(void) {
460c00f21fee3f5cfa3aa7e5d46ff94cb8cf340451tomhudson@google.com    SkDEBUGFAIL("sk_out_of_memory");
4754f20e0df694d0428442827bd0534afd579682ceKevin Lubick#if defined(IS_FUZZING_WITH_AFL)
48edee1ae9e3b87983ed0ff0ea55b3c49892901260Kevin Lubick    exit(1);
49edee1ae9e3b87983ed0ff0ea55b3c49892901260Kevin Lubick#else
507a561082645315215949fb7ad9c80c883ffd89adreed@android.com    abort();
51edee1ae9e3b87983ed0ff0ea55b3c49892901260Kevin Lubick#endif
527a561082645315215949fb7ad9c80c883ffd89adreed@android.com}
537a561082645315215949fb7ad9c80c883ffd89adreed@android.com
547a561082645315215949fb7ad9c80c883ffd89adreed@android.comvoid* sk_realloc_throw(void* addr, size_t size) {
55dd6cde5235d5d36607f4f1df66057d807b432b99commit-bot@chromium.org    return throw_on_failure(size, realloc(addr, size));
567a561082645315215949fb7ad9c80c883ffd89adreed@android.com}
577a561082645315215949fb7ad9c80c883ffd89adreed@android.com
587a561082645315215949fb7ad9c80c883ffd89adreed@android.comvoid sk_free(void* p) {
597a561082645315215949fb7ad9c80c883ffd89adreed@android.com    if (p) {
607a561082645315215949fb7ad9c80c883ffd89adreed@android.com        free(p);
617a561082645315215949fb7ad9c80c883ffd89adreed@android.com    }
627a561082645315215949fb7ad9c80c883ffd89adreed@android.com}
637a561082645315215949fb7ad9c80c883ffd89adreed@android.com
647a561082645315215949fb7ad9c80c883ffd89adreed@android.comvoid* sk_malloc_flags(size_t size, unsigned flags) {
658dc8dbc8211e7b0245a6e7db911265efbe0fccafMike Reed    void* p;
668dc8dbc8211e7b0245a6e7db911265efbe0fccafMike Reed    if (flags & SK_MALLOC_ZERO_INITIALIZE) {
678dc8dbc8211e7b0245a6e7db911265efbe0fccafMike Reed        p = calloc(size, 1);
688dc8dbc8211e7b0245a6e7db911265efbe0fccafMike Reed    } else {
698dc8dbc8211e7b0245a6e7db911265efbe0fccafMike Reed        p = malloc(size);
708dc8dbc8211e7b0245a6e7db911265efbe0fccafMike Reed    }
71519f9677a41239808f41a7c13ef1f6e05eb1ed50mtklein@google.com    if (flags & SK_MALLOC_THROW) {
72dd6cde5235d5d36607f4f1df66057d807b432b99commit-bot@chromium.org        return throw_on_failure(size, p);
73519f9677a41239808f41a7c13ef1f6e05eb1ed50mtklein@google.com    } else {
74519f9677a41239808f41a7c13ef1f6e05eb1ed50mtklein@google.com        return p;
757a561082645315215949fb7ad9c80c883ffd89adreed@android.com    }
76519f9677a41239808f41a7c13ef1f6e05eb1ed50mtklein@google.com}
77