Commit 7335a850 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Add a simple region-allocator for the Rewriter

ie a simple bump-pointer allocator that will release all
of its memory when the rewrite itself gets deallocated.

Not a huge help itself, since most of the mallocs have been removed
from the rewriter, except for the std::functions which don't take
a custom allocator (at least not in libstdc++ 4.8 [and 4.9 I think]).
parent 08fe3815
......@@ -961,7 +961,7 @@ test_cpp_dwarf:
objdump -W test_asm | less
rm test_asm
test_cpp_ll:
$(CLANGPP_EXE) $(TEST_DIR)/test.cpp -o test.ll -c -O3 -emit-llvm -S -std=c++11 -g
$(CLANGPP_EXE) $(TEST_DIR)/test.cpp -o test.ll -c -O3 -emit-llvm -S -std=c++11
less test.ll
rm test.ll
.PHONY: bench_exceptions
......
......@@ -2128,4 +2128,16 @@ PatchpointInitializationInfo initializePatchpoint3(void* slowpath_func, uint8_t*
return PatchpointInitializationInfo(slowpath_start, slowpath_rtn_addr, continue_addr,
std::move(live_outs_for_slot));
}
void* Rewriter::RegionAllocator::alloc(size_t bytes) {
assert(bytes <= BLOCK_SIZE);
if (cur_offset + bytes > BLOCK_SIZE) {
blocks.emplace_back();
cur_offset = 0;
}
char* rtn = blocks.back() + cur_offset;
cur_offset += bytes;
return rtn;
}
}
......@@ -296,7 +296,34 @@ enum class ActionType { NORMAL, GUARD, MUTATION };
#define LOCATION_PLACEHOLDER ((RewriterVar*)1)
class Rewriter : public ICSlotRewrite::CommitHook {
private:
class RegionAllocator {
public:
static const int BLOCK_SIZE = 200; // reserve a bit of space for list/malloc overhead
std::list<char[BLOCK_SIZE]> blocks;
int cur_offset = BLOCK_SIZE + 1;
void* alloc(size_t bytes);
};
template <typename T> class RegionAllocatorAdaptor : public std::allocator<T> {
private:
RegionAllocator* allocator;
public:
T* allocate(size_t n) { return (T*)allocator->alloc(n); }
void deallocate(T* p, size_t n) {
// do nothing
}
};
// This needs to be the first member:
RegionAllocator allocator;
protected:
// Allocates `bytes` bytes of data. The allocation will get freed when the rewriter gets freed.
void* regionAlloc(size_t bytes) { return allocator.alloc(bytes); }
// Helps generating the best code for loading a const integer value.
// By keeping track of the last known value of every register and reusing it.
class ConstLoader {
......@@ -357,8 +384,8 @@ protected:
Rewriter(std::unique_ptr<ICSlotRewrite> rewrite, int num_args, const std::vector<int>& live_outs);
llvm::SmallVector<RewriterAction, 32> actions;
void addAction(std::function<void()> action, llvm::ArrayRef<RewriterVar*> vars, ActionType type) {
std::deque<RewriterAction, RegionAllocatorAdaptor<RewriterAction>> actions;
template <typename F> void addAction(F&& action, llvm::ArrayRef<RewriterVar*> vars, ActionType type) {
assertPhaseCollecting();
for (RewriterVar* var : vars) {
assert(var != NULL);
......@@ -377,7 +404,7 @@ protected:
assert(!added_changing_action);
last_guard_action = (int)actions.size();
}
actions.emplace_back(std::move(action));
actions.emplace_back(std::forward<F>(action));
}
bool added_changing_action;
bool marked_inside_ic;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment