mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 11:30: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/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);
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
py_TypeInfo* ti = pk__type_info(obj->type);
|
void* ud = PyObject__userdata(obj);
|
||||||
if(ti->gc_mark) ti->gc_mark(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) {
|
void FuncDecl__gc_mark(const FuncDecl* self) {
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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__);
|
||||||
|
@ -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__);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user