[Bf-blender-cvs] [aa179bdfa39] functions: separate tuple from its meta data

Jacques Lucke noreply at git.blender.org
Sat Mar 2 22:01:01 CET 2019


Commit: aa179bdfa3915295fda0148cb7396fc8fc0452c7
Author: Jacques Lucke
Date:   Sat Mar 2 22:00:47 2019 +0100
Branches: functions
https://developer.blender.org/rBaa179bdfa3915295fda0148cb7396fc8fc0452c7

separate tuple from its meta data

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

M	source/blender/functions/backends/llvm/to_tuple_call.cpp
M	source/blender/functions/backends/tuple_call/tuple.hpp
M	source/blender/functions/c_wrapper.cpp

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

diff --git a/source/blender/functions/backends/llvm/to_tuple_call.cpp b/source/blender/functions/backends/llvm/to_tuple_call.cpp
index 2dc3e9e911a..ddb755750e5 100644
--- a/source/blender/functions/backends/llvm/to_tuple_call.cpp
+++ b/source/blender/functions/backends/llvm/to_tuple_call.cpp
@@ -121,11 +121,15 @@ namespace FN {
 
 		void call(const Tuple &fn_in, Tuple &fn_out) const override
 		{
+			BLI_assert(fn_in.all_initialized());
+
 			m_call(
 				fn_in.data_ptr(),
 				fn_in.offsets_ptr(),
 				fn_out.data_ptr(),
 				fn_out.offsets_ptr());
+
+			fn_out.set_all_initialized();
 		}
 	};
 
