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::vector<FuncDecl_> func_decls;
// may be.. just use a large NameDict?
uint32_t perfect_locals_capacity = 2;
uint32_t perfect_hash_seed = 0;
uint32_t perfect_locals_capacity = NameDict::__Capacity;
uint32_t perfect_hash_seed = kHashSeeds[0];
void optimize(VM* vm);

View File

@ -26,7 +26,7 @@ struct Frame {
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) {
}
@ -153,6 +153,8 @@ struct Frame {
}
void _gc_mark() const {
// this frame has been moved
if(_data._data == nullptr) return;
for(PyObject* obj : _data) OBJ_MARK(obj);
OBJ_MARK(_module);
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 {
using Item = std::pair<StrName, PyObject*>;
static constexpr uint16_t __Capacity = 128/sizeof(Item);
float _load_factor;
uint16_t _capacity;
uint16_t _size;
float _load_factor;
uint16_t _hash_seed;
uint16_t _mask;
Item* _items;
@ -46,8 +47,8 @@ struct NameDict {
memset(_items, 0, cap * sizeof(Item));
}
NameDict(uint16_t capacity=2, float load_factor=0.67, uint16_t hash_seed=kHashSeeds[0]):
_capacity(capacity), _size(0), _load_factor(load_factor),
NameDict(float load_factor=0.67, uint16_t capacity=__Capacity, uint16_t hash_seed=kHashSeeds[0]):
_load_factor(load_factor), _capacity(capacity), _size(0),
_hash_seed(hash_seed), _mask(capacity-1) {
_alloc(capacity);
}

View File

@ -131,11 +131,11 @@ struct Py_ : PyObject {
void _init() noexcept {
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>){
_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>){
_attr = new(pool64.alloc<NameDict>()) NameDict(8, kInstAttrLoadFactor);
_attr = new(pool64.alloc<NameDict>()) NameDict(kInstAttrLoadFactor);
}else{
_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
// TODO: ...
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);
}
@ -701,8 +701,8 @@ inline PyObject* VM::call(PyObject* callable, Args args, const Args& kwargs, boo
} else if(is_type(callable, tp_function)){
const Function& fn = CAST(Function&, callable);
NameDict_ locals = make_sp<NameDict>(
fn.decl->code->perfect_locals_capacity,
kLocalsLoadFactor,
fn.decl->code->perfect_locals_capacity,
fn.decl->code->perfect_hash_seed
);
@ -910,6 +910,7 @@ inline PyObject* VM::_exec(){
FrameId frame = top_frame();
const int base_id = frame.index;
bool need_raise = false;
PyObject* ret;
while(true){
#if DEBUG_EXTRA_CHECK
@ -917,7 +918,7 @@ inline PyObject* VM::_exec(){
#endif
try{
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_call){
if(frame.index == base_id){ // [ frameBase<- ]