diff --git a/experiments/placer/placer.cc b/experiments/placer/placer.cc index 58b7724eacb..80136d7a27c 100644 --- a/experiments/placer/placer.cc +++ b/experiments/placer/placer.cc @@ -3,6 +3,7 @@ #include #include +#include class Container { private: @@ -57,44 +58,57 @@ class Container { } }; +// Raw reference to data, meaning T*, only for cleaness of intentions. template -class Ref { +class RawRef { + private: + T* ptr_; + public: + RawRef(T* ptr) : ptr_(ptr) {} + const T& get() const { return *ptr_; } + void set(const T& value) { *ptr_ = value; } +}; + +// Object reference, adds reference counting in container. In real implementation +// we may want to differentiate between +template +class ObjRef { private: void* ptr_; - explicit Ref(void* ptr) : ptr_(ptr) { + explicit ObjRef(void* ptr) : ptr_(ptr) { if (ptr_) { container()->AddRef(); } } - public: - Ref() : ptr_(nullptr) {} - Ref(const Ref& other) : ptr_(nullptr) { - Assign(other); - } - Ref& operator=(const Ref& other) { - Assign(other); - return *this; - } - - ~Ref() { - if (ptr_) { - container()->Release(); - } - } - T* ref() const { if (!ptr_) return nullptr; return reinterpret_cast(reinterpret_cast(ptr_) + sizeof(Container*)); } + public: + ObjRef() : ptr_(nullptr) {} + ObjRef(const ObjRef& other) : ptr_(nullptr) { + Assign(other); + } + ObjRef& operator=(const ObjRef& other) { + Assign(other); + return *this; + } + + ~ObjRef() { + if (ptr_) { + container()->Release(); + } + } + Container* container() { return *reinterpret_cast(ptr_); } - void Assign(const Ref& other) { - // TODO: optimize for an important case where containers matches. + void Assign(const ObjRef& other) { + // TODO: optimize for an important case where containers match. if (ptr_) { container()->Release(); } @@ -104,38 +118,42 @@ class Ref { } } - T* operator->() const { - return ref(); + template + RawRef at() const { + return RawRef( + reinterpret_cast(reinterpret_cast(ref()) + offset)); } bool null() const { return ptr_ == nullptr; } - static Ref Alloc(Container* container) { - return Ref(container->Place(sizeof(T))); + static ObjRef Alloc(Container* container) { + return ObjRef(container->Place(sizeof(T))); } }; struct List { - Ref next_; + ObjRef next_; int data_; }; void test_placer() { printf("Start placement\n"); Container heap(1024); + constexpr int next_offset = offsetof(struct List, next_); + constexpr int data_offset = offsetof(struct List, data_); { - Ref head = Ref::Alloc(&heap); - head->data_ = 1; - Ref cur = head; + ObjRef head = ObjRef::Alloc(&heap); + head.at().set(1); + ObjRef cur = head; for (int i = 0; i < 10; ++i) { - cur->next_ = Ref::Alloc(&heap); - cur = cur->next_; - cur->data_ = i + 2; + cur.at, next_offset>().set(ObjRef::Alloc(&heap)); + cur = cur.at, next_offset>().get(); + cur.at().set(i + 2); } cur = head; while (!cur.null()) { - printf("next is %d\n", cur->data_); - cur = cur->next_; + printf("next is %d\n", cur.at().get()); + cur = cur.at, next_offset>().get(); } } heap.Dispose();