[Bf-blender-cvs] [8c5041b] object_nodes: Fix for memleaks caused by un-freed Value instances, kudos to Kevin Dietrich!

Lukas Tönne noreply at git.blender.org
Thu Dec 31 14:50:57 CET 2015


Commit: 8c5041be5ce799b87debda28884bfc5de8ff3080
Author: Lukas Tönne
Date:   Thu Dec 31 13:11:19 2015 +0100
Branches: object_nodes
https://developer.blender.org/rB8c5041be5ce799b87debda28884bfc5de8ff3080

Fix for memleaks caused by un-freed Value instances, kudos to Kevin Dietrich!

These values are heap-allocated virtual classes, because general node code is
largely agnostic to data types. After adding values to a node (either as
default input values or per instance), care must be taken to free them when
the node type or instance is destroyed.

===================================================================

M	source/blender/blenvm/compile/bvm_codegen.cc
M	source/blender/blenvm/compile/bvm_nodegraph.cc
M	source/blender/blenvm/compile/bvm_nodegraph.h
M	source/blender/blenvm/intern/bvm_api.cc
M	source/blender/blenvm/util/bvm_util_typedesc.h

===================================================================

diff --git a/source/blender/blenvm/compile/bvm_codegen.cc b/source/blender/blenvm/compile/bvm_codegen.cc
index 9244521..f7195c2 100644
--- a/source/blender/blenvm/compile/bvm_codegen.cc
+++ b/source/blender/blenvm/compile/bvm_codegen.cc
@@ -533,7 +533,7 @@ int BVMCompiler::codegen_function(const BVMCompiler::FunctionInfo &func,
 			}
 			else {
 				/* create a value node for the input */
-				Value *value = (node.has_input_value(i)) ? node.find_input_value(i) : input->default_value;
+				const Value *value = (node.has_input_value(i)) ? node.find_input_value(i) : input->default_value;
 				codegen_value(value, func.input_index.at(key));
 			}
 		}
