blueloveTH 2 ani în urmă
părinte
comite
887c9cea38
5 a modificat fișierele cu 16 adăugiri și 13 ștergeri
  1. 2 3
      src/codeobject.h
  2. 3 1
      src/frame.h
  3. 4 3
      src/namedict.h
  4. 3 3
      src/obj.h
  5. 4 3
      src/vm.h

+ 2 - 3
src/codeobject.h

@@ -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);
 

+ 3 - 1
src/frame.h

@@ -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();

+ 4 - 3
src/namedict.h

@@ -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);
     }

+ 3 - 3
src/obj.h

@@ -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;
         }

+ 4 - 3
src/vm.h

@@ -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<- ]