diff --git a/src/common.h b/src/common.h
index 2303030f..fee6d8fe 100644
--- a/src/common.h
+++ b/src/common.h
@@ -36,11 +36,13 @@
#define DEBUG_DIS_EXEC 0
#define DEBUG_DIS_EXEC_MIN 1
#define DEBUG_CEVAL_STEP 0
-#define DEBUG_FULL_EXCEPTION 1
+#define DEBUG_FULL_EXCEPTION 0
#define DEBUG_MEMORY_POOL 0
#define DEBUG_NO_AUTO_GC 0
#define DEBUG_GC_STATS 0
+#define DEBUG_FRAME_USE_POOL 1
+
#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 7b162f43..69f02cd3 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -1,6 +1,7 @@
#pragma once
#include "codeobject.h"
+#include "memory.h"
#include "vector.h"
namespace pkpy{
@@ -166,4 +167,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
+
}; // namespace pkpy
\ No newline at end of file
diff --git a/src/memory.h b/src/memory.h
index 24d78f90..e5d8255f 100644
--- a/src/memory.h
+++ b/src/memory.h
@@ -231,6 +231,8 @@ struct MemoryPool{
DoubleLinkedList _empty_arenas;
DoubleLinkedList _full_arenas;
+ static constexpr int FULL_ARENA_SIZE = 4;
+
template
void* alloc() { return alloc(sizeof(__T)); }
@@ -272,9 +274,9 @@ struct MemoryPool{
arena->dealloc(block);
}else{
arena->dealloc(block);
- if(arena->full()){ // && _arenas.size() > 2
+ if(arena->full() && _arenas.size()>2){
_arenas.erase(arena);
- if(_full_arenas.size() < 8){
+ if(_full_arenas.size() < FULL_ARENA_SIZE){
_full_arenas.push_back(arena);
}else{
delete arena;
diff --git a/src/obj.h b/src/obj.h
index d5cbca40..8d9fe55d 100644
--- a/src/obj.h
+++ b/src/obj.h
@@ -160,7 +160,10 @@ Str obj_type_name(VM* vm, Type type);
const int kTpIntIndex = 2;
const int kTpFloatIndex = 3;
-inline bool is_type(PyObject* obj, Type type) noexcept {
+inline bool is_type(PyObject* obj, Type type) {
+#if DEBUG_EXTRA_CHECK
+ if(obj == nullptr) throw std::runtime_error("is_type() called with nullptr");
+#endif
switch(type.index){
case kTpIntIndex: return is_int(obj);
case kTpFloatIndex: return is_float(obj);
diff --git a/src/vector.h b/src/vector.h
index 25b21e0b..8caeb362 100644
--- a/src/vector.h
+++ b/src/vector.h
@@ -56,8 +56,12 @@ struct pod_vector{
void reserve(int cap){
if(cap < _capacity) return;
_capacity = cap;
- if(_data!=nullptr) pool128.dealloc(_data);
+ T* old_data = _data;
_data = (T*)pool128.alloc(_capacity * sizeof(T));
+ if(old_data!=nullptr){
+ memcpy(_data, old_data, sizeof(T) * _size);
+ pool128.dealloc(old_data);
+ }
}
void pop_back() { _size--; }
diff --git a/src/vm.h b/src/vm.h
index fa51dcea..7cf26ce9 100644
--- a/src/vm.h
+++ b/src/vm.h
@@ -4,8 +4,10 @@
#include "frame.h"
#include "error.h"
#include "gc.h"
+#include "memory.h"
#include "obj.h"
#include "str.h"
+#include
namespace pkpy{
@@ -31,10 +33,10 @@ Str _read_file_cwd(const Str& name, bool* ok);
class Generator: public BaseIter {
- std::unique_ptr frame;
+ Frame_ frame;
int state; // 0,1,2
public:
- Generator(VM* vm, std::unique_ptr&& frame)
+ Generator(VM* vm, Frame_&& frame)
: BaseIter(vm), frame(std::move(frame)), state(0) {}
PyObject* next() override;
@@ -51,7 +53,7 @@ class VM {
VM* vm; // self reference for simplify code
public:
ManagedHeap heap;
- stack< std::unique_ptr > callstack;
+ stack< Frame_ > callstack;
std::vector _all_types;
PyObject* run_frame(Frame* frame);
@@ -183,11 +185,16 @@ public:
}
template
- std::unique_ptr _new_frame(Args&&... args){
+ Frame_ _new_frame(Args&&... args){
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
}
template