From 1a174c118e63e04bdce22b1074f3c423860ebb79 Mon Sep 17 00:00:00 2001 From: Nikolay Igotti Date: Fri, 16 Sep 2016 18:01:52 +0300 Subject: [PATCH] Reference is single value. --- experiments/placer/placer.cc | 105 ++++++++++++++++++++++------------- 1 file changed, 65 insertions(+), 40 deletions(-) diff --git a/experiments/placer/placer.cc b/experiments/placer/placer.cc index ceb7f14fcd9..58b7724eacb 100644 --- a/experiments/placer/placer.cc +++ b/experiments/placer/placer.cc @@ -4,12 +4,14 @@ #include -struct Container { +class Container { + private: uint8_t* data_; uint8_t* current_; int size_; int ref_count_; + public: Container(int size) : size_(size), ref_count_(1) { data_ = reinterpret_cast(calloc(size_, 1)); @@ -22,22 +24,26 @@ struct Container { } void* Place(int size) { + size += sizeof(Container*); if (current_ + size > data_ + size_) { return nullptr; } - void* result = current_; + Container** result = reinterpret_cast(current_); + *result = this; current_ += size; return result; } void AddRef() { if (data_) { + //printf("addref %d\n", ref_count_); ref_count_++; } } void Release() { if (data_) { + // printf("release %d\n", ref_count_); ref_count_--; } } @@ -52,43 +58,61 @@ struct Container { }; template -struct Ref { - T* ref_; - Container* container_; +class Ref { + private: + void* ptr_; - Ref() : ref_(nullptr), container_(nullptr) {} - Ref(const Ref& other) : ref_(nullptr), container_(nullptr) { + explicit Ref(void* ptr) : ptr_(ptr) { + if (ptr_) { + container()->AddRef(); + } + } + + public: + Ref() : ptr_(nullptr) {} + Ref(const Ref& other) : ptr_(nullptr) { Assign(other); } - Ref(T* ref, Container* container) : ref_(ref), container_(container) { - if (container_) { - container_->AddRef(); - } + Ref& operator=(const Ref& other) { + Assign(other); + return *this; } + ~Ref() { - if (ref_ && container_) { - container_->Release(); + if (ptr_) { + container()->Release(); } } - - static Ref Alloc(Container* container) { - return Ref(reinterpret_cast(container->Place(sizeof(T))), container); + + T* ref() const { + if (!ptr_) return nullptr; + return reinterpret_cast(reinterpret_cast(ptr_) + sizeof(Container*)); + } + + Container* container() { + return *reinterpret_cast(ptr_); } void Assign(const Ref& other) { - if (ref_) { - container_->Release(); + // TODO: optimize for an important case where containers matches. + if (ptr_) { + container()->Release(); + } + ptr_ = other.ptr_; + if (ptr_) { + container()->AddRef(); } - container_ = other.container_; - container_->AddRef(); - ref_ = other.ref_; } - T* operator->() const { - return ref_; - } - - bool null() const { return ref_ == nullptr; } + T* operator->() const { + return ref(); + } + + bool null() const { return ptr_ == nullptr; } + + static Ref Alloc(Container* container) { + return Ref(container->Place(sizeof(T))); + } }; struct List { @@ -99,24 +123,25 @@ struct List { void test_placer() { printf("Start placement\n"); Container heap(1024); - - Ref head = Ref::Alloc(&heap); - head->data_ = 1; - Ref cur = head; - for (int i = 0; i < 10; ++i) { - cur->next_ = Ref::Alloc(&heap); - cur = cur->next_; - cur->data_ = i + 2; + { + Ref head = Ref::Alloc(&heap); + head->data_ = 1; + Ref cur = head; + for (int i = 0; i < 10; ++i) { + cur->next_ = Ref::Alloc(&heap); + cur = cur->next_; + cur->data_ = i + 2; + } + cur = head; + while (!cur.null()) { + printf("next is %d\n", cur->data_); + cur = cur->next_; + } } - cur = head; - while (!cur.null()) { - printf("next is %d\n", cur->data_); - cur = cur->next_; - } - heap.Dispose(); } int main() { test_placer(); + return 0; }