diff --git a/src/frame.h b/src/frame.h index 85cc698d..facf2388 100644 --- a/src/frame.h +++ b/src/frame.h @@ -110,7 +110,7 @@ struct Frame { const CodeObject* co; PyObject* _module; - PyObject* _callable; + PyObject* _callable; // weak ref FastLocals _locals; NameDict& f_globals() noexcept { return _module->attr(); } @@ -189,7 +189,6 @@ struct Frame { void _gc_mark() const { OBJ_MARK(_module); - if(_callable != nullptr) OBJ_MARK(_callable); co->_gc_mark(); } }; diff --git a/src/pocketpy.h b/src/pocketpy.h index a1d3f3ac..8919d60a 100644 --- a/src/pocketpy.h +++ b/src/pocketpy.h @@ -453,9 +453,10 @@ inline void init_builtins(VM* _vm) { }); _vm->bind_method<1>("str", "join", [](VM* vm, ArgsView args) { + auto _lock = vm->heap.gc_scope_lock(); const Str& self = _CAST(Str&, args[0]); FastStrStream ss; - PyObject* it = vm->asIter(args[1]); + PyObject* it = vm->asIter(args[1]); // strong ref PyObject* obj = vm->PyIterNext(it); while(obj != vm->StopIteration){ if(!ss.empty()) ss << self; @@ -477,8 +478,9 @@ inline void init_builtins(VM* _vm) { }); _vm->bind_method<1>("list", "extend", [](VM* vm, ArgsView args) { + auto _lock = vm->heap.gc_scope_lock(); List& self = _CAST(List&, args[0]); - PyObject* it = vm->asIter(args[1]); + PyObject* it = vm->asIter(args[1]); // strong ref PyObject* obj = vm->PyIterNext(it); while(obj != vm->StopIteration){ self.push_back(obj); diff --git a/src/tuplelist.h b/src/tuplelist.h index 1403c504..e5bbf045 100644 --- a/src/tuplelist.h +++ b/src/tuplelist.h @@ -38,12 +38,9 @@ public: for(PyObject* p : list) _args[i++] = p; } - // TODO: poor performance - // List is allocated by pool128 while tuple is by pool64 - // ... Tuple(List&& other) noexcept : Tuple(other.size()){ - for(int i=0; i<_size; i++) _args[i] = other[i]; - other.clear(); + _args = other._data; + other._data = nullptr; } PyObject*& operator[](int i){ return _args[i]; } diff --git a/src/vector.h b/src/vector.h index 6c67c19a..a350d073 100644 --- a/src/vector.h +++ b/src/vector.h @@ -7,24 +7,24 @@ namespace pkpy{ template struct pod_vector{ - static_assert(128 % sizeof(T) == 0); + static_assert(64 % sizeof(T) == 0); static_assert(std::is_pod_v); - static constexpr int N = 128 / sizeof(T); - static_assert(N > 4); + static constexpr int N = 64 / sizeof(T); + static_assert(N >= 4); int _size; int _capacity; T* _data; pod_vector(): _size(0), _capacity(N) { - _data = (T*)pool128.alloc(_capacity * sizeof(T)); + _data = (T*)pool64.alloc(_capacity * sizeof(T)); } pod_vector(int size): _size(size), _capacity(std::max(N, size)) { - _data = (T*)pool128.alloc(_capacity * sizeof(T)); + _data = (T*)pool64.alloc(_capacity * sizeof(T)); } pod_vector(const pod_vector& other): _size(other._size), _capacity(other._capacity) { - _data = (T*)pool128.alloc(_capacity * sizeof(T)); + _data = (T*)pool64.alloc(_capacity * sizeof(T)); memcpy(_data, other._data, sizeof(T) * _size); } @@ -36,7 +36,7 @@ struct pod_vector{ } pod_vector& operator=(pod_vector&& other) noexcept { - if(_data!=nullptr) pool128.dealloc(_data); + if(_data!=nullptr) pool64.dealloc(_data); _size = other._size; _capacity = other._capacity; _data = other._data; @@ -63,10 +63,10 @@ struct pod_vector{ if(cap <= _capacity) return; _capacity = cap; T* old_data = _data; - _data = (T*)pool128.alloc(_capacity * sizeof(T)); + _data = (T*)pool64.alloc(_capacity * sizeof(T)); if(old_data!=nullptr){ memcpy(_data, old_data, sizeof(T) * _size); - pool128.dealloc(old_data); + pool64.dealloc(old_data); } } @@ -111,7 +111,7 @@ struct pod_vector{ } ~pod_vector() { - if(_data!=nullptr) pool128.dealloc(_data); + if(_data!=nullptr) pool64.dealloc(_data); } }; @@ -137,6 +137,6 @@ public: Container& data() { return vec; } }; -template -using pod_stack = stack>; +// template +// using pod_stack = stack>; } // namespace pkpy \ No newline at end of file diff --git a/src/vm.h b/src/vm.h index f0a24369..c4fed72c 100644 --- a/src/vm.h +++ b/src/vm.h @@ -576,6 +576,7 @@ inline bool VM::asBool(PyObject* obj){ } inline PyObject* VM::asList(PyObject* it){ + auto _lock = heap.gc_scope_lock(); it = asIter(it); List list; PyObject* obj = PyIterNext(it); @@ -1051,9 +1052,9 @@ inline PyObject* VM::_py_call(PyObject** p0, PyObject* callable, ArgsView args, // handle *args if(fn.decl->starred_arg != -1){ - List vargs; // handle *args - while(i < args.size()) vargs.push_back(args[i++]); - buffer[fn.decl->starred_arg] = VAR(Tuple(std::move(vargs))); + ArgsView vargs(args.begin() + i, args.end()); + buffer[fn.decl->starred_arg] = VAR(vargs.to_tuple()); + i += vargs.size(); }else{ // kwdefaults override for(auto& kv: fn.decl->kwargs){ @@ -1070,8 +1071,9 @@ inline PyObject* VM::_py_call(PyObject** p0, PyObject* callable, ArgsView args, buffer[index] = kwargs[i+1]; } - s_data.reset(p0); + if(co->is_generator){ + s_data.reset(p0); PyObject* ret = PyIter(Generator( this, Frame(&s_data, nullptr, co, fn._module, callable), @@ -1080,9 +1082,10 @@ inline PyObject* VM::_py_call(PyObject** p0, PyObject* callable, ArgsView args, return ret; } - // copy buffer to stack + // copy buffer back to stack + s_data.reset(args.begin()); for(int i=0; i