From ca088a7b126be3e08025b83d6ac6aafa7519985c Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 24 Jan 2018 15:46:34 +0100 Subject: [PATCH] Fix T53115: Memleak with instanced groups and Cycles The issue was caused by Cycles allocating ID property in a temporary object which gets overwritten and thrown away every so often. Now dependency graph will try to reliably check whether ID properties from a temp object are to be freed. --- .../depsgraph/intern/depsgraph_query_iter.cc | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/source/blender/depsgraph/intern/depsgraph_query_iter.cc b/source/blender/depsgraph/intern/depsgraph_query_iter.cc index 019bc613632..30c9d9f10be 100644 --- a/source/blender/depsgraph/intern/depsgraph_query_iter.cc +++ b/source/blender/depsgraph/intern/depsgraph_query_iter.cc @@ -58,6 +58,30 @@ extern "C" { /* ************************ DEG ITERATORS ********************* */ +static void verify_id_proeprties_freed(DEGObjectIterData *data) +{ + if (data->dupli_object_current == NULL) { + // We didn't enter duplication yet, so we can't have any dangling + // pointers. + return; + } + const Object *dupli_object = data->dupli_object_current->ob; + Object *temp_dupli_object = &data->temp_dupli_object; + if (temp_dupli_object->id.properties == NULL) { + // No ID proeprties in temp datablock -- no leak is possible. + return; + } + if (temp_dupli_object->id.properties == dupli_object->id.properties) { + // Temp copy of object did not modify ID properties. + return; + } + // Free memory which is owned by temporary storage which is about to + // get overwritten. + IDP_FreeProperty(temp_dupli_object->id.properties); + MEM_freeN(temp_dupli_object->id.properties); + temp_dupli_object->id.properties = NULL; +} + static bool deg_objects_dupli_iterator_next(BLI_Iterator *iter) { DEGObjectIterData *data = (DEGObjectIterData *)iter->data; @@ -78,6 +102,8 @@ static bool deg_objects_dupli_iterator_next(BLI_Iterator *iter) continue; } + verify_id_proeprties_freed(data); + data->dupli_object_current = dob; /* Temporary object to evaluate. */ @@ -215,6 +241,7 @@ void DEG_iterator_objects_next(BLI_Iterator *iter) return; } else { + verify_id_proeprties_freed(data); free_object_duplilist(data->dupli_list); data->dupli_parent = NULL; data->dupli_list = NULL;