Skip to content

Commit a21147b

Browse files
committed
fix(values) Fix memory leak inside get_node_values.
The code was acting like this before: 1. Allocate a new `Vec<LLVMValueRef>`, 2. Get a mutable pointer to it, 3. Forget the vector, 4. Fill the vector with `LLVMGetMDNodeOperands`, 5. Read back the vector as a slice, 6. Map slice values, and collect them in a newly allocated vector. Here, the first vector is lost. That's a memory leak. This patch changes the step 5: Instead of reading the results as a slice, results are read as a vector, the same vector, with the same pointer. That way, the new `vec` vector will be dropped by Rust nicely. Compiling and running the documentation of the `Module::get_global_metadata` method, valgrind gives us the following results: (before) ``` ==35805== LEAK SUMMARY: ==35805== definitely lost: 24 bytes in 2 blocks ==35805== indirectly lost: 0 bytes in 0 blocks ==35805== possibly lost: 0 bytes in 0 blocks ==35805== still reachable: 145 bytes in 1 blocks ==35805== suppressed: 137,663 bytes in 1,484 blocks ``` (after) ``` ==37629== LEAK SUMMARY: ==37629== definitely lost: 16 bytes in 1 blocks ==37629== indirectly lost: 0 bytes in 0 blocks ==37629== possibly lost: 0 bytes in 0 blocks ==37629== still reachable: 145 bytes in 1 blocks ==37629== suppressed: 137,663 bytes in 1,484 blocks ```
1 parent 5e64c01 commit a21147b

File tree

1 file changed

+7
-5
lines changed

1 file changed

+7
-5
lines changed

src/values/metadata_value.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -109,19 +109,21 @@ impl<'ctx> MetadataValue<'ctx> {
109109
return Vec::new();
110110
}
111111

112-
let count = self.get_node_size();
113-
let mut raw_vec: Vec<LLVMValueRef> = Vec::with_capacity(count as usize);
112+
let count = self.get_node_size() as usize;
113+
let mut raw_vec: Vec<LLVMValueRef> = Vec::with_capacity(count);
114114
let ptr = raw_vec.as_mut_ptr();
115115

116116
forget(raw_vec);
117117

118-
let slice = unsafe {
118+
let vec = unsafe {
119119
LLVMGetMDNodeOperands(self.as_value_ref(), ptr);
120120

121-
from_raw_parts(ptr, count as usize)
121+
Vec::from_raw_parts(ptr, count, count)
122122
};
123123

124-
slice.iter().map(|val| BasicMetadataValueEnum::new(*val)).collect()
124+
vec.iter()
125+
.map(|val| BasicMetadataValueEnum::new(*val))
126+
.collect()
125127
}
126128

127129
pub fn print_to_string(self) -> LLVMString {

0 commit comments

Comments
 (0)