This commit is contained in:
blueloveTH 2023-04-09 22:03:59 +08:00
parent 3581e06ed5
commit 887c9cea38
5 changed files with 16 additions and 13 deletions

View File

@ -62,9 +62,8 @@ struct CodeObject {
std::map<StrName, int> labels; std::map<StrName, int> labels;
std::vector<FuncDecl_> func_decls; std::vector<FuncDecl_> func_decls;
// may be.. just use a large NameDict? uint32_t perfect_locals_capacity = NameDict::__Capacity;
uint32_t perfect_locals_capacity = 2; uint32_t perfect_hash_seed = kHashSeeds[0];
uint32_t perfect_hash_seed = 0;
void optimize(VM* vm); void optimize(VM* vm);

View File

@ -26,7 +26,7 @@ struct Frame {
return _closure->try_get(name); return _closure->try_get(name);
} }
Frame(const CodeObject_& co, PyObject* _module, NameDict_ _locals=nullptr, NameDict_ _closure=nullptr) Frame(const CodeObject_& co, PyObject* _module, const NameDict_& _locals=nullptr, const NameDict_& _closure=nullptr)
: co(co.get()), _module(_module), _locals(_locals), _closure(_closure) { : co(co.get()), _module(_module), _locals(_locals), _closure(_closure) {
} }
@ -153,6 +153,8 @@ struct Frame {
} }
void _gc_mark() const { void _gc_mark() const {
// this frame has been moved
if(_data._data == nullptr) return;
for(PyObject* obj : _data) OBJ_MARK(obj); for(PyObject* obj : _data) OBJ_MARK(obj);
OBJ_MARK(_module); OBJ_MARK(_module);
if(_locals != nullptr) _locals->_gc_mark(); if(_locals != nullptr) _locals->_gc_mark();

View File

@ -34,9 +34,10 @@ inline static uint16_t find_perfect_hash_seed(uint16_t capacity, const std::vect
struct NameDict { struct NameDict {
using Item = std::pair<StrName, PyObject*>; using Item = std::pair<StrName, PyObject*>;
static constexpr uint16_t __Capacity = 128/sizeof(Item);
float _load_factor;
uint16_t _capacity; uint16_t _capacity;
uint16_t _size; uint16_t _size;
float _load_factor;
uint16_t _hash_seed; uint16_t _hash_seed;
uint16_t _mask; uint16_t _mask;
Item* _items; Item* _items;
@ -46,8 +47,8 @@ struct NameDict {
memset(_items, 0, cap * sizeof(Item)); memset(_items, 0, cap * sizeof(Item));
} }
NameDict(uint16_t capacity=2, float load_factor=0.67, uint16_t hash_seed=kHashSeeds[0]): NameDict(float load_factor=0.67, uint16_t capacity=__Capacity, uint16_t hash_seed=kHashSeeds[0]):
_capacity(capacity), _size(0), _load_factor(load_factor), _load_factor(load_factor), _capacity(capacity), _size(0),
_hash_seed(hash_seed), _mask(capacity-1) { _hash_seed(hash_seed), _mask(capacity-1) {
_alloc(capacity); _alloc(capacity);
} }

View File

@ -131,11 +131,11 @@ struct Py_ : PyObject {
void _init() noexcept { void _init() noexcept {
if constexpr (std::is_same_v<T, Type> || std::is_same_v<T, DummyModule>) { if constexpr (std::is_same_v<T, Type> || std::is_same_v<T, DummyModule>) {
_attr = new(pool64.alloc<NameDict>()) NameDict(8, kTypeAttrLoadFactor); _attr = new(pool64.alloc<NameDict>()) NameDict(kTypeAttrLoadFactor);
}else if constexpr(std::is_same_v<T, DummyInstance>){ }else if constexpr(std::is_same_v<T, DummyInstance>){
_attr = new(pool64.alloc<NameDict>()) NameDict(8, kInstAttrLoadFactor); _attr = new(pool64.alloc<NameDict>()) NameDict(kInstAttrLoadFactor);
}else if constexpr(std::is_same_v<T, Function> || std::is_same_v<T, NativeFunc>){ }else if constexpr(std::is_same_v<T, Function> || std::is_same_v<T, NativeFunc>){
_attr = new(pool64.alloc<NameDict>()) NameDict(8, kInstAttrLoadFactor); _attr = new(pool64.alloc<NameDict>()) NameDict(kInstAttrLoadFactor);
}else{ }else{
_attr = nullptr; _attr = nullptr;
} }

View File

@ -365,7 +365,7 @@ inline void CodeObject::optimize(VM* vm){
// here we simple pass all names, but only some of them are NAME_LOCAL // here we simple pass all names, but only some of them are NAME_LOCAL
// TODO: ... // TODO: ...
uint32_t base_n = (uint32_t)(names.size() / kLocalsLoadFactor + 0.5); uint32_t base_n = (uint32_t)(names.size() / kLocalsLoadFactor + 0.5);
perfect_locals_capacity = find_next_capacity(base_n); perfect_locals_capacity = std::max(find_next_capacity(base_n), NameDict::__Capacity);
perfect_hash_seed = find_perfect_hash_seed(perfect_locals_capacity, names); perfect_hash_seed = find_perfect_hash_seed(perfect_locals_capacity, names);
} }
@ -701,8 +701,8 @@ inline PyObject* VM::call(PyObject* callable, Args args, const Args& kwargs, boo
} else if(is_type(callable, tp_function)){ } else if(is_type(callable, tp_function)){
const Function& fn = CAST(Function&, callable); const Function& fn = CAST(Function&, callable);
NameDict_ locals = make_sp<NameDict>( NameDict_ locals = make_sp<NameDict>(
fn.decl->code->perfect_locals_capacity,
kLocalsLoadFactor, kLocalsLoadFactor,
fn.decl->code->perfect_locals_capacity,
fn.decl->code->perfect_hash_seed fn.decl->code->perfect_hash_seed
); );
@ -910,6 +910,7 @@ inline PyObject* VM::_exec(){
FrameId frame = top_frame(); FrameId frame = top_frame();
const int base_id = frame.index; const int base_id = frame.index;
bool need_raise = false; bool need_raise = false;
PyObject* ret;
while(true){ while(true){
#if DEBUG_EXTRA_CHECK #if DEBUG_EXTRA_CHECK
@ -917,7 +918,7 @@ inline PyObject* VM::_exec(){
#endif #endif
try{ try{
if(need_raise){ need_raise = false; _raise(); } if(need_raise){ need_raise = false; _raise(); }
PyObject* ret = run_frame(frame); ret = run_frame(frame);
if(ret == _py_op_yield) return _py_op_yield; if(ret == _py_op_yield) return _py_op_yield;
if(ret != _py_op_call){ if(ret != _py_op_call){
if(frame.index == base_id){ // [ frameBase<- ] if(frame.index == base_id){ // [ frameBase<- ]