mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 03:20:18 +00:00
improve performance
This commit is contained in:
parent
160bc99d04
commit
b3084a5c87
25
include/pocketpy/interpreter/types.h
Normal file
25
include/pocketpy/interpreter/types.h
Normal 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;
|
@ -8,6 +8,7 @@
|
||||
#include "pocketpy/interpreter/modules.h"
|
||||
#include "pocketpy/interpreter/typeinfo.h"
|
||||
#include "pocketpy/interpreter/name.h"
|
||||
#include "pocketpy/interpreter/types.h"
|
||||
|
||||
// TODO:
|
||||
// 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);
|
||||
|
||||
#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*));
|
||||
bool pk__object_new(int argc, py_Ref argv);
|
||||
py_TypeInfo* pk__type_info(py_Type type);
|
||||
|
@ -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 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, __next__, generator__next__);
|
||||
return type;
|
||||
|
@ -604,13 +604,6 @@ void PyObject__dtor(PyObject* 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*)) {
|
||||
py_TypeInfo* ti = pk__type_info(type);
|
||||
assert(ti->gc_mark == NULL);
|
||||
@ -627,12 +620,42 @@ void PyObject__mark(PyObject* obj) {
|
||||
for(int i = 0; i < obj->slots; i++)
|
||||
pk__mark_value(p + i);
|
||||
} else if(obj->slots == -1) {
|
||||
NameDict* dict = PyObject__dict(obj);
|
||||
pk__mark_namedict(dict);
|
||||
NameDict* namedict = PyObject__dict(obj);
|
||||
for(int i = 0; i < namedict->length; i++) {
|
||||
NameDict_KV* kv = c11__at(NameDict_KV, namedict, i);
|
||||
pk__mark_value(&kv->value);
|
||||
}
|
||||
}
|
||||
|
||||
py_TypeInfo* ti = pk__type_info(obj->type);
|
||||
if(ti->gc_mark) ti->gc_mark(PyObject__userdata(obj));
|
||||
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);
|
||||
if(ti->gc_mark) ti->gc_mark(ud);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FuncDecl__gc_mark(const FuncDecl* self) {
|
||||
|
@ -776,7 +776,13 @@ py_TValue pk_builtins__register() {
|
||||
static void function__gc_mark(void* ud) {
|
||||
Function* func = ud;
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -5,8 +5,6 @@
|
||||
#include "pocketpy/objects/object.h"
|
||||
#include "pocketpy/interpreter/vm.h"
|
||||
|
||||
#define PK_DICT_MAX_COLLISION 4
|
||||
|
||||
static uint32_t Dict__next_cap(uint32_t cap) {
|
||||
switch(cap) {
|
||||
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 {
|
||||
DictEntry* curr;
|
||||
@ -525,21 +508,9 @@ static bool dict_values(int argc, py_Ref argv) {
|
||||
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 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, __init__, dict__init__);
|
||||
py_bindmagic(type, __getitem__, dict__getitem__);
|
||||
|
@ -5,8 +5,6 @@
|
||||
#include "pocketpy/interpreter/vm.h"
|
||||
#include "pocketpy/common/sstream.h"
|
||||
|
||||
typedef c11_vector List;
|
||||
|
||||
void py_newlist(py_Ref out) {
|
||||
List* ud = py_newobject(out, tp_list, 0, sizeof(List));
|
||||
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));
|
||||
}
|
||||
|
||||
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 type =
|
||||
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, __eq__, list__eq__);
|
||||
py_bindmagic(type, __ne__, list__ne__);
|
||||
|
Loading…
x
Reference in New Issue
Block a user