diff options
author | Juan Linietsky <reduzio@gmail.com> | 2017-01-06 10:15:44 -0300 |
---|---|---|
committer | Juan Linietsky <reduzio@gmail.com> | 2017-01-06 10:15:44 -0300 |
commit | 53ce643e520de193c085c0c23046dcbd2e5308a5 (patch) | |
tree | d8336629c4ce789eb441fc3bd428e317d8ad8e9c /core/vector.h | |
parent | 99ceddd11ef652a3b8e6bf5d09dcc519d957ce14 (diff) | |
download | redot-engine-53ce643e520de193c085c0c23046dcbd2e5308a5.tar.gz |
-Changed memory functions, Memory::alloc_static*, simplified them, made them aligned to 16
-Changed Vector<> template to fit this.
Diffstat (limited to 'core/vector.h')
-rw-r--r-- | core/vector.h | 71 |
1 files changed, 39 insertions, 32 deletions
diff --git a/core/vector.h b/core/vector.h index 8113099a61..3227561000 100644 --- a/core/vector.h +++ b/core/vector.h @@ -46,19 +46,20 @@ class Vector { // internal helpers - _FORCE_INLINE_ SafeRefCount* _get_refcount() const { + _FORCE_INLINE_ uint32_t* _get_refcount() const { if (!_ptr) return NULL; - return reinterpret_cast<SafeRefCount*>((uint8_t*)_ptr-sizeof(int)-sizeof(SafeRefCount)); + return reinterpret_cast<uint32_t*>(_ptr)-2; } - _FORCE_INLINE_ int* _get_size() const { + _FORCE_INLINE_ uint32_t* _get_size() const { if (!_ptr) - return NULL; - return reinterpret_cast<int*>((uint8_t*)_ptr-sizeof(int)); + return NULL; + + return reinterpret_cast<uint32_t*>(_ptr)-1; } _FORCE_INLINE_ T* _get_data() const { @@ -71,7 +72,7 @@ class Vector { _FORCE_INLINE_ size_t _get_alloc_size(size_t p_elements) const { //return nearest_power_of_2_templated(p_elements*sizeof(T)+sizeof(SafeRefCount)+sizeof(int)); - return nearest_power_of_2(p_elements*sizeof(T)+sizeof(SafeRefCount)+sizeof(int)); + return nearest_power_of_2(p_elements*sizeof(T)); } _FORCE_INLINE_ bool _get_alloc_size_checked(size_t p_elements, size_t *out) const { @@ -79,8 +80,8 @@ class Vector { size_t o; size_t p; if (_mul_overflow(p_elements, sizeof(T), &o)) return false; - if (_add_overflow(o, sizeof(SafeRefCount)+sizeof(int), &p)) return false; - *out = nearest_power_of_2(p); + *out = nearest_power_of_2(o); + if (_add_overflow(o, 32, &p)) return false; //no longer allocated here return true; #else // Speed is more important than correctness here, do the operations unchecked @@ -104,7 +105,7 @@ public: _FORCE_INLINE_ void clear() { resize(0); } _FORCE_INLINE_ int size() const { - int* size = _get_size(); + uint32_t* size = (uint32_t*)_get_size(); if (size) return *size; else @@ -190,22 +191,22 @@ void Vector<T>::_unref(void *p_data) { if (!p_data) return; - SafeRefCount *src = reinterpret_cast<SafeRefCount*>((uint8_t*)p_data-sizeof(int)-sizeof(SafeRefCount)); + uint32_t *refc = _get_refcount(); - if (!src->unref()) + if (atomic_decrement(refc)>0) return; // still in use // clean up - int *count = (int*)(src+1); + uint32_t *count = _get_size(); T *data = (T*)(count+1); - for (int i=0;i<*count;i++) { + for (uint32_t i=0;i<*count;i++) { // call destructors data[i].~T(); } // free mem - memfree((uint8_t*)p_data-sizeof(int)-sizeof(SafeRefCount)); + Memory::free_static((uint8_t*)p_data,true); } @@ -215,18 +216,22 @@ void Vector<T>::_copy_on_write() { if (!_ptr) return; - if (_get_refcount()->get() > 1 ) { + uint32_t *refc = _get_refcount(); + + if (*refc > 1) { /* in use by more than me */ - void* mem_new = memalloc(_get_alloc_size(*_get_size())); - SafeRefCount *src_new=(SafeRefCount *)mem_new; - src_new->init(); - int * _size = (int*)(src_new+1); - *_size=*_get_size(); + uint32_t current_size = *_get_size(); + + uint32_t* mem_new = (uint32_t*)Memory::alloc_static(_get_alloc_size(current_size),true); - T*_data=(T*)(_size+1); + + *(mem_new-2)=1; //refcount + *(mem_new-1)=current_size; //size + + T*_data=(T*)(mem_new); // initialize new elements - for (int i=0;i<*_size;i++) { + for (uint32_t i=0;i<current_size;i++) { memnew_placement(&_data[i], T( _get_data()[i] ) ); } @@ -280,16 +285,17 @@ Error Vector<T>::resize(int p_size) { if (size()==0) { // alloc from scratch - void* ptr=memalloc(alloc_size); + uint32_t *ptr=(uint32_t*)Memory::alloc_static(alloc_size,true); ERR_FAIL_COND_V( !ptr ,ERR_OUT_OF_MEMORY); - _ptr=(T*)((uint8_t*)ptr+sizeof(int)+sizeof(SafeRefCount)); - _get_refcount()->init(); // init refcount - *_get_size()=0; // init size (currently, none) + *(ptr-1)=0; //size, currently none + *(ptr-2)=1; //refcount + + _ptr=(T*)ptr; } else { - void *_ptrnew = (T*)memrealloc((uint8_t*)_ptr-sizeof(int)-sizeof(SafeRefCount), alloc_size); + void *_ptrnew = (T*)Memory::realloc_static(_ptr, alloc_size,true); ERR_FAIL_COND_V( !_ptrnew ,ERR_OUT_OF_MEMORY); - _ptr=(T*)((uint8_t*)_ptrnew+sizeof(int)+sizeof(SafeRefCount)); + _ptr=(T*)(_ptrnew); } // construct the newly created elements @@ -305,16 +311,16 @@ Error Vector<T>::resize(int p_size) { } else if (p_size<size()) { // deinitialize no longer needed elements - for (int i=p_size;i<*_get_size();i++) { + for (uint32_t i=p_size;i<*_get_size();i++) { T* t = &_get_data()[i]; t->~T(); } - void *_ptrnew = (T*)memrealloc((uint8_t*)_ptr-sizeof(int)-sizeof(SafeRefCount), alloc_size); + void *_ptrnew = (T*)Memory::realloc_static(_ptr, alloc_size,true); ERR_FAIL_COND_V( !_ptrnew ,ERR_OUT_OF_MEMORY); - _ptr=(T*)((uint8_t*)_ptrnew+sizeof(int)+sizeof(SafeRefCount)); + _ptr=(T*)(_ptrnew); *_get_size()=p_size; @@ -382,8 +388,9 @@ void Vector<T>::_copy_from(const Vector& p_from) { if (!p_from._ptr) return; //nothing to do - if (p_from._get_refcount()->ref()) // could reference + if (atomic_conditional_increment(p_from._get_refcount())>0) { // could reference _ptr=p_from._ptr; + } } |