mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-23 13:00:17 +00:00
some fix
This commit is contained in:
parent
0946c67fe0
commit
4b687d36ff
@ -10,13 +10,14 @@ namespace pkpy {
|
||||
|
||||
const inline int kPoolExprBlockSize = 128;
|
||||
const inline int kPoolFrameBlockSize = 80;
|
||||
const inline int kPoolObjectBlockSize = 80;
|
||||
|
||||
void* PoolExpr_alloc() noexcept;
|
||||
void PoolExpr_dealloc(void*) noexcept;
|
||||
void* PoolFrame_alloc() noexcept;
|
||||
void PoolFrame_dealloc(void*) noexcept;
|
||||
|
||||
void* PoolObject_alloc(size_t size) noexcept;
|
||||
void* PoolObject_alloc() noexcept;
|
||||
void PoolObject_dealloc(void* p) noexcept;
|
||||
void PoolObject_shrink_to_fit() noexcept;
|
||||
|
||||
|
@ -40,7 +40,12 @@ struct ManagedHeap {
|
||||
using __T = std::decay_t<T>;
|
||||
static_assert(!is_sso_v<__T>, "gcnew cannot be used with SSO types");
|
||||
// https://github.com/pocketpy/pocketpy/issues/94#issuecomment-1594784476
|
||||
PyObject* p = new (PoolObject_alloc(py_sizeof<__T>)) PyObject(type);
|
||||
PyObject* p;
|
||||
if constexpr(py_sizeof<__T> <= kPoolObjectBlockSize){
|
||||
p = new (PoolObject_alloc()) PyObject(type, false);
|
||||
}else{
|
||||
p = new (std::malloc(py_sizeof<__T>)) PyObject(type, true);
|
||||
}
|
||||
p->placement_new<__T>(std::forward<Args>(args)...);
|
||||
gen.push_back(p);
|
||||
gc_counter++;
|
||||
@ -51,7 +56,12 @@ struct ManagedHeap {
|
||||
PyObject* _new(Type type, Args&&... args) {
|
||||
using __T = std::decay_t<T>;
|
||||
static_assert(!is_sso_v<__T>);
|
||||
PyObject* p = new (PoolObject_alloc(py_sizeof<__T>)) PyObject(type);
|
||||
PyObject* p;
|
||||
if constexpr(py_sizeof<__T> <= kPoolObjectBlockSize){
|
||||
p = new (PoolObject_alloc()) PyObject(type, false);
|
||||
}else{
|
||||
p = new (std::malloc(py_sizeof<__T>)) PyObject(type, true);
|
||||
}
|
||||
p->placement_new<__T>(std::forward<Args>(args)...);
|
||||
_no_gc.push_back(p);
|
||||
return p;
|
||||
|
@ -9,8 +9,9 @@ namespace pkpy {
|
||||
struct NameDict;
|
||||
|
||||
struct PyObject final {
|
||||
bool gc_marked; // whether this object is marked
|
||||
Type type; // we have a duplicated type here for convenience
|
||||
bool gc_is_large;
|
||||
bool gc_marked;
|
||||
NameDict* _attr; // gc will delete this on destruction
|
||||
|
||||
bool is_attr_valid() const noexcept { return _attr != nullptr; }
|
||||
@ -28,7 +29,7 @@ struct PyObject final {
|
||||
return *_attr;
|
||||
}
|
||||
|
||||
PyObject(Type type) : gc_marked(false), type(type), _attr(nullptr) {}
|
||||
PyObject(Type type, bool gc_is_large) : type(type), gc_is_large(gc_is_large), gc_marked(false), _attr(nullptr) {}
|
||||
|
||||
PyVar attr(StrName name) const;
|
||||
static NameDict* __init_namedict(float lf);
|
||||
|
@ -87,8 +87,8 @@ struct DoubleLinkedList {
|
||||
}
|
||||
};
|
||||
|
||||
template <int __BlockSize>
|
||||
struct MemoryPool {
|
||||
const static int __BlockSize = kPoolObjectBlockSize;
|
||||
const static int __MaxBlocks = 256 * 1024 / __BlockSize;
|
||||
const static int __MinArenaCount = PK_GC_MIN_THRESHOLD * 100 / (256 * 1024);
|
||||
|
||||
@ -138,14 +138,8 @@ struct MemoryPool {
|
||||
DoubleLinkedList<Arena> _arenas;
|
||||
DoubleLinkedList<Arena> _empty_arenas;
|
||||
|
||||
void* alloc(size_t size) {
|
||||
void* alloc() {
|
||||
PK_GLOBAL_SCOPE_LOCK();
|
||||
if(size > __BlockSize) {
|
||||
void* p = std::malloc(sizeof(void*) + size);
|
||||
std::memset(p, 0, sizeof(void*));
|
||||
return (char*)p + sizeof(void*);
|
||||
}
|
||||
|
||||
if(_arenas.empty()) { _arenas.push_back(new Arena()); }
|
||||
Arena* arena = _arenas.back();
|
||||
void* p = arena->alloc()->data;
|
||||
@ -160,17 +154,14 @@ struct MemoryPool {
|
||||
PK_GLOBAL_SCOPE_LOCK();
|
||||
assert(p != nullptr);
|
||||
Block* block = (Block*)((char*)p - sizeof(void*));
|
||||
if(block->arena == nullptr) {
|
||||
std::free(block);
|
||||
assert(block->arena != nullptr);
|
||||
Arena* arena = (Arena*)block->arena;
|
||||
if(arena->empty()) {
|
||||
_empty_arenas.erase(arena);
|
||||
_arenas.push_front(arena);
|
||||
arena->dealloc(block);
|
||||
} else {
|
||||
Arena* arena = (Arena*)block->arena;
|
||||
if(arena->empty()) {
|
||||
_empty_arenas.erase(arena);
|
||||
_arenas.push_front(arena);
|
||||
arena->dealloc(block);
|
||||
} else {
|
||||
arena->dealloc(block);
|
||||
}
|
||||
arena->dealloc(block);
|
||||
}
|
||||
}
|
||||
|
||||
@ -248,7 +239,7 @@ struct FixedMemoryPool {
|
||||
|
||||
static FixedMemoryPool<kPoolExprBlockSize, 64> PoolExpr;
|
||||
static FixedMemoryPool<kPoolFrameBlockSize, 128> PoolFrame;
|
||||
static MemoryPool<80> PoolObject;
|
||||
static MemoryPool PoolObject;
|
||||
|
||||
void* PoolExpr_alloc() noexcept { return PoolExpr.alloc(); }
|
||||
|
||||
@ -258,7 +249,7 @@ void* PoolFrame_alloc() noexcept { return PoolFrame.alloc(); }
|
||||
|
||||
void PoolFrame_dealloc(void* p) noexcept { PoolFrame.dealloc(p); }
|
||||
|
||||
void* PoolObject_alloc(size_t size) noexcept { return PoolObject.alloc(size); }
|
||||
void* PoolObject_alloc() noexcept { return PoolObject.alloc(); }
|
||||
|
||||
void PoolObject_dealloc(void* p) noexcept { PoolObject.dealloc(p); }
|
||||
|
||||
@ -292,7 +283,7 @@ void Pools_debug_info(char* buffer, int size) noexcept {
|
||||
);
|
||||
buffer += n; size -= n;
|
||||
// log each non-empty arena
|
||||
PoolObject._arenas.apply([&](MemoryPool<80>::Arena* arena) {
|
||||
PoolObject._arenas.apply([&](MemoryPool::Arena* arena) {
|
||||
n = snprintf(
|
||||
buffer, size, " - %p: %.2f MB (used) / %.2f MB (total)\n",
|
||||
(void*)arena,
|
||||
|
@ -1902,7 +1902,11 @@ void ManagedHeap::_delete(PyObject* obj) {
|
||||
const PyTypeInfo* ti = vm->_tp_info(obj->type);
|
||||
if(ti->vt._dtor) ti->vt._dtor(obj->_value_ptr());
|
||||
delete obj->_attr; // delete __dict__ if exists
|
||||
PoolObject_dealloc(obj);
|
||||
if(obj->gc_is_large){
|
||||
std::free(obj);
|
||||
}else{
|
||||
PoolObject_dealloc(obj);
|
||||
}
|
||||
}
|
||||
|
||||
void Dict::_gc_mark(VM* vm) const {
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "pocketpy/objects/builtins.hpp"
|
||||
|
||||
namespace pkpy {
|
||||
const PyVar PY_OP_CALL(Type(), new PyObject(Type()));
|
||||
const PyVar PY_OP_YIELD(Type(), new PyObject(Type()));
|
||||
const PyVar PY_OP_CALL(Type(), new PyObject(Type(), true));
|
||||
const PyVar PY_OP_YIELD(Type(), new PyObject(Type(), true));
|
||||
} // namespace pkpy
|
||||
|
Loading…
x
Reference in New Issue
Block a user