mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 03:20: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)
|
return fib(n-1) + fib(n-2)
|
||||||
|
|
||||||
assert fib(32) == 2178309
|
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_NO_AUTO_GC 0
|
||||||
#define DEBUG_GC_STATS 0
|
#define DEBUG_GC_STATS 0
|
||||||
|
|
||||||
#define DEBUG_FRAME_USE_POOL 0
|
|
||||||
|
|
||||||
#if (defined(__ANDROID__) && __ANDROID_API__ <= 22) || defined(__EMSCRIPTEN__)
|
#if (defined(__ANDROID__) && __ANDROID_API__ <= 22) || defined(__EMSCRIPTEN__)
|
||||||
#define PK_ENABLE_FILEIO 0
|
#define PK_ENABLE_FILEIO 0
|
||||||
#else
|
#else
|
||||||
|
13
src/frame.h
13
src/frame.h
@ -163,11 +163,12 @@ struct Frame {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#if DEBUG_FRAME_USE_POOL
|
struct FrameDeleter{
|
||||||
inline void frame_deleter (Frame* p) { pool256.dealloc(p); }
|
void operator()(Frame* frame) const {
|
||||||
using Frame_ = std::unique_ptr<Frame, decltype(&frame_deleter)>;
|
frame->~Frame();
|
||||||
#else
|
pool128.dealloc(frame);
|
||||||
using Frame_ = std::unique_ptr<Frame>;
|
}
|
||||||
#endif
|
};
|
||||||
|
using Frame_ = std::unique_ptr<Frame, FrameDeleter>;
|
||||||
|
|
||||||
}; // namespace pkpy
|
}; // namespace pkpy
|
12
src/gc.h
12
src/gc.h
@ -11,11 +11,9 @@ struct ManagedHeap{
|
|||||||
std::vector<PyObject*> _no_gc;
|
std::vector<PyObject*> _no_gc;
|
||||||
std::vector<PyObject*> gen;
|
std::vector<PyObject*> gen;
|
||||||
VM* vm;
|
VM* vm;
|
||||||
MemoryPool<> pool;
|
|
||||||
|
|
||||||
ManagedHeap(VM* vm): vm(vm) {}
|
ManagedHeap(VM* vm): vm(vm) {}
|
||||||
|
|
||||||
static const int kMinGCThreshold = 4096;
|
static const int kMinGCThreshold = 3072;
|
||||||
int gc_threshold = kMinGCThreshold;
|
int gc_threshold = kMinGCThreshold;
|
||||||
int gc_counter = 0;
|
int gc_counter = 0;
|
||||||
|
|
||||||
@ -39,7 +37,7 @@ struct ManagedHeap{
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
PyObject* gcnew(Type type, T&& val){
|
PyObject* gcnew(Type type, T&& val){
|
||||||
using __T = Py_<std::decay_t<T>>;
|
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);
|
gen.push_back(obj);
|
||||||
gc_counter++;
|
gc_counter++;
|
||||||
return obj;
|
return obj;
|
||||||
@ -48,7 +46,7 @@ struct ManagedHeap{
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
PyObject* _new(Type type, T&& val){
|
PyObject* _new(Type type, T&& val){
|
||||||
using __T = Py_<std::decay_t<T>>;
|
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;
|
obj->gc.enabled = false;
|
||||||
_no_gc.push_back(obj);
|
_no_gc.push_back(obj);
|
||||||
return obj;
|
return obj;
|
||||||
@ -59,7 +57,7 @@ struct ManagedHeap{
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
~ManagedHeap(){
|
~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
|
#if DEBUG_GC_STATS
|
||||||
for(auto& [type, count]: deleted){
|
for(auto& [type, count]: deleted){
|
||||||
std::cout << "GC: " << obj_type_name(vm, type) << "=" << count << std::endl;
|
std::cout << "GC: " << obj_type_name(vm, type) << "=" << count << std::endl;
|
||||||
@ -77,7 +75,7 @@ struct ManagedHeap{
|
|||||||
#if DEBUG_GC_STATS
|
#if DEBUG_GC_STATS
|
||||||
deleted[obj->type] += 1;
|
deleted[obj->type] += 1;
|
||||||
#endif
|
#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 empty() const { return _free_list_size == 0; }
|
||||||
bool full() const { return _free_list_size == __MaxBlocks; }
|
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(){
|
Block* alloc(){
|
||||||
#if DEBUG_MEMORY_POOL
|
#if DEBUG_MEMORY_POOL
|
||||||
if(empty()) throw std::runtime_error("Arena::alloc() called on empty arena");
|
if(empty()) throw std::runtime_error("Arena::alloc() called on empty arena");
|
||||||
@ -244,6 +251,7 @@ struct MemoryPool{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(_arenas.empty()){
|
if(_arenas.empty()){
|
||||||
|
// std::cout << _arenas.size() << ',' << _empty_arenas.size() << ',' << _full_arenas.size() << std::endl;
|
||||||
if(_full_arenas.empty()){
|
if(_full_arenas.empty()){
|
||||||
_arenas.push_back(new Arena());
|
_arenas.push_back(new Arena());
|
||||||
}else{
|
}else{
|
||||||
@ -277,6 +285,7 @@ struct MemoryPool{
|
|||||||
if(arena->full() && _arenas.size()>2){
|
if(arena->full() && _arenas.size()>2){
|
||||||
_arenas.erase(arena);
|
_arenas.erase(arena);
|
||||||
if(_full_arenas.size() < FULL_ARENA_SIZE){
|
if(_full_arenas.size() < FULL_ARENA_SIZE){
|
||||||
|
// arena->tidy();
|
||||||
_full_arenas.push_back(arena);
|
_full_arenas.push_back(arena);
|
||||||
}else{
|
}else{
|
||||||
delete arena;
|
delete arena;
|
||||||
@ -287,9 +296,6 @@ struct MemoryPool{
|
|||||||
}
|
}
|
||||||
|
|
||||||
~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; });
|
_arenas.apply([](Arena* arena){ delete arena; });
|
||||||
_empty_arenas.apply([](Arena* arena){ delete arena; });
|
_empty_arenas.apply([](Arena* arena){ delete arena; });
|
||||||
_full_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<64> pool64;
|
||||||
inline MemoryPool<128> pool128;
|
inline MemoryPool<128> pool128;
|
||||||
inline MemoryPool<256> pool256;
|
// inline MemoryPool<256> pool256;
|
||||||
|
|
||||||
}; // namespace pkpy
|
}; // namespace pkpy
|
||||||
|
8
src/vm.h
8
src/vm.h
@ -189,12 +189,8 @@ public:
|
|||||||
if(callstack.size() > recursionlimit){
|
if(callstack.size() > recursionlimit){
|
||||||
_error("RecursionError", "maximum recursion depth exceeded");
|
_error("RecursionError", "maximum recursion depth exceeded");
|
||||||
}
|
}
|
||||||
#if DEBUG_FRAME_USE_POOL
|
Frame* frame = new(pool128.alloc<Frame>()) Frame(std::forward<Args>(args)...);
|
||||||
Frame* frame = new(pool256.alloc(sizeof(Frame))) Frame(std::forward<Args>(args)...);
|
return Frame_(frame);
|
||||||
return Frame_(frame, &frame_deleter);
|
|
||||||
#else
|
|
||||||
return std::make_unique<Frame>(std::forward<Args>(args)...);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename ...Args>
|
template<typename ...Args>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user