Where Online Learning is simpler!
The C and C++ Include Header Files
cat -n /usr/include/nodejs/src/node_mem-inl.h
1 #ifndef SRC_NODE_MEM_INL_H_ 2 #define SRC_NODE_MEM_INL_H_ 3 4 #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 5 6 #include "node_mem.h" 7 #include "node_internals.h" 8 9 namespace node { 10 namespace mem { 11 static constexpr size_t kReserveSizeAndAlign = 12 std::max(sizeof(size_t), alignof(max_align_t)); 13 14 template <typename Class, typename AllocatorStruct> 15 AllocatorStruct NgLibMemoryManager<Class, AllocatorStruct>::MakeAllocator() { 16 return AllocatorStruct { 17 static_cast<void*>(static_cast<Class*>(this)), 18 MallocImpl, 19 FreeImpl, 20 CallocImpl, 21 ReallocImpl 22 }; 23 } 24 25 template <typename Class, typename T> 26 void* NgLibMemoryManager<Class, T>::ReallocImpl(void* ptr, 27 size_t size, 28 void* user_data) { 29 Class* manager = static_cast<Class*>(user_data); 30 31 size_t previous_size = 0; 32 char* original_ptr = nullptr; 33 34 // We prepend each allocated buffer with a size_t containing the full 35 // size of the allocation, while keeping the returned pointer aligned. 36 if (size > 0) size += kReserveSizeAndAlign; 37 38 if (ptr != nullptr) { 39 // We are free()ing or re-allocating. 40 original_ptr = static_cast<char*>(ptr) - kReserveSizeAndAlign; 41 previous_size = *reinterpret_cast<size_t*>(original_ptr); 42 // This means we called StopTracking() on this pointer before. 43 if (previous_size == 0) { 44 // Fall back to the standard Realloc() function. 45 char* ret = UncheckedRealloc(original_ptr, size); 46 if (ret != nullptr) ret += kReserveSizeAndAlign; 47 return ret; 48 } 49 } 50 51 manager->CheckAllocatedSize(previous_size); 52 53 char* mem = UncheckedRealloc(original_ptr, size); 54 55 if (mem != nullptr) { 56 // Adjust the memory info counter. 57 // TODO(addaleax): Avoid the double bookkeeping we do with 58 // current_nghttp2_memory_ + AdjustAmountOfExternalAllocatedMemory 59 // and provide versions of our memory allocation utilities that take an 60 // Environment*/Isolate* parameter and call the V8 method transparently. 61 const int64_t new_size = size - previous_size; 62 manager->IncreaseAllocatedSize(new_size); 63 manager->env()->isolate()->AdjustAmountOfExternalAllocatedMemory( 64 new_size); 65 *reinterpret_cast<size_t*>(mem) = size; 66 mem += kReserveSizeAndAlign; 67 } else if (size == 0) { 68 manager->DecreaseAllocatedSize(previous_size); 69 manager->env()->isolate()->AdjustAmountOfExternalAllocatedMemory( 70 -static_cast<int64_t>(previous_size)); 71 } 72 return mem; 73 } 74 75 template <typename Class, typename T> 76 void* NgLibMemoryManager<Class, T>::MallocImpl(size_t size, void* user_data) { 77 return ReallocImpl(nullptr, size, user_data); 78 } 79 80 template <typename Class, typename T> 81 void NgLibMemoryManager<Class, T>::FreeImpl(void* ptr, void* user_data) { 82 if (ptr == nullptr) return; 83 CHECK_NULL(ReallocImpl(ptr, 0, user_data)); 84 } 85 86 template <typename Class, typename T> 87 void* NgLibMemoryManager<Class, T>::CallocImpl(size_t nmemb, 88 size_t size, 89 void* user_data) { 90 size_t real_size = MultiplyWithOverflowCheck(nmemb, size); 91 void* mem = MallocImpl(real_size, user_data); 92 if (mem != nullptr) 93 memset(mem, 0, real_size); 94 return mem; 95 } 96 97 template <typename Class, typename T> 98 void NgLibMemoryManager<Class, T>::StopTrackingMemory(void* ptr) { 99 size_t* original_ptr = 100 reinterpret_cast<size_t*>(static_cast<char*>(ptr) - kReserveSizeAndAlign); 101 Class* manager = static_cast<Class*>(this); 102 manager->DecreaseAllocatedSize(*original_ptr); 103 manager->env()->isolate()->AdjustAmountOfExternalAllocatedMemory( 104 -static_cast<int64_t>(*original_ptr)); 105 *original_ptr = 0; 106 } 107 108 } // namespace mem 109 } // namespace node 110 111 #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 112 113 #endif // SRC_NODE_MEM_INL_H_