add smallmap

This commit is contained in:
blueloveTH 2024-06-15 19:14:15 +08:00
parent 649fb3cd98
commit 2093f6f10f
11 changed files with 149 additions and 41 deletions

View File

@ -8,7 +8,7 @@ extern "C" {
#define c11__less(a, b) ((a) < (b)) #define c11__less(a, b) ((a) < (b))
#define c11__lower_bound(T, ptr, count, key, less, out) \ #define c11__lower_bound(T, ptr, count, key, less, out_index) \
do { \ do { \
T* __first = ptr; \ T* __first = ptr; \
int __len = count; \ int __len = count; \
@ -22,7 +22,7 @@ extern "C" {
__len = __l2; \ __len = __l2; \
} \ } \
} \ } \
*(out) = __first; \ *(out_index) = __first - (T*)(ptr); \
} while(0) } while(0)
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -1,8 +1,11 @@
#pragma once #pragma once
#include "pocketpy/common/algorithm.h"
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include "pocketpy/common/algorithm.h" #include <stdbool.h>
#include <assert.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -17,7 +20,6 @@ typedef struct c11_array{
void c11_array__ctor(c11_array* self, int elem_size, int count); void c11_array__ctor(c11_array* self, int elem_size, int count);
void c11_array__dtor(c11_array* self); void c11_array__dtor(c11_array* self);
c11_array c11_array__copy(const c11_array* self); c11_array c11_array__copy(const c11_array* self);
void* c11_array__at(c11_array* self, int index);
typedef struct c11_vector{ typedef struct c11_vector{
void* data; void* data;
@ -29,12 +31,12 @@ typedef struct c11_vector{
void c11_vector__ctor(c11_vector* self, int elem_size); void c11_vector__ctor(c11_vector* self, int elem_size);
void c11_vector__dtor(c11_vector* self); void c11_vector__dtor(c11_vector* self);
c11_vector c11_vector__copy(const c11_vector* self); c11_vector c11_vector__copy(const c11_vector* self);
void* c11_vector__at(c11_vector* self, int index);
void c11_vector__reserve(c11_vector* self, int capacity); void c11_vector__reserve(c11_vector* self, int capacity);
void c11_vector__clear(c11_vector* self); void c11_vector__clear(c11_vector* self);
#define c11__getitem(T, self, index) ((T*)(self)->data)[index] #define c11__getitem(T, self, index) (((T*)(self)->data)[index])
#define c11__setitem(T, self, index, value) ((T*)(self)->data)[index] = value; #define c11__setitem(T, self, index, value) ((T*)(self)->data)[index] = value;
#define c11__at(T, self, index) ((T*)(self)->data + index)
#define c11_vector__push(T, self, elem) \ #define c11_vector__push(T, self, elem) \
do{ \ do{ \
@ -56,19 +58,19 @@ void c11_vector__clear(c11_vector* self);
}while(0) }while(0)
#define c11_vector__insert(T, self, p, elem) \ #define c11_vector__insert(T, self, index, elem) \
do{ \ do{ \
if((self)->count == (self)->capacity) c11_vector__reserve((self), (self)->capacity*2); \ if((self)->count == (self)->capacity) c11_vector__reserve((self), (self)->capacity*2); \
int __n = (self)->count - (p - (T*)(self)->data); \ T* p = (T*)(self)->data + (index); \
memmove(p + 1, p, __n * sizeof(T)); \ memmove(p + 1, p, ((self)->count - (index)) * sizeof(T)); \
*p = (elem); \ *p = (elem); \
(self)->count++; \ (self)->count++; \
}while(0) }while(0)
#define c11_vector__erase(T, self, p) \ #define c11_vector__erase(T, self, index) \
do{ \ do{ \
int __n = (self)->count - (p - (T*)(self)->data) - 1; \ T* p = (T*)(self)->data + (index); \
memmove(p, p + 1, __n * sizeof(T)); \ memmove(p, p + 1, ((self)->count - (index) - 1) * sizeof(T)); \
(self)->count--; \ (self)->count--; \
}while(0) }while(0)

View File

@ -189,7 +189,6 @@ public:
PyObject* __last_exception; PyObject* __last_exception;
PyObject* __curr_class; PyObject* __curr_class;
PyVar __cached_object_new; PyVar __cached_object_new;
small_map<std::string_view, CodeObject_> __cached_codes;
small_map<std::string_view, PyVar> __cached_op_funcs; small_map<std::string_view, PyVar> __cached_op_funcs;
FuncDecl_ __dynamic_func_decl; FuncDecl_ __dynamic_func_decl;
PyVar __vectorcall_buffer[PK_MAX_CO_VARNAMES]; PyVar __vectorcall_buffer[PK_MAX_CO_VARNAMES];

View File

@ -4,6 +4,7 @@
#include "pocketpy/objects/tuplelist.hpp" #include "pocketpy/objects/tuplelist.hpp"
#include "pocketpy/objects/namedict.hpp" #include "pocketpy/objects/namedict.hpp"
#include "pocketpy/objects/sourcedata.hpp" #include "pocketpy/objects/sourcedata.hpp"
#include "pocketpy/common/smallmap.h"
namespace pkpy { namespace pkpy {
@ -126,15 +127,22 @@ struct FuncDecl {
const char* docstring; // docstring of this function (weak ref) const char* docstring; // docstring of this function (weak ref)
FuncType type = FuncType::UNSET; FuncType type = FuncType::UNSET;
c11_smallmap_uint16_t_int kw_to_index;
small_map<StrName, int> kw_to_index;
void add_kwarg(int index, StrName key, PyVar value) { void add_kwarg(int index, StrName key, PyVar value) {
kw_to_index.insert(key, index); c11_smallmap_uint16_t_int__set(&kw_to_index, key.index, index);
kwargs.push_back(KwArg{index, key, value}); kwargs.push_back(KwArg{index, key, value});
} }
void _gc_mark(VM*) const; void _gc_mark(VM*) const;
FuncDecl(){
c11_smallmap_uint16_t_int__ctor(&kw_to_index);
}
~FuncDecl(){
c11_smallmap_uint16_t_int__dtor(&kw_to_index);
}
}; };
struct NativeFunc { struct NativeFunc {

View File

@ -0,0 +1,108 @@
#pragma once
#if !defined(SMALLMAP_T__HEADER) && !defined(SMALLMAP_T__SOURCE)
#include "pocketpy/common/vector.h"
/* Input */
#define K int
#define V float
#endif
/* Optional Input */
#ifndef less
#define less(a, b) ((a.key) < (b))
#endif
/* Temprary macros */
#define CONCAT(A, B) CONCAT_(A, B)
#define CONCAT_(A, B) A##B
#define KV CONCAT(CONCAT(c11_smallmap_entry_, K), CONCAT(_, V))
#define SMALLMAP CONCAT(CONCAT(c11_smallmap_, K), CONCAT(_, V))
#define SMALLMAP_METHOD(name) CONCAT(SMALLMAP, CONCAT(__, name))
typedef struct {
K key;
V value;
} KV;
typedef struct{
c11_vector entries;
} SMALLMAP;
void SMALLMAP_METHOD(ctor)(SMALLMAP* self);
void SMALLMAP_METHOD(dtor)(SMALLMAP* self);
void SMALLMAP_METHOD(set)(SMALLMAP* self, K key, V value);
V* SMALLMAP_METHOD(try_get)(SMALLMAP* self, K key);
V SMALLMAP_METHOD(get)(SMALLMAP* self, K key, V default_value);
bool SMALLMAP_METHOD(contains)(SMALLMAP* self, K key);
bool SMALLMAP_METHOD(del)(SMALLMAP* self, K key);
void SMALLMAP_METHOD(clear)(SMALLMAP* self);
#ifdef SMALLMAP_T__SOURCE
/* Implementation */
void SMALLMAP_METHOD(ctor)(SMALLMAP* self) {
c11_vector__ctor(&self->entries, sizeof(KV));
}
void SMALLMAP_METHOD(dtor)(SMALLMAP* self) {
c11_vector__dtor(&self->entries);
}
void SMALLMAP_METHOD(set)(SMALLMAP* self, K key, V value) {
int index;
c11__lower_bound(KV, self->entries.data, self->entries.count, key, less, &index);
KV* it = c11__at(KV, &self->entries, index);
if(index != self->entries.count && it->key == key) {
it->value = value;
} else {
KV kv = {key, value};
c11_vector__insert(KV, &self->entries, index, kv);
}
}
V* SMALLMAP_METHOD(try_get)(SMALLMAP* self, K key) {
int index;
c11__lower_bound(KV, self->entries.data, self->entries.count, key, less, &index);
KV* it = c11__at(KV, &self->entries, index);
if(index != self->entries.count && it->key == key) {
return &it->value;
} else {
return NULL;
}
}
V SMALLMAP_METHOD(get)(SMALLMAP* self, K key, V default_value) {
V* p = SMALLMAP_METHOD(try_get)(self, key);
return p ? *p : default_value;
}
bool SMALLMAP_METHOD(contains)(SMALLMAP* self, K key) {
return SMALLMAP_METHOD(try_get)(self, key) != NULL;
}
bool SMALLMAP_METHOD(del)(SMALLMAP* self, K key) {
int index;
c11__lower_bound(KV, self->entries.data, self->entries.count, key, less, &index);
KV* it = c11__at(KV, &self->entries, index);
if(index != self->entries.count && it->key == key) {
c11_vector__erase(KV, &self->entries, index);
return true;
}
return false;
}
void SMALLMAP_METHOD(clear)(SMALLMAP* self) {
c11_vector__clear(&self->entries);
}
#endif
#undef KV
#undef SMALLMAP
#undef SMALLMAP_METHOD
#undef K
#undef V
#undef less

8
src/common/smallmap.c Normal file
View File

@ -0,0 +1,8 @@
#include "pocketpy/common/vector.h"
#include <stdint.h>
#define SMALLMAP_T__SOURCE
#define K uint16_t
#define V int
#include "pocketpy/xmacros/smallmap.h"
#undef SMALLMAP_T__SOURCE

View File

@ -386,9 +386,8 @@ static const int kLoRangeB[] = {170,186,443,451,660,1514,1522,1599,1610,1647,174
bool c11__is_unicode_Lo_char(int c){ bool c11__is_unicode_Lo_char(int c){
if(c == 0x1f955) return true; if(c == 0x1f955) return true;
const int* p; int index;
c11__lower_bound(const int, kLoRangeA, 476, c, c11__less, &p); c11__lower_bound(const int, kLoRangeA, 476, c, c11__less, &index);
int index = p - kLoRangeA;
if(c == kLoRangeA[index]) return true; if(c == kLoRangeA[index]) return true;
index -= 1; index -= 1;
if(index < 0) return false; if(index < 0) return false;

View File

@ -22,10 +22,6 @@ c11_array c11_array__copy(const c11_array* self){
return retval; return retval;
} }
void* c11_array__at(c11_array* self, int index){
return (char*)self->data + self->elem_size * index;
}
void c11_vector__ctor(c11_vector* self, int elem_size){ void c11_vector__ctor(c11_vector* self, int elem_size){
self->data = NULL; self->data = NULL;
self->count = 0; self->count = 0;
@ -49,10 +45,6 @@ c11_vector c11_vector__copy(const c11_vector* self){
return retval; return retval;
} }
void* c11_vector__at(c11_vector* self, int index){
return (char*)self->data + self->elem_size * index;
}
void c11_vector__reserve(c11_vector* self, int capacity){ void c11_vector__reserve(c11_vector* self, int capacity){
if(capacity < 4) capacity = 4; if(capacity < 4) capacity = 4;
if(capacity <= self->capacity) return; if(capacity <= self->capacity) return;

View File

@ -789,14 +789,8 @@ PyVar VM::__run_top_frame() {
case OP_FSTRING_EVAL: { case OP_FSTRING_EVAL: {
PyVar _0 = frame->co->consts[byte.arg]; PyVar _0 = frame->co->consts[byte.arg];
std::string_view string = CAST(Str&, _0).sv(); std::string_view string = CAST(Str&, _0).sv();
auto it = __cached_codes.try_get(string); // TODO: optimize this
CodeObject_ code; CodeObject_ code = vm->compile(string, "<eval>", EVAL_MODE, true);
if(it == nullptr) {
code = vm->compile(string, "<eval>", EVAL_MODE, true);
__cached_codes.insert(string, code);
} else {
code = *it;
}
_0 = vm->_exec(code.get(), frame->_module, frame->_callable, frame->_locals); _0 = vm->_exec(code.get(), frame->_module, frame->_callable, frame->_locals);
PUSH(_0); PUSH(_0);
} }

View File

@ -1009,7 +1009,7 @@ void VM::__prepare_py_call(PyVar* buffer, ArgsView args, ArgsView kwargs, const
for(int j = 0; j < kwargs.size(); j += 2) { for(int j = 0; j < kwargs.size(); j += 2) {
StrName key(_CAST(uint16_t, kwargs[j])); StrName key(_CAST(uint16_t, kwargs[j]));
int index = decl->kw_to_index.get(key, -1); int index = c11_smallmap_uint16_t_int__get(&decl->kw_to_index, key.index, -1);
// if key is an explicit key, set as local variable // if key is an explicit key, set as local variable
if(index >= 0) { if(index >= 0) {
buffer[index] = kwargs[j + 1]; buffer[index] = kwargs[j + 1];
@ -1865,8 +1865,6 @@ void ManagedHeap::mark() {
vm->callstack.apply([this](Frame& frame) { vm->callstack.apply([this](Frame& frame) {
frame._gc_mark(vm); frame._gc_mark(vm);
}); });
for(auto [_, co]: vm->__cached_codes)
co->_gc_mark(vm);
vm->obj_gc_mark(vm->__last_exception); vm->obj_gc_mark(vm->__last_exception);
vm->obj_gc_mark(vm->__curr_class); vm->obj_gc_mark(vm->__curr_class);
vm->obj_gc_mark(vm->__c.error); vm->obj_gc_mark(vm->__c.error);

View File

@ -199,9 +199,9 @@ struct Random {
List result(k); List result(k);
for(int i = 0; i < k; i++) { for(int i = 0; i < k; i++) {
f64 key = self.gen.uniform(0.0, cum_weights[size - 1]); f64 key = self.gen.uniform(0.0, cum_weights[size - 1]);
f64* p; int index;
c11__lower_bound(f64, cum_weights.begin(), cum_weights.size(), key, c11__less, &p); c11__lower_bound(f64, cum_weights.begin(), cum_weights.size(), key, c11__less, &index);
result[i] = data[p - cum_weights.begin()]; result[i] = data[index];
} }
return VAR(std::move(result)); return VAR(std::move(result));
}); });