/home/uke/oil/cpp/leaky_dumb_alloc.cc
Line | Count | Source |
1 | | // dumb_alloc.cc: Test this C++ mechanism as a lower bound on performance. |
2 | | |
3 | | #include "leaky_dumb_alloc.h" |
4 | | |
5 | | #include <stdio.h> |
6 | | |
7 | | // 400 MiB of memory |
8 | | char kMem[400 << 20]; |
9 | | |
10 | | int gMemPos = 0; |
11 | | int gNumNew = 0; |
12 | | int gNumDelete = 0; |
13 | | |
14 | | // I'm not sure why this matters but we get crashes when aligning to 8 bytes. |
15 | | // That is annoying. |
16 | | // Example: we get a crash in cpp/frontend_flag_spec.cc |
17 | | // auto out = new flag_spec::_FlagSpecAndMore(); |
18 | | // |
19 | | // https://stackoverflow.com/questions/52531695/int128-alignment-segment-fault-with-gcc-o-sse-optimize |
20 | | constexpr int kMask = alignof(max_align_t) - 1; // e.g. 15 or 7 |
21 | | |
22 | | // Align returned pointers to the worst case of 8 bytes (64-bit pointers) |
23 | 201 | inline size_t aligned(size_t n) { |
24 | | // https://stackoverflow.com/questions/2022179/c-quick-calculation-of-next-multiple-of-4 |
25 | | // return (n + 7) & ~7; |
26 | | |
27 | 201 | return (n + kMask) & ~kMask; |
28 | 201 | } |
29 | | |
30 | | // This global interface is silly ... |
31 | | |
32 | | #ifdef DUMB_ALLOC |
33 | 179 | void* operator new(size_t size) { |
34 | 179 | char* p = &(kMem[gMemPos]); |
35 | | #ifdef ALLOC_LOG |
36 | | printf("new %zu\n", size); |
37 | | #endif |
38 | 179 | gMemPos += aligned(size); |
39 | 179 | ++gNumNew; |
40 | 179 | return p; |
41 | 179 | } |
42 | | |
43 | | // noexcept fixes Clang warning |
44 | 19 | void operator delete(void* p) noexcept { |
45 | | // fprintf(stderr, "\tdelete %p\n", p); |
46 | 19 | ++gNumDelete; |
47 | 19 | } |
48 | | #endif |
49 | | |
50 | | char kMem2[400 << 20]; |
51 | | int gMemPos2 = 0; |
52 | | int gNumMalloc = 0; |
53 | | int gNumFree = 0; |
54 | | |
55 | 22 | void* dumb_malloc(size_t size) noexcept { |
56 | 22 | char* p = &(kMem2[gMemPos2]); |
57 | | #ifdef ALLOC_LOG |
58 | | printf("malloc %zu\n", size); |
59 | | #endif |
60 | 22 | gMemPos2 += aligned(size); |
61 | 22 | ++gNumMalloc; |
62 | 22 | return p; |
63 | 22 | } |
64 | | |
65 | 4 | void dumb_free(void* p) noexcept { |
66 | | // fprintf(stderr, "free\n"); |
67 | 4 | ++gNumFree; |
68 | 4 | } |
69 | | |
70 | | namespace dumb_alloc { |
71 | | |
72 | 1 | void Summarize() { |
73 | | #ifdef DUMB_ALLOC_VERBOSE |
74 | | fprintf(stderr, "\n"); |
75 | | fprintf(stderr, "dumb_alloc:\n"); |
76 | | fprintf(stderr, "\tgNumNew = %d\n", gNumNew); |
77 | | fprintf(stderr, "\tgNumDelete = %d\n", gNumDelete); |
78 | | fprintf(stderr, "\tgMemPos = %d\n", gMemPos); |
79 | | fprintf(stderr, "\n"); |
80 | | fprintf(stderr, "\tgNumMalloc = %d\n", gNumMalloc); |
81 | | fprintf(stderr, "\tgNumFree = %d\n", gNumFree); |
82 | | fprintf(stderr, "\tgMemPos2 = %d\n", gMemPos2); |
83 | | #endif |
84 | 1 | } |
85 | | |
86 | | } // namespace dumb_alloc |