| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent ccf0917 commit 041daaa
3 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -627,6 +627,8 @@ | |||
| 627 | 627 | 'src/node_i18n.h', | |
| 628 | 628 | 'src/node_internals.h', | |
| 629 | 629 | 'src/node_main_instance.h', | |
| 630 | + 'src/node_mem.h', | ||
| 631 | + 'src/node_mem-inl.h', | ||
| 630 | 632 | 'src/node_messaging.h', | |
| 631 | 633 | 'src/node_metadata.h', | |
| 632 | 634 | 'src/node_mutex.h', | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,112 @@ | |||
| 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 | + | ||
| 12 | + template <typename Class, typename AllocatorStruct> | ||
| 13 | + AllocatorStruct NgLibMemoryManager<Class, AllocatorStruct>::MakeAllocator() { | ||
| 14 | + return AllocatorStruct { | ||
| 15 | + static_cast<void*>(static_cast<Class*>(this)), | ||
| 16 | + MallocImpl, | ||
| 17 | + FreeImpl, | ||
| 18 | + CallocImpl, | ||
| 19 | + ReallocImpl | ||
| 20 | + }; | ||
| 21 | + } | ||
| 22 | + | ||
| 23 | + template <typename Class, typename T> | ||
| 24 | + void* NgLibMemoryManager<Class, T>::ReallocImpl(void* ptr, | ||
| 25 | + size_t size, | ||
| 26 | + void* user_data) { | ||
| 27 | + Class* manager = static_cast<Class*>(user_data); | ||
| 28 | + | ||
| 29 | + size_t previous_size = 0; | ||
| 30 | + char* original_ptr = nullptr; | ||
| 31 | + | ||
| 32 | + // We prepend each allocated buffer with a size_t containing the full | ||
| 33 | + // size of the allocation. | ||
| 34 | + if (size > 0) size += sizeof(size_t); | ||
| 35 | + | ||
| 36 | + if (ptr != nullptr) { | ||
| 37 | + // We are free()ing or re-allocating. | ||
| 38 | + original_ptr = static_cast<char*>(ptr) - sizeof(size_t); | ||
| 39 | + previous_size = *reinterpret_cast<size_t*>(original_ptr); | ||
| 40 | + // This means we called StopTracking() on this pointer before. | ||
| 41 | + if (previous_size == 0) { | ||
| 42 | + // Fall back to the standard Realloc() function. | ||
| 43 | + char* ret = UncheckedRealloc(original_ptr, size); | ||
| 44 | + if (ret != nullptr) | ||
| 45 | + ret += sizeof(size_t); | ||
| 46 | + return ret; | ||
| 47 | + } | ||
| 48 | + } | ||
| 49 | + | ||
| 50 | + manager->CheckAllocatedSize(previous_size); | ||
| 51 | + | ||
| 52 | + char* mem = UncheckedRealloc(original_ptr, size); | ||
| 53 | + | ||
| 54 | + if (mem != nullptr) { | ||
| 55 | + // Adjust the memory info counter. | ||
| 56 | + // TODO(addaleax): Avoid the double bookkeeping we do with | ||
| 57 | + // current_nghttp2_memory_ + AdjustAmountOfExternalAllocatedMemory | ||
| 58 | + // and provide versions of our memory allocation utilities that take an | ||
| 59 | + // Environment*/Isolate* parameter and call the V8 method transparently. | ||
| 60 | + const int64_t new_size = size - previous_size; | ||
| 61 | + manager->IncreaseAllocatedSize(new_size); | ||
| 62 | + manager->env()->isolate()->AdjustAmountOfExternalAllocatedMemory( | ||
| 63 | + new_size); | ||
| 64 | + *reinterpret_cast<size_t*>(mem) = size; | ||
| 65 | + mem += sizeof(size_t); | ||
| 66 | + } else if (size == 0) { | ||
| 67 | + manager->DecreaseAllocatedSize(previous_size); | ||
| 68 | + manager->env()->isolate()->AdjustAmountOfExternalAllocatedMemory( | ||
| 69 | + -static_cast<int64_t>(previous_size)); | ||
| 70 | + } | ||
| 71 | + return mem; | ||
| 72 | + } | ||
| 73 | + | ||
| 74 | + template <typename Class, typename T> | ||
| 75 | + void* NgLibMemoryManager<Class, T>::MallocImpl(size_t size, void* user_data) { | ||
| 76 | + return ReallocImpl(nullptr, size, user_data); | ||
| 77 | + } | ||
| 78 | + | ||
| 79 | + template <typename Class, typename T> | ||
| 80 | + void NgLibMemoryManager<Class, T>::FreeImpl(void* ptr, void* user_data) { | ||
| 81 | + if (ptr == nullptr) return; | ||
| 82 | + CHECK_NULL(ReallocImpl(ptr, 0, user_data)); | ||
| 83 | + } | ||
| 84 | + | ||
| 85 | + template <typename Class, typename T> | ||
| 86 | + void* NgLibMemoryManager<Class, T>::CallocImpl(size_t nmemb, | ||
| 87 | + size_t size, | ||
| 88 | + void* user_data) { | ||
| 89 | + size_t real_size = MultiplyWithOverflowCheck(nmemb, size); | ||
| 90 | + void* mem = MallocImpl(real_size, user_data); | ||
| 91 | + if (mem != nullptr) | ||
| 92 | + memset(mem, 0, real_size); | ||
| 93 | + return mem; | ||
| 94 | + } | ||
| 95 | + | ||
| 96 | + template <typename Class, typename T> | ||
| 97 | + void NgLibMemoryManager<Class, T>::StopTrackingMemory(void* ptr) { | ||
| 98 | + size_t* original_ptr = reinterpret_cast<size_t*>( | ||
| 99 | + static_cast<char*>(ptr) - sizeof(size_t)); | ||
| 100 | + Class* manager = static_cast<Class*>(this); | ||
| 101 | + manager->DecreaseAllocatedSize(*original_ptr); | ||
| 102 | + manager->env()->isolate()->AdjustAmountOfExternalAllocatedMemory( | ||
| 103 | + -static_cast<int64_t>(*original_ptr)); | ||
| 104 | + *original_ptr = 0; | ||
| 105 | + } | ||
| 106 | + | ||
| 107 | + } // namespace mem | ||
| 108 | + } // namespace node | ||
| 109 | + | ||
| 110 | + #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS | ||
| 111 | + | ||
| 112 | + #endif // SRC_NODE_MEM_INL_H_ | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,41 @@ | |||
| 1 | + #ifndef SRC_NODE_MEM_H_ | ||
| 2 | + #define SRC_NODE_MEM_H_ | ||
| 3 | + | ||
| 4 | + #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS | ||
| 5 | + | ||
| 6 | + #include <cstddef> | ||
| 7 | + | ||
| 8 | + namespace node { | ||
| 9 | + namespace mem { | ||
| 10 | + | ||
| 11 | + // Both ngtcp2 and nghttp2 allow custom allocators that | ||
| 12 | + // follow exactly the same structure and behavior, but | ||
| 13 | + // use different struct names. To allow for code re-use, | ||
| 14 | + // the NgLibMemoryManager template class can be used for both. | ||
| 15 | + | ||
| 16 | + template <typename Class, typename AllocatorStructName> | ||
| 17 | + class NgLibMemoryManager { | ||
| 18 | + public: | ||
| 19 | + // Class needs to provide these methods: | ||
| 20 | + // void CheckAllocatedSize(size_t previous_size) const; | ||
| 21 | + // void IncreaseAllocatedSize(size_t size); | ||
| 22 | + // void DecreaseAllocatedSize(size_t size); | ||
| 23 | + // Environment* env() const; | ||
| 24 | + | ||
| 25 | + AllocatorStructName MakeAllocator(); | ||
| 26 | + | ||
| 27 | + void StopTrackingMemory(void* ptr); | ||
| 28 | + | ||
| 29 | + private: | ||
| 30 | + static void* ReallocImpl(void* ptr, size_t size, void* user_data); | ||
| 31 | + static void* MallocImpl(size_t size, void* user_data); | ||
| 32 | + static void FreeImpl(void* ptr, void* user_data); | ||
| 33 | + static void* CallocImpl(size_t nmemb, size_t size, void* user_data); | ||
| 34 | + }; | ||
| 35 | + | ||
| 36 | + } // namespace mem | ||
| 37 | + } // namespace node | ||
| 38 | + | ||
| 39 | + #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS | ||
| 40 | + | ||
| 41 | + #endif // SRC_NODE_MEM_H_ | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments