improve performance

This commit is contained in:
blueloveTH 2025-03-05 00:37:20 +08:00
parent 160bc99d04
commit b3084a5c87
7 changed files with 67 additions and 61 deletions

View File

@ -0,0 +1,25 @@
#pragma once
#include "pocketpy/common/vector.h"
#include "pocketpy/objects/base.h"
#define PK_DICT_MAX_COLLISION 4
typedef struct {
uint64_t hash;
py_TValue key;
py_TValue val;
} DictEntry;
typedef struct {
int _[PK_DICT_MAX_COLLISION];
} DictIndex;
typedef struct {
int length;
uint32_t capacity;
DictIndex* indices;
c11_vector /*T=DictEntry*/ entries;
} Dict;
typedef c11_vector List;

View File

@ -8,6 +8,7 @@
#include "pocketpy/interpreter/modules.h" #include "pocketpy/interpreter/modules.h"
#include "pocketpy/interpreter/typeinfo.h" #include "pocketpy/interpreter/typeinfo.h"
#include "pocketpy/interpreter/name.h" #include "pocketpy/interpreter/name.h"
#include "pocketpy/interpreter/types.h"
// TODO: // TODO:
// 1. __eq__ and __ne__ fallbacks // 1. __eq__ and __ne__ fallbacks
@ -58,7 +59,6 @@ bool pk__parse_int_slice(py_Ref slice, int length, int* restrict start, int* res
bool pk__normalize_index(int* index, int length); bool pk__normalize_index(int* index, int length);
#define pk__mark_value(val) if((val)->is_ptr && !(val)->_obj->gc_marked) PyObject__mark((val)->_obj) #define pk__mark_value(val) if((val)->is_ptr && !(val)->_obj->gc_marked) PyObject__mark((val)->_obj)
void pk__mark_namedict(NameDict*);
void pk__tp_set_marker(py_Type type, void (*gc_mark)(void*)); void pk__tp_set_marker(py_Type type, void (*gc_mark)(void*));
bool pk__object_new(int argc, py_Ref argv); bool pk__object_new(int argc, py_Ref argv);
py_TypeInfo* pk__type_info(py_Type type); py_TypeInfo* pk__type_info(py_Type type);

View File

@ -76,16 +76,8 @@ static bool generator__next__(int argc, py_Ref argv) {
} }
} }
static void generator__gc_mark(void* ud){
Generator* gen = ud;
if(gen->frame) Frame__gc_mark(gen->frame);
}
py_Type pk_generator__register() { py_Type pk_generator__register() {
py_Type type = pk_newtype("generator", tp_object, NULL, (py_Dtor)Generator__dtor, false, true); py_Type type = pk_newtype("generator", tp_object, NULL, (py_Dtor)Generator__dtor, false, true);
pk__tp_set_marker(type, generator__gc_mark);
py_bindmagic(type, __iter__, pk_wrapper__self); py_bindmagic(type, __iter__, pk_wrapper__self);
py_bindmagic(type, __next__, generator__next__); py_bindmagic(type, __next__, generator__next__);
return type; return type;

View File

@ -604,13 +604,6 @@ void PyObject__dtor(PyObject* self) {
if(self->slots == -1) NameDict__dtor(PyObject__dict(self)); if(self->slots == -1) NameDict__dtor(PyObject__dict(self));
} }
void pk__mark_namedict(NameDict* dict) {
for(int i = 0; i < dict->length; i++) {
NameDict_KV* kv = c11__at(NameDict_KV, dict, i);
pk__mark_value(&kv->value);
}
}
void pk__tp_set_marker(py_Type type, void (*gc_mark)(void*)) { void pk__tp_set_marker(py_Type type, void (*gc_mark)(void*)) {
py_TypeInfo* ti = pk__type_info(type); py_TypeInfo* ti = pk__type_info(type);
assert(ti->gc_mark == NULL); assert(ti->gc_mark == NULL);
@ -627,12 +620,42 @@ void PyObject__mark(PyObject* obj) {
for(int i = 0; i < obj->slots; i++) for(int i = 0; i < obj->slots; i++)
pk__mark_value(p + i); pk__mark_value(p + i);
} else if(obj->slots == -1) { } else if(obj->slots == -1) {
NameDict* dict = PyObject__dict(obj); NameDict* namedict = PyObject__dict(obj);
pk__mark_namedict(dict); for(int i = 0; i < namedict->length; i++) {
NameDict_KV* kv = c11__at(NameDict_KV, namedict, i);
pk__mark_value(&kv->value);
}
} }
void* ud = PyObject__userdata(obj);
switch(obj->type) {
case tp_list: {
List* self = ud;
for(int i = 0; i < self->length; i++) {
pk__mark_value(c11__at(py_TValue, self, i));
}
break;
}
case tp_dict: {
Dict* self = ud;
for(int i = 0; i < self->entries.length; i++) {
DictEntry* entry = c11__at(DictEntry, &self->entries, i);
if(py_isnil(&entry->key)) continue;
pk__mark_value(&entry->key);
pk__mark_value(&entry->val);
}
break;
}
case tp_generator: {
Generator* self = ud;
if(self->frame) Frame__gc_mark(self->frame);
break;
}
default: {
py_TypeInfo* ti = pk__type_info(obj->type); py_TypeInfo* ti = pk__type_info(obj->type);
if(ti->gc_mark) ti->gc_mark(PyObject__userdata(obj)); if(ti->gc_mark) ti->gc_mark(ud);
}
}
} }
void FuncDecl__gc_mark(const FuncDecl* self) { void FuncDecl__gc_mark(const FuncDecl* self) {

View File

@ -776,7 +776,13 @@ py_TValue pk_builtins__register() {
static void function__gc_mark(void* ud) { static void function__gc_mark(void* ud) {
Function* func = ud; Function* func = ud;
if(func->globals) pk__mark_value(func->globals); if(func->globals) pk__mark_value(func->globals);
if(func->closure) pk__mark_namedict(func->closure); if(func->closure) {
NameDict* namedict = func->closure;
for(int i = 0; i < namedict->length; i++) {
NameDict_KV* kv = c11__at(NameDict_KV, namedict, i);
pk__mark_value(&kv->value);
}
}
FuncDecl__gc_mark(func->decl); FuncDecl__gc_mark(func->decl);
} }

View File

@ -5,8 +5,6 @@
#include "pocketpy/objects/object.h" #include "pocketpy/objects/object.h"
#include "pocketpy/interpreter/vm.h" #include "pocketpy/interpreter/vm.h"
#define PK_DICT_MAX_COLLISION 4
static uint32_t Dict__next_cap(uint32_t cap) { static uint32_t Dict__next_cap(uint32_t cap) {
switch(cap) { switch(cap) {
case 7: return 17; case 7: return 17;
@ -53,22 +51,7 @@ static uint32_t Dict__next_cap(uint32_t cap) {
} }
} }
typedef struct {
uint64_t hash;
py_TValue key;
py_TValue val;
} DictEntry;
typedef struct {
int _[PK_DICT_MAX_COLLISION];
} DictIndex;
typedef struct {
int length;
uint32_t capacity;
DictIndex* indices;
c11_vector /*T=DictEntry*/ entries;
} Dict;
typedef struct { typedef struct {
DictEntry* curr; DictEntry* curr;
@ -525,21 +508,9 @@ static bool dict_values(int argc, py_Ref argv) {
return true; return true;
} }
static void dict__gc_mark(void* ud) {
Dict* self = ud;
for(int i = 0; i < self->entries.length; i++) {
DictEntry* entry = c11__at(DictEntry, &self->entries, i);
if(py_isnil(&entry->key)) continue;
pk__mark_value(&entry->key);
pk__mark_value(&entry->val);
}
}
py_Type pk_dict__register() { py_Type pk_dict__register() {
py_Type type = pk_newtype("dict", tp_object, NULL, (void (*)(void*))Dict__dtor, false, false); py_Type type = pk_newtype("dict", tp_object, NULL, (void (*)(void*))Dict__dtor, false, false);
pk__tp_set_marker(type, dict__gc_mark);
py_bindmagic(type, __new__, dict__new__); py_bindmagic(type, __new__, dict__new__);
py_bindmagic(type, __init__, dict__init__); py_bindmagic(type, __init__, dict__init__);
py_bindmagic(type, __getitem__, dict__getitem__); py_bindmagic(type, __getitem__, dict__getitem__);

View File

@ -5,8 +5,6 @@
#include "pocketpy/interpreter/vm.h" #include "pocketpy/interpreter/vm.h"
#include "pocketpy/common/sstream.h" #include "pocketpy/common/sstream.h"
typedef c11_vector List;
void py_newlist(py_Ref out) { void py_newlist(py_Ref out) {
List* ud = py_newobject(out, tp_list, 0, sizeof(List)); List* ud = py_newobject(out, tp_list, 0, sizeof(List));
c11_vector__ctor(ud, sizeof(py_TValue)); c11_vector__ctor(ud, sizeof(py_TValue));
@ -404,19 +402,10 @@ static bool list__contains__(int argc, py_Ref argv) {
return pk_arraycontains(py_arg(0), py_arg(1)); return pk_arraycontains(py_arg(0), py_arg(1));
} }
static void list__gc_mark(void* ud) {
List* self = ud;
for(int i = 0; i < self->length; i++) {
pk__mark_value(c11__at(py_TValue, self, i));
}
}
py_Type pk_list__register() { py_Type pk_list__register() {
py_Type type = py_Type type =
pk_newtype("list", tp_object, NULL, (void (*)(void*))c11_vector__dtor, false, true); pk_newtype("list", tp_object, NULL, (void (*)(void*))c11_vector__dtor, false, true);
pk__tp_set_marker(type, list__gc_mark);
py_bindmagic(type, __len__, list__len__); py_bindmagic(type, __len__, list__len__);
py_bindmagic(type, __eq__, list__eq__); py_bindmagic(type, __eq__, list__eq__);
py_bindmagic(type, __ne__, list__ne__); py_bindmagic(type, __ne__, list__ne__);