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;
 };

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to