// memory manager. shares pages across many basic blocks.#include <vector>
using std::vector;// Provides blocksclass MM {public:MM() {
PAGE_SIZE_ = getpagesize();
}// alloc into a page aligned buffer or fail.
void alloc(void** output, int bytes) {
if (page_capacity_ < bytes) {
new_page(bytes);
}(*output) = (void*)page_offset_;
page_offset_ += bytes;page_capacity_ -= bytes;}private:void new_page(int requested) {
int bytes = requested < PAGE_SIZE_ ? PAGE_SIZE_ : requested;
if (posix_memalign((void**)&page_, PAGE_SIZE_, bytes) != 0) {
puts("memalign failed");
exit(1);
}if (page_ < 0) {
perror("memalign fail: ");
exit(1);
}// NOTE: not w^x friendly, pages are both
// writable and executable.
if (mprotect((void*)page_, bytes, PROT_EXEC | PROT_READ | PROT_WRITE) < 0) {
perror("failed to mprotect");
exit(1);
}page_capacity_ = bytes;page_offset_ = page_;}int PAGE_SIZE_;
char* page_ = nullptr;
char* page_offset_ = nullptr;
int page_capacity_ = 0;
};