BLUELOVETH 2 лет назад
Родитель
Сommit
4e63588589
5 измененных файлов с 46 добавлено и 20 удалено
  1. 1 1
      src/common.h
  2. 8 8
      src/pocketpy.h
  3. 2 1
      src/tuplelist.h
  4. 34 9
      src/vector.h
  5. 1 1
      src/vm.h

+ 1 - 1
src/common.h

@@ -38,7 +38,7 @@
 #define DEBUG_CEVAL_STEP			0
 #define DEBUG_FULL_EXCEPTION		0
 #define DEBUG_NO_AUTO_GC			1
-#define DEBUG_GC_STATS				1
+#define DEBUG_GC_STATS				0
 
 #if (defined(__ANDROID__) && __ANDROID_API__ <= 22) || defined(__EMSCRIPTEN__)
 #define PK_ENABLE_FILEIO 		0

+ 8 - 8
src/pocketpy.h

@@ -429,7 +429,7 @@ inline void init_builtins(VM* _vm) {
         List& self = CAST(List&, args[0]);
         PyObject* obj = vm->asList(args[1]);
         const List& list = CAST(List&, obj);
-        self.insert(self.end(), list.begin(), list.end());
+        self.extend(list);
         return vm->None;
     });
 
@@ -444,7 +444,7 @@ inline void init_builtins(VM* _vm) {
         int n = CAST(int, args[1]);
         List result;
         result.reserve(self.size() * n);
-        for(int i = 0; i < n; i++) result.insert(result.end(), self.begin(), self.end());
+        for(int i = 0; i < n; i++) result.extend(self);
         return VAR(std::move(result));
     });
 
@@ -454,7 +454,7 @@ inline void init_builtins(VM* _vm) {
         if(index < 0) index += self.size();
         if(index < 0) index = 0;
         if(index > self.size()) index = self.size();
-        self.insert(self.begin() + index, args[2]);
+        self.insert(index, args[2]);
         return vm->None;
     });
 
@@ -467,10 +467,10 @@ inline void init_builtins(VM* _vm) {
 
     _vm->bind_method<1>("list", "__add__", [](VM* vm, Args& args) {
         const List& self = CAST(List&, args[0]);
-        const List& obj = CAST(List&, args[1]);
-        List new_list = self;
-        new_list.insert(new_list.end(), obj.begin(), obj.end());
-        return VAR(new_list);
+        const List& other = CAST(List&, args[1]);
+        List new_list(self);    // copy construct
+        new_list.extend(other);
+        return VAR(std::move(new_list));
     });
 
     _vm->bind_method<0>("list", "__len__", [](VM* vm, Args& args) {
@@ -510,7 +510,7 @@ inline void init_builtins(VM* _vm) {
         List& self = CAST(List&, args[0]);
         int index = CAST(int, args[1]);
         index = vm->normalized_index(index, self.size());
-        self.erase(self.begin() + index);
+        self.erase(index);
         return vm->None;
     });
 

+ 2 - 1
src/tuplelist.h

@@ -6,7 +6,7 @@
 
 namespace pkpy {
 
-using List = std::vector<PyObject*>;
+using List = small_vector<PyObject*, 4>;
 
 class Args {
     inline static THREAD_LOCAL FreeListA<PyObject*, 10, false> _pool;
@@ -60,6 +60,7 @@ public:
 
     List to_list() noexcept {
         List ret(_size);
+        // TODO: use move/memcpy
         for(int i=0; i<_size; i++) ret[i] = _args[i];
         return ret;
     }

+ 34 - 9
src/vector.h

@@ -16,6 +16,11 @@ struct small_vector{
         _data = _buffer;
     }
 
+    small_vector(int size): _size(size), _capacity(N){
+        _data = _buffer;
+        reserve(size);
+    }
+
     small_vector(const small_vector& other): _size(other._size), _capacity(other._capacity) {
         if(other.is_small()){
             _data = _buffer;
@@ -57,19 +62,25 @@ struct small_vector{
 
     template<typename __ValueT>
     void push_back(__ValueT&& t) {
-        if (_size == _capacity) {
-            _capacity *= 2;
-            if (is_small()) {
-                _data = (T*)malloc(sizeof(T) * _capacity);
-                memcpy(_data, _buffer, sizeof(T) * _size);
-            } else {
-                _data = (T*)realloc(_data, sizeof(T) * _capacity);
-            }
-        }
+        if (_size == _capacity) reserve(_capacity*2);
         _data[_size++] = std::forward<__ValueT>(t);
     }
 
+    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);
+        }
+    }
+
     void pop_back() { _size--; }
+    void extend(const small_vector& other){
+        for(int i=0; i<other.size(); i++) push_back(other[i]);
+    }
 
     T& operator[](int index) { return _data[index]; }
     const T& operator[](int index) const { return _data[index]; }
@@ -87,6 +98,20 @@ struct small_vector{
     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; }
+
+    template<typename __ValueT>
+    void insert(int i, __ValueT&& val){
+        if (_size == _capacity) reserve(_capacity*2);
+        for(int j=_size; j>i; j--) _data[j] = _data[j-1];
+        _data[i] = std::forward<__ValueT>(val);
+        _size++;
+    }
+
+    void erase(int i){
+        for(int j=i; j<_size-1; j++) _data[j] = _data[j+1];
+        _size--;
+    }
 
     ~small_vector() {
         if (!is_small()) free(_data);

+ 1 - 1
src/vm.h

@@ -780,7 +780,7 @@ inline void VM::unpack_args(Args& args){
         if(is_type(args[i], tp_star_wrapper)){
             auto& star = _CAST(StarWrapper&, args[i]);
             List& list = CAST(List&, asList(star.obj));
-            unpacked.insert(unpacked.end(), list.begin(), list.end());
+            unpacked.extend(list);
         }else{
             unpacked.push_back(args[i]);
         }