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 |
|
1158 |
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 |
|
1158 |
}; |
21 |
|
|
} |
22 |
|
|
|
23 |
|
|
template <typename Class, typename T> |
24 |
|
234380 |
void* NgLibMemoryManager<Class, T>::ReallocImpl(void* ptr, |
25 |
|
|
size_t size, |
26 |
|
|
void* user_data) { |
27 |
|
234380 |
Class* manager = static_cast<Class*>(user_data); |
28 |
|
|
|
29 |
|
234380 |
size_t previous_size = 0; |
30 |
|
234380 |
char* original_ptr = nullptr; |
31 |
|
|
|
32 |
|
|
// We prepend each allocated buffer with a size_t containing the full |
33 |
|
|
// size of the allocation. |
34 |
✓✓ |
234380 |
if (size > 0) size += sizeof(size_t); |
35 |
|
|
|
36 |
✓✓ |
234380 |
if (ptr != nullptr) { |
37 |
|
|
// We are free()ing or re-allocating. |
38 |
|
117217 |
original_ptr = static_cast<char*>(ptr) - sizeof(size_t); |
39 |
|
117217 |
previous_size = *reinterpret_cast<size_t*>(original_ptr); |
40 |
|
|
// This means we called StopTracking() on this pointer before. |
41 |
✓✓ |
117217 |
if (previous_size == 0) { |
42 |
|
|
// Fall back to the standard Realloc() function. |
43 |
|
2129 |
char* ret = UncheckedRealloc(original_ptr, size); |
44 |
✗✓ |
2129 |
if (ret != nullptr) |
45 |
|
|
ret += sizeof(size_t); |
46 |
|
2129 |
return ret; |
47 |
|
|
} |
48 |
|
|
} |
49 |
|
|
|
50 |
|
232251 |
manager->CheckAllocatedSize(previous_size); |
51 |
|
|
|
52 |
|
232251 |
char* mem = UncheckedRealloc(original_ptr, size); |
53 |
|
|
|
54 |
✓✓ |
232251 |
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 |
|
117228 |
const int64_t new_size = size - previous_size; |
61 |
|
117228 |
manager->IncreaseAllocatedSize(new_size); |
62 |
|
117228 |
manager->env()->isolate()->AdjustAmountOfExternalAllocatedMemory( |
63 |
|
|
new_size); |
64 |
|
117228 |
*reinterpret_cast<size_t*>(mem) = size; |
65 |
|
117228 |
mem += sizeof(size_t); |
66 |
✓✗ |
115023 |
} else if (size == 0) { |
67 |
|
115023 |
manager->DecreaseAllocatedSize(previous_size); |
68 |
|
115023 |
manager->env()->isolate()->AdjustAmountOfExternalAllocatedMemory( |
69 |
|
|
-static_cast<int64_t>(previous_size)); |
70 |
|
|
} |
71 |
|
232251 |
return mem; |
72 |
|
|
} |
73 |
|
|
|
74 |
|
|
template <typename Class, typename T> |
75 |
|
115582 |
void* NgLibMemoryManager<Class, T>::MallocImpl(size_t size, void* user_data) { |
76 |
|
115582 |
return ReallocImpl(nullptr, size, user_data); |
77 |
|
|
} |
78 |
|
|
|
79 |
|
|
template <typename Class, typename T> |
80 |
|
262901 |
void NgLibMemoryManager<Class, T>::FreeImpl(void* ptr, void* user_data) { |
81 |
✓✓ |
262901 |
if (ptr == nullptr) return; |
82 |
✗✓ |
117152 |
CHECK_NULL(ReallocImpl(ptr, 0, user_data)); |
83 |
|
|
} |
84 |
|
|
|
85 |
|
|
template <typename Class, typename T> |
86 |
|
2320 |
void* NgLibMemoryManager<Class, T>::CallocImpl(size_t nmemb, |
87 |
|
|
size_t size, |
88 |
|
|
void* user_data) { |
89 |
|
2320 |
size_t real_size = MultiplyWithOverflowCheck(nmemb, size); |
90 |
|
2320 |
void* mem = MallocImpl(real_size, user_data); |
91 |
✓✗ |
2320 |
if (mem != nullptr) |
92 |
|
2320 |
memset(mem, 0, real_size); |
93 |
|
2320 |
return mem; |
94 |
|
|
} |
95 |
|
|
|
96 |
|
|
template <typename Class, typename T> |
97 |
|
26346 |
void NgLibMemoryManager<Class, T>::StopTrackingMemory(void* ptr) { |
98 |
|
26346 |
size_t* original_ptr = reinterpret_cast<size_t*>( |
99 |
|
|
static_cast<char*>(ptr) - sizeof(size_t)); |
100 |
|
26346 |
Class* manager = static_cast<Class*>(this); |
101 |
|
26346 |
manager->DecreaseAllocatedSize(*original_ptr); |
102 |
|
26346 |
manager->env()->isolate()->AdjustAmountOfExternalAllocatedMemory( |
103 |
|
|
-static_cast<int64_t>(*original_ptr)); |
104 |
|
26346 |
*original_ptr = 0; |
105 |
|
26346 |
} |
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_ |