mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-21 12:00:18 +00:00
up
This commit is contained in:
parent
b34317e7ee
commit
ed44520b42
40
src/memory.h
40
src/memory.h
@ -3,44 +3,26 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
namespace pkpy{
|
namespace pkpy{
|
||||||
const int kMaxMemPoolSize = 512;
|
|
||||||
static thread_local std::vector<int*> _mem_pool(kMaxMemPoolSize);
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct sp_deleter {
|
struct SpAllocator {
|
||||||
inline static void call(int* counter){
|
template<typename U>
|
||||||
if constexpr(std::is_same_v<T, i64> || std::is_same_v<T, f64>){
|
inline static int* alloc(){
|
||||||
if(_mem_pool.size() < kMaxMemPoolSize){
|
return (int*)malloc(sizeof(int) + sizeof(U));
|
||||||
_mem_pool.push_back(counter);
|
}
|
||||||
return;
|
|
||||||
}
|
inline static void dealloc(int* counter){
|
||||||
}
|
|
||||||
((T*)(counter + 1))->~T();
|
((T*)(counter + 1))->~T();
|
||||||
free(counter);
|
free(counter);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct sp_allocator {
|
|
||||||
inline static void* call(size_t size){
|
|
||||||
if constexpr(std::is_same_v<T, i64> || std::is_same_v<T, f64>){
|
|
||||||
if(!_mem_pool.empty()){
|
|
||||||
int* p = _mem_pool.back();
|
|
||||||
_mem_pool.pop_back();
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return malloc(size);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class shared_ptr {
|
class shared_ptr {
|
||||||
int* counter = nullptr;
|
int* counter = nullptr;
|
||||||
|
|
||||||
#define _t() ((T*)(counter + 1))
|
#define _t() ((T*)(counter + 1))
|
||||||
#define _inc_counter() if(counter) ++(*counter)
|
#define _inc_counter() if(counter) ++(*counter)
|
||||||
#define _dec_counter() if(counter && --(*counter) == 0){ pkpy::sp_deleter<T>::call(counter); }
|
#define _dec_counter() if(counter && --(*counter) == 0){ SpAllocator<T>::dealloc(counter); }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
shared_ptr() {}
|
shared_ptr() {}
|
||||||
@ -102,16 +84,14 @@ namespace pkpy{
|
|||||||
shared_ptr<T> make_shared(Args&&... args) {
|
shared_ptr<T> make_shared(Args&&... args) {
|
||||||
static_assert(std::is_base_of_v<T, U>, "U must be derived from T");
|
static_assert(std::is_base_of_v<T, U>, "U must be derived from T");
|
||||||
static_assert(std::has_virtual_destructor_v<T>, "T must have virtual destructor");
|
static_assert(std::has_virtual_destructor_v<T>, "T must have virtual destructor");
|
||||||
int* p = (int*)sp_allocator<U>::call(sizeof(int) + sizeof(U));
|
int* p = SpAllocator<T>::template alloc<U>(); *p = 1;
|
||||||
*p = 1;
|
|
||||||
new(p+1) U(std::forward<Args>(args)...);
|
new(p+1) U(std::forward<Args>(args)...);
|
||||||
return shared_ptr<T>(p);
|
return shared_ptr<T>(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename... Args>
|
template <typename T, typename... Args>
|
||||||
shared_ptr<T> make_shared(Args&&... args) {
|
shared_ptr<T> make_shared(Args&&... args) {
|
||||||
int* p = (int*)sp_allocator<T>::call(sizeof(int) + sizeof(T));
|
int* p = SpAllocator<T>::template alloc<T>(); *p = 1;
|
||||||
*p = 1;
|
|
||||||
new(p+1) T(std::forward<Args>(args)...);
|
new(p+1) T(std::forward<Args>(args)...);
|
||||||
return shared_ptr<T>(p);
|
return shared_ptr<T>(p);
|
||||||
}
|
}
|
||||||
|
65
src/obj.h
65
src/obj.h
@ -77,7 +77,7 @@ public:
|
|||||||
struct PyObject {
|
struct PyObject {
|
||||||
Type type;
|
Type type;
|
||||||
pkpy::NameDict* _attr;
|
pkpy::NameDict* _attr;
|
||||||
//void* _tid;
|
void* _tid;
|
||||||
inline bool is_attr_valid() const noexcept { return _attr != nullptr; }
|
inline bool is_attr_valid() const noexcept { return _attr != nullptr; }
|
||||||
inline pkpy::NameDict& attr() noexcept { return *_attr; }
|
inline pkpy::NameDict& attr() noexcept { return *_attr; }
|
||||||
inline PyVar& attr(const Str& name) noexcept { return (*_attr)[name]; }
|
inline PyVar& attr(const Str& name) noexcept { return (*_attr)[name]; }
|
||||||
@ -85,7 +85,7 @@ struct PyObject {
|
|||||||
inline bool is_type(Type type) const noexcept{ return this->type == type; }
|
inline bool is_type(Type type) const noexcept{ return this->type == type; }
|
||||||
virtual void* value() = 0;
|
virtual void* value() = 0;
|
||||||
|
|
||||||
PyObject(Type type) : type(type) {}
|
PyObject(Type type, void* _tid) : type(type), _tid(_tid) {}
|
||||||
virtual ~PyObject() { delete _attr; }
|
virtual ~PyObject() { delete _attr; }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -93,7 +93,7 @@ template <typename T>
|
|||||||
struct Py_ : PyObject {
|
struct Py_ : PyObject {
|
||||||
T _value;
|
T _value;
|
||||||
|
|
||||||
Py_(Type type, T val) : PyObject(type), _value(val) {
|
Py_(Type type, T val) : PyObject(type, tid<T>()), _value(val) {
|
||||||
if constexpr (std::is_same_v<T, Dummy> || std::is_same_v<T, Type>
|
if constexpr (std::is_same_v<T, Dummy> || std::is_same_v<T, Type>
|
||||||
|| std::is_same_v<T, pkpy::Function_> || std::is_same_v<T, pkpy::NativeFunc>) {
|
|| std::is_same_v<T, pkpy::Function_> || std::is_same_v<T, pkpy::NativeFunc>) {
|
||||||
_attr = new pkpy::NameDict();
|
_attr = new pkpy::NameDict();
|
||||||
@ -111,3 +111,62 @@ struct Py_ : PyObject {
|
|||||||
inline static Type _type(VM* vm) { return OBJ_GET(Type, vm->_modules[#mod]->attr(#name)); } \
|
inline static Type _type(VM* vm) { return OBJ_GET(Type, vm->_modules[#mod]->attr(#name)); } \
|
||||||
inline static const char* _mod() { return #mod; } \
|
inline static const char* _mod() { return #mod; } \
|
||||||
inline static const char* _name() { return #name; }
|
inline static const char* _name() { return #name; }
|
||||||
|
|
||||||
|
|
||||||
|
namespace pkpy {
|
||||||
|
template<int N>
|
||||||
|
struct MemBlock {
|
||||||
|
std::vector<void*> a;
|
||||||
|
int block_size;
|
||||||
|
|
||||||
|
MemBlock(int block_size) : block_size(block_size) {
|
||||||
|
new_block();
|
||||||
|
}
|
||||||
|
|
||||||
|
void new_block(){
|
||||||
|
int8_t* total = (int8_t*)malloc(N * block_size);
|
||||||
|
for(int i = 0; i < block_size; ++i){
|
||||||
|
a.push_back((void*)(total + i * N));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void* alloc(){
|
||||||
|
if(a.empty()) new_block();
|
||||||
|
void* p = a.back();
|
||||||
|
a.pop_back();
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void dealloc(void* p) noexcept{
|
||||||
|
a.push_back(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
~MemBlock(){
|
||||||
|
free(a[0]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static_assert(sizeof(i64) == sizeof(f64));
|
||||||
|
static thread_local MemBlock<sizeof(int)+sizeof(Py_<i64>)> _mem_i64(512);
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct SpAllocator<PyObject> {
|
||||||
|
template<typename U>
|
||||||
|
inline static int* alloc(){
|
||||||
|
if constexpr (std::is_same_v<U, Py_<i64>> || std::is_same_v<U, Py_<f64>>) {
|
||||||
|
return (int*)_mem_i64.alloc();
|
||||||
|
}
|
||||||
|
return (int*)malloc(sizeof(int) + sizeof(U));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static void dealloc(int* counter){
|
||||||
|
PyObject* obj = (PyObject*)(counter + 1);
|
||||||
|
obj->~PyObject();
|
||||||
|
if(obj->_tid == tid<i64>() || obj->_tid == tid<f64>()){
|
||||||
|
_mem_i64.dealloc(counter);
|
||||||
|
}else{
|
||||||
|
free(counter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
@ -61,7 +61,7 @@ namespace pkpy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _free(){
|
void _dealloc(){
|
||||||
if(_size == 0 || _args == nullptr) return;
|
if(_size == 0 || _args == nullptr) return;
|
||||||
if(_size >= kMaxPoolSize || _args_pool[_size].size() > 32){
|
if(_size >= kMaxPoolSize || _args_pool[_size].size() > 32){
|
||||||
delete[] _args;
|
delete[] _args;
|
||||||
@ -102,7 +102,7 @@ namespace pkpy {
|
|||||||
const PyVar& operator[](int i) const { return _args[i]; }
|
const PyVar& operator[](int i) const { return _args[i]; }
|
||||||
|
|
||||||
Args& operator=(Args&& other) noexcept {
|
Args& operator=(Args&& other) noexcept {
|
||||||
_free();
|
_dealloc();
|
||||||
this->_args = other._args;
|
this->_args = other._args;
|
||||||
this->_size = other._size;
|
this->_size = other._size;
|
||||||
other._args = nullptr;
|
other._args = nullptr;
|
||||||
@ -135,7 +135,7 @@ namespace pkpy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~Args(){ _free(); }
|
~Args(){ _dealloc(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
static const Args _zero(0);
|
static const Args _zero(0);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user