mirror of
https://github.com/azalea-rs/simdnbt.git
synced 2025-08-02 07:26:04 +00:00
fix memory leak on error
This commit is contained in:
parent
4aa3effbf1
commit
33366ff085
4 changed files with 43 additions and 13 deletions
|
@ -50,10 +50,11 @@ fn bench_file(filename: &str, c: &mut Criterion) {
|
|||
static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;
|
||||
|
||||
fn bench(c: &mut Criterion) {
|
||||
// bench_file("bigtest.nbt", c);
|
||||
// bench_file("simple_player.dat", c);
|
||||
bench_file("bigtest.nbt", c);
|
||||
bench_file("simple_player.dat", c);
|
||||
bench_file("complex_player.dat", c);
|
||||
// bench_file("level.dat", c);
|
||||
bench_file("level.dat", c);
|
||||
|
||||
// bench_file("stringtest.nbt", c);
|
||||
// bench_file("inttest16.nbt", c);
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ impl<'a> NbtCompound<'a> {
|
|||
return Err(Error::MaxDepthExceeded);
|
||||
}
|
||||
|
||||
let alloc_mut = unsafe { alloc.get().as_mut().unwrap() };
|
||||
let alloc_mut = unsafe { alloc.get().as_mut().unwrap_unchecked() };
|
||||
|
||||
let mut tags = alloc_mut.start_named_tags(depth);
|
||||
loop {
|
||||
|
@ -43,14 +43,26 @@ impl<'a> NbtCompound<'a> {
|
|||
if tag_type == END_ID {
|
||||
break;
|
||||
}
|
||||
let tag_name = read_string(data)?;
|
||||
|
||||
tags.push((
|
||||
tag_name,
|
||||
NbtTag::read_with_type(data, alloc, tag_type, depth)?,
|
||||
));
|
||||
let tag_name = match read_string(data) {
|
||||
Ok(name) => name,
|
||||
Err(_) => {
|
||||
alloc_mut.finish_named_tags(tags, depth);
|
||||
// the only error read_string can return is UnexpectedEof, so this makes it
|
||||
// slightly faster
|
||||
return Err(Error::UnexpectedEof);
|
||||
}
|
||||
};
|
||||
let tag = match NbtTag::read_with_type(data, alloc, tag_type, depth) {
|
||||
Ok(tag) => tag,
|
||||
Err(e) => {
|
||||
alloc_mut.finish_named_tags(tags, depth);
|
||||
return Err(e);
|
||||
}
|
||||
};
|
||||
tags.push((tag_name, tag));
|
||||
}
|
||||
let alloc_mut = unsafe { alloc.get().as_mut().unwrap() };
|
||||
let alloc_mut = unsafe { alloc.get().as_mut().unwrap_unchecked() };
|
||||
let values = alloc_mut.finish_named_tags(tags, depth);
|
||||
|
||||
Ok(Self { values })
|
||||
|
|
|
@ -80,7 +80,14 @@ impl<'a> NbtList<'a> {
|
|||
let alloc_mut = unsafe { alloc.get().as_mut().unwrap() };
|
||||
let mut tags = alloc_mut.start_unnamed_list_tags(depth);
|
||||
for _ in 0..length {
|
||||
tags.push(NbtList::read(data, alloc, depth + 1)?)
|
||||
let tag = match NbtList::read(data, alloc, depth + 1) {
|
||||
Ok(tag) => tag,
|
||||
Err(e) => {
|
||||
alloc_mut.finish_unnamed_list_tags(tags, depth);
|
||||
return Err(e);
|
||||
}
|
||||
};
|
||||
tags.push(tag)
|
||||
}
|
||||
let alloc_mut = unsafe { alloc.get().as_mut().unwrap() };
|
||||
alloc_mut.finish_unnamed_list_tags(tags, depth)
|
||||
|
@ -92,7 +99,14 @@ impl<'a> NbtList<'a> {
|
|||
let alloc_mut = unsafe { alloc.get().as_mut().unwrap() };
|
||||
let mut tags = alloc_mut.start_unnamed_compound_tags(depth);
|
||||
for _ in 0..length {
|
||||
tags.push(NbtCompound::read_with_depth(data, alloc, depth + 1)?)
|
||||
let tag = match NbtCompound::read_with_depth(data, alloc, depth + 1) {
|
||||
Ok(tag) => tag,
|
||||
Err(e) => {
|
||||
alloc_mut.finish_unnamed_compound_tags(tags, depth);
|
||||
return Err(e);
|
||||
}
|
||||
};
|
||||
tags.push(tag);
|
||||
}
|
||||
let alloc_mut = unsafe { alloc.get().as_mut().unwrap() };
|
||||
alloc_mut.finish_unnamed_compound_tags(tags, depth)
|
||||
|
|
|
@ -261,6 +261,7 @@ pub struct ContiguousTagsAllocator<T> {
|
|||
}
|
||||
|
||||
impl<T> ContiguousTagsAllocator<T> {
|
||||
#[inline(never)]
|
||||
fn grow(&mut self) {
|
||||
let new_cap = if self.is_new_allocation {
|
||||
// this makes sure we don't allocate 0 bytes
|
||||
|
@ -297,6 +298,7 @@ impl<T> ContiguousTagsAllocator<T> {
|
|||
self.alloc.len = self.size;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn push(&mut self, value: T) {
|
||||
// check if we need to reallocate
|
||||
if self.alloc.len == self.alloc.cap {
|
||||
|
@ -305,7 +307,8 @@ impl<T> ContiguousTagsAllocator<T> {
|
|||
|
||||
// push the new tag
|
||||
unsafe {
|
||||
std::ptr::write(self.alloc.ptr.as_ptr().add(self.alloc.len), value);
|
||||
let end = self.alloc.ptr.as_ptr().add(self.alloc.len);
|
||||
std::ptr::write(end, value);
|
||||
}
|
||||
self.alloc.len += 1;
|
||||
self.size += 1;
|
||||
|
|
Loading…
Add table
Reference in a new issue