diff --git a/src/ZoneCodeGeneratorLib/Generating/Templates/ZoneWriteTemplate.cpp b/src/ZoneCodeGeneratorLib/Generating/Templates/ZoneWriteTemplate.cpp index a8d21d53..8969ecc1 100644 --- a/src/ZoneCodeGeneratorLib/Generating/Templates/ZoneWriteTemplate.cpp +++ b/src/ZoneCodeGeneratorLib/Generating/Templates/ZoneWriteTemplate.cpp @@ -731,31 +731,37 @@ namespace return; } + LINE_STARTF("m_stream->ReusableAddOffset({0}", MakeMemberAccess(info, member, modifier)) + if (writeType == MemberWriteType::ARRAY_POINTER) { - LINEF("m_stream->ReusableAddOffset({0}, {1});", - MakeMemberAccess(info, member, modifier), - MakeEvaluation(modifier.GetArrayPointerCountEvaluation())) + if (member->m_type && !member->m_type->m_has_matching_cross_platform_structure) + { + LINE_MIDDLEF(", {0}", member->m_type->m_definition->GetSize()) + } + + LINE_MIDDLEF(", {0}", MakeEvaluation(modifier.GetArrayPointerCountEvaluation())) } else if (writeType == MemberWriteType::POINTER_ARRAY) { + if (member->m_type && !member->m_type->m_has_matching_cross_platform_structure) + { + LINE_MIDDLEF(", {0}", m_env.m_pointer_size) + } + const auto* evaluation = modifier.GetPointerArrayCountEvaluation(); if (evaluation) { - LINEF("m_stream->ReusableAddOffset({0}, {1});", - MakeMemberAccess(info, member, modifier), - MakeEvaluation(modifier.GetPointerArrayCountEvaluation())) + LINE_MIDDLEF(", {0}", MakeEvaluation(modifier.GetPointerArrayCountEvaluation())) } else { - LINEF("m_stream->ReusableAddOffset({0}, {1});", MakeMemberAccess(info, member, modifier), modifier.GetArraySize()) + LINE_MIDDLEF(", {0}", modifier.GetArraySize()) } } - else - { - LINEF("m_stream->ReusableAddOffset({0});", MakeMemberAccess(info, member, modifier)) - } + + LINE_END(");") WriteMember_TypeCheck(info, member, modifier, writeType); } diff --git a/src/ZoneWriting/Zone/Stream/ZoneOutputStream.cpp b/src/ZoneWriting/Zone/Stream/ZoneOutputStream.cpp index e7dd69d7..2075773a 100644 --- a/src/ZoneWriting/Zone/Stream/ZoneOutputStream.cpp +++ b/src/ZoneWriting/Zone/Stream/ZoneOutputStream.cpp @@ -17,12 +17,13 @@ namespace class ReusableEntry { public: - ReusableEntry(void* startPtr, const size_t entrySize, const size_t entryCount, const uintptr_t startZonePtr) + ReusableEntry(void* startPtr, const size_t entrySize, const size_t entryCount, const size_t blockSize, const uintptr_t startZonePtr) : m_start_ptr(startPtr), m_end_ptr(reinterpret_cast(reinterpret_cast(startPtr) + entrySize * entryCount)), m_start_zone_ptr(startZonePtr), m_entry_size(entrySize), - m_entry_count(entryCount) + m_entry_count(entryCount), + m_block_size(blockSize) { } @@ -31,6 +32,7 @@ namespace uintptr_t m_start_zone_ptr; size_t m_entry_size; size_t m_entry_count; + size_t m_block_size; }; class InMemoryZoneOutputStream final : public ZoneOutputStream @@ -245,7 +247,9 @@ namespace if (ptr >= entry.m_start_ptr && ptr < entry.m_end_ptr) { assert((reinterpret_cast(ptr) - reinterpret_cast(entry.m_start_ptr)) % entrySize == 0); - const auto finalZonePointer = entry.m_start_zone_ptr + (reinterpret_cast(ptr) - reinterpret_cast(entry.m_start_ptr)); + + const auto entryIndex = (reinterpret_cast(ptr) - reinterpret_cast(entry.m_start_ptr)) / entry.m_entry_size; + const auto finalZonePointer = entry.m_start_zone_ptr + entryIndex * entry.m_block_size; auto* writtenPtrOffset = outputOffset.Offset(); for (auto i = 0u; i < m_pointer_byte_count; i++) @@ -258,7 +262,7 @@ namespace return true; } - void ReusableAddOffset(void* ptr, size_t size, size_t count, std::type_index type) override + void ReusableAddOffset(void* ptr, const size_t size, const size_t count, const size_t blockSize, std::type_index type) override { assert(!m_block_stack.empty()); @@ -268,12 +272,12 @@ namespace if (foundEntriesForType == m_reusable_entries.end()) { std::vector entries; - entries.emplace_back(ptr, size, count, zoneOffset); + entries.emplace_back(ptr, size, count, blockSize, zoneOffset); m_reusable_entries.emplace(std::make_pair(type, std::move(entries))); } else { - foundEntriesForType->second.emplace_back(ptr, size, count, zoneOffset); + foundEntriesForType->second.emplace_back(ptr, size, count, blockSize, zoneOffset); } } diff --git a/src/ZoneWriting/Zone/Stream/ZoneOutputStream.h b/src/ZoneWriting/Zone/Stream/ZoneOutputStream.h index 8dba427b..0a32486e 100644 --- a/src/ZoneWriting/Zone/Stream/ZoneOutputStream.h +++ b/src/ZoneWriting/Zone/Stream/ZoneOutputStream.h @@ -93,7 +93,7 @@ public: virtual ZoneStreamFillWriteAccessor WriteWithFill(size_t size) = 0; virtual bool ReusableShouldWrite(void* pPtr, ZoneOutputOffset outputOffset, 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 ReusableAddOffset(void* ptr, size_t size, size_t count, size_t blockSize, std::type_index type) = 0; virtual void MarkFollowing(ZoneOutputOffset offset) = 0; template bool ReusableShouldWrite(T* pPtr, const ZoneOutputOffset outputOffset) @@ -103,12 +103,17 @@ public: template void ReusableAddOffset(T* ptr) { - ReusableAddOffset(const_cast(reinterpret_cast(ptr)), sizeof(T), 1, std::type_index(typeid(T))); + ReusableAddOffset(const_cast(reinterpret_cast(ptr)), sizeof(T), 1, sizeof(T), 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))); + ReusableAddOffset(const_cast(reinterpret_cast(ptr)), sizeof(T), count, sizeof(T), std::type_index(typeid(T))); + } + + template void ReusableAddOffset(T* ptr, const size_t blockSize, const size_t count) + { + ReusableAddOffset(const_cast(reinterpret_cast(ptr)), sizeof(T), count, blockSize, std::type_index(typeid(T))); } template ZoneOutputOffset Write(T* dst)