blueloveTH 1 year ago
parent
commit
b4a836873e

+ 1 - 1
build_g.sh

@@ -2,6 +2,6 @@ python prebuild.py
 
 SRC=$(find src/ -name "*.cpp")
 
-FLAGS="-std=c++17 -Og -stdlib=libc++ -Iinclude -frtti -Wfatal-errors -g"
+FLAGS="-std=c++17 -Og -stdlib=libc++ -Iinclude -frtti -Wfatal-errors -g -DDEBUG"
 
 clang++ $FLAGS -o main src2/main.cpp $SRC

+ 0 - 4
include/pocketpy/common/config.h

@@ -31,10 +31,6 @@
 #define PK_ENABLE_STD_FUNCTION      0
 
 /*************** debug settings ***************/
-
-// Enable this may help you find bugs
-#define PK_DEBUG_EXTRA_CHECK        0
-
 // Do not edit the following settings unless you know what you are doing
 #define PK_DEBUG_CEVAL_STEP         0
 #define PK_DEBUG_MEMORY_POOL        0

+ 11 - 0
include/pocketpy/common/memorypool.hpp

@@ -1,6 +1,9 @@
 #pragma once
 
+#include "pocketpy/common/gil.hpp"
+
 #include <cstddef>
+#include <cassert>
 #include <string>
 
 namespace pkpy{
@@ -13,4 +16,12 @@ void pools_shrink_to_fit() noexcept;
 std::string pool64_info() noexcept;
 std::string pool128_info() noexcept;
 
+inline const int kPoolExprBlockSize = 128;
+inline const int kPoolFrameBlockSize = 80;
+
+void* PoolExpr_alloc() noexcept;
+void PoolExpr_dealloc(void*) noexcept;
+void* PoolFrame_alloc() noexcept;
+void PoolFrame_dealloc(void*) noexcept;
+
 };  // namespace pkpy

+ 5 - 7
include/pocketpy/common/namedict.hpp

@@ -94,7 +94,7 @@ while(!_items[i].first.empty()) {           \
         return _items[i].second;
     }
 
