blueloveTH 2 лет назад
Родитель
Сommit
95c3644dc2
6 измененных файлов с 36 добавлено и 9 удалено
  1. 3 1
      src/common.h
  2. 9 0
      src/frame.h
  3. 4 2
      src/memory.h
  4. 4 1
      src/obj.h
  5. 5 1
      src/vector.h
  6. 11 4
      src/vm.h

+ 3 - 1
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

+ 9 - 0
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<Frame, decltype(&frame_deleter)>;
+#else
+using Frame_ = std::unique_ptr<Frame>;
+#endif
+
 }; // namespace pkpy

+ 4 - 2
src/memory.h

@@ -231,6 +231,8 @@ struct MemoryPool{
     DoubleLinkedList<Arena> _empty_arenas;
     DoubleLinkedList<Arena> _full_arenas;
 
+    static constexpr int FULL_ARENA_SIZE = 4;
+
     template<typename __T>
     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;

+ 4 - 1
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);

+ 5 - 1
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--; }

+ 11 - 4
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 <memory>
 
 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_ frame;
     int state; // 0,1,2
 public:
-    Generator(VM* vm, std::unique_ptr<Frame>&& 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<Frame> > callstack;
+    stack< Frame_ > callstack;
     std::vector<PyTypeInfo> _all_types;
 
     PyObject* run_frame(Frame* frame);
@@ -183,11 +185,16 @@ public:
     }
 
     template<typename ...Args>
-    std::unique_ptr<Frame> _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>(args)...);
+        return Frame_(frame, &frame_deleter);
+#else
         return std::make_unique<Frame>(std::forward<Args>(args)...);
+#endif
     }
 
     template<typename ...Args>