diff --git a/include/pocketpy/dict.h b/include/pocketpy/dict.h index b2f98371..b946cea9 100644 --- a/include/pocketpy/dict.h +++ b/include/pocketpy/dict.h @@ -11,17 +11,12 @@ struct Dict{ struct Item{ PyVar first; PyVar second; - }; - - struct ItemNode{ int prev; int next; }; - static constexpr int __Capacity = 4; + static constexpr int __Capacity = 8; static constexpr float __LoadFactor = 0.67f; - static_assert(sizeof(Item) * __Capacity <= 128); - static_assert(sizeof(ItemNode) * __Capacity <= 64); int _capacity; int _mask; @@ -30,7 +25,6 @@ struct Dict{ int _head_idx; // for order preserving int _tail_idx; // for order preserving Item* _items; - ItemNode* _nodes; // for order preserving Dict(); Dict(Dict&& other); @@ -49,7 +43,7 @@ struct Dict{ PyVar try_get(VM* vm, PyVar key) const; bool contains(VM* vm, PyVar key) const; - bool erase(VM* vm, PyVar key); + bool del(VM* vm, PyVar key); void update(VM* vm, const Dict& other); template @@ -57,7 +51,7 @@ struct Dict{ int i = _head_idx; while(i != -1){ f(_items[i].first, _items[i].second); - i = _nodes[i].next; + i = _items[i].next; } } @@ -66,6 +60,8 @@ struct Dict{ void clear(); ~Dict(); + void __alloc_items(); + void _gc_mark(VM*) const; }; diff --git a/include/pocketpy/memory.h b/include/pocketpy/memory.h index 14327ae4..0b1c3c74 100644 --- a/include/pocketpy/memory.h +++ b/include/pocketpy/memory.h @@ -4,17 +4,8 @@ namespace pkpy{ -void* pool64_alloc(size_t) noexcept; -void pool64_dealloc(void*) noexcept; - void* pool128_alloc(size_t) noexcept; void pool128_dealloc(void*) noexcept; - -template -void* pool64_alloc() noexcept{ - return pool64_alloc(sizeof(T)); -} - template void* pool128_alloc() noexcept{ return pool128_alloc(sizeof(T)); diff --git a/src/dict.cpp b/src/dict.cpp index f83d6bc9..20c81996 100644 --- a/src/dict.cpp +++ b/src/dict.cpp @@ -5,10 +5,17 @@ namespace pkpy{ Dict::Dict(): _capacity(__Capacity), _mask(__Capacity-1), _size(0), _critical_size(__Capacity*__LoadFactor+0.5f), _head_idx(-1), _tail_idx(-1){ - _items = (Item*)pool128_alloc(_capacity * sizeof(Item)); - memset(_items, 0, _capacity * sizeof(Item)); - _nodes = (ItemNode*)pool64_alloc(_capacity * sizeof(ItemNode)); - memset(_nodes, -1, _capacity * sizeof(ItemNode)); + __alloc_items(); + } + + void Dict::__alloc_items(){ + _items = (Item*)malloc(_capacity * sizeof(Item)); + for(int i=0; i<_capacity; i++){ + _items[i].first = nullptr; + _items[i].second = nullptr; + _items[i].prev = -1; + _items[i].next = -1; + } } Dict::Dict(Dict&& other){ @@ -19,9 +26,7 @@ namespace pkpy{ _head_idx = other._head_idx; _tail_idx = other._tail_idx; _items = other._items; - _nodes = other._nodes; other._items = nullptr; - other._nodes = nullptr; } Dict::Dict(const Dict& other){ @@ -31,10 +36,9 @@ namespace pkpy{ _critical_size = other._critical_size; _head_idx = other._head_idx; _tail_idx = other._tail_idx; - _items = (Item*)pool128_alloc(_capacity * sizeof(Item)); + // copy items + _items = (Item*)malloc(_capacity * sizeof(Item)); memcpy(_items, other._items, _capacity * sizeof(Item)); - _nodes = (ItemNode*)pool64_alloc(_capacity * sizeof(ItemNode)); - memcpy(_nodes, other._nodes, _capacity * sizeof(ItemNode)); } void Dict::set(VM* vm, PyVar key, PyVar val){ @@ -51,8 +55,8 @@ namespace pkpy{ _head_idx = i; _tail_idx = i; }else{ - _nodes[i].prev = _tail_idx; - _nodes[_tail_idx].next = i; + _items[i].prev = _tail_idx; + _items[_tail_idx].next = i; _tail_idx = i; } } @@ -61,7 +65,6 @@ namespace pkpy{ void Dict::_rehash(VM* vm){ Item* old_items = _items; - ItemNode* old_nodes = _nodes; int old_head_idx = _head_idx; _capacity *= 4; @@ -71,19 +74,16 @@ namespace pkpy{ _head_idx = -1; _tail_idx = -1; - _items = (Item*)pool128_alloc(_capacity * sizeof(Item)); - memset(_items, 0, _capacity * sizeof(Item)); - _nodes = (ItemNode*)pool64_alloc(_capacity * sizeof(ItemNode)); - memset(_nodes, -1, _capacity * sizeof(ItemNode)); + __alloc_items(); // copy old items to new dict int i = old_head_idx; while(i != -1){ set(vm, old_items[i].first, old_items[i].second); - i = old_nodes[i].next; + i = old_items[i].next; } - pool128_dealloc(old_items); - pool64_dealloc(old_nodes); + + free(old_items); } @@ -100,7 +100,7 @@ namespace pkpy{ return ok; } - bool Dict::erase(VM* vm, PyVar key){ + bool Dict::del(VM* vm, PyVar key){ bool ok; int i; _probe_0(vm, key, ok, i); if(!ok) return false; @@ -113,18 +113,18 @@ namespace pkpy{ _tail_idx = -1; }else{ if(_head_idx == i){ - _head_idx = _nodes[i].next; - _nodes[_head_idx].prev = -1; + _head_idx = _items[i].next; + _items[_head_idx].prev = -1; }else if(_tail_idx == i){ - _tail_idx = _nodes[i].prev; - _nodes[_tail_idx].next = -1; + _tail_idx = _items[i].prev; + _items[_tail_idx].next = -1; }else{ - _nodes[_nodes[i].prev].next = _nodes[i].next; - _nodes[_nodes[i].next].prev = _nodes[i].prev; + _items[_items[i].prev].next = _items[i].next; + _items[_items[i].next].prev = _items[i].prev; } } - _nodes[i].prev = -1; - _nodes[i].next = -1; + _items[i].prev = -1; + _items[i].next = -1; return true; } @@ -138,7 +138,7 @@ namespace pkpy{ int j = 0; while(i != -1){ t[j++] = _items[i].first; - i = _nodes[i].next; + i = _items[i].next; } PK_ASSERT(j == _size); return t; @@ -150,7 +150,7 @@ namespace pkpy{ int j = 0; while(i != -1){ t[j++] = _items[i].second; - i = _nodes[i].next; + i = _items[i].next; } PK_ASSERT(j == _size); return t; @@ -160,13 +160,15 @@ namespace pkpy{ _size = 0; _head_idx = -1; _tail_idx = -1; - memset(_items, 0, _capacity * sizeof(Item)); - memset(_nodes, -1, _capacity * sizeof(ItemNode)); + for(int i=0; i<_capacity; i++){ + _items[i].first = nullptr; + _items[i].second = nullptr; + _items[i].prev = -1; + _items[i].next = -1; + } } Dict::~Dict(){ - if(_items==nullptr) return; - pool128_dealloc(_items); - pool64_dealloc(_nodes); + if(_items) free(_items); } } // namespace pkpy \ No newline at end of file diff --git a/src/iter.cpp b/src/iter.cpp index 9994be55..55964d49 100644 --- a/src/iter.cpp +++ b/src/iter.cpp @@ -118,7 +118,7 @@ namespace pkpy{ if(self.i == -1) return 0; vm->s_data.push(d._items[self.i].first); vm->s_data.push(d._items[self.i].second); - self.i = d._nodes[self.i].next; + self.i = d._items[self.i].next; return 2; }); } diff --git a/src/memory.cpp b/src/memory.cpp index 695c83e5..55ba8357 100644 --- a/src/memory.cpp +++ b/src/memory.cpp @@ -267,21 +267,17 @@ struct MemoryPool{ } }; -static MemoryPool<64> pool64; static MemoryPool<128> pool128; -void* pool64_alloc(size_t size) noexcept { return pool64.alloc(size); } -void pool64_dealloc(void* p) noexcept { pool64.dealloc(p); } void* pool128_alloc(size_t size) noexcept { return pool128.alloc(size); } void pool128_dealloc(void* p) noexcept { pool128.dealloc(p); } void pools_shrink_to_fit() noexcept { - pool64.shrink_to_fit(); pool128.shrink_to_fit(); } -std::string pool64_info() noexcept { return pool64.info(); } +std::string pool64_info() noexcept { return "unavailable"; } std::string pool128_info() noexcept { return pool128.info(); } } \ No newline at end of file diff --git a/src/pocketpy.cpp b/src/pocketpy.cpp index 6be64dbf..6c751b6c 100644 --- a/src/pocketpy.cpp +++ b/src/pocketpy.cpp @@ -1345,7 +1345,7 @@ void __init_builtins(VM* _vm) { _vm->bind__delitem__(VM::tp_dict, [](VM* vm, PyVar _0, PyVar _1) { Dict& self = _CAST(Dict&, _0); - bool ok = self.erase(vm, _1); + bool ok = self.del(vm, _1); if(!ok) vm->KeyError(_1); }); @@ -1362,7 +1362,7 @@ void __init_builtins(VM* _vm) { return args[2]; } } - self.erase(vm, args[1]); + self.del(vm, args[1]); return value; });