1/*
2 * Copyright (C) 2016-2018 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#pragma once
27
28#include "Environment.h"
29#include "Mutex.h"
30#include "StaticPerProcess.h"
31#include <mutex>
32#include <unordered_map>
33
34#if BOS(DARWIN)
35#include <malloc/malloc.h>
36#endif
37
38namespace bmalloc {
39
40class DebugHeap : private StaticPerProcess<DebugHeap> {
41public:
42 DebugHeap(std::lock_guard<Mutex>&);
43
44 void* malloc(size_t, bool crashOnFailure);
45 void* memalign(size_t alignment, size_t, bool crashOnFailure);
46 void* realloc(void*, size_t, bool crashOnFailure);
47 void free(void*);
48
49 void* memalignLarge(size_t alignment, size_t);
50 void freeLarge(void* base);
51
52 void scavenge();
53 void dump();
54
55 static DebugHeap* tryGet();
56
57private:
58#if BOS(DARWIN)
59 malloc_zone_t* m_zone;
60#endif
61
62 // This is the debug heap. We can use whatever data structures we like. It doesn't matter.
63 size_t m_pageSize { 0 };
64 std::unordered_map<void*, size_t> m_sizeMap;
65};
66DECLARE_STATIC_PER_PROCESS_STORAGE(DebugHeap);
67
68extern BEXPORT DebugHeap* debugHeapCache;
69BINLINE DebugHeap* DebugHeap::tryGet()
70{
71 if (debugHeapCache)
72 return debugHeapCache;
73 if (Environment::get()->isDebugHeapEnabled()) {
74 debugHeapCache = DebugHeap::get();
75 return debugHeapCache;
76 }
77 return nullptr;
78}
79
80} // namespace bmalloc
81