11cb0ef41Sopenharmony_ci#ifndef SRC_NODE_MEM_INL_H_ 21cb0ef41Sopenharmony_ci#define SRC_NODE_MEM_INL_H_ 31cb0ef41Sopenharmony_ci 41cb0ef41Sopenharmony_ci#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 51cb0ef41Sopenharmony_ci 61cb0ef41Sopenharmony_ci#include "node_mem.h" 71cb0ef41Sopenharmony_ci#include "node_internals.h" 81cb0ef41Sopenharmony_ci 91cb0ef41Sopenharmony_cinamespace node { 101cb0ef41Sopenharmony_cinamespace mem { 111cb0ef41Sopenharmony_ci 121cb0ef41Sopenharmony_citemplate <typename Class, typename AllocatorStruct> 131cb0ef41Sopenharmony_ciAllocatorStruct NgLibMemoryManager<Class, AllocatorStruct>::MakeAllocator() { 141cb0ef41Sopenharmony_ci return AllocatorStruct { 151cb0ef41Sopenharmony_ci static_cast<void*>(static_cast<Class*>(this)), 161cb0ef41Sopenharmony_ci MallocImpl, 171cb0ef41Sopenharmony_ci FreeImpl, 181cb0ef41Sopenharmony_ci CallocImpl, 191cb0ef41Sopenharmony_ci ReallocImpl 201cb0ef41Sopenharmony_ci }; 211cb0ef41Sopenharmony_ci} 221cb0ef41Sopenharmony_ci 231cb0ef41Sopenharmony_citemplate <typename Class, typename T> 241cb0ef41Sopenharmony_civoid* NgLibMemoryManager<Class, T>::ReallocImpl(void* ptr, 251cb0ef41Sopenharmony_ci size_t size, 261cb0ef41Sopenharmony_ci void* user_data) { 271cb0ef41Sopenharmony_ci Class* manager = static_cast<Class*>(user_data); 281cb0ef41Sopenharmony_ci 291cb0ef41Sopenharmony_ci size_t previous_size = 0; 301cb0ef41Sopenharmony_ci char* original_ptr = nullptr; 311cb0ef41Sopenharmony_ci 321cb0ef41Sopenharmony_ci // We prepend each allocated buffer with a size_t containing the full 331cb0ef41Sopenharmony_ci // size of the allocation. 341cb0ef41Sopenharmony_ci if (size > 0) size += sizeof(size_t); 351cb0ef41Sopenharmony_ci 361cb0ef41Sopenharmony_ci if (ptr != nullptr) { 371cb0ef41Sopenharmony_ci // We are free()ing or re-allocating. 381cb0ef41Sopenharmony_ci original_ptr = static_cast<char*>(ptr) - sizeof(size_t); 391cb0ef41Sopenharmony_ci previous_size = *reinterpret_cast<size_t*>(original_ptr); 401cb0ef41Sopenharmony_ci // This means we called StopTracking() on this pointer before. 411cb0ef41Sopenharmony_ci if (previous_size == 0) { 421cb0ef41Sopenharmony_ci // Fall back to the standard Realloc() function. 431cb0ef41Sopenharmony_ci char* ret = UncheckedRealloc(original_ptr, size); 441cb0ef41Sopenharmony_ci if (ret != nullptr) 451cb0ef41Sopenharmony_ci ret += sizeof(size_t); 461cb0ef41Sopenharmony_ci return ret; 471cb0ef41Sopenharmony_ci } 481cb0ef41Sopenharmony_ci } 491cb0ef41Sopenharmony_ci 501cb0ef41Sopenharmony_ci manager->CheckAllocatedSize(previous_size); 511cb0ef41Sopenharmony_ci 521cb0ef41Sopenharmony_ci char* mem = UncheckedRealloc(original_ptr, size); 531cb0ef41Sopenharmony_ci 541cb0ef41Sopenharmony_ci if (mem != nullptr) { 551cb0ef41Sopenharmony_ci // Adjust the memory info counter. 561cb0ef41Sopenharmony_ci // TODO(addaleax): Avoid the double bookkeeping we do with 571cb0ef41Sopenharmony_ci // current_nghttp2_memory_ + AdjustAmountOfExternalAllocatedMemory 581cb0ef41Sopenharmony_ci // and provide versions of our memory allocation utilities that take an 591cb0ef41Sopenharmony_ci // Environment*/Isolate* parameter and call the V8 method transparently. 601cb0ef41Sopenharmony_ci const int64_t new_size = size - previous_size; 611cb0ef41Sopenharmony_ci manager->IncreaseAllocatedSize(new_size); 621cb0ef41Sopenharmony_ci manager->env()->isolate()->AdjustAmountOfExternalAllocatedMemory( 631cb0ef41Sopenharmony_ci new_size); 641cb0ef41Sopenharmony_ci *reinterpret_cast<size_t*>(mem) = size; 651cb0ef41Sopenharmony_ci mem += sizeof(size_t); 661cb0ef41Sopenharmony_ci } else if (size == 0) { 671cb0ef41Sopenharmony_ci manager->DecreaseAllocatedSize(previous_size); 681cb0ef41Sopenharmony_ci manager->env()->isolate()->AdjustAmountOfExternalAllocatedMemory( 691cb0ef41Sopenharmony_ci -static_cast<int64_t>(previous_size)); 701cb0ef41Sopenharmony_ci } 711cb0ef41Sopenharmony_ci return mem; 721cb0ef41Sopenharmony_ci} 731cb0ef41Sopenharmony_ci 741cb0ef41Sopenharmony_citemplate <typename Class, typename T> 751cb0ef41Sopenharmony_civoid* NgLibMemoryManager<Class, T>::MallocImpl(size_t size, void* user_data) { 761cb0ef41Sopenharmony_ci return ReallocImpl(nullptr, size, user_data); 771cb0ef41Sopenharmony_ci} 781cb0ef41Sopenharmony_ci 791cb0ef41Sopenharmony_citemplate <typename Class, typename T> 801cb0ef41Sopenharmony_civoid NgLibMemoryManager<Class, T>::FreeImpl(void* ptr, void* user_data) { 811cb0ef41Sopenharmony_ci if (ptr == nullptr) return; 821cb0ef41Sopenharmony_ci CHECK_NULL(ReallocImpl(ptr, 0, user_data)); 831cb0ef41Sopenharmony_ci} 841cb0ef41Sopenharmony_ci 851cb0ef41Sopenharmony_citemplate <typename Class, typename T> 861cb0ef41Sopenharmony_civoid* NgLibMemoryManager<Class, T>::CallocImpl(size_t nmemb, 871cb0ef41Sopenharmony_ci size_t size, 881cb0ef41Sopenharmony_ci void* user_data) { 891cb0ef41Sopenharmony_ci size_t real_size = MultiplyWithOverflowCheck(nmemb, size); 901cb0ef41Sopenharmony_ci void* mem = MallocImpl(real_size, user_data); 911cb0ef41Sopenharmony_ci if (mem != nullptr) 921cb0ef41Sopenharmony_ci memset(mem, 0, real_size); 931cb0ef41Sopenharmony_ci return mem; 941cb0ef41Sopenharmony_ci} 951cb0ef41Sopenharmony_ci 961cb0ef41Sopenharmony_citemplate <typename Class, typename T> 971cb0ef41Sopenharmony_civoid NgLibMemoryManager<Class, T>::StopTrackingMemory(void* ptr) { 981cb0ef41Sopenharmony_ci size_t* original_ptr = reinterpret_cast<size_t*>( 991cb0ef41Sopenharmony_ci static_cast<char*>(ptr) - sizeof(size_t)); 1001cb0ef41Sopenharmony_ci Class* manager = static_cast<Class*>(this); 1011cb0ef41Sopenharmony_ci manager->DecreaseAllocatedSize(*original_ptr); 1021cb0ef41Sopenharmony_ci manager->env()->isolate()->AdjustAmountOfExternalAllocatedMemory( 1031cb0ef41Sopenharmony_ci -static_cast<int64_t>(*original_ptr)); 1041cb0ef41Sopenharmony_ci *original_ptr = 0; 1051cb0ef41Sopenharmony_ci} 1061cb0ef41Sopenharmony_ci 1071cb0ef41Sopenharmony_ci} // namespace mem 1081cb0ef41Sopenharmony_ci} // namespace node 1091cb0ef41Sopenharmony_ci 1101cb0ef41Sopenharmony_ci#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 1111cb0ef41Sopenharmony_ci 1121cb0ef41Sopenharmony_ci#endif // SRC_NODE_MEM_INL_H_ 113