#ifndef __MALLOC_REPLAY_H
#define __MALLOC_REPLAY_H
#include "trace.h"
#include <vector>
#define MALLOC_EVENTS_TAG (uint32_t)0xe001e001
#define MALLOC_EVENTS_V_MAJOR 1
#define MALLOC_EVENTS_V_MINOR 1
enum operation {
op_malloc = 0x01,
op_free = 0x02,
op_realloc = 0x03,
op_memalign = 0x04,
op_calloc = 0x05,
op_valloc = 0x06,
};
static const int operation_count = op_valloc;
static const char *mcall_names[] = {"malloc", "free", "realloc", "memalign", "calloc", "valloc"};
static inline const char *
mcall_to_name(int call_num) {
if (call_num > 0 && call_num <= operation_count) {
return mcall_names[call_num - 1];
}
return NULL;
}
enum flags {
flag_stacks = 0x00000001,
flag_timestamps = 0x00000002
};
struct compressed_header {
uint16_t version;
uint64_t flags;
} __attribute__((packed));
struct compressed_operation {
uint8_t opcode;
uint8_t core;
uint32_t body[];
}__attribute__((packed));
struct compressed_alloc {
uint64_t address;
uint32_t size;
} __attribute__((packed));
struct compressed_calloc {
uint64_t address;
uint32_t count;
uint32_t size;
} __attribute__((packed));
struct compressed_memalign {
uint64_t address;
uint32_t alignment;
uint32_t size;
} __attribute__((packed));
struct compressed_free {
uint64_t address;
} __attribute__((packed));
struct compressed_realloc {
uint64_t oldAddress;
uint64_t newAddress;
uint32_t size;
} __attribute__((packed));
struct compressed_stack_key {
uint64_t stackKey;
} __attribute__((packed));
struct compressed_time {
uint64_t timestamp;
} __attribute__((packed));
extern malloc_zone_t* s_zone;
template <class T>
class ReplayAllocator {
public:
typedef T value_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
template <class U>
struct rebind {
typedef ReplayAllocator<U> other;
};
pointer address (reference value) const
{
return &value;
}
const_pointer address (const_reference value) const
{
return &value;
}
ReplayAllocator() throw() { }
ReplayAllocator(const ReplayAllocator&) throw() { }
template <class U>
ReplayAllocator (const ReplayAllocator<U>&) throw() { }
~ReplayAllocator() throw() { }
size_type max_size () const throw()
{
return std::numeric_limits<std::size_t>::max() / sizeof(T);
}
pointer allocate (size_type num, const void* = 0)
{
return (pointer)malloc_zone_malloc(s_zone, num * sizeof(T));
}
void construct (pointer p, const T& value)
{
new((void*)p)T(value);
}
void destroy (pointer p)
{
p->~T();
}
void deallocate (pointer p, size_type num)
{
malloc_zone_free(s_zone, p);
}
};
template <class T1, class T2>
bool operator== (const ReplayAllocator<T1>&,
const ReplayAllocator<T2>&) throw()
{
return true;
}
template <class T1, class T2>
bool operator!= (const ReplayAllocator<T1>&,
const ReplayAllocator<T2>&) throw()
{
return false;
}
typedef struct replay_malloc_magazine {
uint64_t baseAddress;
uint64_t extent;
uint32_t pages_resident;
uint32_t pages_dirty;
} *replay_malloc_magazine_t;
typedef struct replay_malloc_zone {
const char* name;
std::vector<replay_malloc_magazine, ReplayAllocator<replay_malloc_magazine> > magazines;
} *replay_malloc_zone_t;
#endif // __MALLOC_REPLAY_H