mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 11:30:18 +00:00
up
This commit is contained in:
parent
e03ce955fc
commit
ef3e172fbd
@ -4,3 +4,5 @@ def fib(n):
|
||||
return fib(n-1) + fib(n-2)
|
||||
|
||||
assert fib(32) == 2178309
|
||||
|
||||
# 7049155 calls
|
5
run_profile.sh
Normal file
5
run_profile.sh
Normal file
@ -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
|
@ -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
|
||||
|
13
src/frame.h
13
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<Frame, decltype(&frame_deleter)>;
|
||||
#else
|
||||
using Frame_ = std::unique_ptr<Frame>;
|
||||
#endif
|
||||
struct FrameDeleter{
|
||||
void operator()(Frame* frame) const {
|
||||
frame->~Frame();
|
||||
pool128.dealloc(frame);
|
||||
}
|
||||
};
|
||||
using Frame_ = std::unique_ptr<Frame, FrameDeleter>;
|
||||
|
||||
}; // namespace pkpy
|
12
src/gc.h
12
src/gc.h
@ -11,11 +11,9 @@ struct ManagedHeap{
|
||||
std::vector<PyObject*> _no_gc;
|
||||
std::vector<PyObject*> 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<typename T>
|
||||
PyObject* gcnew(Type type, T&& val){
|
||||
using __T = Py_<std::decay_t<T>>;
|
||||
PyObject* obj = new(pool.alloc<__T>()) __T(type, std::forward<T>(val));
|
||||
PyObject* obj = new(pool128.alloc<__T>()) __T(type, std::forward<T>(val));
|
||||
gen.push_back(obj);
|
||||
gc_counter++;
|
||||
return obj;
|
||||
@ -48,7 +46,7 @@ struct ManagedHeap{
|
||||
template<typename T>
|
||||
PyObject* _new(Type type, T&& val){
|
||||
using __T = Py_<std::decay_t<T>>;
|
||||
PyObject* obj = new(pool.alloc<__T>()) __T(type, std::forward<T>(val));
|
||||
PyObject* obj = new(pool128.alloc<__T>()) __T(type, std::forward<T>(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);
|
||||
}
|
||||
}
|
||||
|
||||
|
14
src/memory.h
14
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
|
||||
|
8
src/vm.h
8
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>(args)...);
|
||||
return Frame_(frame, &frame_deleter);
|
||||
#else
|
||||
return std::make_unique<Frame>(std::forward<Args>(args)...);
|
||||
#endif
|
||||
Frame* frame = new(pool128.alloc<Frame>()) Frame(std::forward<Args>(args)...);
|
||||
return Frame_(frame);
|
||||
}
|
||||
|
||||
template<typename ...Args>
|
||||
|
Loading…
x
Reference in New Issue
Block a user