mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 03:20:18 +00:00
add some gc guard
This commit is contained in:
parent
345215e17a
commit
c8b2387002
@ -110,7 +110,7 @@ struct Frame {
|
|||||||
|
|
||||||
const CodeObject* co;
|
const CodeObject* co;
|
||||||
PyObject* _module;
|
PyObject* _module;
|
||||||
PyObject* _callable;
|
PyObject* _callable; // weak ref
|
||||||
FastLocals _locals;
|
FastLocals _locals;
|
||||||
|
|
||||||
NameDict& f_globals() noexcept { return _module->attr(); }
|
NameDict& f_globals() noexcept { return _module->attr(); }
|
||||||
@ -189,7 +189,6 @@ struct Frame {
|
|||||||
|
|
||||||
void _gc_mark() const {
|
void _gc_mark() const {
|
||||||
OBJ_MARK(_module);
|
OBJ_MARK(_module);
|
||||||
if(_callable != nullptr) OBJ_MARK(_callable);
|
|
||||||
co->_gc_mark();
|
co->_gc_mark();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -453,9 +453,10 @@ inline void init_builtins(VM* _vm) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
_vm->bind_method<1>("str", "join", [](VM* vm, ArgsView args) {
|
_vm->bind_method<1>("str", "join", [](VM* vm, ArgsView args) {
|
||||||
|
auto _lock = vm->heap.gc_scope_lock();
|
||||||
const Str& self = _CAST(Str&, args[0]);
|
const Str& self = _CAST(Str&, args[0]);
|
||||||
FastStrStream ss;
|
FastStrStream ss;
|
||||||
PyObject* it = vm->asIter(args[1]);
|
PyObject* it = vm->asIter(args[1]); // strong ref
|
||||||
PyObject* obj = vm->PyIterNext(it);
|
PyObject* obj = vm->PyIterNext(it);
|
||||||
while(obj != vm->StopIteration){
|
while(obj != vm->StopIteration){
|
||||||
if(!ss.empty()) ss << self;
|
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) {
|
_vm->bind_method<1>("list", "extend", [](VM* vm, ArgsView args) {
|
||||||
|
auto _lock = vm->heap.gc_scope_lock();
|
||||||
List& self = _CAST(List&, args[0]);
|
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);
|
PyObject* obj = vm->PyIterNext(it);
|
||||||
while(obj != vm->StopIteration){
|
while(obj != vm->StopIteration){
|
||||||
self.push_back(obj);
|
self.push_back(obj);
|
||||||
|
@ -38,12 +38,9 @@ public:
|
|||||||
for(PyObject* p : list) _args[i++] = p;
|
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()){
|
Tuple(List&& other) noexcept : Tuple(other.size()){
|
||||||
for(int i=0; i<_size; i++) _args[i] = other[i];
|
_args = other._data;
|
||||||
other.clear();
|
other._data = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject*& operator[](int i){ return _args[i]; }
|
PyObject*& operator[](int i){ return _args[i]; }
|
||||||
|
24
src/vector.h
24
src/vector.h
@ -7,24 +7,24 @@ namespace pkpy{
|
|||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct pod_vector{
|
struct pod_vector{
|
||||||
static_assert(128 % sizeof(T) == 0);
|
static_assert(64 % sizeof(T) == 0);
|
||||||
static_assert(std::is_pod_v<T>);
|
static_assert(std::is_pod_v<T>);
|
||||||
static constexpr int N = 128 / sizeof(T);
|
static constexpr int N = 64 / sizeof(T);
|
||||||
static_assert(N > 4);
|
static_assert(N >= 4);
|
||||||
int _size;
|
int _size;
|
||||||
int _capacity;
|
int _capacity;
|
||||||
T* _data;
|
T* _data;
|
||||||
|
|
||||||
pod_vector(): _size(0), _capacity(N) {
|
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)) {
|
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) {
|
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);
|
memcpy(_data, other._data, sizeof(T) * _size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,7 +36,7 @@ struct pod_vector{
|
|||||||
}
|
}
|
||||||
|
|
||||||
pod_vector& operator=(pod_vector&& other) noexcept {
|
pod_vector& operator=(pod_vector&& other) noexcept {
|
||||||
if(_data!=nullptr) pool128.dealloc(_data);
|
if(_data!=nullptr) pool64.dealloc(_data);
|
||||||
_size = other._size;
|
_size = other._size;
|
||||||
_capacity = other._capacity;
|
_capacity = other._capacity;
|
||||||
_data = other._data;
|
_data = other._data;
|
||||||
@ -63,10 +63,10 @@ struct pod_vector{
|
|||||||
if(cap <= _capacity) return;
|
if(cap <= _capacity) return;
|
||||||
_capacity = cap;
|
_capacity = cap;
|
||||||
T* old_data = _data;
|
T* old_data = _data;
|
||||||
_data = (T*)pool128.alloc(_capacity * sizeof(T));
|
_data = (T*)pool64.alloc(_capacity * sizeof(T));
|
||||||
if(old_data!=nullptr){
|
if(old_data!=nullptr){
|
||||||
memcpy(_data, old_data, sizeof(T) * _size);
|
memcpy(_data, old_data, sizeof(T) * _size);
|
||||||
pool128.dealloc(old_data);
|
pool64.dealloc(old_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,7 +111,7 @@ struct pod_vector{
|
|||||||
}
|
}
|
||||||
|
|
||||||
~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; }
|
Container& data() { return vec; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
// template <typename T>
|
||||||
using pod_stack = stack<T, pod_vector<T>>;
|
// using pod_stack = stack<T, pod_vector<T>>;
|
||||||
} // namespace pkpy
|
} // namespace pkpy
|
15
src/vm.h
15
src/vm.h
@ -576,6 +576,7 @@ inline bool VM::asBool(PyObject* obj){
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline PyObject* VM::asList(PyObject* it){
|
inline PyObject* VM::asList(PyObject* it){
|
||||||
|
auto _lock = heap.gc_scope_lock();
|
||||||
it = asIter(it);
|
it = asIter(it);
|
||||||
List list;
|
List list;
|
||||||
PyObject* obj = PyIterNext(it);
|
PyObject* obj = PyIterNext(it);
|
||||||
@ -1051,9 +1052,9 @@ inline PyObject* VM::_py_call(PyObject** p0, PyObject* callable, ArgsView args,
|
|||||||
|
|
||||||
// handle *args
|
// handle *args
|
||||||
if(fn.decl->starred_arg != -1){
|
if(fn.decl->starred_arg != -1){
|
||||||
List vargs; // handle *args
|
ArgsView vargs(args.begin() + i, args.end());
|
||||||
while(i < args.size()) vargs.push_back(args[i++]);
|
buffer[fn.decl->starred_arg] = VAR(vargs.to_tuple());
|
||||||
buffer[fn.decl->starred_arg] = VAR(Tuple(std::move(vargs)));
|
i += vargs.size();
|
||||||
}else{
|
}else{
|
||||||
// kwdefaults override
|
// kwdefaults override
|
||||||
for(auto& kv: fn.decl->kwargs){
|
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];
|
buffer[index] = kwargs[i+1];
|
||||||
}
|
}
|
||||||
|
|
||||||
s_data.reset(p0);
|
|
||||||
if(co->is_generator){
|
if(co->is_generator){
|
||||||
|
s_data.reset(p0);
|
||||||
PyObject* ret = PyIter(Generator(
|
PyObject* ret = PyIter(Generator(
|
||||||
this,
|
this,
|
||||||
Frame(&s_data, nullptr, co, fn._module, callable),
|
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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy buffer to stack
|
// copy buffer back to stack
|
||||||
|
s_data.reset(args.begin());
|
||||||
for(int i=0; i<co_nlocals; i++) PUSH(buffer[i]);
|
for(int i=0; i<co_nlocals; i++) PUSH(buffer[i]);
|
||||||
callstack.emplace(&s_data, p0, co, fn._module, callable);
|
callstack.emplace(&s_data, p0, co, fn._module, callable, FastLocals(co, args.begin()));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user