UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
MemoryImage.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "Containers/Array.h"
7#include "Containers/HashTable.h"
8#include "Containers/Map.h"
9#include "Containers/Set.h"
11#include "CoreTypes.h"
12#include "HAL/MemoryBase.h"
13#include "HAL/PlatformCrt.h"
14#include "HAL/PlatformString.h"
16#include "HAL/UnrealMemory.h"
19#include "Misc/CString.h"
20#include "Misc/Crc.h"
21#include "Misc/SecureHash.h"
26#include "Templates/EnableIf.h"
28#include "Templates/TypeHash.h"
29#include "Traits/IsCharType.h"
30#include "UObject/NameTypes.h"
31
32class FCbFieldView;
33class FCbWriter;
34template <typename T> struct TIsContiguousContainer;
35
36#if defined(WITH_RTTI) || defined(_CPPRTTI) || defined(__GXX_RTTI) || WITH_EDITOR
37#include <typeinfo>
38#endif
39
40class FMemoryImage;
42
43// Store type dependencies for loaded frozen memory images
44// This uses a bit of memory and adds small CPU cost to loading, but is required to support unfreezing memory images that target platforms other than the current
45// This is also required for creating frozen memory images
46#define UE_MEMORYIMAGE_TRACK_TYPE_DEPENDENCIES (WITH_EDITORONLY_DATA)
47
49{
50public:
51 virtual ~FPointerTableBase() {}
52 virtual int32 AddIndexedPointer(const FTypeLayoutDesc& TypeDesc, void* Ptr) = 0;
53 virtual void* GetIndexedPointer(const FTypeLayoutDesc& TypeDesc, uint32 i) const = 0;
54
55 CORE_API virtual void SaveToArchive(FArchive& Ar, const FPlatformTypeLayoutParameters& LayoutParams, const void* FrozenObject) const;
56 CORE_API virtual bool LoadFromArchive(FArchive& Ar, const FPlatformTypeLayoutParameters& LayoutParams, void* FrozenObject);
57
58#if UE_MEMORYIMAGE_TRACK_TYPE_DEPENDENCIES
60 inline const FTypeLayoutDesc* GetTypeDependency(int32 Index) const { return TypeDependencies[Index]; }
61private:
63#else
65 inline const FTypeLayoutDesc* GetTypeDependency(int32 Index) const { return nullptr; }
66#endif
67};
68
69template<typename T>
71{
72 TMemoryImageObject() : TypeDesc(nullptr), Object(nullptr), FrozenSize(0u) {}
73
79
80 template<typename TOther>
82 : TypeDesc(InObject ? &GetTypeLayoutDesc(nullptr, *InObject) : nullptr)
83 , Object(InObject)
84 , FrozenSize(0u)
85 {}
86
87 template<typename TOther>
89 : TypeDesc(Rhs.TypeDesc)
90 , Object(static_cast<T*>(Rhs.Object))
92 {}
93
94 void Destroy(const FPointerTableBase* PointerTable);
95
96 // Returns true if the frozen/unfrozen state of the object was changed
97 bool Freeze(FPointerTableBase* PointerTable);
98 bool Unfreeze(const FPointerTableBase* PointerTable);
99
103};
105
107CORE_API void* UnfreezeMemoryImageObject(const void* FrozenObject, const FTypeLayoutDesc& TypeDesc, const FPointerTableBase* PointerTable);
108
109template<typename T>
110inline void TMemoryImageObject<T>::Destroy(const FPointerTableBase* PointerTable)
111{
112 if (Object)
113 {
114 InternalDeleteObjectFromLayout(Object, *TypeDesc, PointerTable, FrozenSize > 0u);
115 if (FrozenSize > 0u)
116 {
117 // InternalDeleteObjectFromLayout will delete unfrozen objects,
118 // but won't free frozen objects, since that's not safe for internal object pointers
119 // Here we are working with a root-level object, so it's safe to free it
121 }
122 Object = nullptr;
123 FrozenSize = 0u;
124 }
125}
126
127
128template<typename T>
130{
131 if (FrozenSize == 0u && Object)
132 {
133 const FMemoryImageObject FrozenContent = FreezeMemoryImageObject(Object, *TypeDesc, PointerTable);
134 Destroy(nullptr);
135 Object = static_cast<T*>(FrozenContent.Object);
136 FrozenSize = FrozenContent.FrozenSize;
137 return true;
138 }
139 return false;
140}
141
142template<typename T>
144{
145 if (FrozenSize > 0u)
146 {
147 void* UnfrozenObject = UnfreezeMemoryImageObject(Object, *TypeDesc, PointerTable);
148 Destroy(PointerTable);
149 Object = static_cast<T*>(UnfrozenObject);
150 FrozenSize = 0u;
151 return true;
152 }
153 return false;
154}
155
157{
161
162 inline bool operator==(const FMemoryImageVTablePointer& Rhs) const
163 {
164 return TypeNameHash == Rhs.TypeNameHash && VTableOffset == Rhs.VTableOffset && Offset == Rhs.Offset;
165 }
166 inline bool operator!=(const FMemoryImageVTablePointer& Rhs) const
167 {
168 return !(*this == Rhs);
169 }
170 inline bool operator<(const FMemoryImageVTablePointer& Rhs) const
171 {
172 if (TypeNameHash != Rhs.TypeNameHash) return TypeNameHash < Rhs.TypeNameHash;
173 if (VTableOffset != Rhs.VTableOffset) return VTableOffset < Rhs.VTableOffset;
174 return Offset < Rhs.Offset;
175 }
176};
177
179{
182
183 inline bool operator==(const FMemoryImageNamePointer& Rhs) const
184 {
185 return Offset == Rhs.Offset && Name.Compare(Rhs.Name) == 0;
186 }
187 inline bool operator!=(const FMemoryImageNamePointer& Rhs) const
188 {
189 return !(*this == Rhs);
190 }
191 inline bool operator<(const FMemoryImageNamePointer& Rhs) const
192 {
193 if (Name != Rhs.Name)
194 {
195 return Name.LexicalLess(Rhs.Name);
196 }
197 return Offset < Rhs.Offset;
198 }
199};
200
214
216{
217public:
224
229
230 uint32 GetOffset() const { return Bytes.Num(); }
231
233 {
234 const uint32 PrevSize = Bytes.Num();
235 const uint32 Offset = Align(PrevSize, Alignment);
237 MaxAlignment = FMath::Max(MaxAlignment, Alignment);
238 return Offset;
239 }
240
246
247 uint32 WriteBytes(const void* Data, uint32 Size)
248 {
249 const uint32 Offset = GetOffset();
252 return Offset;
253 }
254
256 {
257 const uint32 Offset = GetOffset();
259 return Offset;
260 }
261
262 template<typename T>
263 uint32 WriteBytes(const T& Data) { return WriteBytes(&Data, sizeof(T)); }
264
271
272 CORE_API void ComputeHash();
273
282};
283
285{
286public:
288 : PointerTable(nullptr)
289 , PrevPointerTable(nullptr)
290 , CurrentStruct(nullptr)
291 {
293 }
294
297
299 {
300 FMemoryImageSection* Section = new FMemoryImageSection(this);
301 // reserving memory here could reduce the reallocations, but leads to huge spikes for images with many sections. TODO: try chunked array or a better heuristic value for reservation
302 Sections.Add(Section);
303 return Section;
304 }
305
310
316 const class UStruct* CurrentStruct;
317};
318
324{
325 static constexpr uint64 bIsFrozenBits = 1;
326 static constexpr uint64 OffsetBits = 40;
327 static constexpr uint64 TypeIndexBits = 64 - OffsetBits - bIsFrozenBits;
328
329 static constexpr uint64 bIsFrozenShift = 0;
332
333 static constexpr uint64 bIsFrozenMask = (1ULL << bIsFrozenShift);
334 static constexpr uint64 TypeIndexMask = (((1ULL << TypeIndexBits) - 1ULL) << TypeIndexShift);
335 static constexpr uint64 OffsetMask = (((1ULL << OffsetBits) - 1ULL) << OffsetShift);
336
338
340 bool IsFrozen() const
341 {
342 return (Packed & bIsFrozenMask) != 0;
343 }
344
346 {
347 Packed = (Packed & ~bIsFrozenMask) | (bTrue ? 1 : 0);
348 }
349
352 {
353 // Since the offset occupies the highest part of the int64, its sign is preserved.
354 // Not masking as there's nothing to the left of the Offset
355 static_assert(OffsetShift + OffsetBits == 64);
356 return static_cast<int64>(Packed/* & OffsetMask*/) >> OffsetShift;
357 }
358
360 {
361 Packed = (Packed & ~OffsetMask) | (static_cast<uint64>(Offset << OffsetShift) & OffsetMask);
362 }
363
366 {
367 return static_cast<int32>((Packed & TypeIndexMask) >> TypeIndexShift) - 1;
368 }
369
370 void SetTypeIndex(int32 TypeIndex)
371 {
372 static_assert(INDEX_NONE == -1, "TypeIndex cannot store INDEX_NONE when it's not -1");
373 // PVS warns about a possible overflow in TypeIndex + 1. We don't care as we don't expect 2^31 type indices anyway
374 Packed = (Packed & ~TypeIndexMask) | ((static_cast<uint64>(TypeIndex + 1) << TypeIndexShift) & TypeIndexMask); //-V1028
375 }
376};
377
378static_assert(sizeof(FFrozenMemoryImagePtr) == sizeof(uint64), "FFrozenMemoryImagePtr is larger than a native pointer would be");
379
380template<typename T>
382{
383public:
384 inline bool IsFrozen() const { return Frozen.IsFrozen(); }
385 inline bool IsValid() const { return UnfrozenPtr != nullptr; }
386 inline bool IsNull() const { return UnfrozenPtr == nullptr; }
387
388 inline TMemoryImagePtr() : UnfrozenPtr(nullptr) {}
391 inline TMemoryImagePtr& operator=(T* InPtr) { UnfrozenPtr = InPtr; check(!Frozen.IsFrozen()); return *this; }
393
395 {
396
397 }
398
400 inline int32 GetFrozenTypeIndex() const { check(IsFrozen()); return Frozen.GetTypeIndex(); }
401
402 inline T* Get() const
403 {
404 return IsFrozen() ? GetFrozenPtrInternal() : UnfrozenPtr;
405 }
406
407 inline T* GetChecked() const { T* Value = Get(); check(Value); return Value; }
408 inline T* operator->() const { return GetChecked(); }
409 inline T& operator*() const { return *GetChecked(); }
410 inline operator T*() const { return Get(); }
411
412 void SafeDelete(const FPointerTableBase* PtrTable = nullptr)
413 {
414 T* RawPtr = Get();
415 if (RawPtr)
416 {
418 UnfrozenPtr = nullptr;
419 }
420 }
421
423 {
424 const T* RawPtr = Get();
425 if (RawPtr)
426 {
428 uint32 OffsetToBase = 0u;
431 }
432 else
433 {
434 Writer.WriteNullPointer();
435 }
436 }
437
438private:
439 inline T* GetFrozenPtrInternal() const
440 {
441 return (T*)((char*)this + Frozen.GetOffsetFromThis());
442 }
443
444protected:
445 union
446 {
450 };
451};
452
453namespace Freeze
454{
455 template<typename T>
457 {
458 T* RawPtr = Object.Get();
459 if (RawPtr)
460 {
462
463 uint32 OffsetToBase = 0u;
466 }
467 else
468 {
469 Writer.WriteNullPointer();
470 }
471 }
472
473 template<typename T>
475 {
476 const T* RawPtr = Object.Get();
477 if (RawPtr)
478 {
479 // Compile-time type of the thing we're pointing to
481
482 // Actual run-time type of the thing we're pointing to
483 const FTypeLayoutDesc* DerivedTypeDesc = Context.GetDerivedTypeDesc(StaticTypeDesc, Object.GetFrozenTypeIndex());
484 if (!DerivedTypeDesc && Context.bIsFrozenForCurrentPlatform)
485 {
486 // It's possible we won't be able to get derived type desc from the context, if we're not storing type dependencies
487 // In this case, if we're unfreezing data for the current platform, we can just grab the derived type directly from the frozen object
488 // If we're NOT unfreezing data for current platform, we can't access the frozen object, so we'll fail in that case
489 DerivedTypeDesc = &GetTypeLayoutDesc(Context.PrevPointerTable, *RawPtr);
490 }
491 if (DerivedTypeDesc)
492 {
493 // 'this' offset to adjust from the compile-time type to the run-time type
494 const uint32 OffsetToBase = DerivedTypeDesc->GetOffsetToBase(StaticTypeDesc);
495
496 void* UnfrozenMemory = ::operator new(DerivedTypeDesc->Size);
497 Context.UnfreezeObject((uint8*)RawPtr - OffsetToBase, *DerivedTypeDesc, UnfrozenMemory);
500 }
501 else
502 {
503 new(OutDst) TMemoryImagePtr<T>(nullptr);
504 }
505 }
506 else
507 {
508 new(OutDst) TMemoryImagePtr<T>(nullptr);
509 }
510 return sizeof(Object);
511 }
512
513 template<typename T>
515 {
516 return AppendHashForNameAndSize(TypeDesc.Name, sizeof(TMemoryImagePtr<T>), Hasher);
517 }
518
519 template<typename T>
521 {
522 return FMath::Min(8u, LayoutParams.MaxFieldAlignment);
523 }
524
525 template<typename T>
527 {
528 T* RawPtr = Object.Get();
529 if (RawPtr)
530 {
531 // Compile-time type of the thing we're pointing to
533 // Actual run-time type of the thing we're pointing to
534 const FTypeLayoutDesc& DerivedTypeDesc = GetTypeLayoutDesc(OutContext.TryGetPrevPointerTable(), *RawPtr);
535 // 'this' offset to adjust from the compile-time type to the run-time type
536 const uint32 OffsetToBase = DerivedTypeDesc.GetOffsetToBase(StaticTypeDesc);
537
538 if (Object.IsFrozen())
539 {
540 OutContext.AppendFrozenPointer(StaticTypeDesc, Object.GetFrozenTypeIndex());
541 }
542 else
543 {
544 OutContext.AppendUnfrozenPointer(StaticTypeDesc);
545 }
546 DerivedTypeDesc.ToStringFunc((uint8*)RawPtr - OffsetToBase, DerivedTypeDesc, LayoutParams, OutContext);
547 }
548 else
549 {
550 OutContext.AppendNullptr();
551 }
552 }
553}
554
556
557template<typename T>
559{
560public:
562 : TMemoryImagePtr<T>(nullptr)
563 {}
564 explicit inline TUniqueMemoryImagePtr(T* InPtr)
566 { }
567
569 {
570 this->SafeDelete();
571 this->Ptr = Other.Ptr;
572 Other.Ptr = nullptr;
573 }
575 {
576 this->SafeDelete();
577 }
579 {
580 this->SafeDelete();
581 this->Ptr = InPtr;
582 return *this;
583 }
585 {
586 if (this != &Other)
587 {
588 // We _should_ delete last like TUniquePtr, but we have issues with SafeDelete, and being Frozen or not
589 this->SafeDelete();
590 this->Ptr = Other.Ptr;
591 Other.Ptr = nullptr;
592 }
593
594 return *this;
595 }
596
597};
598
600{
602public:
604
611
614
615 // FContainerAllocatorInterface
617 {
618 return Data.Get();
619 }
620
621 UE_FORCEINLINE_HINT SIZE_T GetAllocatedSize(int32 CurrentMax, SIZE_T NumBytesPerElement) const
622 {
623 return CurrentMax * NumBytesPerElement;
624 }
626 {
627 return Data.IsValid();
628 }
630
631 CORE_API void ResizeAllocation(int32 PreviousNumElements, int32 NumElements, SIZE_T NumBytesPerElement, uint32 Alignment);
632 CORE_API void WriteMemoryImage(FMemoryImageWriter& Writer, const FTypeLayoutDesc& TypeDesc, int32 NumAllocatedElements, uint32 Alignment) const;
633 CORE_API void ToString(const FTypeLayoutDesc& TypeDesc, int32 NumAllocatedElements, int32 MaxAllocatedElements, const FPlatformTypeLayoutParameters& LayoutParams, FMemoryToStringContext& OutContext) const;
634 CORE_API void CopyUnfrozen(const FMemoryUnfreezeContent& Context, const FTypeLayoutDesc& TypeDesc, int32 NumAllocatedElements, void* Dst) const;
635
636private:
638};
639
640template<uint32 Alignment = DEFAULT_ALIGNMENT>
642{
643public:
645
646 enum { NeedsElementType = false };
647 enum { RequireRangeCheck = true };
649
651 {
652 public:
654 ForAnyElementType() = default;
655
657 {
658 return 0;
659 }
661 {
662 return DefaultCalculateSlackReserve(NewMax, NumBytesPerElement, true, Alignment);
663 }
668 UE_FORCEINLINE_HINT int32 CalculateSlackShrink(int32 NewMax, int32 CurrentMax, int32 NumBytesPerElement) const
669 {
670 return DefaultCalculateSlackShrink(NewMax, CurrentMax, NumBytesPerElement, true, Alignment);
671 }
673 {
674 return DefaultCalculateSlackShrink(NewMax, CurrentMax, NumBytesPerElement, true, AlignmentOfElement);
675 }
676 UE_FORCEINLINE_HINT int32 CalculateSlackGrow(int32 NewMax, int32 CurrentMax, int32 NumBytesPerElement) const
677 {
678 return DefaultCalculateSlackGrow(NewMax, CurrentMax, NumBytesPerElement, true, Alignment);
679 }
681 {
682 return DefaultCalculateSlackGrow(NewMax, CurrentMax, NumBytesPerElement, true, AlignmentOfElement);
683 }
684 UE_FORCEINLINE_HINT void ResizeAllocation(int32 CurrentNum, int32 NewMax, SIZE_T NumBytesPerElement)
685 {
686 FMemoryImageAllocatorBase::ResizeAllocation(CurrentNum, NewMax, NumBytesPerElement, Alignment);
687 }
689 {
691 }
692
693 UE_FORCEINLINE_HINT void WriteMemoryImage(FMemoryImageWriter& Writer, const FTypeLayoutDesc& TypeDesc, int32 NumAllocatedElements) const
694 {
695 FMemoryImageAllocatorBase::WriteMemoryImage(Writer, TypeDesc, NumAllocatedElements, Alignment);
696 }
697 };
698
699 template<typename ElementType>
701 {
702 public:
704 UE_FORCEINLINE_HINT ElementType* GetAllocation() const { return (ElementType*)ForAnyElementType::GetAllocation(); }
705 };
706};
707
708//@todo stever
709/*static_assert(
710 sizeof(TMemoryImageAllocator<>::ForAnyElementType) == sizeof(FDefaultAllocator::ForAnyElementType) && alignof(TMemoryImageAllocator<>::ForAnyElementType) == alignof(FDefaultAllocator::ForAnyElementType),
711 "TMemoryImageAllocator must be the same layout as FDefaultAllocator for our FScriptArray hacks to work"
712);*/
713
714template <uint32 Alignment>
715struct TAllocatorTraits<TMemoryImageAllocator<Alignment>> : TAllocatorTraitsBase<TMemoryImageAllocator<Alignment>>
716{
717 enum { IsZeroConstruct = true };
720};
721
723
726
727template<typename T>
729
730template<typename ElementType, typename KeyFuncs = DefaultKeyFuncs<ElementType>>
732
733template <typename KeyType, typename ValueType, typename KeyFuncs = TDefaultMapHashableKeyFuncs<KeyType, ValueType, false>>
735
736template <>
738{
739 static constexpr bool Value = true;
740};
741
743{
745private:
748 LAYOUT_FIELD(DataType, Data);
749
750 CORE_API void ToString(FMemoryToStringContext& OutContext) const;
751 LAYOUT_TOSTRING(ToString);
752public:
754
760
761 UE_FORCEINLINE_HINT FMemoryImageString(const FString& Other) : Data(Other.GetCharArray()) {}
762
763 template <
764 typename CharType,
765 typename = typename TEnableIf<TIsCharType<CharType>::Value>::Type // This TEnableIf is to ensure we don't instantiate this constructor for non-char types, like id* in Obj-C
766 >
767 inline FMemoryImageString(const CharType* Src)
768 {
769 if (Src && *Src)
770 {
771 int32 SrcLen = TCString<CharType>::Strlen(Src) + 1;
772 int32 DestLen = FPlatformString::ConvertedLength<TCHAR>(Src, SrcLen);
773 Data.AddUninitialized(DestLen);
774 FPlatformString::Convert(Data.GetData(), DestLen, Src, SrcLen);
775 }
776 }
777
778 UE_FORCEINLINE_HINT operator FString() const
779 {
780 return FString::ConstructFromPtrSize(Data.GetData(), Len());
781 }
782
784 {
785 return Data.Num() ? Data.GetData() : TEXT("");
786 }
787
788 UE_FORCEINLINE_HINT bool IsEmpty() const { return Data.Num() <= 1; }
789 UE_FORCEINLINE_HINT SIZE_T GetAllocatedSize() const { return Data.GetAllocatedSize(); }
790
792 {
793 return Data.Num() ? Data.Num() - 1 : 0;
794 }
795
796 friend inline const TCHAR* GetData(const FMemoryImageString& String)
797 {
798 return *String;
799 }
800
801 friend inline int32 GetNum(const FMemoryImageString& String)
802 {
803 return String.Len();
804 }
805
807 {
808 Ar << Ref.Data;
809 return Ar;
810 }
811
812 inline bool operator==(const FMemoryImageString& Rhs) const
813 {
814 return FCString::Stricmp(**this, *Rhs) == 0;
815 }
816
817 inline bool operator!=(const FMemoryImageString& Rhs) const
818 {
819 return FCString::Stricmp(**this, *Rhs) != 0;
820 }
821
822 inline bool operator==(const FString& Rhs) const
823 {
824 return FCString::Stricmp(**this, *Rhs) == 0;
825 }
826
827 inline bool operator!=(const FString& Rhs) const
828 {
829 return FCString::Stricmp(**this, *Rhs) != 0;
830 }
831
832 inline DataType::ElementAllocatorType& GetAllocatorInstance() { return Data.GetAllocatorInstance(); }
833
839};
840
841#if WITH_EDITORONLY_DATA
843{
845};
846
847namespace Freeze
848{
851}
852
854
855#endif // WITH_EDITORONLY_DATA
856
858{
860public:
861 inline FHashedName() : Hash(0u) {}
863 CORE_API FHashedName(const FHashedName& InName);
866 CORE_API FHashedName(const FString& InString);
867 CORE_API FHashedName(const FName& InName);
868
869 inline uint64 GetHash() const { return Hash; }
870 inline bool IsNone() const { return Hash == 0u; }
871
872#if WITH_EDITORONLY_DATA
873 const FHashedNameDebugString& GetDebugString() const { return DebugString; }
874#endif
875
876 inline bool operator==(const FHashedName& Rhs) const { return Hash == Rhs.Hash; }
877 inline bool operator!=(const FHashedName& Rhs) const { return Hash != Rhs.Hash; }
878
880 inline bool operator<(const FHashedName& Rhs) const { return Hash < Rhs.Hash; }
881
883 {
884 Ar << String.Hash;
885 return Ar;
886 }
887
888 friend inline uint32 GetTypeHash(const FHashedName& Name)
889 {
890 return GetTypeHash(Name.Hash);
891 }
892
893 /*inline FString ToString() const
894 {
895 return FString::Printf(TEXT("0x%016X"), Hash);
896 }*/
897
898private:
901
902#if WITH_EDITOR
903 // Compact binary API with hidden friend operator<<
904 CORE_API void Save(FCbWriter& Writer) const;
905 bool TryLoad(FCbFieldView Field);
906 friend inline FCbWriter& operator<<(FCbWriter& Writer, const FHashedName& Value)
907 {
908 Value.Save(Writer);
909 return Writer;
910 }
912#endif
913};
914
915namespace Freeze
916{
918}
919
920
922{
923public:
924 template<typename PtrType>
925 static void LoadAndApplyPatchesFromArchive(FArchive& Ar, void* FrozenBase, const PtrType& Ptr)
926 {
927 int32 NumOffsets = 0;
928 Ar << NumOffsets;
929 for (int32 OffsetIndex = 0; OffsetIndex < NumOffsets; ++OffsetIndex)
930 {
931 uint32 Offset = 0u;
932 Ar << Offset;
933 new((char*)FrozenBase + Offset) PtrType(Ptr);
934 }
935 }
936
938
939protected:
945
952
954
957};
958
959template<typename T, typename PtrType>
961{
962public:
964
965 void Empty(int32 NewSize = 0)
966 {
967 Pointers.Reset(NewSize);
968 }
969
970 uint32 Num() const { return Pointers.Num(); }
971 uint32 AddIndexedPointer(T* Ptr) { check(Ptr); return Pointers.AddUnique(Ptr); }
972
973 bool TryAddIndexedPtr(const FTypeLayoutDesc& TypeDesc, void* Ptr, int32& OutIndex)
974 {
975 if (TypeDesc == StaticGetPtrTypeLayoutDesc())
976 {
977 OutIndex = AddIndexedPointer(static_cast<T*>(Ptr));
978 return true;
979 }
980 return false;
981 }
982
984 {
985 if (Ptr)
986 {
987 checkSlow(!Pointers.Contains(Ptr));
988 Pointers.Add(Ptr);
989 }
990 else
991 {
992 // allow duplicate nullptrs
993 // pointers that were valid when saving may not be found when loading, need to preserve indices
994 Pointers.Add(nullptr);
995 }
996 }
997
1003
1004 T* GetIndexedPointer(uint32 i) const { return Pointers[i]; }
1005
1006 bool TryGetIndexedPtr(const FTypeLayoutDesc& TypeDesc, uint32 i, void*& OutPtr) const
1007 {
1008 if (TypeDesc == StaticGetPtrTypeLayoutDesc())
1009 {
1011 return true;
1012 }
1013 return false;
1014 }
1015
1017 {
1018 for (int32 PtrIndex = 0; PtrIndex < PatchLists.Num(); ++PtrIndex)
1019 {
1020 uint32 PatchIndex = PatchLists[PtrIndex].FirstIndex;
1021 while (PatchIndex != ~0u)
1022 {
1024 new((char*)FrozenBase + Patch.Offset) PtrType(Pointers[PtrIndex]);
1025 PatchIndex = Patch.NextIndex;
1026 }
1027 }
1028 }
1029
1030 inline typename TArray<PtrType>::RangedForIteratorType begin() { return Pointers.begin(); }
1031 inline typename TArray<PtrType>::RangedForIteratorType end() { return Pointers.end(); }
1032 inline typename TArray<PtrType>::RangedForConstIteratorType begin() const { return Pointers.begin(); }
1033 inline typename TArray<PtrType>::RangedForConstIteratorType end() const { return Pointers.end(); }
1034private:
1035 TArray<PtrType> Pointers;
1036};
1037
1038template<typename T>
1039class TPtrTable : public TPtrTableBase<T, T*> {};
1040
1041template<typename T>
1042class TRefCountPtrTable : public TPtrTableBase<T, TRefCountPtr<T>>
1043{
1045};
1046
1047class FVoidPtrTable : public TPtrTableBase<void, void*> {};
1048
1049#ifdef _MSC_VER
1050#pragma warning(push)
1051#pragma warning(disable : 4583) // destructor is not implicitly called
1052#endif
1053
1060template<typename T, typename PtrType>
1062{
1063public:
1065
1066 inline TIndexedPtrBase(T* InPtr = nullptr) : Ptr(InPtr) {}
1067 inline ~TIndexedPtrBase() { if(!IsFrozen()) Ptr.~PtrType(); }
1068
1069 // Copy constructor requires an unfrozen source
1071
1073
1075 {
1076 // If not currently frozen, invoke the standard assignment operator for the underlying pointer type
1077 // If frozen, construct a new (non-frozen) pointer over the existing frozen offset
1078 if (!IsFrozen()) Ptr = Rhs;
1079 else new(&Ptr) PtrType(Rhs);
1080 check(!IsFrozen());
1081 return *this;
1082 }
1083
1084 inline TIndexedPtrBase& operator=(const PtrType& Rhs)
1085 {
1086 if (!IsFrozen()) Ptr = Rhs;
1087 else new(&Ptr) PtrType(Rhs);
1088 check(!IsFrozen());
1089 return *this;
1090 }
1091
1092 inline TIndexedPtrBase& operator=(PtrType&& Rhs)
1093 {
1094 if (!IsFrozen()) Ptr = Rhs;
1095 else new(&Ptr) PtrType(Rhs);
1096 check(!IsFrozen());
1097 return *this;
1098 }
1099
1100 inline bool IsFrozen() const { return PackedIndex & IsFrozenMask; }
1101 inline bool IsValid() const { return PackedIndex != 0u; } // works for both frozen/unfrozen cases
1102 inline bool IsNull() const { return PackedIndex == 0u; }
1103
1104 inline void SafeRelease()
1105 {
1106 if (!IsFrozen())
1107 {
1108 SafeReleaseImpl(Ptr);
1109 }
1110 }
1111
1112 inline T* Get(const FPtrTable& PtrTable) const
1113 {
1114 if (IsFrozen())
1115 {
1116 return PtrTable.GetIndexedPointer((uint32)(PackedIndex >> IndexShift));
1117 }
1118 return Ptr;
1119 }
1120
1121 inline T* Get(const FPointerTableBase* PtrTable) const
1122 {
1123 if (IsFrozen())
1124 {
1125 check(PtrTable);
1127 return static_cast<T*>(PtrTable->GetIndexedPointer(TypeDesc, (uint32)(PackedIndex >> IndexShift)));
1128 }
1129 return Ptr;
1130 }
1131
1132 inline T* GetUnfrozen() const { check(!IsFrozen()); return Ptr; }
1133
1134private:
1135 enum
1136 {
1137 IsFrozenMask = (1 << 0),
1138 IndexShift = 1,
1139 };
1140
1141 static void SafeReleaseImpl(T*& InPtr)
1142 {
1143 if (InPtr)
1144 {
1145 delete InPtr;
1146 InPtr = nullptr;
1147 }
1148 }
1149
1150 static void SafeReleaseImpl(TRefCountPtr<T>& InPtr)
1151 {
1152 InPtr.SafeRelease();
1153 }
1154
1155 static_assert(sizeof(PtrType) <= sizeof(uint64), "PtrType must fit within a standard pointer");
1156 union
1157 {
1158 PtrType Ptr;
1160 };
1161};
1162
1163#ifdef _MSC_VER
1164#pragma warning(pop)
1165#endif
1166
1167template<typename T, typename PtrType>
1172
1173namespace Freeze
1174{
1175 template<typename T, typename PtrType>
1177 {
1178 T* RawPtr = Object.Get(Writer.TryGetPrevPointerTable());
1179 if (RawPtr)
1180 {
1181 const uint32 Index = Writer.GetPointerTable().AddIndexedPointer(TypeDesc, RawPtr);
1183 const uint64 FrozenPackedIndex = ((uint64)Index << 1u) | 1u;
1185 }
1186 else
1187 {
1188 Writer.WriteBytes(uint64(0u));
1189 }
1190 }
1191
1192 template<typename T, typename PtrType>
1194 {
1195 new(OutDst) TIndexedPtrBase<T, PtrType>(Object.Get(Context.TryGetPrevPointerTable()));
1196 return sizeof(Object);
1197 }
1198
1199 template<typename T, typename PtrType>
1201 {
1202 return AppendHashForNameAndSize(TypeDesc.Name, sizeof(TIndexedPtrBase<T, PtrType>), Hasher);
1203 }
1204
1205 template<typename T, typename PtrType>
1207 {
1208 return FMath::Min(8u, LayoutParams.MaxFieldAlignment);
1209 }
1210}
1211
1212template<typename T>
1214
1215template<typename T>
1217
1218template<typename T, typename PtrType>
1220{
1221public:
1223
1224 inline TPatchedPtrBase(T* InPtr = nullptr) : Ptr(InPtr) {}
1225
1226 inline T* Get() const
1227 {
1228 return Ptr;
1229 }
1230
1231 inline T* GetChecked() const { T* Value = Get(); check(Value); return Value; }
1232 inline T* operator->() const { return GetChecked(); }
1233 inline T& operator*() const { return *GetChecked(); }
1234 inline operator T*() const { return Get(); }
1235
1236private:
1237 static_assert(sizeof(PtrType) == sizeof(void*), "PtrType must be a standard pointer");
1238 PtrType Ptr;
1239};
1240
1241template<typename T>
1243
1244template<typename T>
1246
constexpr T Align(T Val, uint64 Alignment)
Definition AlignmentTemplates.h:18
#define checkSlow(expr)
Definition AssertionMacros.h:332
#define check(expr)
Definition AssertionMacros.h:314
bool LoadFromCompactBinary(FCbFieldView Field, FAssetDependency &Dependency)
Definition AssetRegistry.cpp:10420
UE_FORCEINLINE_HINT SizeType DefaultCalculateSlackReserve(SizeType NewMax, SIZE_T BytesPerElement, bool bAllowQuantize, uint32 Alignment=DEFAULT_ALIGNMENT)
Definition ContainerAllocationPolicies.h:223
UE_FORCEINLINE_HINT SizeType DefaultCalculateSlackShrink(SizeType NewMax, SizeType CurrentMax, SIZE_T BytesPerElement, bool bAllowQuantize, uint32 Alignment=DEFAULT_ALIGNMENT)
Definition ContainerAllocationPolicies.h:139
UE_FORCEINLINE_HINT SizeType DefaultCalculateSlackGrow(SizeType NewMax, SizeType CurrentMax, SIZE_T BytesPerElement, bool bAllowQuantize, uint32 Alignment=DEFAULT_ALIGNMENT)
Definition ContainerAllocationPolicies.h:169
@ INDEX_NONE
Definition CoreMiscDefines.h:150
#define UE_NONCOPYABLE(TypeName)
Definition CoreMiscDefines.h:457
#define TEXT(x)
Definition Platform.h:1272
FPlatformTypes::SIZE_T SIZE_T
An unsigned integer the same size as a pointer, the same as UPTRINT.
Definition Platform.h:1150
FPlatformTypes::TCHAR TCHAR
Either ANSICHAR or WIDECHAR, depending on whether the platform supports wide characters or the requir...
Definition Platform.h:1135
FPlatformTypes::int64 int64
A 64-bit signed integer.
Definition Platform.h:1127
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
#define UE_FORCEINLINE_HINT
Definition Platform.h:723
FPlatformTypes::uint64 uint64
A 64-bit unsigned integer.
Definition Platform.h:1117
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
@ Patch
Patch version increments fix existing functionality without changing the API.
void InternalDeleteObjectFromLayout(void *Object, const FTypeLayoutDesc &TypeDesc, const FPointerTableBase *PtrTable, bool bIsFrozen)
Definition MemoryImage.cpp:330
CORE_API void * UnfreezeMemoryImageObject(const void *FrozenObject, const FTypeLayoutDesc &TypeDesc, const FPointerTableBase *PointerTable)
Definition MemoryImage.cpp:1451
TSet< ElementType, KeyFuncs, FMemoryImageSetAllocator > TMemoryImageSet
Definition MemoryImage.h:731
CORE_API FMemoryImageObject FreezeMemoryImageObject(const void *Object, const FTypeLayoutDesc &TypeDesc, FPointerTableBase *PointerTable)
Definition MemoryImage.cpp:1427
#define DECLARE_TEMPLATE_INTRINSIC_TYPE_LAYOUT(TemplatePrefix, T)
Definition MemoryLayout.h:661
#define LAYOUT_FIELD(T, Name,...)
Definition MemoryLayout.h:471
#define LAYOUT_TOSTRING(Func)
Definition MemoryLayout.h:481
#define DECLARE_EXPORTED_TYPE_LAYOUT(T, RequiredAPI, Interface)
Definition MemoryLayout.h:559
void DeleteObjectFromLayout(T *Object, const FPointerTableBase *PtrTable=nullptr, bool bIsFrozen=false)
Definition MemoryLayout.h:654
const FTypeLayoutDesc & GetTypeLayoutDesc(const FPointerTableBase *, const T &Object)
Definition MemoryLayout.h:649
#define LAYOUT_FIELD_EDITORONLY(T, Name,...)
Definition MemoryLayout.h:488
#define DECLARE_INTRINSIC_TYPE_LAYOUT(T)
Definition MemoryLayout.h:760
@ Num
Definition MetalRHIPrivate.h:234
uint32 Offset
Definition VulkanMemory.cpp:4033
uint32 Size
Definition VulkanMemory.cpp:4034
uint8_t uint8
Definition binka_ue_file_header.h:8
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition Archive.h:1208
Definition CompactBinary.h:610
Definition CompactBinaryWriter.h:68
Definition MemoryImage.h:858
FHashedName()
Definition MemoryImage.h:861
bool IsNone() const
Definition MemoryImage.h:870
bool operator==(const FHashedName &Rhs) const
Definition MemoryImage.h:876
bool operator!=(const FHashedName &Rhs) const
Definition MemoryImage.h:877
CORE_API FHashedName & operator=(const FHashedName &InName)
Definition MemoryImage.cpp:1286
uint64 GetHash() const
Definition MemoryImage.h:869
friend uint32 GetTypeHash(const FHashedName &Name)
Definition MemoryImage.h:888
friend FArchive & operator<<(FArchive &Ar, FHashedName &String)
Definition MemoryImage.h:882
bool operator<(const FHashedName &Rhs) const
Definition MemoryImage.h:880
Definition MemoryImage.h:600
CORE_API void CopyUnfrozen(const FMemoryUnfreezeContent &Context, const FTypeLayoutDesc &TypeDesc, int32 NumAllocatedElements, void *Dst) const
Definition MemoryImageAllocator.cpp:90
FMemoryImageAllocatorBase()=default
CORE_API ~FMemoryImageAllocatorBase()
Definition MemoryImageAllocator.cpp:21
CORE_API void MoveToEmpty(FMemoryImageAllocatorBase &Other)
Definition MemoryImageAllocator.cpp:33
CORE_API void WriteMemoryImage(FMemoryImageWriter &Writer, const FTypeLayoutDesc &TypeDesc, int32 NumAllocatedElements, uint32 Alignment) const
Definition MemoryImageAllocator.cpp:74
UE_FORCEINLINE_HINT bool HasAllocation()
Definition MemoryImage.h:625
UE_FORCEINLINE_HINT FScriptContainerElement * GetAllocation() const
Definition MemoryImage.h:616
CORE_API void ResizeAllocation(int32 PreviousNumElements, int32 NumElements, SIZE_T NumBytesPerElement, uint32 Alignment)
Definition MemoryImageAllocator.cpp:48
UE_FORCEINLINE_HINT int64 GetFrozenOffsetFromThis() const
Definition MemoryImage.h:629
UE_FORCEINLINE_HINT SIZE_T GetAllocatedSize(int32 CurrentMax, SIZE_T NumBytesPerElement) const
Definition MemoryImage.h:621
Definition MemoryImage.h:216
TArray< FSectionPointer > Pointers
Definition MemoryImage.h:276
TArray< FMemoryImageVTablePointer > VTables
Definition MemoryImage.h:277
uint32 WriteBytes(const T &Data)
Definition MemoryImage.h:263
CORE_API uint32 WriteFScriptName(const FScriptName &Name)
Definition MemoryImage.cpp:1937
uint32 MaxAlignment
Definition MemoryImage.h:281
FSHAHash Hash
Definition MemoryImage.h:280
CORE_API uint32 WriteVTable(const FTypeLayoutDesc &TypeDesc, const FTypeLayoutDesc &DerivedTypeDesc)
Definition MemoryImage.cpp:1913
FMemoryImageSection(FMemoryImage *InImage)
Definition MemoryImage.h:225
uint32 WriteZeroBytes(int32 Num)
Definition MemoryImage.h:255
CORE_API FMemoryImageSection * WritePointer(const FTypeLayoutDesc &StaticTypeDesc, const FTypeLayoutDesc &DerivedTypeDesc, uint32 *OutOffsetToBase=nullptr)
Definition MemoryImage.cpp:1870
FMemoryImage * ParentImage
Definition MemoryImage.h:274
void WritePaddingToSize(uint32 Offset)
Definition MemoryImage.h:241
uint32 WriteBytes(const void *Data, uint32 Size)
Definition MemoryImage.h:247
TArray< FMemoryImageNamePointer > MemoryImageNames
Definition MemoryImage.h:279
CORE_API uint32 WriteRawPointerSizedBytes(uint64 PointerValue)
Definition MemoryImage.cpp:1901
TArray< uint8 > Bytes
Definition MemoryImage.h:275
CORE_API uint32 Flatten(FMemoryImageResult &OutResult) const
Definition MemoryImage.cpp:1949
CORE_API void ComputeHash()
Definition MemoryImage.cpp:1994
TArray< FMemoryImageNamePointer > ScriptNames
Definition MemoryImage.h:278
CORE_API uint32 WriteFMemoryImageName(int32 NumBytes, const FName &Name)
Definition MemoryImage.cpp:1925
uint32 GetOffset() const
Definition MemoryImage.h:230
uint32 WriteAlignment(uint32 Alignment)
Definition MemoryImage.h:232
Definition MemoryImage.h:743
FMemoryImageString & operator=(FMemoryImageString &&)=default
friend FArchive & operator<<(FArchive &Ar, FMemoryImageString &Ref)
Definition MemoryImage.h:806
UE_FORCEINLINE_HINT const TCHAR * operator*() const
Definition MemoryImage.h:783
bool operator==(const FString &Rhs) const
Definition MemoryImage.h:822
FMemoryImageString & operator=(const FMemoryImageString &)=default
friend int32 GetNum(const FMemoryImageString &String)
Definition MemoryImage.h:801
friend const TCHAR * GetData(const FMemoryImageString &String)
Definition MemoryImage.h:796
UE_FORCEINLINE_HINT int32 Len() const
Definition MemoryImage.h:791
FMemoryImageString()=default
UE_FORCEINLINE_HINT SIZE_T GetAllocatedSize() const
Definition MemoryImage.h:789
UE_FORCEINLINE_HINT FMemoryImageString(const FString &Other)
Definition MemoryImage.h:761
UE_FORCEINLINE_HINT bool IsEmpty() const
Definition MemoryImage.h:788
TCHAR ElementType
Definition MemoryImage.h:753
bool operator==(const FMemoryImageString &Rhs) const
Definition MemoryImage.h:812
FMemoryImageString(const FMemoryImageString &)=default
friend UE_FORCEINLINE_HINT uint32 GetTypeHash(const FMemoryImageString &S)
Definition MemoryImage.h:835
DataType::ElementAllocatorType & GetAllocatorInstance()
Definition MemoryImage.h:832
bool operator!=(const FMemoryImageString &Rhs) const
Definition MemoryImage.h:817
FMemoryImageString(FMemoryImageString &&)=default
FMemoryImageString(const CharType *Src)
Definition MemoryImage.h:767
bool operator!=(const FString &Rhs) const
Definition MemoryImage.h:827
Definition MemoryImageWriter.h:14
CORE_API void WriteObject(const void *Object, const FTypeLayoutDesc &TypeDesc)
Definition MemoryImage.cpp:2099
CORE_API uint32 WriteBytes(const void *Data, uint32 Size)
Definition MemoryImage.cpp:2143
CORE_API uint32 WriteNullPointer()
Definition MemoryImage.cpp:2148
CORE_API FPointerTableBase & GetPointerTable() const
Definition MemoryImage.cpp:2091
CORE_API const FPointerTableBase * TryGetPrevPointerTable() const
Definition MemoryImage.cpp:2092
CORE_API FMemoryImageWriter WritePointer(const FTypeLayoutDesc &StaticTypeDesc, const FTypeLayoutDesc &DerivedTypeDesc, uint32 *OutOffsetToBase=nullptr)
Definition MemoryImage.cpp:2153
Definition MemoryImage.h:285
TArray< TRefCountPtr< FMemoryImageSection > > Sections
Definition MemoryImage.h:311
const FPointerTableBase * PrevPointerTable
Definition MemoryImage.h:313
CORE_API void Flatten(FMemoryImageResult &OutResult, bool bMergeDuplicateSections=false)
Definition MemoryImage.cpp:2006
const FPointerTableBase & GetPrevPointerTable() const
Definition MemoryImage.h:296
FPointerTableBase & GetPointerTable() const
Definition MemoryImage.h:295
FMemoryImageSection * AllocateSection()
Definition MemoryImage.h:298
FPlatformTypeLayoutParameters HostLayoutParameters
Definition MemoryImage.h:314
FPointerTableBase * PointerTable
Definition MemoryImage.h:312
FPlatformTypeLayoutParameters TargetLayoutParameters
Definition MemoryImage.h:315
FMemoryImage()
Definition MemoryImage.h:287
const class UStruct * CurrentStruct
Definition MemoryImage.h:316
Definition MemoryImageWriter.h:78
Definition NameTypes.h:617
CORE_API int32 Compare(const FName &Other) const
Definition UnrealNames.cpp:3478
FORCEINLINE bool LexicalLess(const FName &Other) const
Definition NameTypes.h:821
Definition MemoryImage.h:49
const FTypeLayoutDesc * GetTypeDependency(int32 Index) const
Definition MemoryImage.h:65
virtual int32 AddIndexedPointer(const FTypeLayoutDesc &TypeDesc, void *Ptr)=0
virtual CORE_API void SaveToArchive(FArchive &Ar, const FPlatformTypeLayoutParameters &LayoutParams, const void *FrozenObject) const
Definition MemoryImage.cpp:1337
virtual ~FPointerTableBase()
Definition MemoryImage.h:51
virtual void * GetIndexedPointer(const FTypeLayoutDesc &TypeDesc, uint32 i) const =0
virtual CORE_API bool LoadFromArchive(FArchive &Ar, const FPlatformTypeLayoutParameters &LayoutParams, void *FrozenObject)
Definition MemoryImage.cpp:1358
int32 AddTypeDependency(const FTypeLayoutDesc &TypeDesc)
Definition MemoryImage.h:64
Definition MemoryImage.h:922
static void LoadAndApplyPatchesFromArchive(FArchive &Ar, void *FrozenBase, const PtrType &Ptr)
Definition MemoryImage.h:925
TArray< FPatchOffset > PatchOffsets
Definition MemoryImage.h:956
CORE_API void AddPatchedPointerBase(uint32 PtrIndex, uint64 Offset)
Definition MemoryImage.cpp:1855
CORE_API void SavePatchesToArchive(FArchive &Ar, uint32 PtrIndex) const
Definition MemoryImage.cpp:1832
TArray< FPatchOffsetList > PatchLists
Definition MemoryImage.h:955
Definition RefCounting.h:252
Definition SecureHash.h:314
Definition SecureHash.h:226
Definition MemoryImage.h:1047
Definition Array.h:670
UE_REWRITE SizeType Num() const
Definition Array.h:1144
void SetNumZeroed(SizeType NewNum, EAllowShrinking AllowShrinking=UE::Core::Private::AllowShrinkingByDefault< AllocatorType >())
Definition Array.h:2340
void Reset(SizeType NewSize=0)
Definition Array.h:2246
UE_NODEBUG UE_FORCEINLINE_HINT ElementType * GetData() UE_LIFETIMEBOUND
Definition Array.h:1027
UE_NODEBUG UE_FORCEINLINE_HINT RangedForIteratorType end()
Definition Array.h:3391
bool Contains(const ComparisonType &Item) const
Definition Array.h:1518
UE_NODEBUG UE_FORCEINLINE_HINT SizeType Add(ElementType &&Item)
Definition Array.h:2696
UE_NODEBUG UE_FORCEINLINE_HINT RangedForIteratorType begin()
Definition Array.h:3389
std::conditional_t< AllocatorType::NeedsElementType, typename AllocatorType::template ForElementType< ElementType >, typename AllocatorType::ForAnyElementType > ElementAllocatorType
Definition Array.h:687
void SetNumUninitialized(SizeType NewNum, EAllowShrinking AllowShrinking=UE::Core::Private::AllowShrinkingByDefault< AllocatorType >())
Definition Array.h:2369
UE_FORCEINLINE_HINT SizeType AddUnique(ElementType &&Item)
Definition Array.h:2993
Definition EnableIf.h:20
Definition MemoryImage.h:1062
bool IsValid() const
Definition MemoryImage.h:1101
TIndexedPtrBase(const TIndexedPtrBase< T, PtrType > &Rhs, const FPtrTable &InTable)
Definition MemoryImage.h:1072
PtrType Ptr
Definition MemoryImage.h:1158
T * GetUnfrozen() const
Definition MemoryImage.h:1132
uint64 PackedIndex
Definition MemoryImage.h:1159
TIndexedPtrBase & operator=(T *Rhs)
Definition MemoryImage.h:1074
T * Get(const FPtrTable &PtrTable) const
Definition MemoryImage.h:1112
~TIndexedPtrBase()
Definition MemoryImage.h:1067
bool IsFrozen() const
Definition MemoryImage.h:1100
T * Get(const FPointerTableBase *PtrTable) const
Definition MemoryImage.h:1121
TIndexedPtrBase & operator=(PtrType &&Rhs)
Definition MemoryImage.h:1092
TIndexedPtrBase & operator=(const PtrType &Rhs)
Definition MemoryImage.h:1084
bool IsNull() const
Definition MemoryImage.h:1102
TIndexedPtrBase(T *InPtr=nullptr)
Definition MemoryImage.h:1066
TIndexedPtrBase(const TIndexedPtrBase< T, PtrType > &Rhs)
Definition MemoryImage.h:1070
void SafeRelease()
Definition MemoryImage.h:1104
Definition UnrealString.h.inl:34
Definition MemoryImage.h:651
UE_FORCEINLINE_HINT int32 CalculateSlackShrink(int32 NewMax, int32 CurrentMax, int32 NumBytesPerElement) const
Definition MemoryImage.h:668
UE_FORCEINLINE_HINT int32 CalculateSlackReserve(int32 NewMax, int32 NumBytesPerElement, uint32 AlignmentOfElement) const
Definition MemoryImage.h:664
UE_FORCEINLINE_HINT int32 CalculateSlackGrow(int32 NewMax, int32 CurrentMax, int32 NumBytesPerElement, uint32 AlignmentOfElement) const
Definition MemoryImage.h:680
UE_FORCEINLINE_HINT void ResizeAllocation(int32 CurrentNum, int32 NewMax, SIZE_T NumBytesPerElement, uint32 AlignmentOfElement)
Definition MemoryImage.h:688
UE_FORCEINLINE_HINT int32 CalculateSlackShrink(int32 NewMax, int32 CurrentMax, int32 NumBytesPerElement, uint32 AlignmentOfElement) const
Definition MemoryImage.h:672
UE_FORCEINLINE_HINT void ResizeAllocation(int32 CurrentNum, int32 NewMax, SIZE_T NumBytesPerElement)
Definition MemoryImage.h:684
UE_FORCEINLINE_HINT int32 CalculateSlackGrow(int32 NewMax, int32 CurrentMax, int32 NumBytesPerElement) const
Definition MemoryImage.h:676
UE_FORCEINLINE_HINT void WriteMemoryImage(FMemoryImageWriter &Writer, const FTypeLayoutDesc &TypeDesc, int32 NumAllocatedElements) const
Definition MemoryImage.h:693
UE_FORCEINLINE_HINT int32 CalculateSlackReserve(int32 NewMax, int32 NumBytesPerElement) const
Definition MemoryImage.h:660
UE_FORCEINLINE_HINT SizeType GetInitialCapacity() const
Definition MemoryImage.h:656
Definition MemoryImage.h:701
UE_FORCEINLINE_HINT ElementType * GetAllocation() const
Definition MemoryImage.h:704
ForElementType()
Definition MemoryImage.h:703
Definition MemoryImage.h:642
@ NeedsElementType
Definition MemoryImage.h:646
int32 SizeType
Definition MemoryImage.h:644
@ SupportsFreezeMemoryImage
Definition MemoryImage.h:648
@ RequireRangeCheck
Definition MemoryImage.h:647
Definition MemoryImage.h:382
TMemoryImagePtr()
Definition MemoryImage.h:388
bool IsValid() const
Definition MemoryImage.h:385
TMemoryImagePtr(T *InPtr)
Definition MemoryImage.h:389
T * operator->() const
Definition MemoryImage.h:408
void SafeDelete(const FPointerTableBase *PtrTable=nullptr)
Definition MemoryImage.h:412
TMemoryImagePtr & operator=(const TMemoryImagePtr< T > &InPtr)
Definition MemoryImage.h:392
int64 GetFrozenOffsetFromThis() const
Definition MemoryImage.h:399
TMemoryImagePtr & operator=(T *InPtr)
Definition MemoryImage.h:391
FFrozenMemoryImagePtr Frozen
Definition MemoryImage.h:448
T * Get() const
Definition MemoryImage.h:402
T * GetChecked() const
Definition MemoryImage.h:407
~TMemoryImagePtr()
Definition MemoryImage.h:394
bool IsFrozen() const
Definition MemoryImage.h:384
uint64 Packed
Definition MemoryImage.h:447
TMemoryImagePtr(const TMemoryImagePtr< T > &InPtr)
Definition MemoryImage.h:390
bool IsNull() const
Definition MemoryImage.h:386
int32 GetFrozenTypeIndex() const
Definition MemoryImage.h:400
void WriteMemoryImageWithDerivedType(FMemoryImageWriter &Writer, const FTypeLayoutDesc *DerivedTypeDesc) const
Definition MemoryImage.h:422
T & operator*() const
Definition MemoryImage.h:409
T * UnfrozenPtr
Definition MemoryImage.h:449
Definition MemoryImage.h:1220
T & operator*() const
Definition MemoryImage.h:1233
TPatchedPtrBase(T *InPtr=nullptr)
Definition MemoryImage.h:1224
T * operator->() const
Definition MemoryImage.h:1232
T * GetChecked() const
Definition MemoryImage.h:1231
T * Get() const
Definition MemoryImage.h:1226
Definition MemoryImage.h:961
TArray< PtrType >::RangedForConstIteratorType end() const
Definition MemoryImage.h:1033
bool TryAddIndexedPtr(const FTypeLayoutDesc &TypeDesc, void *Ptr, int32 &OutIndex)
Definition MemoryImage.h:973
void Empty(int32 NewSize=0)
Definition MemoryImage.h:965
TArray< PtrType >::RangedForIteratorType end()
Definition MemoryImage.h:1031
void AddPatchedPointer(T *Ptr, uint64 Offset)
Definition MemoryImage.h:998
void LoadIndexedPointer(T *Ptr)
Definition MemoryImage.h:983
TArray< PtrType >::RangedForIteratorType begin()
Definition MemoryImage.h:1030
bool TryGetIndexedPtr(const FTypeLayoutDesc &TypeDesc, uint32 i, void *&OutPtr) const
Definition MemoryImage.h:1006
static const FTypeLayoutDesc & StaticGetPtrTypeLayoutDesc()
Definition MemoryImage.h:1168
void ApplyPointerPatches(void *FrozenBase) const
Definition MemoryImage.h:1016
TArray< PtrType >::RangedForConstIteratorType begin() const
Definition MemoryImage.h:1032
T * GetIndexedPointer(uint32 i) const
Definition MemoryImage.h:1004
uint32 AddIndexedPointer(T *Ptr)
Definition MemoryImage.h:971
uint32 Num() const
Definition MemoryImage.h:970
Definition MemoryImage.h:1039
Definition MemoryImage.h:1043
Definition RefCounting.h:454
Definition ContainerAllocationPolicies.h:1662
Definition ContainerAllocationPolicies.h:1383
Definition MemoryImage.h:559
TUniqueMemoryImagePtr & operator=(T *InPtr)
Definition MemoryImage.h:578
TUniqueMemoryImagePtr & operator=(TUniqueMemoryImagePtr &&Other)
Definition MemoryImage.h:584
~TUniqueMemoryImagePtr()
Definition MemoryImage.h:574
TUniqueMemoryImagePtr(T *InPtr)
Definition MemoryImage.h:564
TUniqueMemoryImagePtr(TUniqueMemoryImagePtr &&Other)
Definition MemoryImage.h:568
TUniqueMemoryImagePtr()
Definition MemoryImage.h:561
Definition Class.h:480
Definition FieldSystemNoiseAlgo.cpp:6
Definition Array.h:3955
CORE_API uint32 AppendHashForNameAndSize(const TCHAR *Name, uint32 Size, FSHA1 &Hasher)
Definition MemoryImage.cpp:568
UE_NODEBUG void IntrinsicWriteMemoryImage(FMemoryImageWriter &Writer, const TArray< T, AllocatorType > &Object, const FTypeLayoutDesc &)
Definition Array.h:3957
UE_NODEBUG uint32 IntrinsicUnfrozenCopy(const FMemoryUnfreezeContent &Context, const TArray< T, AllocatorType > &Object, void *OutDst)
Definition Array.h:3963
UE_NODEBUG void IntrinsicToString(const TArray< T, AllocatorType > &Object, const FTypeLayoutDesc &TypeDesc, const FPlatformTypeLayoutParameters &LayoutParams, FMemoryToStringContext &OutContext)
Definition Array.h:3983
UE_NODEBUG uint32 IntrinsicGetTargetAlignment(const TArray< T, AllocatorType > *DummyObject, const FTypeLayoutDesc &TypeDesc, const FPlatformTypeLayoutParameters &LayoutParams)
Definition Array.h:3976
UE_NODEBUG uint32 IntrinsicAppendHash(const TArray< T, AllocatorType > *DummyObject, const FTypeLayoutDesc &TypeDesc, const FPlatformTypeLayoutParameters &LayoutParams, FSHA1 &Hasher)
Definition Array.h:3970
U16 Index
Definition radfft.cpp:71
static uint32 Strihash_DEPRECATED(const CharType *Data)
Definition MemoryImage.h:324
static constexpr uint64 bIsFrozenMask
Definition MemoryImage.h:333
void SetOffsetFromThis(int64 Offset)
Definition MemoryImage.h:359
int64 GetOffsetFromThis() const
Definition MemoryImage.h:351
uint64 Packed
Definition MemoryImage.h:337
static constexpr uint64 TypeIndexMask
Definition MemoryImage.h:334
static constexpr uint64 bIsFrozenShift
Definition MemoryImage.h:329
static constexpr uint64 OffsetShift
Definition MemoryImage.h:331
void SetIsFrozen(bool bTrue)
Definition MemoryImage.h:345
static constexpr uint64 TypeIndexBits
Definition MemoryImage.h:327
static constexpr uint64 TypeIndexShift
Definition MemoryImage.h:330
bool IsFrozen() const
Definition MemoryImage.h:340
static constexpr uint64 OffsetMask
Definition MemoryImage.h:335
static constexpr uint64 bIsFrozenBits
Definition MemoryImage.h:325
static constexpr uint64 OffsetBits
Definition MemoryImage.h:326
int32 GetTypeIndex() const
Definition MemoryImage.h:365
void SetTypeIndex(int32 TypeIndex)
Definition MemoryImage.h:370
Definition MemoryImage.h:179
bool operator==(const FMemoryImageNamePointer &Rhs) const
Definition MemoryImage.h:183
bool operator<(const FMemoryImageNamePointer &Rhs) const
Definition MemoryImage.h:191
bool operator!=(const FMemoryImageNamePointer &Rhs) const
Definition MemoryImage.h:187
uint32 Offset
Definition MemoryImage.h:181
FName Name
Definition MemoryImage.h:180
Definition MemoryImage.h:202
FPointerTableBase * PointerTable
Definition MemoryImage.h:204
FPlatformTypeLayoutParameters TargetLayoutParameters
Definition MemoryImage.h:205
static CORE_API FMemoryImageObject LoadFromArchive(FArchive &Ar, const FTypeLayoutDesc &TypeDesc, FPointerTableBase *PointerTable, FPlatformTypeLayoutParameters &OutLayoutParameters)
Definition MemoryImage.cpp:1696
TArray< FMemoryImageVTablePointer > VTables
Definition MemoryImage.h:206
TArray< FMemoryImageNamePointer > MemoryImageNames
Definition MemoryImage.h:208
CORE_API void SaveToArchive(FArchive &Ar) const
Definition MemoryImage.cpp:1503
CORE_API bool ApplyPatches(void *FrozenObject, uint64 FrozenObjectSize) const
Definition MemoryImage.cpp:1665
TArray< uint8 > Bytes
Definition MemoryImage.h:203
TArray< FMemoryImageNamePointer > ScriptNames
Definition MemoryImage.h:207
Definition MemoryImage.h:219
uint32 Offset
Definition MemoryImage.h:222
uint32 PointerOffset
Definition MemoryImage.h:221
uint32 SectionIndex
Definition MemoryImage.h:220
Definition MemoryImage.h:157
uint64 TypeNameHash
Definition MemoryImage.h:158
bool operator==(const FMemoryImageVTablePointer &Rhs) const
Definition MemoryImage.h:162
bool operator!=(const FMemoryImageVTablePointer &Rhs) const
Definition MemoryImage.h:166
bool operator<(const FMemoryImageVTablePointer &Rhs) const
Definition MemoryImage.h:170
uint32 Offset
Definition MemoryImage.h:160
uint32 VTableOffset
Definition MemoryImage.h:159
Definition MemoryLayout.h:51
static FORCENOINLINE CORE_API void Free(void *Original)
Definition UnrealMemory.cpp:685
static UE_FORCEINLINE_HINT void * Memcpy(void *Dest, const void *Src, SIZE_T Count)
Definition UnrealMemory.h:160
Definition MemoryLayout.h:799
CORE_API void InitializeForCurrent()
Definition MemoryImage.cpp:81
Definition MemoryImage.h:947
uint32 FirstIndex
Definition MemoryImage.h:949
uint32 NumOffsets
Definition MemoryImage.h:950
FPatchOffsetList()
Definition MemoryImage.h:948
Definition MemoryImage.h:941
uint32 NextIndex
Definition MemoryImage.h:943
uint32 Offset
Definition MemoryImage.h:942
Definition ContainerAllocationPolicies.h:242
Definition NameTypes.h:491
Definition MemoryLayout.h:108
const TCHAR * Name
Definition MemoryLayout.h:127
Definition ContainerAllocationPolicies.h:247
@ SupportsElementAlignment
Definition ContainerAllocationPolicies.h:250
@ SupportsFreezeMemoryImage
Definition ContainerAllocationPolicies.h:249
@ IsZeroConstruct
Definition ContainerAllocationPolicies.h:248
Definition ContainerAllocationPolicies.h:256
static UE_FORCEINLINE_HINT int32 Stricmp(const CharType *String1, const CharType *String2)
Definition CString.h:1030
static int32 Strlen(const CharType *String)
Definition CString.h:1047
Definition Array.h:206
Definition IsContiguousContainer.h:16
static constexpr bool Value
Definition IsContiguousContainer.h:20
Definition MemoryImage.h:71
TMemoryImageObject(const FTypeLayoutDesc &InTypeDesc, T *InObject, uint32 InFrozenSize)
Definition MemoryImage.h:74
const FTypeLayoutDesc * TypeDesc
Definition MemoryImage.h:100
uint32 FrozenSize
Definition MemoryImage.h:102
TMemoryImageObject()
Definition MemoryImage.h:72
void Destroy(const FPointerTableBase *PointerTable)
Definition MemoryImage.h:110
TMemoryImageObject(const TMemoryImageObject< TOther > &Rhs)
Definition MemoryImage.h:88
T * Object
Definition MemoryImage.h:101
bool Unfreeze(const FPointerTableBase *PointerTable)
Definition MemoryImage.h:143
TMemoryImageObject(TOther *InObject)
Definition MemoryImage.h:81
bool Freeze(FPointerTableBase *PointerTable)
Definition MemoryImage.h:129