diff --git a/src/checkpoint/dispatch/dispatch.impl.h b/src/checkpoint/dispatch/dispatch.impl.h index fc6a5dc3..c5d4afc6 100644 --- a/src/checkpoint/dispatch/dispatch.impl.h +++ b/src/checkpoint/dispatch/dispatch.impl.h @@ -291,18 +291,44 @@ void deserializeType(InPlaceTag, SerialByteType* data, T* t) { Standard::unpack>(t, data); } +template +void validatePrefix(vrt::TypeIdx prefix) { + if (!vrt::objregistry::isValidIdx(prefix)) { + std::string const err = std::string("Unpacking invalid prefix type (") + + std::to_string(prefix) + std::string(") from object registry for type=") + + std::string(typeregistry::getTypeName()); + throw serialization_error(err); + } +} + template struct PrefixedType { + using BaseType = vrt::checkpoint_base_type_t; + explicit PrefixedType(T* target) : target_(target) { prefix_ = target->_checkpointDynamicTypeIndex(); } - vrt::TypeIdx prefix_; - T* target_; + explicit PrefixedType(SerialByteType* allocBuf) + : unpack_buf_(allocBuf) { + } + + vrt::TypeIdx prefix_ = 0; + T* target_ = nullptr; + SerialByteType* unpack_buf_ = nullptr; template void serialize(SerializerT& s) { s | prefix_; + + // Determine the correct type and allocate memory + if (s.isUnpacking()) { + validatePrefix(prefix_); + + auto mem = unpack_buf_ ? unpack_buf_ : vrt::objregistry::allocateConcreteType(prefix_); + target_ = vrt::objregistry::constructConcreteType(prefix_, mem); + } + s | *target_; } }; @@ -321,38 +347,14 @@ serializeType(T& target, BufferObtainFnType fn) { return packBuffer(prefixed, len, fn); } -template -void validatePrefix(vrt::TypeIdx prefix) { - if (!vrt::objregistry::isValidIdx(prefix)) { - std::string const err = std::string("Unpacking invalid prefix type (") + - std::to_string(prefix) + std::string(") from object registry for type=") + - std::string(typeregistry::getTypeName()); - throw serialization_error(err); - } -} - template typename std::enable_if::has_virtual_serialize, T*>::type deserializeType(SerialByteType* data, SerialByteType* allocBuf) { using BaseType = vrt::checkpoint_base_type_t; using PrefixedType = PrefixedType; - auto prefix_mem = allocBuf ? allocBuf : vrt::objregistry::allocateConcreteType(0); - auto prefix_buf = vrt::objregistry::constructConcreteType(0, prefix_mem); - auto prefix_struct = PrefixedType(prefix_buf); - // Disable memory check during first unpacking. - // Unpacking BaseType will always result in memory amount missmatch between serialization/deserialization - auto* prefix = Standard::unpack>(&prefix_struct, data, false); - - validatePrefix(prefix->prefix_); - - // allocate memory based on the readed TypeIdx - auto mem = allocBuf ? allocBuf : vrt::objregistry::allocateConcreteType(prefix->prefix_); - auto t_buf = vrt::objregistry::constructConcreteType(prefix->prefix_, mem); - auto prefixed = PrefixedType(t_buf); + auto prefixed = PrefixedType(allocBuf); auto* traverser = Standard::unpack>(&prefixed, data); - - delete prefix_buf; return static_cast(traverser->target_); }