blueloveTH 2 vuotta sitten
vanhempi
commit
7efb440388
8 muutettua tiedostoa jossa 201 lisäystä ja 104 poistoa
  1. 1 0
      src/compiler.h
  2. 1 1
      src/frame.h
  3. 1 1
      src/lexer.h
  4. 8 38
      src/memory.h
  5. 12 9
      src/namedict.h
  6. 143 0
      src/new_str.h
  7. 6 7
      src/tuplelist.h
  8. 29 48
      src/vector.h

+ 1 - 0
src/compiler.h

@@ -55,6 +55,7 @@ class Compiler {
     }
 
     static void init_pratt_rules(){
+        if(rules[TK(".")].precedence != PREC_NONE) return;
 // http://journal.stuffwithstuff.com/2011/03/19/pratt-parsers-expression-parsing-made-easy/
 #define METHOD(name) &Compiler::name
 #define NO_INFIX nullptr, PREC_NONE

+ 1 - 1
src/frame.h

@@ -7,7 +7,7 @@ namespace pkpy{
 
 static THREAD_LOCAL uint64_t kFrameGlobalId = 0;
 
-using ValueStack = small_vector<PyObject*, 6>;
+using ValueStack = pod_vector<PyObject*>;
 
 struct Frame {
     ValueStack _data;

+ 1 - 1
src/lexer.h

@@ -100,7 +100,7 @@ struct Lexer {
     const char* curr_char;
     int current_line = 1;
     std::vector<Token> nexts;
-    small_stack<int, 4> indents;
+    stack<int> indents;
     int brackets_level = 0;
     bool used = false;
 

+ 8 - 38
src/memory.h

@@ -1,7 +1,6 @@
 #pragma once
 
 #include "common.h"
-#include "vector.h"
 
 namespace pkpy{
 
@@ -69,48 +68,12 @@ shared_ptr<T> make_sp(Args&&... args) {
     return shared_ptr<T>(p);
 }
 
-template<typename T, int __Bucket, bool __ZeroInit>
-struct FreeListA {
-    std::vector<T*> buckets[__Bucket+1];
-
-    T* alloc(int n){
-        static_assert(std::is_standard_layout_v<T>);
-        T* p;
-        if(n > __Bucket || buckets[n].empty()){
-            p = (T*)malloc(sizeof(T) * n);
-        }else{
-            p = buckets[n].back();
-            buckets[n].pop_back();
-        }
-        if constexpr(__ZeroInit){
-            // the constructor of T should be equivalent to zero initialization
-            memset((void*)p, 0, sizeof(T) * n);
-        }
-        return p;
-    }
-
-    void dealloc(T* p, int n){
-        if(p == nullptr) return;
-        if(n > __Bucket || buckets[n].size() >= 80){
-            free(p);
-        }else{
-            buckets[n].push_back(p);
-        }
-    }
-
-    ~FreeListA(){
-        for(int i=0; i<=__Bucket; i++){
-            for(T* p : buckets[i]) free(p);
-        }
-    }
-};
-
-
 struct LinkedListNode{
     LinkedListNode* prev;
     LinkedListNode* next;
 };
 
+
 template<typename T>
 struct DoubleLinkedList{
     static_assert(std::is_base_of_v<LinkedListNode, T>);
@@ -295,6 +258,9 @@ struct MemoryPool{
     }
 
     void dealloc(void* p){
+#if DEBUG_MEMORY_POOL
+        if(p == nullptr) throw std::runtime_error("MemoryPool::dealloc() called on nullptr");
+#endif
         Block* block = (Block*)((char*)p - sizeof(void*));
         if(block->arena == nullptr){
             free(block);
@@ -328,4 +294,8 @@ struct MemoryPool{
     }
 };
 
+inline MemoryPool<64> pool64;
+inline MemoryPool<128> pool128;
+inline MemoryPool<256> pool256;
+
 };  // namespace pkpy

+ 12 - 9
src/namedict.h

@@ -34,8 +34,6 @@ inline static uint16_t find_perfect_hash_seed(uint16_t capacity, const std::vect
 
 struct NameDict {
     using Item = std::pair<StrName, PyObject*>;
-    inline static THREAD_LOCAL FreeListA<Item, 32, true> _pool;
-
     uint16_t _capacity;
     uint16_t _size;
     float _load_factor;
@@ -43,31 +41,36 @@ struct NameDict {
     uint16_t _mask;
     Item* _items;
 
+    void _alloc(int cap){
+        _items = (Item*)pool128.alloc(cap * sizeof(Item));
+        memset(_items, 0, cap * sizeof(Item));
+    }
+
     NameDict(uint16_t capacity=2, float load_factor=0.67, uint16_t hash_seed=kHashSeeds[0]):
         _capacity(capacity), _size(0), _load_factor(load_factor),
         _hash_seed(hash_seed), _mask(capacity-1) {
-        _items = _pool.alloc(_capacity);
+        _alloc(capacity);
     }
 
     NameDict(const NameDict& other) {
         memcpy(this, &other, sizeof(NameDict));
-        _items = _pool.alloc(_capacity);
+        _alloc(_capacity);
         for(int i=0; i<_capacity; i++){
             _items[i] = other._items[i];
         }
     }
 
     NameDict& operator=(const NameDict& other) {
-        _pool.dealloc(_items, _capacity);
+        pool128.dealloc(_items);
         memcpy(this, &other, sizeof(NameDict));
-        _items = _pool.alloc(_capacity);
+        _alloc(_capacity);
         for(int i=0; i<_capacity; i++){
             _items[i] = other._items[i];
         }
         return *this;
     }
     
-    ~NameDict(){ _pool.dealloc(_items, _capacity); }
+    ~NameDict(){ pool128.dealloc(_items); }
 
     NameDict(NameDict&&) = delete;
     NameDict& operator=(NameDict&&) = delete;
@@ -109,7 +112,7 @@ while(!_items[i].first.empty()) {       \
             _capacity = find_next_capacity(_capacity * 2);
             _mask = _capacity - 1;
         }
-        _items = _pool.alloc(_capacity);
+        _alloc(_capacity);
         for(uint16_t i=0; i<old_capacity; i++){
             if(old_items[i].first.empty()) continue;
             bool ok; uint16_t j;
@@ -117,7 +120,7 @@ while(!_items[i].first.empty()) {       \
             if(ok) UNREACHABLE();
             _items[j] = old_items[i];
         }
-        _pool.dealloc(old_items, old_capacity);
+        pool128.dealloc(old_items);
     }
 
     void _try_perfect_rehash(){

+ 143 - 0
src/new_str.h

@@ -0,0 +1,143 @@
+#pragma once
+
+#include "common.h"
+#include "memory.h"
+#include <string_view>
+
+namespace pkpy{
+
+struct String{
+    char* data;
+    int size;
+
+    String(): data((char*)pool64.alloc(0)), size(0) {}
+    String(int size): data((char*)pool64.alloc(size)), size(size) {}
+    String(const char* str) {
+        size = strlen(str);
+        data = (char*)pool64.alloc(size);
+        memcpy(data, str, size);
+    }
+
+    String(const String& other): data((char*)pool64.alloc(other.size)), size(other.size) {
+        memcpy(data, other.data, size);
+    }
+
+    String(String&& other): data(other.data), size(other.size) {
+        other.data = nullptr;
+    }
+
+    String& operator=(const String& other){
+        if(data!=nullptr) pool64.dealloc(data);
+        size = other.size;
+        data = (char*)pool64.alloc(size);
+        memcpy(data, other.data, size);
+        return *this;
+    }
+
+    String& operator=(String&& other){
+        if(data!=nullptr) pool64.dealloc(data);
+        size = other.size;
+        data = other.data;
+        other.data = nullptr;
+        return *this;
+    }
+
+    ~String(){
+        if(data!=nullptr) pool64.dealloc(data);
+    }
+
+    char operator[](int idx) const {
+        return data[idx];
+    }
+
+    int length() const {
+        return size;
+    }
+
+    String operator+(const String& other) const {
+        String ret(size + other.size);
+        memcpy(ret.data, data, size);
+        memcpy(ret.data + size, other.data, other.size);
+        return ret;
+    }
+
+    friend std::ostream& operator<<(std::ostream& os, const String& str){
+        os.write(str.data, str.size);
+        return os;
+    }
+
+    bool operator==(const String& other) const {
+        if(size != other.size) return false;
+        return memcmp(data, other.data, size) == 0;
+    }
+
+    bool operator!=(const String& other) const {
+        if(size != other.size) return true;
+        return memcmp(data, other.data, size) != 0;
+    }
+
+    bool operator<(const String& other) const {
+        int ret = strncmp(data, other.data, std::min(size, other.size));
+        if(ret != 0) return ret < 0;
+        return size < other.size;
+    }
+
+    bool operator>(const String& other) const {
+        int ret = strncmp(data, other.data, std::min(size, other.size));
+        if(ret != 0) return ret > 0;
+        return size > other.size;
+    }
+
+    bool operator<=(const String& other) const {
+        int ret = strncmp(data, other.data, std::min(size, other.size));
+        if(ret != 0) return ret < 0;
+        return size <= other.size;
+    }
+
+    bool operator>=(const String& other) const {
+        int ret = strncmp(data, other.data, std::min(size, other.size));
+        if(ret != 0) return ret > 0;
+        return size >= other.size;
+    }
+
+    String substr(int start, int len) const {
+        String ret(len);
+        memcpy(ret.data, data + start, len);
+        return ret;
+    }
+
+    String substr(int start) const {
+        return substr(start, size - start);
+    }
+
+    char* dup_c_str() const {
+        char* p = (char*)malloc(size + 1);
+        memcpy(p, data, size);
+        p[size] = 0;
+        return p;
+    }
+
+    std::string_view view() const {
+        return std::string_view(data, size);
+    }
+
+    std::string str() const {
+        return std::string(data, size);
+    }
+
+    String lstrip() const {
+        std::string copy = str();
+        copy.erase(copy.begin(), std::find_if(copy.begin(), copy.end(), [](char c) {
+            // std::isspace(c) does not working on windows (Debug)
+            return c != ' ' && c != '\t' && c != '\r' && c != '\n';
+        }));
+        return String(copy.c_str());
+    }
+};
+
+struct UnicodeString: String{
+
+};
+
+
+}   // namespace pkpy

+ 6 - 7
src/tuplelist.h

@@ -3,19 +3,18 @@
 #include "common.h"
 #include "memory.h"
 #include "str.h"
+#include "vector.h"
 
 namespace pkpy {
 
-using List = small_vector<PyObject*, 4>;
+using List = pod_vector<PyObject*>;
 
 class Args {
-    inline static THREAD_LOCAL FreeListA<PyObject*, 10, false> _pool;
-
     PyObject** _args;
     int _size;
 
     void _alloc(int n){
-        this->_args = (n==0) ? nullptr : _pool.alloc(n);
+        this->_args = (n==0) ? nullptr : (PyObject**)pool64.alloc(n * sizeof(void*));
         this->_size = n;
     }
 
@@ -48,7 +47,7 @@ public:
     PyObject* operator[](int i) const { return _args[i]; }
 
     Args& operator=(Args&& other) noexcept {
-        _pool.dealloc(_args, _size);
+        if(_args!=nullptr) pool64.dealloc(_args);
         this->_args = other._args;
         this->_size = other._size;
         other._args = nullptr;
@@ -71,10 +70,10 @@ public:
         _alloc(old_size+1);
         _args[0] = self;
         for(int i=0; i<old_size; i++) _args[i+1] = old_args[i];
-        _pool.dealloc(old_args, old_size);
+        if(old_args!=nullptr) pool64.dealloc(old_args);
     }
 
-    ~Args(){ _pool.dealloc(_args, _size); }
+    ~Args(){ if(_args!=nullptr) pool64.dealloc(_args); }
 };
 
 inline const Args& no_arg() {

+ 29 - 48
src/vector.h

@@ -1,65 +1,51 @@
 #pragma once
 
 #include "common.h"
+#include "memory.h"
 
 namespace pkpy{
 
-template<typename T, int N>
-struct small_vector{
+template<typename T>
+struct pod_vector{
+    static_assert(128 % sizeof(T) == 0);
+    static_assert(std::is_pod_v<T>);
+    static constexpr int N = 128 / sizeof(T);
+    static_assert(N > 4);
     int _size;
     int _capacity;
     T* _data;
-    T _buffer[N];
 
-    small_vector(): _size(0), _capacity(N) {
-        static_assert(std::is_pod_v<T>);
-        _data = _buffer;
+    pod_vector(): _size(0), _capacity(N) {
+        _data = (T*)pool128.alloc(_capacity * sizeof(T));
     }
 
-    small_vector(int size): _size(0), _capacity(N){
-        _data = _buffer;
-        reserve(size);
-        _size = size;
+    pod_vector(int size): _size(size), _capacity(std::max(N, size)) {
+        _data = (T*)pool128.alloc(_capacity * sizeof(T));
     }
 
-    small_vector(const small_vector& other): _size(other._size), _capacity(other._capacity) {
-        if(other.is_small()){
-            _data = _buffer;
-            memcpy(_buffer, other._buffer, sizeof(T) * _size);
-        } else {
-            _data = (T*)malloc(sizeof(T) * _capacity);
-            memcpy(_data, other._data, sizeof(T) * _size);
-        }
+    pod_vector(const pod_vector& other): _size(other._size), _capacity(other._capacity) {
+        _data = (T*)pool128.alloc(_capacity * sizeof(T));
+        memcpy(_data, other._data, sizeof(T) * _size);
     }
 
-    small_vector(small_vector&& other) noexcept {
+    pod_vector(pod_vector&& other) noexcept {
         _size = other._size;
         _capacity = other._capacity;
-        if(other.is_small()){
-            _data = _buffer;
-            memcpy(_buffer, other._buffer, sizeof(T) * _size);
-        } else {
-            _data = other._data;
-            other._data = other._buffer;
-        }
+        _data = other._data;
+        other._data = nullptr;
     }
 
-    small_vector& operator=(small_vector&& other) noexcept {
-        if (!is_small()) free(_data);
+    pod_vector& operator=(pod_vector&& other) noexcept {
+        if(_data!=nullptr) pool128.dealloc(_data);
         _size = other._size;
         _capacity = other._capacity;
-        if(other.is_small()){
-            _data = _buffer;
-            memcpy(_buffer, other._buffer, sizeof(T) * _size);
-        } else {
-            _data = other._data;
-            other._data = other._buffer;
-        }
+        _data = other._data;
+        other._data = nullptr;
         return *this;
     }
 
     // remove copy assignment
-    small_vector& operator=(const small_vector& other) = delete;
+    pod_vector& operator=(const pod_vector& other) = delete;
 
     template<typename __ValueT>
     void push_back(__ValueT&& t) {
@@ -70,16 +56,12 @@ struct small_vector{
     void reserve(int cap){
         if(cap < _capacity) return;
         _capacity = cap;
-        if (is_small()) {
-            _data = (T*)malloc(sizeof(T) * _capacity);
-            memcpy(_data, _buffer, sizeof(T) * _size);
-        } else {
-            _data = (T*)realloc(_data, sizeof(T) * _capacity);
-        }
+        if(_data!=nullptr) pool128.dealloc(_data);
+        _data = (T*)pool128.alloc(_capacity * sizeof(T));
     }
 
     void pop_back() { _size--; }
-    void extend(const small_vector& other){
+    void extend(const pod_vector& other){
         for(int i=0; i<other.size(); i++) push_back(other[i]);
     }
 
@@ -97,7 +79,6 @@ struct small_vector{
     int size() const { return _size; }
     T* data() { return _data; }
     const T* data() const { return _data; }
-    bool is_small() const { return _data == _buffer; }
     void pop_back_n(int n) { _size -= n; }
     void clear() { _size=0; }
 
@@ -114,8 +95,8 @@ struct small_vector{
         _size--;
     }
 
-    ~small_vector() {
-        if (!is_small()) free(_data);
+    ~pod_vector() {
+        if(_data!=nullptr) pool128.dealloc(_data);
     }
 };
 
@@ -136,6 +117,6 @@ public:
 	const Container& data() const { return vec; }
 };
 
-template <typename T, int N>
-using small_stack = stack<T, small_vector<T, N>>;
+template <typename T>
+using pod_stack = stack<T, pod_vector<T>>;
 } // namespace pkpy