-    T* try_get_2(StrName key) {
+    T* try_get_2(StrName key) const{
         bool ok; uint16_t i;
         HASH_PROBE_0(key, ok, i);
         if(!ok) return nullptr;
@@ -109,7 +109,7 @@ while(!_items[i].first.empty()) {           \
         return try_get(key);
     }
 
-    T* try_get_2_likely_found(StrName key) {
+    T* try_get_2_likely_found(StrName key) const{
         uint16_t i = key.index & _mask;
         if(_items[i].first == key) return &_items[i].second;
         i = (i + 1) & _mask;
@@ -152,13 +152,11 @@ while(!_items[i].first.empty()) {           \
     }
 
     T operator[](StrName key) const {
-        T val = try_get_likely_found(key);
-#if PK_DEBUG_EXTRA_CHECK
-        if(val == default_invalid_value<T>()){
+        T* val = try_get_2_likely_found(key);
+        if(val == nullptr){
             throw std::runtime_error(_S("NameDict key not found: ", key.escape()).str());
         }
-#endif
-        return val;
+        return *val;
     }
 
     array<StrName> keys() const {

+ 2 - 1
include/pocketpy/compiler/compiler.hpp

@@ -59,7 +59,8 @@ class Compiler {
 
     template <typename T, typename... Args>
     unique_ptr_128<T> make_expr(Args&&... args) {
-        void* p = pool128_alloc(sizeof(T));
+        static_assert(sizeof(T) <= kPoolExprBlockSize);
+        void* p = PoolExpr_alloc();
         unique_ptr_128<T> expr(new (p) T(std::forward<Args>(args)...));
         expr->line = prev().line;
         return expr;

+ 1 - 1
include/pocketpy/compiler/expr.hpp

@@ -8,7 +8,7 @@ namespace pkpy{
 struct CodeEmitContext;
 struct Expr;
 
-#define PK_POOL128_DELETE(ptr) if(ptr != nullptr) { ptr->~T(); pool128_dealloc(ptr); ptr = nullptr; }
+#define PK_POOL128_DELETE(ptr) if(ptr != nullptr) { ptr->~T(); PoolExpr_dealloc(ptr); ptr = nullptr; }
 
 template<typename T>
 class unique_ptr_128{

+ 2 - 1
include/pocketpy/interpreter/frame.hpp

@@ -147,7 +147,8 @@ struct CallStack{
 
     template<typename... Args>
     void emplace(Args&&... args){
-        _tail = new(pool128_alloc(sizeof(LinkedFrame))) LinkedFrame(_tail, std::forward<Args>(args)...);
+        static_assert(sizeof(LinkedFrame) <= kPoolFrameBlockSize);
+        _tail = new(PoolFrame_alloc()) LinkedFrame(_tail, std::forward<Args>(args)...);
         ++_size;
     }
 

+ 1 - 1
include/pocketpy/interpreter/iter.hpp

@@ -61,7 +61,7 @@ struct Generator{
     ~Generator(){
         if(lf){
             lf->~LinkedFrame();
-            pool128_dealloc(lf);
+            PoolFrame_dealloc(lf);
         }
     }
 };

+ 54 - 2
src/common/memorypool.cpp

@@ -1,5 +1,4 @@
 #include "pocketpy/common/memorypool.hpp"
-#include "pocketpy/common/gil.hpp"
 #include "pocketpy/common/config.h"
 
 #include <cstdlib>
@@ -273,4 +272,57 @@ void pools_shrink_to_fit() noexcept {
 std::string pool64_info() noexcept { return "unavailable"; }
 std::string pool128_info() noexcept { return pool128.info(); }
 
-}
+template<int BlockSize, int BlockCount>
+struct FixedMemoryPool{
+    struct Block{
+        char data[BlockSize];
+    };
+
+    static_assert(BlockSize % 4 == 0);
+    static_assert(sizeof(Block) == BlockSize);
+
+    Block _blocks[BlockCount];
+    Block* _free_list[BlockCount];
+    Block** _free_list_end;
+
+    FixedMemoryPool() {
+        _free_list_end = _free_list + BlockCount;
+        for(int i = 0; i < BlockCount; ++i){
+            _free_list[i] = _blocks + i;
+        }
+    }
+
+    bool is_valid(void* p){
+        return p >= _blocks && p < _blocks + BlockCount;
+    }
+
+    void* alloc(){
+        PK_GLOBAL_SCOPE_LOCK()
+        if(_free_list_end != _free_list){
+            --_free_list_end;
+            return *_free_list_end;
+        }else{
+            return std::malloc(BlockSize);
+        }
+    }
+
+    void dealloc(void* p){
+        PK_GLOBAL_SCOPE_LOCK()
+        if(is_valid(p)){
+            *_free_list_end = static_cast<Block*>(p);
+            ++_free_list_end;
+        }else{
+            std::free(p);
+        }
+    }
+};
+
+static FixedMemoryPool<kPoolExprBlockSize, 32> PoolExpr;
+static FixedMemoryPool<kPoolFrameBlockSize, 64> PoolFrame;
+void* PoolExpr_alloc() noexcept { return PoolExpr.alloc(); }
+void PoolExpr_dealloc(void* p) noexcept { PoolExpr.dealloc(p); }
+void* PoolFrame_alloc() noexcept { return PoolFrame.alloc(); }
+void PoolFrame_dealloc(void* p) noexcept { PoolFrame.dealloc(p); }
+
+
+}   // namespace pkpy

+ 1 - 1
src/interpreter/frame.cpp

@@ -107,7 +107,7 @@ namespace pkpy{
         LinkedFrame* p = _tail;
         _tail = p->f_back;
         p->~LinkedFrame();
-        pool128_dealloc(p);
+        PoolFrame_dealloc(p);
         --_size;
     }