Jelajahi Sumber

-Changed memory functions, Memory::alloc_static*, simplified them, made them aligned to 16
-Changed Vector<> template to fit this.

Juan Linietsky 8 tahun lalu
induk
melakukan
53ce643e52

+ 181 - 24
core/os/memory.cpp

@@ -30,9 +30,68 @@
 #include "error_macros.h"
 #include "copymem.h"
 #include <stdio.h>
+#include <stdlib.h>
+
+
+MID::MID(MemoryPoolDynamic::ID p_id) {
+
+	data = (Data*)memalloc(sizeof(Data));
+	data->refcount.init();
+	data->id=p_id;
+}
+
+void MID::unref() {
+
+	if (!data)
+		return;
+	if (data->refcount.unref()) {
+
+		if (data->id!=MemoryPoolDynamic::INVALID_ID)
+			MemoryPoolDynamic::get_singleton()->free(data->id);
+		memfree(data);
+	}
+
+	data=NULL;
+}
+Error MID::_resize(size_t p_size) {
+
+	if (p_size==0 && (!data || data->id==MemoryPoolDynamic::INVALID_ID))
+			return OK;
+	if (p_size && !data) {
+		// create data because we'll need it
+		data = (Data*)memalloc(sizeof(Data));
+		ERR_FAIL_COND_V( !data,ERR_OUT_OF_MEMORY );
+		data->refcount.init();
+		data->id=MemoryPoolDynamic::INVALID_ID;
+	}
+
+	if (p_size==0 && data && data->id==MemoryPoolDynamic::INVALID_ID) {
+
+		MemoryPoolDynamic::get_singleton()->free(data->id);
+		data->id=MemoryPoolDynamic::INVALID_ID;
+	}
+
+	if (p_size>0) {
+
+		if (data->id==MemoryPoolDynamic::INVALID_ID) {
+
+			data->id=MemoryPoolDynamic::get_singleton()->alloc(p_size,"Unnamed MID");
+			ERR_FAIL_COND_V( data->id==MemoryPoolDynamic::INVALID_ID, ERR_OUT_OF_MEMORY );
+
+		} else {
+
+			MemoryPoolDynamic::get_singleton()->realloc(data->id,p_size);
+			ERR_FAIL_COND_V( data->id==MemoryPoolDynamic::INVALID_ID, ERR_OUT_OF_MEMORY );
+
+		}
+	}
+
+	return OK;
+}
+
 void * operator new(size_t p_size,const char *p_description) {
 
-	return Memory::alloc_static( p_size, p_description );
+	return Memory::alloc_static( p_size, false );
 }
 
 void * operator new(size_t p_size,void* (*p_allocfunc)(size_t p_size)) {
@@ -42,49 +101,147 @@ void * operator new(size_t p_size,void* (*p_allocfunc)(size_t p_size)) {
 
 #include <stdio.h>
 
-void * Memory::alloc_static(size_t p_bytes,const char *p_alloc_from) {
+#ifdef DEBUG_ENABLED
+size_t Memory::mem_usage=0;
+size_t Memory::max_usage=0;
+#endif
 
-	ERR_FAIL_COND_V( !MemoryPoolStatic::get_singleton(), NULL );
-	return MemoryPoolStatic::get_singleton()->alloc(p_bytes,p_alloc_from);
-}
-void * Memory::realloc_static(void *p_memory,size_t p_bytes) {
+size_t Memory::alloc_count=0;
 
-	ERR_FAIL_COND_V( !MemoryPoolStatic::get_singleton(), NULL );
-	return MemoryPoolStatic::get_singleton()->realloc(p_memory,p_bytes);
-}
 
-void Memory::free_static(void *p_ptr) {
+void * Memory::alloc_static(size_t p_bytes,bool p_pad_align) {
 
-	ERR_FAIL_COND( !MemoryPoolStatic::get_singleton());
-	MemoryPoolStatic::get_singleton()->free(p_ptr);
-}
 
+#ifdef DEBUG_ENABLED
+	bool prepad=true;
+#else
+	bool prepad=p_pad_align;
+#endif
+
+	void * mem = malloc( p_bytes + (prepad?PAD_ALIGN:0));
+
+	alloc_count++;
 
-size_t Memory::get_static_mem_available() {
+	ERR_FAIL_COND_V(!mem,NULL);
 
-	ERR_FAIL_COND_V( !MemoryPoolStatic::get_singleton(), 0);
-	return MemoryPoolStatic::get_singleton()->get_available_mem();
+	if (prepad) {
+		uint64_t *s = (uint64_t*)mem;
+		*s=p_bytes;
 
+		uint8_t *s8 = (uint8_t*)mem;
+
+#ifdef DEBUG_ENABLED
+		mem_usage+=p_bytes;
+		if (mem_usage>max_usage) {
+			max_usage=mem_usage;
+		}
+#endif
+		return s8 + PAD_ALIGN;
+	} else {
+		return mem;
+	}
 }
 
-size_t Memory::get_static_mem_max_usage() {
+void * Memory::realloc_static(void *p_memory,size_t p_bytes,bool p_pad_align) {
+
+	if (p_memory==NULL) {
+		return alloc_static(p_bytes,p_pad_align);
+	}
+
+	uint8_t *mem = (uint8_t*)p_memory;
+
+#ifdef DEBUG_ENABLED
+	bool prepad=true;
+#else
+	bool prepad=p_pad_align;
+#endif
+
+	if (prepad) {
+		mem-=PAD_ALIGN;
+		uint64_t *s = (uint64_t*)mem;
+
+#ifdef DEBUG_ENABLED
+		mem_usage-=*s;
+		mem_usage+=p_bytes;
+#endif
+
+		if (p_bytes==0) {
+			free(mem);
+			return NULL;
+		} else {
+			*s=p_bytes;
+
+			mem = (uint8_t*)realloc(mem,p_bytes+PAD_ALIGN);
+			ERR_FAIL_COND_V(!mem,NULL);
+
+			s = (uint64_t*)mem;
+
+			*s=p_bytes;
+
+			return mem+PAD_ALIGN;
+		}
+	} else {
+
+		mem = (uint8_t*)realloc(mem,p_bytes);
+
+		ERR_FAIL_COND_V(mem==NULL && p_bytes>0,NULL);
 
-	ERR_FAIL_COND_V( !MemoryPoolStatic::get_singleton(), 0);
-	return MemoryPoolStatic::get_singleton()->get_max_usage();
+		return mem;
+	}
 }
 
-size_t Memory::get_static_mem_usage() {
+void Memory::free_static(void *p_ptr,bool p_pad_align) {
 
-	ERR_FAIL_COND_V( !MemoryPoolStatic::get_singleton(), 0);
-	return MemoryPoolStatic::get_singleton()->get_total_usage();
+	ERR_FAIL_COND(p_ptr==NULL);
+
+	uint8_t *mem = (uint8_t*)p_ptr;
+
+#ifdef DEBUG_ENABLED
+	bool prepad=true;
+#else
+	bool prepad=p_pad_align;
+#endif
+
+	alloc_count--;
+
+	if (prepad) {
+		mem-=PAD_ALIGN;
+		uint64_t *s = (uint64_t*)mem;
+
+#ifdef DEBUG_ENABLED
+		mem_usage-=*s;
+#endif
+
+		free(mem);
+	} else {
+
+		free(mem);
+	}
 
 }
 
-void Memory::dump_static_mem_to_file(const char* p_file) {
+size_t Memory::get_mem_available() {
+
+	return 0xFFFFFFFFFFFFF;
+
+}
 
-	MemoryPoolStatic::get_singleton()->dump_mem_to_file(p_file);
+size_t Memory::get_mem_usage(){
+#ifdef DEBUG_ENABLED
+	return mem_usage;
+#else
+	return 0;
+#endif
+}
+size_t Memory::get_mem_max_usage(){
+#ifdef DEBUG_ENABLED
+	return max_usage;
+#else
+	return 0;
+#endif
 }
 
+
 MID Memory::alloc_dynamic(size_t p_bytes, const char *p_descr) {
 
 	MemoryPoolDynamic::ID id = MemoryPoolDynamic::get_singleton()->alloc(p_bytes,p_descr);

+ 37 - 98
core/os/memory.h

@@ -32,13 +32,18 @@
 #include <stddef.h>
 #include "safe_refcount.h"
 #include "os/memory_pool_dynamic.h"
-#include "os/memory_pool_static.h"
+
 
 
 /**
 	@author Juan Linietsky <[email protected]>
 */
 
+#ifndef PAD_ALIGN
+#define PAD_ALIGN 16 //must always be greater than this at much
+#endif
+
+
 class MID {
 
 	struct Data {
@@ -49,19 +54,7 @@ class MID {
 
 	mutable Data *data;
 
-	void unref() {
 
-		if (!data)
-			return;
-		if (data->refcount.unref()) {
-
-			if (data->id!=MemoryPoolDynamic::INVALID_ID)
-				MemoryPoolDynamic::get_singleton()->free(data->id);
-			MemoryPoolStatic::get_singleton()->free(data);
-		}
-
-		data=NULL;
-	}
 
 	void ref(Data *p_data) {
 
@@ -95,49 +88,13 @@ friend class MID_Lock;
 		return NULL;
 	}
 
-	Error _resize(size_t p_size) {
-
-		if (p_size==0 && (!data || data->id==MemoryPoolDynamic::INVALID_ID))
-				return OK;
-		if (p_size && !data) {
-			// create data because we'll need it
-			data = (Data*)MemoryPoolStatic::get_singleton()->alloc(sizeof(Data),"MID::Data");
-			ERR_FAIL_COND_V( !data,ERR_OUT_OF_MEMORY );
-			data->refcount.init();
-			data->id=MemoryPoolDynamic::INVALID_ID;
-		}
-
-		if (p_size==0 && data && data->id==MemoryPoolDynamic::INVALID_ID) {
-
-			MemoryPoolDynamic::get_singleton()->free(data->id);
-			data->id=MemoryPoolDynamic::INVALID_ID;
-		}
-
-		if (p_size>0) {
-
-		 	if (data->id==MemoryPoolDynamic::INVALID_ID) {
 
-				data->id=MemoryPoolDynamic::get_singleton()->alloc(p_size,"Unnamed MID");
-				ERR_FAIL_COND_V( data->id==MemoryPoolDynamic::INVALID_ID, ERR_OUT_OF_MEMORY );
+	void unref();
+	Error _resize(size_t p_size);
 
-			} else {
-
-				MemoryPoolDynamic::get_singleton()->realloc(data->id,p_size);
-				ERR_FAIL_COND_V( data->id==MemoryPoolDynamic::INVALID_ID, ERR_OUT_OF_MEMORY );
-
-			}
-		}
-
-		return OK;
-	}
 friend class Memory;
 
-	MID(MemoryPoolDynamic::ID p_id) {
-
-		data = (Data*)MemoryPoolStatic::get_singleton()->alloc(sizeof(Data),"MID::Data");
-		data->refcount.init();
-		data->id=p_id;
-	}
+	MID(MemoryPoolDynamic::ID p_id);
 public:
 
 	bool is_valid() const { return data; }
@@ -173,15 +130,23 @@ public:
 class Memory{
 
 	Memory();
+#ifdef DEBUG_ENABLED
+	static size_t mem_usage;
+	static size_t max_usage;
+#endif
+
+	static size_t alloc_count;
+
 public:
 
-	static void * alloc_static(size_t p_bytes,const char *p_descr="");
-	static void * realloc_static(void *p_memory,size_t p_bytes);
-	static void free_static(void *p_ptr);
-	static size_t get_static_mem_available();
-	static size_t get_static_mem_usage();
-	static size_t get_static_mem_max_usage();
-	static void dump_static_mem_to_file(const char* p_file);
+	static void * alloc_static(size_t p_bytes,bool p_pad_align=false);
+	static void * realloc_static(void *p_memory,size_t p_bytes,bool p_pad_align=false);
+	static void free_static(void *p_ptr,bool p_pad_align=false);
+
+	static size_t get_mem_available();
+	static size_t get_mem_usage();
+	static size_t get_mem_max_usage();
+
 
 	static MID alloc_dynamic(size_t p_bytes, const char *p_descr="");
 	static Error realloc_dynamic(MID p_mid,size_t p_bytes);
@@ -191,15 +156,10 @@ public:
 
 };
 
-template<class T>
-struct MemAalign {
-	static _FORCE_INLINE_ int get_align() { return DEFAULT_ALIGNMENT; }
-};
-
 class DefaultAllocator {
 public:
-	_FORCE_INLINE_ static void *alloc(size_t p_memory) { return Memory::alloc_static(p_memory, ""); }
-	_FORCE_INLINE_ static void free(void *p_ptr) { return Memory::free_static(p_ptr); }
+	_FORCE_INLINE_ static void *alloc(size_t p_memory) { return Memory::alloc_static(p_memory, false); }
+	_FORCE_INLINE_ static void free(void *p_ptr) { return Memory::free_static(p_ptr,false); }
 
 };
 
@@ -209,19 +169,10 @@ void * operator new(size_t p_size,void* (*p_allocfunc)(size_t p_size)); ///< ope
 
 void * operator new(size_t p_size,void *p_pointer,size_t check, const char *p_description); ///< operator new that takes a description and uses a pointer to the preallocated memory
 
-#ifdef DEBUG_MEMORY_ENABLED
-
-#define memalloc(m_size) Memory::alloc_static(m_size, __FILE__ ":" __STR(__LINE__) ", memalloc.")
-#define memrealloc(m_mem,m_size) Memory::realloc_static(m_mem,m_size)
-#define memfree(m_size) Memory::free_static(m_size)
-
-#else
-
 #define memalloc(m_size) Memory::alloc_static(m_size)
 #define memrealloc(m_mem,m_size) Memory::realloc_static(m_mem,m_size)
 #define memfree(m_size) Memory::free_static(m_size)
 
-#endif
 
 #ifdef DEBUG_MEMORY_ENABLED
 #define dynalloc(m_size) Memory::alloc_dynamic(m_size, __FILE__ ":" __STR(__LINE__) ", type: DYNAMIC")
@@ -245,16 +196,8 @@ _ALWAYS_INLINE_ T *_post_initialize(T *p_obj) {
 	return p_obj;
 }
 
-#ifdef DEBUG_MEMORY_ENABLED
-
-#define memnew(m_class) _post_initialize(new(__FILE__ ":" __STR(__LINE__) ", memnew type: " __STR(m_class)) m_class)
-
-#else
-
 #define memnew(m_class) _post_initialize(new("") m_class)
 
-#endif
-
 _ALWAYS_INLINE_ void * operator new(size_t p_size,void *p_pointer,size_t check, const char *p_description) {
 //	void *failptr=0;
 //	ERR_FAIL_COND_V( check < p_size , failptr); /** bug, or strange compiler, most likely */
@@ -275,7 +218,7 @@ void memdelete(T *p_class) {
 	if (!predelete_handler(p_class))
 		return; // doesn't want to be deleted
 	p_class->~T();
-	Memory::free_static(p_class);
+	Memory::free_static(p_class,false);
 }
 
 template<class T,class A>
@@ -288,15 +231,9 @@ void memdelete_allocator(T *p_class) {
 }
 
 #define memdelete_notnull(m_v) { if (m_v) memdelete(m_v); }
-#ifdef DEBUG_MEMORY_ENABLED
-
-#define memnew_arr( m_class, m_count ) memnew_arr_template<m_class>(m_count,__FILE__ ":" __STR(__LINE__) ", memnew_arr type: " _STR(m_class))
-
-#else
 
 #define memnew_arr( m_class, m_count ) memnew_arr_template<m_class>(m_count)
 
-#endif
 
 template<typename T>
 T* memnew_arr_template(size_t p_elements,const char *p_descr="") {
@@ -307,11 +244,11 @@ T* memnew_arr_template(size_t p_elements,const char *p_descr="") {
 	same strategy used by std::vector, and the DVector class, so it should be safe.*/
 
 	size_t len = sizeof(T) * p_elements;
-	unsigned int *mem = (unsigned int*)Memory::alloc_static( len + MAX(sizeof(size_t), DEFAULT_ALIGNMENT), p_descr );
+	uint64_t *mem = (uint64_t*)Memory::alloc_static( len , true );
 	T *failptr=0; //get rid of a warning
 	ERR_FAIL_COND_V( !mem, failptr );
-	*mem=p_elements;
-	mem = (unsigned int *)( ((uint8_t*)mem) + MAX(sizeof(size_t), DEFAULT_ALIGNMENT));
+	*(mem-1)=p_elements;
+
 	T* elems = (T*)mem;
 
 	/* call operator new */
@@ -330,20 +267,22 @@ T* memnew_arr_template(size_t p_elements,const char *p_descr="") {
 template<typename T>
 size_t memarr_len(const T *p_class) {
 
-	uint8_t* ptr = ((uint8_t*)p_class) - MAX(sizeof(size_t), DEFAULT_ALIGNMENT);
-	return *(size_t*)ptr;
+	uint64_t* ptr = (uint64_t*)p_class;
+	return *(ptr-1);
 }
 
 template<typename T>
 void memdelete_arr(T *p_class) {
 
-	unsigned int * elems = (unsigned int*)(((uint8_t*)p_class) - MAX(sizeof(size_t), DEFAULT_ALIGNMENT));
+	uint64_t* ptr = (uint64_t*)p_class;
+
+	uint64_t elem_count = *(ptr-1);
 
-	for (unsigned int i=0;i<*elems;i++) {
+	for (uint64_t i=0;i<elem_count;i++) {
 
 		p_class[i].~T();
 	};
-	Memory::free_static(elems);
+	Memory::free_static(ptr,true);
 }
 
 

+ 1 - 1
core/os/memory_pool_dynamic_static.cpp

@@ -221,7 +221,7 @@ Error MemoryPoolDynamicStatic::unlock(ID p_id) {
 
 size_t MemoryPoolDynamicStatic::get_available_mem() const {
 
-	return Memory::get_static_mem_available();
+	return Memory::get_mem_available();
 }
 
 size_t MemoryPoolDynamicStatic::get_total_usage() const {

+ 1 - 1
core/os/memory_pool_dynamic_static.h

@@ -5,7 +5,7 @@
 /*                           GODOT ENGINE                                */
 /*                    http://www.godotengine.org                         */
 /*************************************************************************/
-/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur.                 */
+/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur.                 */
 /*                                                                       */
 /* Permission is hereby granted, free of charge, to any person obtaining */
 /* a copy of this software and associated documentation files (the       */

+ 0 - 49
core/os/memory_pool_static.cpp

@@ -1,49 +0,0 @@
-/*************************************************************************/
-/*  memory_pool_static.cpp                                               */
-/*************************************************************************/
-/*                       This file is part of:                           */
-/*                           GODOT ENGINE                                */
-/*                    http://www.godotengine.org                         */
-/*************************************************************************/
-/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur.                 */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the       */
-/* "Software"), to deal in the Software without restriction, including   */
-/* without limitation the rights to use, copy, modify, merge, publish,   */
-/* distribute, sublicense, and/or sell copies of the Software, and to    */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions:                                             */
-/*                                                                       */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#include "memory_pool_static.h"
-
-MemoryPoolStatic *MemoryPoolStatic::singleton=0;
-
-MemoryPoolStatic *MemoryPoolStatic::get_singleton() {
-
-	return singleton;
-}
-
-
-MemoryPoolStatic::MemoryPoolStatic() {
-
-	singleton=this;
-}
-
-
-MemoryPoolStatic::~MemoryPoolStatic() {
-	singleton=NULL;
-}
-
-

+ 0 - 69
core/os/memory_pool_static.h

@@ -1,69 +0,0 @@
-/*************************************************************************/
-/*  memory_pool_static.h                                                 */
-/*************************************************************************/
-/*                       This file is part of:                           */
-/*                           GODOT ENGINE                                */
-/*                    http://www.godotengine.org                         */
-/*************************************************************************/
-/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur.                 */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the       */
-/* "Software"), to deal in the Software without restriction, including   */
-/* without limitation the rights to use, copy, modify, merge, publish,   */
-/* distribute, sublicense, and/or sell copies of the Software, and to    */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions:                                             */
-/*                                                                       */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#ifndef MEMORY_POOL_STATIC_H
-#define MEMORY_POOL_STATIC_H
-
-#include <stddef.h>
-
-#include "core/typedefs.h"
-
-/**
-	@author Juan Linietsky <red@lunatea>
-*/
-class MemoryPoolStatic {
-private:
-
-	static MemoryPoolStatic *singleton;
-
-public:
-
-	static MemoryPoolStatic *get_singleton();
-
-	virtual void* alloc(size_t p_bytes,const char *p_description)=0; ///< Pointer in p_description shold be to a const char const like "hello"
-	virtual void* realloc(void * p_memory,size_t p_bytes)=0; ///< Pointer in p_description shold be to a const char const like "hello"
-	virtual void free(void *p_ptr)=0; ///< Pointer in p_description shold be to a const char const
-
-	virtual size_t get_available_mem() const=0;
-	virtual size_t get_total_usage()=0;
-	virtual size_t get_max_usage()=0;
-
-	/* Most likely available only if memory debugger was compiled in */
-	virtual int get_alloc_count()=0;
-	virtual void * get_alloc_ptr(int p_alloc_idx)=0;
-	virtual const char* get_alloc_description(int p_alloc_idx)=0;
-	virtual size_t get_alloc_size(int p_alloc_idx)=0;
-
-	virtual void dump_mem_to_file(const char* p_file)=0;
-
-	MemoryPoolStatic();
-	virtual ~MemoryPoolStatic();
-
-};
-
-#endif

+ 4 - 4
core/os/os.cpp

@@ -187,7 +187,7 @@ const char *OS::get_last_error() const {
 
 void OS::dump_memory_to_file(const char* p_file) {
 
-	Memory::dump_static_mem_to_file(p_file);
+//	Memory::dump_static_mem_to_file(p_file);
 }
 
 static FileAccess *_OSPRF=NULL;
@@ -367,7 +367,7 @@ Error OS::dialog_input_text(String p_title, String p_description, String p_parti
 
 int OS::get_static_memory_usage() const {
 
-	return Memory::get_static_mem_usage();
+	return Memory::get_mem_usage();
 }
 int OS::get_dynamic_memory_usage() const{
 
@@ -376,7 +376,7 @@ int OS::get_dynamic_memory_usage() const{
 
 int OS::get_static_memory_peak_usage() const {
 
-	return Memory::get_static_mem_max_usage();
+	return Memory::get_mem_max_usage();
 }
 
 Error OS::set_cwd(const String& p_cwd) {
@@ -392,7 +392,7 @@ bool OS::has_touchscreen_ui_hint() const {
 
 int OS::get_free_static_memory() const {
 
-	return Memory::get_static_mem_available();
+	return Memory::get_mem_available();
 }
 
 void OS::yield() {

+ 2 - 2
core/pool_allocator.cpp

@@ -604,7 +604,7 @@ void PoolAllocator::create_pool(void * p_mem,int p_size,int p_max_entries) {
 
 PoolAllocator::PoolAllocator(int p_size,bool p_needs_locking,int p_max_entries) {
 
-	mem_ptr=Memory::alloc_static( p_size,"PoolAllocator()");
+	mem_ptr=memalloc( p_size);
 	ERR_FAIL_COND(!mem_ptr);
 	align=1;
 	create_pool(mem_ptr,p_size,p_max_entries);
@@ -648,7 +648,7 @@ PoolAllocator::PoolAllocator(int p_align,int p_size,bool p_needs_locking,int p_m
 PoolAllocator::~PoolAllocator() {
 
 	if (mem_ptr)
-		Memory::free_static( mem_ptr );
+		memfree( mem_ptr );
 
 	memdelete_arr( entry_array );
 	memdelete_arr( entry_indices );

+ 55 - 6
core/safe_refcount.cpp

@@ -29,27 +29,76 @@
 #include "safe_refcount.h"
 
 
+// Atomic functions, these are used for multithread safe reference counters!
+
+#ifdef NO_THREADS
+
+
+uint32_t atomic_conditional_increment( register uint32_t * pw ) {
+
+	if (*pw==0)
+		return 0;
+
+	(*pw)++;
+
+	return *pw;
+}
+
+uint32_t atomic_decrement( register uint32_t * pw ) {
+
+	(*pw)--;
+
+	return *pw;
+
+}
+
+#else
+
 #ifdef _MSC_VER
 
 // don't pollute my namespace!
 #include <windows.h>
-long atomic_conditional_increment( register long * pw ) {
+uint32_t atomic_conditional_increment( register uint32_t * pw ) {
 
 	/* try to increment until it actually works */
 	// taken from boost
 
 	while (true) {
-		long tmp = static_cast< long const volatile& >( *pw );
+		uint32_t tmp = static_cast< uint32_t const volatile& >( *pw );
 		if( tmp == 0 )
-      return 0; // if zero, can't add to it anymore
-		if( InterlockedCompareExchange( pw, tmp + 1, tmp ) == tmp )
+			 return 0; // if zero, can't add to it anymore
+		if( InterlockedCompareExchange( (LONG volatile*)pw, tmp + 1, tmp ) == tmp )
 			return tmp+1;
 	}
+}
+
+uint32_t atomic_decrement( register uint32_t * pw ) {
+	return InterlockedDecrement( (LONG volatile*)pw );
+}
+
+#elif defined(__GNUC__)
 
+uint32_t atomic_conditional_increment( register uint32_t * pw ) {
+
+	while (true) {
+		uint32_t tmp = static_cast< uint32_t const volatile& >( *pw );
+		if( tmp == 0 )
+			 return 0; // if zero, can't add to it anymore
+		if( __sync_val_compare_and_swap( pw, tmp, tmp + 1 ) == tmp )
+			return tmp+1;
+	}
 }
 
-long atomic_decrement( register long * pw ) {
-	return InterlockedDecrement( pw );
+uint32_t atomic_decrement( register uint32_t * pw ) {
+
+	return __sync_sub_and_fetch(pw,1);
+
 }
 
+#else
+	//no threads supported?
+#error Must provide atomic functions for this platform or compiler!
+
+#endif
+
 #endif

+ 9 - 303
core/safe_refcount.h

@@ -33,309 +33,17 @@
 /* x86/x86_64 GCC */
 
 #include "platform_config.h"
+#include "typedefs.h"
 
 
-#ifdef NO_THREADS
-
-struct SafeRefCount {
-
-	int count;
-
-public:
-
-	// destroy() is called when weak_count_ drops to zero.
-
-	bool ref() {  //true on success
-
-		if (count==0)
-			return false;
-		count++;
-
-		return true;
-	}
-
-	int refval() {  //true on success
-
-		if (count==0)
-			return 0;
-		count++;
-		return count;
-	}
-
-	bool unref() { // true if must be disposed of
-
-		if (count>0)
-			count--;
-
-		return count==0;
-	}
-
-	long get() const { // nothrow
-
-		return static_cast<int const volatile &>( count );
-	}
-
-	void init(int p_value=1) {
-
-		count=p_value;
-	};
-
-};
-
-
-
-
-
-
-
-
-#else
-
-#if defined( PLATFORM_REFCOUNT )
-
-#include "platform_refcount.h"
-
-
-#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) )
-
-#define REFCOUNT_T volatile int
-#define REFCOUNT_GET_T int const volatile&
-
-static inline int atomic_conditional_increment( volatile int * pw ) {
-	// int rv = *pw;
-	// if( rv != 0 ) ++*pw;
-	// return rv;
-
-	int rv, tmp;
-
-	__asm__
-	(
-		"movl %0, %%eax\n\t"
-		"0:\n\t"
-		"test %%eax, %%eax\n\t"
-		"je 1f\n\t"
-		"movl %%eax, %2\n\t"
-		"incl %2\n\t"
-		"lock\n\t"
-		"cmpxchgl %2, %0\n\t"
-		"jne 0b\n\t"
-		"1:":
-		"=m"( *pw ), "=&a"( rv ), "=&r"( tmp ): // outputs (%0, %1, %2)
-		"m"( *pw ): // input (%3)
-		"cc" // clobbers
-	);
-
-	return rv;
-}
-
-static inline int atomic_decrement( volatile int *pw) {
-
-	// return --(*pw);
-
-	unsigned char rv;
-
-	__asm__
-	(
-		"lock\n\t"
-		"decl %0\n\t"
-		"setne %1":
-		"=m" (*pw), "=qm" (rv):
-		"m" (*pw):
-		"memory"
-	);
-	return static_cast<int>(rv);
-}
-
-/* PowerPC32/64 GCC */
-
-#elif ( defined( __GNUC__ ) ) && ( defined( __powerpc__ ) || defined( __ppc__ ) )
-
-#define REFCOUNT_T int
-#define REFCOUNT_GET_T int const volatile&
-
-inline int atomic_conditional_increment( int * pw )
-{
-    // if( *pw != 0 ) ++*pw;
-    // return *pw;
-
-    int rv;
-
-    __asm__
-    (
-        "0:\n\t"
-        "lwarx %1, 0, %2\n\t"
-        "cmpwi %1, 0\n\t"
-        "beq 1f\n\t"
-        "addi %1, %1, 1\n\t"
-        "1:\n\t"
-        "stwcx. %1, 0, %2\n\t"
-        "bne- 0b":
-
-        "=m"( *pw ), "=&b"( rv ):
-        "r"( pw ), "m"( *pw ):
-        "cc"
-    );
-
-    return rv;
-}
-
-
-inline int atomic_decrement( int * pw )
-{
-    // return --*pw;
-
-    int rv;
-
-    __asm__ __volatile__
-    (
-        "sync\n\t"
-        "0:\n\t"
-        "lwarx %1, 0, %2\n\t"
-        "addi %1, %1, -1\n\t"
-        "stwcx. %1, 0, %2\n\t"
-        "bne- 0b\n\t"
-        "isync":
-
-        "=m"( *pw ), "=&b"( rv ):
-        "r"( pw ), "m"( *pw ):
-        "memory", "cc"
-    );
-
-    return rv;
-}
-
-/* CW ARM */
-
-#elif defined( __GNUC__ ) && ( defined( __arm__ )  )
-
-#define REFCOUNT_T int
-#define REFCOUNT_GET_T int const volatile&
-
-inline int atomic_conditional_increment(volatile int* v)
-{
-   int t;
-   int tmp;
-
-   __asm__ __volatile__(
-			 "1:  ldrex   %0, [%2]        \n"
-			 "    cmp     %0, #0      \n"
-			 "    beq     2f          \n"
-			 "    add     %0, %0, #1      \n"
-			 "2: \n"
-			 "    strex   %1, %0, [%2]    \n"
-			 "    cmp     %1, #0          \n"
-			 "    bne     1b              \n"
-
-			 : "=&r" (t), "=&r" (tmp)
-			 : "r" (v)
-			 : "cc", "memory");
-
-   return t;
-}
-
-
-inline int atomic_decrement(volatile int* v)
-{
-   int t;
-   int tmp;
-
-   __asm__ __volatile__(
-			 "1:  ldrex   %0, [%2]        \n"
-			 "    add     %0, %0, #-1      \n"
-			 "    strex   %1, %0, [%2]    \n"
-			 "    cmp     %1, #0          \n"
-			 "    bne     1b              \n"
-
-			 : "=&r" (t), "=&r" (tmp)
-			 : "r" (v)
-			 : "cc", "memory");
-
-   return t;
-}
-
-
-
-/* CW PPC */
-
-#elif ( defined( __MWERKS__ ) ) && defined( __POWERPC__ )
-
-inline long atomic_conditional_increment( register long * pw )
-{
-    register int a;
-
-	asm
-	{
-	loop:
-
-	lwarx   a, 0, pw
-	cmpwi   a, 0
-	beq     store
-
-	addi    a, a, 1
-
-	store:
-
-	stwcx.  a, 0, pw
-	bne-    loop
-    }
-
-    return a;
-}
-
-
-inline long atomic_decrement( register long * pw )
-{
-    register int a;
-
-    asm {
-
-	sync
-
-	loop:
-
-	lwarx   a, 0, pw
-	addi    a, a, -1
-	stwcx.  a, 0, pw
-	bne-    loop
-
-	isync
-    }
-
-    return a;
-}
-
-/* Any Windows (MSVC) */
-
-#elif defined( _MSC_VER )
-
-// made functions to not pollute namespace..
-
-#define REFCOUNT_T long
-#define REFCOUNT_GET_T long const volatile&
-
-long atomic_conditional_increment( register long * pw );
-long atomic_decrement( register long * pw );
-
-#if 0
-#elif defined( __GNUC__ ) && defined( ARMV6_ENABLED)
-
-
-#endif
-
-
-
-
-#else
-
-#error This platform cannot use safe refcount, compile with NO_THREADS or implement it.
-
-#endif
+uint32_t atomic_conditional_increment( register uint32_t * counter );
+uint32_t atomic_decrement( register uint32_t * pw );
 
 
 
 struct SafeRefCount {
 
-  REFCOUNT_T count;
+  uint32_t count;
 
 public:
 
@@ -346,7 +54,7 @@ public:
 		return atomic_conditional_increment( &count ) != 0;
 	}
 
-	int refval() {  //true on success
+	uint32_t refval() {  //true on success
 
 		return atomic_conditional_increment( &count );
 	}
@@ -360,20 +68,18 @@ public:
 		return false;
 	}
 
-	long get() const { // nothrow
+	uint32_t get() const { // nothrow
 
-		return static_cast<REFCOUNT_GET_T>( count );
+		return count;
 	}
 
-	void init(int p_value=1) {
+	void init(uint32_t p_value=1) {
 
 		count=p_value;
-	};
+	}
 
 };
 
 
 
-#endif // no thread safe
-
 #endif

+ 0 - 4
core/typedefs.h

@@ -77,10 +77,6 @@
 
 #endif
 
-#ifndef DEFAULT_ALIGNMENT
-#define DEFAULT_ALIGNMENT 1
-#endif
-
 
 //custom, gcc-safe offsetof, because gcc complains a lot.
 template<class T>

+ 39 - 32
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;
+	}
 
 }
 

+ 4 - 4
drivers/gles3/shader_gles3.cpp

@@ -370,7 +370,7 @@ ShaderGLES3::Version* ShaderGLES3::get_current_version() {
 			}
 
 			
-			char *ilogmem = (char*)Memory::alloc_static(iloglen+1);
+			char *ilogmem = (char*)memalloc(iloglen+1);
 			ilogmem[iloglen]=0;
 			glGetShaderInfoLog(v.vert_id, iloglen, &iloglen, ilogmem); 	
 			
@@ -378,7 +378,7 @@ ShaderGLES3::Version* ShaderGLES3::get_current_version() {
 			
 			err_string+=ilogmem;
 			_display_error_with_code(err_string,strings);
-			Memory::free_static(ilogmem);
+			memfree(ilogmem);
 			glDeleteShader(v.vert_id);
 			glDeleteProgram( v.id );
 			v.id=0;
@@ -473,7 +473,7 @@ ShaderGLES3::Version* ShaderGLES3::get_current_version() {
 				iloglen = 4096; //buggy driver (Adreno 220+....)
 			}
 
-			char *ilogmem = (char*)Memory::alloc_static(iloglen+1);
+			char *ilogmem = (char*)memalloc(iloglen+1);
 			ilogmem[iloglen]=0;
 			glGetShaderInfoLog(v.frag_id, iloglen, &iloglen, ilogmem); 	
 			
@@ -482,7 +482,7 @@ ShaderGLES3::Version* ShaderGLES3::get_current_version() {
 			err_string+=ilogmem;
 			_display_error_with_code(err_string,strings);
 			ERR_PRINT(err_string.ascii().get_data());
-			Memory::free_static(ilogmem);
+			memfree(ilogmem);
 			glDeleteShader(v.frag_id);
 			glDeleteShader(v.vert_id);
 			glDeleteProgram( v.id );

+ 0 - 432
drivers/unix/memory_pool_static_malloc.cpp

@@ -1,434 +1,2 @@
-/*************************************************************************/
-/*  memory_pool_static_malloc.cpp                                        */
-/*************************************************************************/
-/*                       This file is part of:                           */
-/*                           GODOT ENGINE                                */
-/*                    http://www.godotengine.org                         */
-/*************************************************************************/
-/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur.                 */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the       */
-/* "Software"), to deal in the Software without restriction, including   */
-/* without limitation the rights to use, copy, modify, merge, publish,   */
-/* distribute, sublicense, and/or sell copies of the Software, and to    */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions:                                             */
-/*                                                                       */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#include "memory_pool_static_malloc.h"
-#include "error_macros.h"
-#include "os/memory.h"
-#include <stdlib.h>
-#include <stdio.h>
-#include "os/copymem.h"
-#include "os/os.h"
-
-/**
- * NOTE NOTE NOTE NOTE
- * in debug mode, this prepends the memory size to the allocated block
- * so BE CAREFUL!
- */
-
-void* MemoryPoolStaticMalloc::alloc(size_t p_bytes,const char *p_description) {
-
-	#if DEFAULT_ALIGNMENT == 1
-
-		return _alloc(p_bytes, p_description);
-
-	#else
-
-		size_t total;
-		#if defined(_add_overflow)
-			if (_add_overflow(p_bytes, DEFAULT_ALIGNMENT, &total)) return NULL;
-		#else
-			total = p_bytes + DEFAULT_ALIGNMENT;
-		#endif
-		uint8_t* ptr = (uint8_t*)_alloc(total, p_description);
-		ERR_FAIL_COND_V( !ptr, ptr );
-		int ofs = (DEFAULT_ALIGNMENT - ((uintptr_t)ptr & (DEFAULT_ALIGNMENT - 1)));
-		ptr[ofs-1] = ofs;
-		return (void*)(ptr + ofs);
-	#endif
-};
- 
-void* MemoryPoolStaticMalloc::_alloc(size_t p_bytes,const char *p_description) {
- 
- 	ERR_FAIL_COND_V(p_bytes==0,0);
-	
-	MutexLock lock(mutex);
-	
-#ifdef DEBUG_MEMORY_ENABLED
-
-	size_t total;
-	#if defined(_add_overflow)
-		if (_add_overflow(p_bytes, sizeof(RingPtr), &total)) return NULL;
-	#else
-		total = p_bytes + sizeof(RingPtr);
-	#endif
-	void *mem=malloc(total); /// add for size and ringlist
-
-	if (!mem) {
-		printf("**ERROR: out of memory while allocating %lu bytes by %s?\n", (unsigned long) p_bytes, p_description);
-		printf("**ERROR: memory usage is %lu\n", (unsigned long) get_total_usage());
-	};
-	
-	ERR_FAIL_COND_V(!mem,0); //out of memory, or unreasonable request
-		
-	/* setup the ringlist element */
-	
-	RingPtr *ringptr = (RingPtr*)mem;
-	
-	/* setup the ringlist element data (description and size ) */
-	
-	ringptr->size = p_bytes;
-	ringptr->descr=p_description;
-	
-	if (ringlist) { /* existing ringlist */
-		
-		/* assign next */
-		ringptr->next = ringlist->next;
-		ringlist->next = ringptr;
-		/* assign prev */
-		ringptr->prev = ringlist;
-		ringptr->next->prev = ringptr;
-	} else { /* non existing ringlist */
-		
-		ringptr->next=ringptr;
-		ringptr->prev=ringptr;
-		ringlist=ringptr;
-		
-	}
-	
-	total_mem+=p_bytes;
-	
-	/* update statistics */
-	if (total_mem > max_mem )
-		max_mem = total_mem;
-	
-	total_pointers++;
-	
-	if (total_pointers > max_pointers)
-		max_pointers=total_pointers;
-	
-	return ringptr + 1; /* return memory after ringptr */
-		
-#else		
-	void *mem=malloc(p_bytes);
-
-	ERR_FAIL_COND_V(!mem,0); //out of memory, or unreasonable request
-	return mem;			
-#endif	
-}
-
-
-void* MemoryPoolStaticMalloc::realloc(void *p_memory,size_t p_bytes) {
-
-	#if DEFAULT_ALIGNMENT == 1
-
-		return _realloc(p_memory,p_bytes);
-	#else
-		if (!p_memory)
-			return alloc(p_bytes);
-
-		size_t total;
-		#if defined(_add_overflow)
-			if (_add_overflow(p_bytes, DEFAULT_ALIGNMENT, &total)) return NULL;
-		#else
-			total = p_bytes + DEFAULT_ALIGNMENT;
-		#endif
-		uint8_t* mem = (uint8_t*)p_memory;
-		int ofs = *(mem-1);
-		mem = mem - ofs;
-		uint8_t* ptr = (uint8_t*)_realloc(mem, total);
-		ERR_FAIL_COND_V(ptr == NULL, NULL);
-		int new_ofs = (DEFAULT_ALIGNMENT - ((uintptr_t)ptr & (DEFAULT_ALIGNMENT - 1)));
-		if (new_ofs != ofs) {
-
-			//printf("realloc moving %i bytes\n", p_bytes);
-			movemem((ptr + new_ofs), (ptr + ofs), p_bytes);
-			ptr[new_ofs-1] = new_ofs;
-		};
-		return ptr + new_ofs;
-	#endif
-};
-
-void* MemoryPoolStaticMalloc::_realloc(void *p_memory,size_t p_bytes) {
-	
-	if (p_memory==NULL) {
-		
-		return alloc( p_bytes );
-	}
-		
-	if (p_bytes==0) {
-		
-		this->free(p_memory);
-		ERR_FAIL_COND_V( p_bytes < 0 , NULL );
-		return NULL;
-	}
-	
-	MutexLock lock(mutex);
-	
-#ifdef DEBUG_MEMORY_ENABLED
-	
-	
-	RingPtr *ringptr = (RingPtr*)p_memory;
-	ringptr--; /* go back an element to find the tingptr */
-	
-	bool single_element = (ringptr->next == ringptr) && (ringptr->prev == ringptr);
-	bool is_list = ( ringlist == ringptr );
-	
-	RingPtr *new_ringptr=(RingPtr*)::realloc(ringptr, p_bytes+sizeof(RingPtr));
-	
-	ERR_FAIL_COND_V( new_ringptr == 0, NULL ); /// reallocation failed 
-		
-	/* actualize mem used */
-	total_mem -= new_ringptr->size;
-	new_ringptr->size = p_bytes;
-	total_mem +=  new_ringptr->size;
-	
-	if (total_mem > max_mem ) //update statistics
-		max_mem = total_mem;
-	
-	if (new_ringptr == ringptr )
-		return ringptr + 1; // block didn't move, don't do anything
-	
-	if (single_element) {
-		
-		new_ringptr->next=new_ringptr;
-		new_ringptr->prev=new_ringptr;
-	} else {
-		
-		new_ringptr->next->prev=new_ringptr;
-		new_ringptr->prev->next=new_ringptr;		
-	}
-	
-	if (is_list)
-		ringlist=new_ringptr;
-	
-	
-	return new_ringptr + 1;
-		
-#else
-	return ::realloc( p_memory, p_bytes );
-#endif
-}
-
-void MemoryPoolStaticMalloc::free(void *p_ptr) {
-
-	ERR_FAIL_COND( !MemoryPoolStatic::get_singleton());
-
-	#if DEFAULT_ALIGNMENT == 1
-
-		_free(p_ptr);
-	#else
-
-		uint8_t* mem = (uint8_t*)p_ptr;
-		int ofs = *(mem-1);
-		mem = mem - ofs;
-
-		_free(mem);
-	#endif
-};
-
-
-void MemoryPoolStaticMalloc::_free(void *p_ptr) {
-	
-	MutexLock lock(mutex);
-	
-#ifdef DEBUG_MEMORY_ENABLED
-		
-	if (p_ptr==0) {
-		printf("**ERROR: STATIC ALLOC: Attempted free of NULL pointer.\n");
-		return;
-	};
-	
-	RingPtr *ringptr = (RingPtr*)p_ptr;
-	
-	ringptr--; /* go back an element to find the ringptr */
-	
-	
-#if 0	
-	{ // check for existing memory on free.
-		RingPtr *p = ringlist;
-		
-		bool found=false;
-		
-		if (ringlist) {
-			do {
-				if (p==ringptr) {
-					found=true;
-					break;
-				}
-						
-				p=p->next;
-			} while (p!=ringlist);
-		}
-		
-		if (!found) {
-			printf("**ERROR: STATIC ALLOC: Attempted free of unknown pointer at %p\n",(ringptr+1));
-			return;
-		}
-		
-	}		
-#endif	
-	/* proceed to erase */
-	
-	bool single_element = (ringptr->next == ringptr) && (ringptr->prev == ringptr);
-	bool is_list = ( ringlist == ringptr );
-	
-	if (single_element) {
-		/* just get rid of it */
-		ringlist=0;
-			
-	} else {
-		/* auto-remove from ringlist */
-		if (is_list)
-			ringlist=ringptr->next;
-			
-		ringptr->prev->next = ringptr->next;
-		ringptr->next->prev = ringptr->prev;
-	}
-	
-	total_mem -= ringptr->size;
-	total_pointers--;
-	// catch more errors
-	zeromem(ringptr,sizeof(RingPtr)+ringptr->size);
-	::free(ringptr); //just free that pointer
-		
-#else
-	ERR_FAIL_COND(p_ptr==0);
-		
-	::free(p_ptr);
-#endif
-}
-
-
-size_t MemoryPoolStaticMalloc::get_available_mem() const {
-
-	return 0xffffffff;
-}
-
-size_t MemoryPoolStaticMalloc::get_total_usage() {
-	
-#ifdef DEBUG_MEMORY_ENABLED
-		
-	return total_mem;
-#else	
-	return 0;
-#endif
-
-}
-
-size_t MemoryPoolStaticMalloc::get_max_usage() {
-
-	return max_mem;
-}
-			
-/* Most likely available only if memory debugger was compiled in */
-int MemoryPoolStaticMalloc::get_alloc_count() {
-	
-	return total_pointers;
-}
-void * MemoryPoolStaticMalloc::get_alloc_ptr(int p_alloc_idx) {
-	
-	return 0;
-}
-const char* MemoryPoolStaticMalloc::get_alloc_description(int p_alloc_idx) {
-	
-	
-	return "";
-}
-size_t MemoryPoolStaticMalloc::get_alloc_size(int p_alloc_idx) {
-	
-	return 0;
-}
-
-void MemoryPoolStaticMalloc::dump_mem_to_file(const char* p_file) {
-
-#ifdef DEBUG_MEMORY_ENABLED
-	
-	ERR_FAIL_COND( !ringlist ); /** WTF BUG !? */
-	RingPtr *p = ringlist;
-	FILE *f = fopen(p_file,"wb");
-	
-	do {
-		fprintf(f,"%p-%i-%s\n", p+1, (int)p->size, (p->descr?p->descr:"") );
-		p=p->next;
-	} while (p!=ringlist);
-
-	fclose(f);
-#endif 
-
-}
-
-MemoryPoolStaticMalloc::MemoryPoolStaticMalloc() {
-	
-#ifdef DEBUG_MEMORY_ENABLED
-	total_mem=0;
-	total_pointers=0;
-	ringlist=0;
-	max_mem=0;
-	max_pointers=0;
-
-
-#endif
-		
-	mutex=NULL;
-#ifndef NO_THREADS
-
-	mutex=Mutex::create(); // at this point, this should work
-#endif
-
-}
-
-
-MemoryPoolStaticMalloc::~MemoryPoolStaticMalloc() {
-	
-	Mutex *old_mutex=mutex;
-	mutex=NULL;
-	if (old_mutex)
-		memdelete(old_mutex);
-	
-#ifdef DEBUG_MEMORY_ENABLED
-
-	if (OS::get_singleton()->is_stdout_verbose()) {
-		if (total_mem > 0 ) {
-			printf("**ERROR: STATIC ALLOC: ** MEMORY LEAKS DETECTED **\n");
-			printf("**ERROR: STATIC ALLOC: %i bytes of memory in use at exit.\n",(int)total_mem);
-
-			if (1){
-				printf("**ERROR: STATIC ALLOC: Following is the list of leaked allocations: \n");
-
-				ERR_FAIL_COND( !ringlist ); /** WTF BUG !? */
-				RingPtr *p = ringlist;
-
-				do {
-					printf("\t%p - %i bytes - %s\n", (RingPtr*)(p+1), (int)p->size, (p->descr?p->descr:"") );
-					p=p->next;
-				} while (p!=ringlist);
-
-				printf("**ERROR: STATIC ALLOC: End of Report.\n");
-			};
-
-			printf("mem - max %i, pointers %i, leaks %i.\n",(int)max_mem,max_pointers,(int)total_mem);
-		} else {
-
-			printf("INFO: mem - max %i, pointers %i, no leaks.\n",(int)max_mem,max_pointers);
-		}
-	}
-	
-#endif
-}
 
 

+ 0 - 82
drivers/unix/memory_pool_static_malloc.h

@@ -1,82 +0,0 @@
-/*************************************************************************/
-/*  memory_pool_static_malloc.h                                          */
-/*************************************************************************/
-/*                       This file is part of:                           */
-/*                           GODOT ENGINE                                */
-/*                    http://www.godotengine.org                         */
-/*************************************************************************/
-/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur.                 */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the       */
-/* "Software"), to deal in the Software without restriction, including   */
-/* without limitation the rights to use, copy, modify, merge, publish,   */
-/* distribute, sublicense, and/or sell copies of the Software, and to    */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions:                                             */
-/*                                                                       */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#ifndef MEMORY_POOL_STATIC_MALLOC_H
-#define MEMORY_POOL_STATIC_MALLOC_H
-
-#include "os/memory_pool_static.h"
-#include "os/mutex.h"
-/**
-	@author Juan Linietsky <red@lunatea>
-*/
-class MemoryPoolStaticMalloc : public MemoryPoolStatic {
-
-	struct RingPtr {
-		
-		size_t size;
-		const char *descr; /* description of memory */
-		RingPtr *next;
-		RingPtr *prev;
-	};
-	
-	RingPtr *ringlist;
-	size_t total_mem;
-	int total_pointers;
-	
-	size_t max_mem;
-	int max_pointers;
-			
-	Mutex *mutex;
-
-	void* _alloc(size_t p_bytes,const char *p_description=""); ///< Pointer in p_description shold be to a const char const like "hello"
-	void* _realloc(void *p_memory,size_t p_bytes); ///< Pointer in
-	void _free(void *p_ptr); ///< Pointer in p_description shold be to a const char const
-
-public:
-
-	virtual void* alloc(size_t p_bytes,const char *p_description=""); ///< Pointer in p_description shold be to a const char const like "hello"
-	virtual void free(void *p_ptr); ///< Pointer in p_description shold be to a const char const
-	virtual void* realloc(void *p_memory,size_t p_bytes); ///< Pointer in
-	virtual size_t get_available_mem() const;
-	virtual size_t get_total_usage();
-	virtual size_t get_max_usage();
-
-	/* Most likely available only if memory debugger was compiled in */
-	virtual int get_alloc_count();
-	virtual void * get_alloc_ptr(int p_alloc_idx);
-	virtual const char* get_alloc_description(int p_alloc_idx);
-	virtual size_t get_alloc_size(int p_alloc_idx);
-	
-	void dump_mem_to_file(const char* p_file);
-	
-	MemoryPoolStaticMalloc();
-	~MemoryPoolStaticMalloc();
-
-};
-
-#endif

+ 1 - 4
drivers/unix/os_unix.cpp

@@ -30,7 +30,7 @@
 
 #ifdef UNIX_ENABLED
 
-#include "memory_pool_static_malloc.h"
+
 #include "os/memory_pool_dynamic_static.h"
 #include "thread_posix.h"
 #include "semaphore_posix.h"
@@ -116,7 +116,6 @@ int OS_Unix::unix_initialize_audio(int p_audio_driver) {
 	return 0;
 }
 	
-static MemoryPoolStaticMalloc *mempool_static=NULL;
 static MemoryPoolDynamicStatic *mempool_dynamic=NULL;
 	
 	
@@ -145,7 +144,6 @@ void OS_Unix::initialize_core() {
 	PacketPeerUDPPosix::make_default();
 	IP_Unix::make_default();
 #endif
-	mempool_static = new MemoryPoolStaticMalloc;
 	mempool_dynamic = memnew( MemoryPoolDynamicStatic );
 
 	ticks_start=0;
@@ -157,7 +155,6 @@ void OS_Unix::finalize_core() {
 
 	if (mempool_dynamic)
 		memdelete( mempool_dynamic );
-	delete mempool_static;
 
 }
 

+ 2 - 2
main/performance.cpp

@@ -121,9 +121,9 @@ float Performance::get_monitor(Monitor p_monitor) const {
 		case TIME_FPS: return OS::get_singleton()->get_frames_per_second();
 		case TIME_PROCESS: return _process_time;
 		case TIME_FIXED_PROCESS: return _fixed_process_time;
-		case MEMORY_STATIC: return Memory::get_static_mem_usage();
+		case MEMORY_STATIC: return Memory::get_mem_usage();
 		case MEMORY_DYNAMIC: return Memory::get_dynamic_mem_usage();
-		case MEMORY_STATIC_MAX: return Memory::get_static_mem_max_usage();
+		case MEMORY_STATIC_MAX: return Memory::get_mem_max_usage();
 		case MEMORY_DYNAMIC_MAX: return Memory::get_dynamic_mem_available();
 		case MEMORY_MESSAGE_BUFFER_MAX: return MessageQueue::get_singleton()->get_max_buffer_usage();
 		case OBJECT_COUNT: return ObjectDB::get_object_count();

+ 0 - 4
platform/windows/os_windows.cpp

@@ -30,7 +30,6 @@
 #include "os_windows.h"
 
 #include "drivers/gles3/rasterizer_gles3.h"
-#include "drivers/unix/memory_pool_static_malloc.h"
 #include "os/memory_pool_dynamic_static.h"
 #include "drivers/windows/thread_windows.h"
 #include "drivers/windows/semaphore_windows.h"
@@ -167,7 +166,6 @@ const char * OS_Windows::get_audio_driver_name(int p_driver) const {
 	return AudioDriverManagerSW::get_driver(p_driver)->get_name();
 }
 
-static MemoryPoolStatic *mempool_static=NULL;
 static MemoryPoolDynamic *mempool_dynamic=NULL;
 
 void OS_Windows::initialize_core() {
@@ -196,7 +194,6 @@ void OS_Windows::initialize_core() {
 	StreamPeerWinsock::make_default();
 	PacketPeerUDPWinsock::make_default();
 
-	mempool_static = new MemoryPoolStaticMalloc;
 #if 1
 	mempool_dynamic = memnew( MemoryPoolDynamicStatic );
 #else
@@ -1308,7 +1305,6 @@ void OS_Windows::finalize_core() {
 
 	if (mempool_dynamic)
 		memdelete( mempool_dynamic );
-	delete mempool_static;
 
 
 	TCPServerWinsock::cleanup();