diff --git a/benchmarks/fib.py b/benchmarks/fib.py
index 377a1a87..1bb89670 100644
--- a/benchmarks/fib.py
+++ b/benchmarks/fib.py
@@ -3,4 +3,6 @@ def fib(n):
return n
return fib(n-1) + fib(n-2)
-assert fib(32) == 2178309
\ No newline at end of file
+assert fib(32) == 2178309
+
+# 7049155 calls
\ No newline at end of file
diff --git a/run_profile.sh b/run_profile.sh
new file mode 100644
index 00000000..d345e39c
--- /dev/null
+++ b/run_profile.sh
@@ -0,0 +1,5 @@
+# THIS SCRIPT IS NOT WORKING
+clang++ -pg -O2 -std=c++17 -fno-rtti -stdlib=libc++ -Wall -o pocketpy src/main.cpp
+time ./pocketpy benchmarks/fib.py
+gprof pocketpy gmon.out > gprof.txt
+rm gmon.out
\ No newline at end of file
diff --git a/src/common.h b/src/common.h
index 8717cba5..5a41d237 100644
--- a/src/common.h
+++ b/src/common.h
@@ -41,8 +41,6 @@
#define DEBUG_NO_AUTO_GC 0
#define DEBUG_GC_STATS 0
-#define DEBUG_FRAME_USE_POOL 0
-
#if (defined(__ANDROID__) && __ANDROID_API__ <= 22) || defined(__EMSCRIPTEN__)
#define PK_ENABLE_FILEIO 0
#else
diff --git a/src/frame.h b/src/frame.h
index 70d11921..ec253a36 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -163,11 +163,12 @@ struct Frame {
};
-#if DEBUG_FRAME_USE_POOL
-inline void frame_deleter (Frame* p) { pool256.dealloc(p); }
-using Frame_ = std::unique_ptr;
-#else
-using Frame_ = std::unique_ptr;
-#endif
+struct FrameDeleter{
+ void operator()(Frame* frame) const {
+ frame->~Frame();
+ pool128.dealloc(frame);
+ }
+};
+using Frame_ = std::unique_ptr;
}; // namespace pkpy
\ No newline at end of file
diff --git a/src/gc.h b/src/gc.h
index 4cb16eab..74739fa2 100644
--- a/src/gc.h
+++ b/src/gc.h
@@ -11,11 +11,9 @@ struct ManagedHeap{
std::vector _no_gc;
std::vector gen;
VM* vm;
- MemoryPool<> pool;
-
ManagedHeap(VM* vm): vm(vm) {}
- static const int kMinGCThreshold = 4096;
+ static const int kMinGCThreshold = 3072;
int gc_threshold = kMinGCThreshold;
int gc_counter = 0;
@@ -39,7 +37,7 @@ struct ManagedHeap{
template
PyObject* gcnew(Type type, T&& val){
using __T = Py_>;
- PyObject* obj = new(pool.alloc<__T>()) __T(type, std::forward(val));
+ PyObject* obj = new(pool128.alloc<__T>()) __T(type, std::forward(val));
gen.push_back(obj);
gc_counter++;
return obj;
@@ -48,7 +46,7 @@ struct ManagedHeap{
template
PyObject* _new(Type type, T&& val){
using __T = Py_>;
- PyObject* obj = new(pool.alloc<__T>()) __T(type, std::forward(val));
+ PyObject* obj = new(pool128.alloc<__T>()) __T(type, std::forward(val));
obj->gc.enabled = false;
_no_gc.push_back(obj);
return obj;
@@ -59,7 +57,7 @@ struct ManagedHeap{
#endif
~ManagedHeap(){
- for(PyObject* obj: _no_gc) obj->~PyObject(), pool.dealloc(obj);
+ for(PyObject* obj: _no_gc) obj->~PyObject(), pool128.dealloc(obj);
#if DEBUG_GC_STATS
for(auto& [type, count]: deleted){
std::cout << "GC: " << obj_type_name(vm, type) << "=" << count << std::endl;
@@ -77,7 +75,7 @@ struct ManagedHeap{
#if DEBUG_GC_STATS
deleted[obj->type] += 1;
#endif
- obj->~PyObject(), pool.dealloc(obj);
+ obj->~PyObject(), pool128.dealloc(obj);
}
}
diff --git a/src/memory.h b/src/memory.h
index e5d8255f..6b1f8278 100644
--- a/src/memory.h
+++ b/src/memory.h
@@ -210,6 +210,13 @@ struct MemoryPool{
bool empty() const { return _free_list_size == 0; }
bool full() const { return _free_list_size == __MaxBlocks; }
+ void tidy(){
+#if DEBUG_MEMORY_POOL
+ if(!full()) throw std::runtime_error("Arena::tidy() called on non-full arena");
+#endif
+ std::sort(_free_list, _free_list+__MaxBlocks);
+ }
+
Block* alloc(){
#if DEBUG_MEMORY_POOL
if(empty()) throw std::runtime_error("Arena::alloc() called on empty arena");
@@ -244,6 +251,7 @@ struct MemoryPool{
}
if(_arenas.empty()){
+ // std::cout << _arenas.size() << ',' << _empty_arenas.size() << ',' << _full_arenas.size() << std::endl;
if(_full_arenas.empty()){
_arenas.push_back(new Arena());
}else{
@@ -277,6 +285,7 @@ struct MemoryPool{
if(arena->full() && _arenas.size()>2){
_arenas.erase(arena);
if(_full_arenas.size() < FULL_ARENA_SIZE){
+ // arena->tidy();
_full_arenas.push_back(arena);
}else{
delete arena;
@@ -287,9 +296,6 @@ struct MemoryPool{
}
~MemoryPool(){
- // std::cout << _arenas.size() << std::endl;
- // std::cout << _empty_arenas.size() << std::endl;
- // std::cout << _full_arenas.size() << std::endl;
_arenas.apply([](Arena* arena){ delete arena; });
_empty_arenas.apply([](Arena* arena){ delete arena; });
_full_arenas.apply([](Arena* arena){ delete arena; });
@@ -298,6 +304,6 @@ struct MemoryPool{
inline MemoryPool<64> pool64;
inline MemoryPool<128> pool128;
-inline MemoryPool<256> pool256;
+// inline MemoryPool<256> pool256;
}; // namespace pkpy
diff --git a/src/vm.h b/src/vm.h
index f694e3a1..da085687 100644
--- a/src/vm.h
+++ b/src/vm.h
@@ -189,12 +189,8 @@ public:
if(callstack.size() > recursionlimit){
_error("RecursionError", "maximum recursion depth exceeded");
}
-#if DEBUG_FRAME_USE_POOL
- Frame* frame = new(pool256.alloc(sizeof(Frame))) Frame(std::forward(args)...);
- return Frame_(frame, &frame_deleter);
-#else
- return std::make_unique(std::forward(args)...);
-#endif
+ Frame* frame = new(pool128.alloc()) Frame(std::forward(args)...);
+ return Frame_(frame);
}
template