@@ -564,7 +564,7 @@ int BVMCompiler::codegen_function(const BVMCompiler::FunctionInfo &func,
 				ConstSocketPair key(&node, input->name);
 				
 				if (node.is_input_constant(i)) {
-					Value *value = node.find_input_value(i);
+					const Value *value = node.find_input_value(i);
 					if (!value)
 						value = node.type->find_input(i)->default_value;
 					push_constant(value);
diff --git a/source/blender/blenvm/compile/bvm_nodegraph.cc b/source/blender/blenvm/compile/bvm_nodegraph.cc
index fb938a8..c221468 100644
--- a/source/blender/blenvm/compile/bvm_nodegraph.cc
+++ b/source/blender/blenvm/compile/bvm_nodegraph.cc
@@ -82,6 +82,12 @@ NodeType::NodeType(const string &name, bool is_kernel_node, bool is_pass_node) :
 
 NodeType::~NodeType()
 {
+	/* input values are owned by the node type */
+	for (InputList::const_iterator it = m_inputs.begin(); it != m_inputs.end(); ++it) {
+		const NodeInput &input = *it;
+		if (input.default_value)
+			delete input.default_value;
+	}
 }
 
 const NodeInput *NodeType::find_input(int index) const
@@ -235,6 +241,17 @@ NodeInstance::NodeInstance(const NodeType *type, const string &name) :
 
 NodeInstance::~NodeInstance()
 {
+	/* value instances are managed by the node */
+	for (InputMap::const_iterator it = inputs.begin(); it != inputs.end(); ++it) {
+		const InputInstance &input = it->second;
+		if (input.value)
+			delete input.value;
+	}
+	for (OutputMap::const_iterator it = outputs.begin(); it != outputs.end(); ++it) {
+		const OutputInstance &output = it->second;
+		if (output.value)
+			delete output.value;
+	}
 }
 
 SocketPair NodeInstance::input(const string &name)
@@ -328,25 +345,25 @@ SocketPair NodeInstance::link(int index) const
 	return socket ? link(socket->name) : SocketPair(NULL, "");
 }
 
-Value *NodeInstance::find_input_value(const string &name) const
+const Value *NodeInstance::find_input_value(const string &name) const
 {
 	InputMap::const_iterator it = inputs.find(name);
 	return (it != inputs.end()) ? it->second.value : NULL;
 }
 
-Value *NodeInstance::find_input_value(int index) const
+const Value *NodeInstance::find_input_value(int index) const
 {
 	const NodeInput *socket = type->find_input(index);
 	return socket ? find_input_value(socket->name) : NULL;
 }
 
-Value *NodeInstance::find_output_value(const string &name) const
+const Value *NodeInstance::find_output_value(const string &name) const
 {
 	OutputMap::const_iterator it = outputs.find(name);
 	return (it != outputs.end()) ? it->second.value : NULL;
 }
 
-Value *NodeInstance::find_output_value(int index) const
+const Value *NodeInstance::find_output_value(int index) const
 {
 	const NodeOutput *socket = type->find_output(index);
 	return socket ? find_output_value(socket->name) : NULL;
@@ -678,7 +695,7 @@ SocketPair NodeGraph::find_root(const SocketPair &key)
 {
 	SocketPair root = key;
 	/* value is used to create a valid root node if necessary */
-	Value *value = NULL;
+	const Value *value = NULL;
 	while (root.node && root.node->type->is_pass_node()) {
 		value = root.node->has_input_value(0) ?
 		            root.node->find_input_value(0) :
@@ -692,7 +709,7 @@ SocketPair NodeGraph::find_root(const SocketPair &key)
 	/* create a value node as valid root if necessary */
 	if (!root.node) {
 		assert(value != NULL);
-		root = add_value_node(value);
+		root = add_value_node(value->copy());
 	}
 	
 	return root;
@@ -896,6 +913,8 @@ static mesh_ptr __empty_mesh__;
 
 static void register_opcode_node_types()
 {
+	static DupliList *__empty_duplilist__ = new DupliList();
+	
 	NodeType *nt;
 	
 	nt = NodeGraph::add_function_node_type("FLOAT_TO_INT");
@@ -939,7 +958,7 @@ static void register_opcode_node_types()
 	nt->add_output("value", TYPE_MESH);
 	
 	nt = NodeGraph::add_pass_node_type("PASS_DUPLIS");
-	nt->add_input("value", TYPE_DUPLIS, duplis_ptr(new DupliList()));
+	nt->add_input("value", TYPE_DUPLIS, duplis_ptr(__empty_duplilist__));
 	nt->add_output("value", TYPE_DUPLIS);
 	
 	nt = NodeGraph::add_pass_node_type("PASS_FLOAT_ARRAY");
@@ -1038,7 +1057,7 @@ static void register_opcode_node_types()
 	nt->add_output("value", TYPE_MESH);
 	
 	nt = NodeGraph::add_function_node_type("VALUE_DUPLIS");
-	nt->add_input("value", TYPE_DUPLIS, duplis_ptr(new DupliList()), INPUT_CONSTANT);
+	nt->add_input("value", TYPE_DUPLIS, duplis_ptr(__empty_duplilist__), INPUT_CONSTANT);
 	nt->add_output("value", TYPE_DUPLIS);
 	
 	nt = NodeGraph::add_function_node_type("GET_ELEM_FLOAT3");
@@ -1272,8 +1291,8 @@ static void register_opcode_node_types()
 	nt->add_output("dupli", TYPE_DUPLIS);
 	
 	nt = NodeGraph::add_function_node_type("DUPLIS_COMBINE");
-	nt->add_input("duplis_a", TYPE_DUPLIS, duplis_ptr(new DupliList()));
-	nt->add_input("duplis_b", TYPE_DUPLIS, duplis_ptr(new DupliList()));
+	nt->add_input("duplis_a", TYPE_DUPLIS, duplis_ptr(__empty_duplilist__));
+	nt->add_input("duplis_b", TYPE_DUPLIS, duplis_ptr(__empty_duplilist__));
 	nt->add_output("duplis", TYPE_DUPLIS);
 	
 	nt = NodeGraph::add_function_node_type("ADD_MATRIX44");
diff --git a/source/blender/blenvm/compile/bvm_nodegraph.h b/source/blender/blenvm/compile/bvm_nodegraph.h
index 1afd27f..341816e 100644
--- a/source/blender/blenvm/compile/bvm_nodegraph.h
+++ b/source/blender/blenvm/compile/bvm_nodegraph.h
@@ -199,12 +199,22 @@ struct SocketPair {
 
 struct NodeInstance {
 	struct InputInstance {
+		InputInstance() :
+		    link_node(NULL),
+		    link_socket(NULL),
+		    value(NULL)
+		{}
+		
 		NodeInstance *link_node;
 		const NodeOutput *link_socket;
 		Value *value;
 	};
 	
 	struct OutputInstance {
+		OutputInstance() :
+		    value(NULL)
+		{}
+		
 		Value *value;
 	};
 	
@@ -234,10 +244,10 @@ struct NodeInstance {
 	SocketPair link(int index) const;
 	const NodeOutput *find_input_link_socket(const string &name) const;
 	const NodeOutput *find_input_link_socket(int index) const;
-	Value *find_input_value(const string &name) const;
-	Value *find_input_value(int index) const;
-	Value *find_output_value(const string &name) const;
-	Value *find_output_value(int index) const;
+	const Value *find_input_value(const string &name) const;
+	const Value *find_input_value(int index) const;
+	const Value *find_output_value(const string &name) const;
+	const Value *find_output_value(int index) const;
 	
 	bool set_input_value(const string &name, Value *value);
 	bool set_input_link(const string &name, NodeInstance *from_node, const NodeOutput *from_socket);
diff --git a/source/blender/blenvm/intern/bvm_api.cc b/source/blender/blenvm/intern/bvm_api.cc
index 8f22b68..f22dfdc 100644
--- a/source/blender/blenvm/intern/bvm_api.cc
+++ b/source/blender/blenvm/intern/bvm_api.cc
@@ -1165,6 +1165,6 @@ void BVM_eval_dupli(struct BVMEvalGlobals *globals,
 			                       false, dupli.hide, dupli.recursive);
 		}
 		
-//		delete duplis;
+		delete duplis;
 	}
 }
diff --git a/source/blender/blenvm/util/bvm_util_typedesc.h b/source/blender/blenvm/util/bvm_util_typedesc.h
index ee0034f..e02706a 100644
--- a/source/blender/blenvm/util/bvm_util_typedesc.h
+++ b/source/blender/blenvm/util/bvm_util_typedesc.h
@@ -557,6 +557,8 @@ struct Value {
 	template <typename T>
 	bool get(T *data) const;
 	
+	virtual Value *copy() const = 0;
+	
 protected:
 	Value(const TypeDesc &typedesc) :
 	    m_typedesc(typedesc)
@@ -596,6 +598,11 @@ struct SingleValue : public Value {
 		return false;
 	}
 	
+	Value *copy() const
+	{
+		return new SingleValue<type>(m_data);
+	}
+	
 private:
 	POD m_data;
 };
@@ -643,6 +650,11 @@ struct ArrayValue : public Value {
 		return false;
 	}
 	
+	Value *copy() const
+	{
+		return new ArrayValue<type>(m_data);
+	}
+	
 private:
 	array_t m_data;
 };




More information about the Bf-blender-cvs mailing list