| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | /*  memory.cpp                                                           */ | 
					
						
							|  |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | /*                       This file is part of:                           */ | 
					
						
							|  |  |  | /*                           GODOT ENGINE                                */ | 
					
						
							| 
									
										
										
										
											2017-08-27 14:16:55 +02:00
										 |  |  | /*                      https://godotengine.org                          */ | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /*************************************************************************/ | 
					
						
							| 
									
										
										
										
											2022-01-13 09:45:09 +01:00
										 |  |  | /* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur.                 */ | 
					
						
							|  |  |  | /* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md).   */ | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* 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.                */ | 
					
						
							|  |  |  | /*************************************************************************/ | 
					
						
							| 
									
										
										
										
											2018-01-05 00:50:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | #include "memory.h"
 | 
					
						
							| 
									
										
										
										
											2018-09-11 18:13:45 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "core/error_macros.h"
 | 
					
						
							| 
									
										
										
										
											2017-07-25 02:29:46 +02:00
										 |  |  | #include "core/safe_refcount.h"
 | 
					
						
							| 
									
										
										
										
											2018-09-11 18:13:45 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | #include <stdio.h>
 | 
					
						
							| 
									
										
										
										
											2017-01-06 10:15:44 -03:00
										 |  |  | #include <stdlib.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | void *operator new(size_t p_size, const char *p_description) { | 
					
						
							|  |  |  | 	return Memory::alloc_static(p_size, false); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | void *operator new(size_t p_size, void *(*p_allocfunc)(size_t p_size)) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	return p_allocfunc(p_size); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-18 08:46:53 +01:00
										 |  |  | #ifdef _MSC_VER
 | 
					
						
							|  |  |  | void operator delete(void *p_mem, const char *p_description) { | 
					
						
							| 
									
										
										
										
											2019-11-11 10:24:04 +01:00
										 |  |  | 	CRASH_NOW_MSG("Call to placement delete should not happen."); | 
					
						
							| 
									
										
										
										
											2017-11-18 08:46:53 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void operator delete(void *p_mem, void *(*p_allocfunc)(size_t p_size)) { | 
					
						
							| 
									
										
										
										
											2019-11-11 10:24:04 +01:00
										 |  |  | 	CRASH_NOW_MSG("Call to placement delete should not happen."); | 
					
						
							| 
									
										
										
										
											2017-11-18 08:46:53 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void operator delete(void *p_mem, void *p_pointer, size_t check, const char *p_description) { | 
					
						
							| 
									
										
										
										
											2019-11-11 10:24:04 +01:00
										 |  |  | 	CRASH_NOW_MSG("Call to placement delete should not happen."); | 
					
						
							| 
									
										
										
										
											2017-11-18 08:46:53 +01:00
										 |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 10:15:44 -03:00
										 |  |  | #ifdef DEBUG_ENABLED
 | 
					
						
							| 
									
										
										
										
											2021-01-31 13:34:42 +01:00
										 |  |  | SafeNumeric<uint64_t> Memory::mem_usage; | 
					
						
							|  |  |  | SafeNumeric<uint64_t> Memory::max_usage; | 
					
						
							| 
									
										
										
										
											2017-01-06 10:15:44 -03:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-31 13:34:42 +01:00
										 |  |  | SafeNumeric<uint64_t> Memory::alloc_count; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | void *Memory::alloc_static(size_t p_bytes, bool p_pad_align) { | 
					
						
							| 
									
										
										
										
											2017-07-11 14:26:34 +02:00
										 |  |  | #ifdef DEBUG_ENABLED
 | 
					
						
							|  |  |  | 	bool prepad = true; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	bool prepad = p_pad_align; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	void *mem = malloc(p_bytes + (prepad ? PAD_ALIGN : 0)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-04 16:00:45 +02:00
										 |  |  | 	ERR_FAIL_COND_V(!mem, nullptr); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-31 13:34:42 +01:00
										 |  |  | 	alloc_count.increment(); | 
					
						
							| 
									
										
										
										
											2017-07-25 02:29:46 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-11 14:26:34 +02:00
										 |  |  | 	if (prepad) { | 
					
						
							|  |  |  | 		uint64_t *s = (uint64_t *)mem; | 
					
						
							|  |  |  | 		*s = p_bytes; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		uint8_t *s8 = (uint8_t *)mem; | 
					
						
							| 
									
										
										
										
											2017-01-06 10:15:44 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef DEBUG_ENABLED
 | 
					
						
							| 
									
										
										
										
											2021-01-31 13:34:42 +01:00
										 |  |  | 		uint64_t new_mem_usage = mem_usage.add(p_bytes); | 
					
						
							|  |  |  | 		max_usage.exchange_if_greater(new_mem_usage); | 
					
						
							| 
									
										
										
										
											2017-01-06 10:15:44 -03:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2017-07-11 14:26:34 +02:00
										 |  |  | 		return s8 + PAD_ALIGN; | 
					
						
							| 
									
										
										
										
											2017-01-06 10:15:44 -03:00
										 |  |  | 	} else { | 
					
						
							|  |  |  | 		return mem; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | void *Memory::realloc_static(void *p_memory, size_t p_bytes, bool p_pad_align) { | 
					
						
							| 
									
										
										
										
											2021-05-04 16:00:45 +02:00
										 |  |  | 	if (p_memory == nullptr) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		return alloc_static(p_bytes, p_pad_align); | 
					
						
							| 
									
										
										
										
											2017-01-06 10:15:44 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	uint8_t *mem = (uint8_t *)p_memory; | 
					
						
							| 
									
										
										
										
											2017-01-06 10:15:44 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-11 14:26:34 +02:00
										 |  |  | #ifdef DEBUG_ENABLED
 | 
					
						
							|  |  |  | 	bool prepad = true; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	bool prepad = p_pad_align; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (prepad) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		mem -= PAD_ALIGN; | 
					
						
							|  |  |  | 		uint64_t *s = (uint64_t *)mem; | 
					
						
							| 
									
										
										
										
											2017-01-06 10:15:44 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef DEBUG_ENABLED
 | 
					
						
							| 
									
										
										
										
											2017-07-25 02:29:46 +02:00
										 |  |  | 		if (p_bytes > *s) { | 
					
						
							| 
									
										
										
										
											2021-01-31 13:34:42 +01:00
										 |  |  | 			uint64_t new_mem_usage = mem_usage.add(p_bytes - *s); | 
					
						
							|  |  |  | 			max_usage.exchange_if_greater(new_mem_usage); | 
					
						
							| 
									
										
										
										
											2017-07-25 02:29:46 +02:00
										 |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2021-01-31 13:34:42 +01:00
										 |  |  | 			mem_usage.sub(*s - p_bytes); | 
					
						
							| 
									
										
										
										
											2017-07-25 02:29:46 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-01-06 10:15:44 -03:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2017-07-11 14:26:34 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if (p_bytes == 0) { | 
					
						
							| 
									
										
										
										
											2017-01-06 10:15:44 -03:00
										 |  |  | 			free(mem); | 
					
						
							| 
									
										
										
										
											2021-05-04 16:00:45 +02:00
										 |  |  | 			return nullptr; | 
					
						
							| 
									
										
										
										
											2017-01-06 10:15:44 -03:00
										 |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2017-07-11 14:26:34 +02:00
										 |  |  | 			*s = p_bytes; | 
					
						
							| 
									
										
										
										
											2017-06-22 05:29:14 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			mem = (uint8_t *)realloc(mem, p_bytes + PAD_ALIGN); | 
					
						
							| 
									
										
										
										
											2021-05-04 16:00:45 +02:00
										 |  |  | 			ERR_FAIL_COND_V(!mem, nullptr); | 
					
						
							| 
									
										
										
										
											2017-01-06 10:15:44 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			s = (uint64_t *)mem; | 
					
						
							| 
									
										
										
										
											2017-07-11 14:26:34 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			*s = p_bytes; | 
					
						
							| 
									
										
										
										
											2017-01-06 10:15:44 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			return mem + PAD_ALIGN; | 
					
						
							| 
									
										
										
										
											2017-01-06 10:15:44 -03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		mem = (uint8_t *)realloc(mem, p_bytes); | 
					
						
							| 
									
										
										
										
											2017-01-06 10:15:44 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-04 16:00:45 +02:00
										 |  |  | 		ERR_FAIL_COND_V(mem == nullptr && p_bytes > 0, nullptr); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-06 10:15:44 -03:00
										 |  |  | 		return mem; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | void Memory::free_static(void *p_ptr, bool p_pad_align) { | 
					
						
							| 
									
										
										
										
											2021-05-04 16:00:45 +02:00
										 |  |  | 	ERR_FAIL_COND(p_ptr == nullptr); | 
					
						
							| 
									
										
										
										
											2017-01-06 10:15:44 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	uint8_t *mem = (uint8_t *)p_ptr; | 
					
						
							| 
									
										
										
										
											2017-01-06 10:15:44 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef DEBUG_ENABLED
 | 
					
						
							| 
									
										
										
										
											2017-07-11 14:26:34 +02:00
										 |  |  | 	bool prepad = true; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	bool prepad = p_pad_align; | 
					
						
							| 
									
										
										
										
											2017-06-22 05:29:14 +02:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2017-07-11 14:26:34 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-31 13:34:42 +01:00
										 |  |  | 	alloc_count.decrement(); | 
					
						
							| 
									
										
										
										
											2017-07-11 14:26:34 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (prepad) { | 
					
						
							|  |  |  | 		mem -= PAD_ALIGN; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef DEBUG_ENABLED
 | 
					
						
							| 
									
										
										
										
											2018-10-04 15:38:01 +02:00
										 |  |  | 		uint64_t *s = (uint64_t *)mem; | 
					
						
							| 
									
										
										
										
											2021-01-31 13:34:42 +01:00
										 |  |  | 		mem_usage.sub(*s); | 
					
						
							| 
									
										
										
										
											2017-01-06 10:15:44 -03:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2017-07-05 10:15:42 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-11 14:26:34 +02:00
										 |  |  | 		free(mem); | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		free(mem); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-25 02:29:46 +02:00
										 |  |  | uint64_t Memory::get_mem_available() { | 
					
						
							|  |  |  | 	return -1; // 0xFFFF...
 | 
					
						
							| 
									
										
										
										
											2017-01-06 10:15:44 -03:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-25 02:29:46 +02:00
										 |  |  | uint64_t Memory::get_mem_usage() { | 
					
						
							| 
									
										
										
										
											2017-01-06 10:15:44 -03:00
										 |  |  | #ifdef DEBUG_ENABLED
 | 
					
						
							| 
									
										
										
										
											2021-01-31 13:34:42 +01:00
										 |  |  | 	return mem_usage.get(); | 
					
						
							| 
									
										
										
										
											2017-01-06 10:15:44 -03:00
										 |  |  | #else
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2017-07-25 02:29:46 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | uint64_t Memory::get_mem_max_usage() { | 
					
						
							| 
									
										
										
										
											2017-01-06 10:15:44 -03:00
										 |  |  | #ifdef DEBUG_ENABLED
 | 
					
						
							| 
									
										
										
										
											2021-01-31 13:34:42 +01:00
										 |  |  | 	return max_usage.get(); | 
					
						
							| 
									
										
										
										
											2017-01-06 10:15:44 -03:00
										 |  |  | #else
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | _GlobalNil::_GlobalNil() { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	color = 1; | 
					
						
							|  |  |  | 	left = this; | 
					
						
							|  |  |  | 	right = this; | 
					
						
							|  |  |  | 	parent = this; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | _GlobalNil _GlobalNilClass::_nil; |