cpp

Coverage Report

Created: 2024-03-13 14:13

/home/andy/git/oilshell/oil/mycpp/bump_leak_heap.cc
Line
Count
Source
1
// mycpp/bump_leak_heap.cc: Leaky Bump Allocator
2
3
#include "mycpp/bump_leak_heap.h"
4
5
#include <inttypes.h>  // PRId64
6
#include <stddef.h>
7
#include <stdio.h>
8
#include <string.h>  // memcpy
9
#include <unistd.h>  // STDERR_FILENO
10
11
#include "mycpp/common.h"  // aligned
12
13
// We need this #ifdef because we don't want the global var in other binaries
14
15
#if defined(BUMP_LEAK) || defined(BUMP_SMALL) || defined(BUMP_BIG)
16
17
// some benchmarks take more than 1 GiB
18
// but cachegrind can't work with static data of 2 GiB (get mmap() error)
19
char gMemory[MiB(1400)];
20
21
// This type is for "layout"; it's not instantiated
22
struct LayoutBlock {
23
  size_t num_bytes;
24
  char data[1];  // flexible array
25
};
26
27
// offsetof() accounts for possible padding, but it should equal sizeof(size_t)
28
const int kHeaderSize = offsetof(LayoutBlock, data);
29
30
// Allocate() bumps a pointer
31
4
void* BumpLeakHeap::Allocate(size_t num_bytes) {
32
4
  char* p = &(gMemory[mem_pos_]);
33
4
  LayoutBlock* block = reinterpret_cast<LayoutBlock*>(p);
34
4
  block->num_bytes = num_bytes;  // record size for Reallocate()
35
36
4
  mem_pos_ += aligned(kHeaderSize + num_bytes);
37
38
  // Update stats
39
4
  num_allocated_++;
40
4
  bytes_allocated_ += num_bytes;
41
42
  // log("Allocate() -> %p", block->data);
43
4
  return block->data;  // pointer user can write to
44
4
}
45
46
// Reallocate() calls Allocate() and then copies the old data
47
2
void* BumpLeakHeap::Reallocate(void* old_data, size_t num_bytes) {
48
  // log("");
49
  // log("Reallocate(%d) got %p", num_bytes, old_data);
50
2
  char* new_data = reinterpret_cast<char*>(Allocate(num_bytes));
51
52
2
  char* p_old = reinterpret_cast<char*>(old_data) - kHeaderSize;
53
2
  LayoutBlock* old_block = reinterpret_cast<LayoutBlock*>(p_old);
54
55
2
  memcpy(new_data, old_block->data, old_block->num_bytes);
56
57
2
  return new_data;
58
2
}
59
60
4
void BumpLeakHeap::PrintStats(int fd) {
61
4
  dprintf(fd, "[BumpLeakHeap]");
62
  #ifdef BUMP_ROOT
63
  dprintf(fd, "      max roots = %10d\n", max_roots_);
64
  #endif
65
4
  dprintf(fd, "  num allocated = %10d\n", num_allocated_);
66
4
  dprintf(fd, "bytes allocated = %10" PRId64 "\n", bytes_allocated_);
67
4
  dprintf(fd, "  mem pos       = %10d\n", mem_pos_);
68
4
}
69
70
2
void BumpLeakHeap::CleanProcessExit() {
71
2
  PrintStats(STDERR_FILENO);
72
2
}
73
74
1
void BumpLeakHeap::ProcessExit() {
75
1
  PrintStats(STDERR_FILENO);
76
1
}
77
#endif
78
79
#ifdef BUMP_LEAK
80
BumpLeakHeap gHeap;
81
#endif