diff --git a/source/blender/functions/backends/tuple_call/tuple.hpp b/source/blender/functions/backends/tuple_call/tuple.hpp
index f17c3e478f5..8b11581712e 100644
--- a/source/blender/functions/backends/tuple_call/tuple.hpp
+++ b/source/blender/functions/backends/tuple_call/tuple.hpp
@@ -4,68 +4,130 @@
 
 namespace FN {
 
-	class Tuple {
+	class TupleMeta {
+	private:
+		SmallTypeVector m_types;
+		SmallVector<CPPTypeInfo *> m_type_info;
+		SmallVector<uint> m_offsets;
+		uint m_total_size;
+
 	public:
-		Tuple(const SmallTypeVector &types = {})
+		TupleMeta(const SmallTypeVector &types = {})
 			: m_types(types)
 		{
-			int total_size = 0;
+			m_total_size = 0;
 			for (const SharedType &type : types) {
 				CPPTypeInfo *info = type->extension<CPPTypeInfo>();
-
-				m_offsets.append(total_size);
-				m_initialized.append(false);
+				m_offsets.append(m_total_size);
 				m_type_info.append(info);
-				total_size += info->size_of_type();
+				m_total_size += info->size_of_type();
 			}
-			m_offsets.append(total_size);
-			m_data = std::malloc(total_size);
+			m_offsets.append(m_total_size);
+		}
+
+		const SmallTypeVector &types() const
+		{
+			return m_types;
+		}
+
+		const SmallVector<CPPTypeInfo *> &type_infos() const
+		{
+			return m_type_info;
+		}
+
+		const SmallVector<uint> &offsets() const
+		{
+			return m_offsets;
 		}
 
+		uint total_size() const
+		{
+			return m_total_size;
+		}
+
+		uint element_amount() const
+		{
+			return m_types.size();
+		}
+
+		uint element_size(uint index) const
+		{
+			return m_offsets[index + 1] - m_offsets[index];
+		}
+	};
+
+	using SharedTupleMeta = Shared<TupleMeta>;
+
+	class Tuple {
+	public:
+		Tuple(SharedTupleMeta meta)
+			: m_meta(std::move(meta))
+		{
+			m_initialized = SmallVector<bool>(m_meta->element_amount());
+			m_initialized.fill(false);
+
+			m_data = std::malloc(m_meta->total_size());
+			m_owns_data = true;
+		}
+
+		Tuple(SharedTupleMeta meta, void *data, bool take_ownership)
+			: m_meta(std::move(meta))
+		{
+			m_initialized = SmallVector<bool>(m_meta->element_amount());
+			m_initialized.fill(false);
+
+			BLI_assert(data != nullptr);
+			m_data = data;
+			m_owns_data = take_ownership;
+		}
+
+		Tuple(SmallTypeVector types)
+			: Tuple(SharedTupleMeta::New(types)) {}
+
 		/* Has to be implemented explicitely in the future. */
 		Tuple(const Tuple &tuple) = delete;
 
 		~Tuple()
 		{
-			for (uint i = 0; i < m_types.size(); i++) {
-				m_type_info[i]->destruct_type(this->element_ptr(i));
+			for (uint i = 0; i < m_meta->element_amount(); i++) {
+				if (m_initialized[i]) {
+					m_meta->type_infos()[i]->destruct_type(this->element_ptr(i));
+				}
+			}
+			if (m_owns_data) {
+				std::free(m_data);
 			}
-			std::free(m_data);
 		}
 
 		template<typename T>
 		inline void set(uint index, const T &value)
 		{
-			BLI_assert(index < m_types.size());
-			BLI_assert(sizeof(T) == this->element_size(index));
+			BLI_assert(index < m_meta->element_amount());
+			BLI_assert(sizeof(T) == m_meta->element_size(index));
 
 			if (std::is_trivial<T>::value) {
 				std::memcpy(this->element_ptr(index), &value, sizeof(T));
 			}
 			else {
-				const T *begin = &value;
-				const T *end = begin + 1;
 				T *dst = (T *)this->element_ptr(index);
 
 				if (m_initialized[index]) {
-					std::copy(begin, end, dst);
+					std::copy_n(&value, 1, dst);
 				}
 				else {
-					std::uninitialized_copy(begin, end, dst);
-					m_initialized[index] = true;
+					std::uninitialized_copy_n(&value, 1, dst);
 				}
 			}
+
+			m_initialized[index] = true;
 		}
 
 		template<typename T>
 		inline const T &get(uint index) const
 		{
-			BLI_assert(index < m_types.size());
-			BLI_assert(sizeof(T) == this->element_size(index));
-
-			if (!std::is_trivial<T>::value) {
-				BLI_assert(m_initialized[index]);
-			}
+			BLI_assert(index < m_meta->element_amount());
+			BLI_assert(sizeof(T) == m_meta->element_size(index));
+			BLI_assert(m_initialized[index]);
 
 			return *(T *)this->element_ptr(index);
 		}
@@ -74,21 +136,38 @@ namespace FN {
 			const Tuple &from, uint from_index,
 			Tuple &to, uint to_index)
 		{
-			BLI_assert(from.m_types[from_index] == to.m_types[to_index]);
+			BLI_assert(from.m_initialized[from_index]);
+			BLI_assert(from.m_meta->types()[from_index] == to.m_meta->types()[to_index]);
+
+			void *src = from.element_ptr(from_index);
+			void *dst = to.element_ptr(to_index);
+			CPPTypeInfo *type_info = from.m_meta->type_infos()[from_index];
 
-			from.m_type_info[from_index]->copy_to_initialized(
-				from.element_ptr(from_index), to.element_ptr(to_index));
+			if (to.m_initialized[to_index]) {
+				type_info->copy_to_initialized(src, dst);
+			}
+			else {
+				type_info->copy_to_uninitialized(src, dst);
+				to.m_initialized[to_index] = true;
+			}
 		}
 
 		inline void init_default(uint index) const
 		{
-			m_type_info[index]->construct_default(this->element_ptr(index));
+			CPPTypeInfo *type_info = m_meta->type_infos()[index];
+			void *ptr = this->element_ptr(index);
+
+			if (m_initialized[index]) {
+				type_info->destruct_type(ptr);
+			}
+
+			type_info->construct_default(ptr);
 			m_initialized[index] = true;
 		}
 
 		inline void init_default_all() const
 		{
-			for (uint i = 0; i < m_types.size(); i++) {
+			for (uint i = 0; i < m_meta->element_amount(); i++) {
 				this->init_default(i);
 			}
 		}
@@ -100,25 +179,34 @@ namespace FN {
 
 		const uint *offsets_ptr() const
 		{
-			return m_offsets.begin();
+			return m_meta->offsets().begin();
 		}
 
-	private:
-		inline uint element_size(uint index) const
+		bool all_initialized() const
 		{
-			return m_offsets[index + 1] - m_offsets[index];
+			for (bool initialized : m_initialized) {
+				if (!initialized) {
+					return false;
+				}
+			}
+			return true;
 		}
 
+		void set_all_initialized()
+		{
+			m_initialized.fill(true);
+		}
+
+	private:
 		inline void *element_ptr(uint index) const
 		{
-			return (void *)((char *)m_data + m_offsets[index]);
+			return (void *)((char *)m_data + m_meta->offsets()[index]);
 		}
 
-		SmallTypeVector m_types;
-		SmallVector<CPPTypeInfo *> m_type_info;
-		SmallVector<uint> m_offsets;
 		SmallVector<bool> m_initialized;
 		void *m_data;
+		bool m_owns_data;
+		SharedTupleMeta m_meta;
 	};
 
 } /* namespace FN */
\ No newline at end of file
diff --git a/source/blender/functions/c_wrapper.cpp b/source/blender/functions/c_wrapper.cpp
index 1d8a8a4d190..34407dffa4e 100644
--- a/source/blender/functions/c_wrapper.cpp
+++ b/source/blender/functions/c_wrapper.cpp
@@ -46,7 +46,12 @@ void FN_initialize()
 
 void FN_function_call(FnTupleCallBody fn_call, FnTuple fn_in, FnTuple fn_out)
 {
-	unwrap(fn_call)->call(*unwrap(fn_in), *unwrap(fn_out));
+	Tuple &fn_in_ = *unwrap(fn_in);
+	Tuple &fn_out_ = *unwrap(fn_out);
+
+	BLI_assert(fn_in_.all_initialized());
+	unwrap(fn_call)->call(fn_in_, fn_out_);
+	BLI_assert(fn_out_.all_initialized());
 }
 
 FnTupleCallBody FN_function_get_callable(FnFunction fn)



More information about the Bf-blender-cvs mailing list