From 2f700a48a9e9f427499bfc5fe62c388c35aabcff Mon Sep 17 00:00:00 2001 From: Jan Date: Fri, 19 Mar 2021 15:09:44 +0100 Subject: [PATCH] Make sure fastfile offset is taken after alignment, marking following is done on the originally written data and writing partially uses the original data when writing dynamic sized data too lazy to split into single commits --- .../Templates/Internal/BaseTemplate.cpp | 9 ++ .../Templates/Internal/BaseTemplate.h | 1 + .../Templates/ZoneWriteTemplate.cpp | 127 ++++++++++++++---- .../Zone/Stream/IZoneOutputStream.h | 15 ++- .../Stream/Impl/InMemoryZoneOutputStream.cpp | 30 +++-- .../Stream/Impl/InMemoryZoneOutputStream.h | 3 +- 6 files changed, 145 insertions(+), 40 deletions(-) diff --git a/src/ZoneCodeGeneratorLib/Generating/Templates/Internal/BaseTemplate.cpp b/src/ZoneCodeGeneratorLib/Generating/Templates/Internal/BaseTemplate.cpp index 9b8b39d1..57b8f6d4 100644 --- a/src/ZoneCodeGeneratorLib/Generating/Templates/Internal/BaseTemplate.cpp +++ b/src/ZoneCodeGeneratorLib/Generating/Templates/Internal/BaseTemplate.cpp @@ -98,6 +98,15 @@ std::string BaseTemplate::MakeMemberAccess(StructureInformation* info, MemberInf return str.str(); } +std::string BaseTemplate::MakeMemberAccess(const std::string& variableName, StructureInformation* info, MemberInformation* member, const DeclarationModifierComputations& modifier) +{ + std::ostringstream str; + str << variableName << "->" << member->m_member->m_name; + MakeArrayIndicesInternal(modifier, str); + + return str.str(); +} + std::string BaseTemplate::MakeTypeDecl(const TypeDeclaration* decl) { std::ostringstream str; diff --git a/src/ZoneCodeGeneratorLib/Generating/Templates/Internal/BaseTemplate.h b/src/ZoneCodeGeneratorLib/Generating/Templates/Internal/BaseTemplate.h index 194c2d49..8b478cb6 100644 --- a/src/ZoneCodeGeneratorLib/Generating/Templates/Internal/BaseTemplate.h +++ b/src/ZoneCodeGeneratorLib/Generating/Templates/Internal/BaseTemplate.h @@ -40,6 +40,7 @@ protected: static std::string MakeTypePtrVarName(const DataDefinition* def); static std::string MakeSafeTypeName(const DataDefinition* def); static std::string MakeMemberAccess(StructureInformation* info, MemberInformation* member, const DeclarationModifierComputations& modifier); + static std::string MakeMemberAccess(const std::string& variableName, StructureInformation* info, MemberInformation* member, const DeclarationModifierComputations& modifier); static std::string MakeTypeDecl(const TypeDeclaration* decl); static std::string MakeFollowingReferences(const std::vector& modifiers); static std::string MakeArrayIndices(const DeclarationModifierComputations& modifierComputations); diff --git a/src/ZoneCodeGeneratorLib/Generating/Templates/ZoneWriteTemplate.cpp b/src/ZoneCodeGeneratorLib/Generating/Templates/ZoneWriteTemplate.cpp index 3ab13566..ecda827c 100644 --- a/src/ZoneCodeGeneratorLib/Generating/Templates/ZoneWriteTemplate.cpp +++ b/src/ZoneCodeGeneratorLib/Generating/Templates/ZoneWriteTemplate.cpp @@ -128,7 +128,7 @@ class ZoneWriteTemplate::Internal final : BaseTemplate { LINE("varScriptString = " << MakeMemberAccess(info, member, modifier) << ";") LINE("WriteScriptStringArray(true, " << MakeEvaluation(modifier.GetArrayPointerCountEvaluation()) << ");") - LINE("m_stream->MarkFollowing("<MarkFollowing("<MarkFollowing(" << MakeMemberAccess("writtenData", info, member, modifier) << ");") } } else @@ -209,8 +210,8 @@ class ZoneWriteTemplate::Internal final : BaseTemplate { LINE("m_stream->Write<" << MakeTypeDecl(member->m_member->m_type_declaration.get()) << MakeFollowingReferences(modifier.GetFollowingDeclarationModifiers()) << ">(" << MakeMemberAccess(info, member, modifier) << ", " << MakeEvaluation(modifier.GetArrayPointerCountEvaluation()) << ");") - LINE("m_stream->MarkFollowing("<MarkFollowing(" << MakeMemberAccess("writtenData", info, member, modifier) << ");") } void WriteMember_PointerArray(StructureInformation* info, MemberInformation* member, const DeclarationModifierComputations& modifier) const @@ -223,6 +224,7 @@ class ZoneWriteTemplate::Internal final : BaseTemplate else { LINE("WritePtrArray_" << MakeSafeTypeName(member->m_member->m_type_declaration->m_type) << "(true, " << MakeEvaluation(modifier.GetPointerArrayCountEvaluation()) << ");") + LINE("m_stream->MarkFollowing("<m_definition->GetType() == DataDefinitionType::UNION && StructureComputations(info).GetDynamicMember())) + memberAccess = MakeMemberAccess("originalData", info, member, modifier); + else + memberAccess = MakeMemberAccess(info, member, modifier); + if (!member->m_is_leaf) { - LINE(MakeTypeVarName(member->m_member->m_type_declaration->m_type) << " = " << MakeMemberAccess(info, member, modifier) << ";") - if (computations.IsAfterPartialLoad()) { + LINE(MakeTypeVarName(member->m_member->m_type_declaration->m_type)<<" = "<m_member->m_type_declaration->m_type) << "(true, " << arraySizeStr << ");") } else { + LINE(MakeTypeVarName(member->m_member->m_type_declaration->m_type) << " = " << MakeMemberAccess(info, member, modifier) << ";") LINE("WriteArray_" << MakeSafeTypeName(member->m_member->m_type_declaration->m_type) << "(false, " << arraySizeStr << ");") } } else if (computations.IsAfterPartialLoad()) { LINE("m_stream->Write<" << MakeTypeDecl(member->m_member->m_type_declaration.get()) << MakeFollowingReferences(modifier.GetFollowingDeclarationModifiers()) - << ">(" << MakeMemberAccess(info, member, modifier) << ", " << arraySizeStr << ");") + << ">(" << memberAccess << ", " << arraySizeStr << ");") } } void WriteMember_DynamicArray(StructureInformation* info, MemberInformation* member, const DeclarationModifierComputations& modifier) const { + std::string memberAccess; + if(!(info->m_definition->GetType() == DataDefinitionType::UNION && StructureComputations(info).GetDynamicMember())) + memberAccess = MakeMemberAccess("originalData", info, member, modifier); + else + memberAccess = MakeMemberAccess(info, member, modifier); + if (member->m_type && !member->m_type->m_is_leaf) { - LINE(MakeTypeVarName(member->m_member->m_type_declaration->m_type) << " = " << MakeMemberAccess(info, member, modifier) << ";") + LINE(MakeTypeVarName(member->m_member->m_type_declaration->m_type) << " = " << memberAccess << ";") LINE("WriteArray_" << MakeSafeTypeName(member->m_member->m_type_declaration->m_type) << "(true, " << MakeEvaluation(modifier.GetDynamicArraySizeEvaluation()) << ");") } else { LINE("m_stream->Write<" << MakeTypeDecl(member->m_member->m_type_declaration.get()) << MakeFollowingReferences(modifier.GetFollowingDeclarationModifiers()) - << ">(" << MakeMemberAccess(info, member, modifier) << ", " << MakeEvaluation(modifier.GetDynamicArraySizeEvaluation()) << ");") + << ">(" << memberAccess << ", " << MakeEvaluation(modifier.GetDynamicArraySizeEvaluation()) << ");") } } void WriteMember_Embedded(StructureInformation* info, MemberInformation* member, const DeclarationModifierComputations& modifier) const { const MemberComputations computations(member); + + std::string memberAccess; + if (!(info->m_definition->GetType() == DataDefinitionType::UNION && StructureComputations(info).GetDynamicMember())) + memberAccess = MakeMemberAccess("originalData", info, member, modifier); + else + memberAccess = MakeMemberAccess(info, member, modifier); + if (!member->m_is_leaf) { - LINE(MakeTypeVarName(member->m_member->m_type_declaration->m_type) << " = &" << MakeMemberAccess(info, member, modifier) << ";") - if (computations.IsAfterPartialLoad()) { + LINE(MakeTypeVarName(member->m_member->m_type_declaration->m_type) << " = &" << memberAccess << ";") LINE("Write_" << MakeSafeTypeName(member->m_member->m_type_declaration->m_type) << "(true);") } else { + LINE(MakeTypeVarName(member->m_member->m_type_declaration->m_type) << " = &" << MakeMemberAccess(info, member, modifier) << ";") LINE("Write_" << MakeSafeTypeName(member->m_member->m_type_declaration->m_type) << "(false);") } } else if (computations.IsAfterPartialLoad()) { LINE("m_stream->Write<" << MakeTypeDecl(member->m_member->m_type_declaration.get()) << MakeFollowingReferences(modifier.GetFollowingDeclarationModifiers()) - << ">(&" << MakeMemberAccess(info, member, modifier) << ");") + << ">(&" << memberAccess << ");") } } @@ -305,8 +326,8 @@ class ZoneWriteTemplate::Internal final : BaseTemplate { LINE("m_stream->Write<" << MakeTypeDecl(member->m_member->m_type_declaration.get()) << MakeFollowingReferences(modifier.GetFollowingDeclarationModifiers()) << ">(" << MakeMemberAccess(info, member, modifier) << ");") - LINE("m_stream->MarkFollowing("<MarkFollowing(" << MakeMemberAccess("writtenData", info, member, modifier) << ");") } void WriteMember_TypeCheck(StructureInformation* info, MemberInformation* member, const DeclarationModifierComputations& modifier, const MemberWriteType writeType) const @@ -358,7 +379,50 @@ class ZoneWriteTemplate::Internal final : BaseTemplate } } - static bool WriteMember_ShouldMakeAlloc(StructureInformation* info, MemberInformation* member, const DeclarationModifierComputations& modifier, const MemberWriteType writeType) + static bool WriteMember_ShouldMakeInsertReuse(StructureInformation* info, MemberInformation* member, const DeclarationModifierComputations& modifier, const MemberWriteType writeType) + { + if (writeType != MemberWriteType::ARRAY_POINTER + && writeType != MemberWriteType::SINGLE_POINTER + && writeType != MemberWriteType::POINTER_ARRAY) + { + return false; + } + + if (writeType == MemberWriteType::POINTER_ARRAY + && modifier.IsArray()) + { + return false; + } + + return true; + } + + void WriteMember_InsertReuse(StructureInformation* info, MemberInformation* member, const DeclarationModifierComputations& modifier, const MemberWriteType writeType) + { + if (!WriteMember_ShouldMakeInsertReuse(info, member, modifier, writeType) + || !member->m_is_reusable) + { + WriteMember_TypeCheck(info, member, modifier, writeType); + return; + } + + if(writeType == MemberWriteType::ARRAY_POINTER) + { + LINE("m_stream->ReusableAddOffset("<ReusableAddOffset("<ReusableAddOffset("<Align("<m_is_reusable) { - WriteMember_Alloc(info, member, modifier, writeType); + WriteMember_Align(info, member, modifier, writeType); return; } @@ -439,7 +503,7 @@ class ZoneWriteTemplate::Internal final : BaseTemplate LINE("{") m_intendation++; - WriteMember_Alloc(info, member, modifier, writeType); + WriteMember_Align(info, member, modifier, writeType); m_intendation--; LINE("}") @@ -679,23 +743,31 @@ class ZoneWriteTemplate::Internal final : BaseTemplate if (!(info->m_definition->GetType() == DataDefinitionType::UNION && dynamicMember)) { LINE("") + + if(dynamicMember) + { + LINE("auto* originalData = "<m_definition)<<";") + } + LINE("if(atStreamStart)") m_intendation++; if (dynamicMember == nullptr) { - LINE(MakeTypeVarName(info->m_definition)<<"= m_stream->Write<" << info->m_definition->GetFullName() << ">(" << MakeTypeVarName(info->m_definition) << "); // Size: " << info-> + LINE(MakeTypeVarName(info->m_definition)<<" = m_stream->Write<" << info->m_definition->GetFullName() << ">(" << MakeTypeVarName(info->m_definition) << "); // Size: " << info-> m_definition->GetSize()) } else { - // TODO: Introduce "full" variable that enables writing of second part - LINE(MakeTypeVarName(info->m_definition) << "= m_stream->WritePartial<" << info->m_definition->GetFullName() << ">(" << MakeTypeVarName(info->m_definition) << ", offsetof(" << info-> + LINE(MakeTypeVarName(info->m_definition) << " = m_stream->WritePartial<" << info->m_definition->GetFullName() << ">(" << MakeTypeVarName(info->m_definition) << ", offsetof(" << info-> m_definition->GetFullName() << ", " << dynamicMember->m_member->m_name << "));") } m_intendation--; + + LINE("") + LINE("auto* writtenData = "<m_definition)<<";") } else { @@ -750,7 +822,7 @@ class ZoneWriteTemplate::Internal final : BaseTemplate m_intendation++; LINE("m_stream->Align(" << info->m_definition->GetAlignment() << ");") - + LINE("m_stream->ReusableAddOffset(*"<m_definition)<<");") LINE("") if (!info->m_is_leaf) { @@ -824,10 +896,15 @@ class ZoneWriteTemplate::Internal final : BaseTemplate LINE("}") } - void PrintWritePtrArrayMethod_Loading(const DataDefinition* def, StructureInformation* info) const + void PrintWritePtrArrayMethod_Loading(const DataDefinition* def, StructureInformation* info, const bool reusable) const { LINE("m_stream->Align("<GetAlignment()<<");") + if(reusable) + { + LINE("m_stream->ReusableAddOffset(*"<m_is_leaf) { LINE(MakeTypeVarName(info->m_definition) << " = *" << MakeTypePtrVarName(def) << ";") @@ -859,14 +936,14 @@ class ZoneWriteTemplate::Internal final : BaseTemplate LINE("{") m_intendation++; - PrintWritePtrArrayMethod_Loading(def, info); + PrintWritePtrArrayMethod_Loading(def, info, reusable); m_intendation--; LINE("}") } else { - PrintWritePtrArrayMethod_Loading(def, info); + PrintWritePtrArrayMethod_Loading(def, info, reusable); } } diff --git a/src/ZoneWriting/Zone/Stream/IZoneOutputStream.h b/src/ZoneWriting/Zone/Stream/IZoneOutputStream.h index e1244a4c..40768515 100644 --- a/src/ZoneWriting/Zone/Stream/IZoneOutputStream.h +++ b/src/ZoneWriting/Zone/Stream/IZoneOutputStream.h @@ -19,19 +19,26 @@ public: virtual void IncBlockPos(size_t size) = 0; virtual void WriteNullTerminated(const void* dst) = 0; - virtual bool ReusableShouldWrite(void** pPtr, size_t size, size_t count, std::type_index type) = 0; + virtual bool ReusableShouldWrite(void** pPtr, size_t size, std::type_index type) = 0; + virtual void ReusableAddOffset(void* ptr, size_t size, size_t count, std::type_index type) = 0; virtual void MarkFollowing(void** pPtr) = 0; template bool ReusableShouldWrite(T** pPtr) { - return ReusableShouldWrite(reinterpret_cast(reinterpret_cast(pPtr)), sizeof(T), 1, std::type_index(typeid(T))); + return ReusableShouldWrite(reinterpret_cast(reinterpret_cast(pPtr)), sizeof(T), std::type_index(typeid(T))); } template - bool ReusableShouldWrite(T** pPtr, const size_t count) + void ReusableAddOffset(T* ptr) { - return ReusableShouldWrite(reinterpret_cast(reinterpret_cast(pPtr)), sizeof(T), count, std::type_index(typeid(T))); + ReusableAddOffset(const_cast(reinterpret_cast(ptr)), sizeof(T), 1, std::type_index(typeid(T))); + } + + template + void ReusableAddOffset(T* ptr, const size_t count) + { + ReusableAddOffset(const_cast(reinterpret_cast(ptr)), sizeof(T), count, std::type_index(typeid(T))); } template diff --git a/src/ZoneWriting/Zone/Stream/Impl/InMemoryZoneOutputStream.cpp b/src/ZoneWriting/Zone/Stream/Impl/InMemoryZoneOutputStream.cpp index 633c3cf0..df4411ed 100644 --- a/src/ZoneWriting/Zone/Stream/Impl/InMemoryZoneOutputStream.cpp +++ b/src/ZoneWriting/Zone/Stream/Impl/InMemoryZoneOutputStream.cpp @@ -170,7 +170,7 @@ void InMemoryZoneOutputStream::MarkFollowing(void** pPtr) *pPtr = m_block_stack.top()->m_type == XBlock::Type::BLOCK_TYPE_TEMP ? PTR_INSERT : PTR_FOLLOWING; } -bool InMemoryZoneOutputStream::ReusableShouldWrite(void** pPtr, const size_t entrySize, const size_t entryCount, std::type_index type) +bool InMemoryZoneOutputStream::ReusableShouldWrite(void** pPtr, const size_t entrySize, const std::type_index type) { assert(!m_block_stack.empty()); assert(pPtr != nullptr); @@ -178,15 +178,9 @@ bool InMemoryZoneOutputStream::ReusableShouldWrite(void** pPtr, const size_t ent if (*pPtr == nullptr) return false; - const auto inTemp = m_block_stack.top()->m_type == XBlock::Type::BLOCK_TYPE_TEMP; const auto foundEntriesForType = m_reusable_entries.find(type); if (foundEntriesForType == m_reusable_entries.end()) { - std::vector entries; - auto zoneOffset = inTemp ? InsertPointer() : GetCurrentZonePointer(); - entries.emplace_back(*pPtr, entrySize, entryCount, zoneOffset); - m_reusable_entries.emplace(std::make_pair(type, std::move(entries))); - return true; } @@ -199,9 +193,25 @@ bool InMemoryZoneOutputStream::ReusableShouldWrite(void** pPtr, const size_t ent return false; } } - - auto zoneOffset = inTemp ? InsertPointer() : GetCurrentZonePointer(); - foundEntriesForType->second.emplace_back(*pPtr, entrySize, entryCount, zoneOffset); return true; } + +void InMemoryZoneOutputStream::ReusableAddOffset(void* ptr, size_t size, size_t count, std::type_index type) +{ + assert(!m_block_stack.empty()); + + const auto inTemp = m_block_stack.top()->m_type == XBlock::Type::BLOCK_TYPE_TEMP; + auto zoneOffset = inTemp ? InsertPointer() : GetCurrentZonePointer(); + const auto foundEntriesForType = m_reusable_entries.find(type); + if (foundEntriesForType == m_reusable_entries.end()) + { + std::vector entries; + entries.emplace_back(ptr, size, count, zoneOffset); + m_reusable_entries.emplace(std::make_pair(type, std::move(entries))); + } + else + { + foundEntriesForType->second.emplace_back(ptr, size, count, zoneOffset); + } +} diff --git a/src/ZoneWriting/Zone/Stream/Impl/InMemoryZoneOutputStream.h b/src/ZoneWriting/Zone/Stream/Impl/InMemoryZoneOutputStream.h index 183ea4bb..f255591c 100644 --- a/src/ZoneWriting/Zone/Stream/Impl/InMemoryZoneOutputStream.h +++ b/src/ZoneWriting/Zone/Stream/Impl/InMemoryZoneOutputStream.h @@ -46,5 +46,6 @@ public: void IncBlockPos(size_t size) override; void WriteNullTerminated(const void* src) override; void MarkFollowing(void** pPtr) override; - bool ReusableShouldWrite(void** pPtr, size_t entrySize, size_t entryCount, std::type_index type) override; + bool ReusableShouldWrite(void** pPtr, size_t entrySize, std::type_index type) override; + void ReusableAddOffset(void* ptr, size_t size, size_t count, std::type_index type) override; };