Skip to content

Commit 0c8571f

Browse files
committed
Reduce and pad IMC allocations and log allocations.
1 parent 8779f4b commit 0c8571f

File tree

6 files changed

+29
-14
lines changed

6 files changed

+29
-14
lines changed

Penumbra.GameData

Penumbra/Collections/Cache/ImcCache.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ private void ApplyFile(ImcIdentifier identifier, ImcEntry entry)
5151
if (!_imcFiles.TryGetValue(path, out var pair))
5252
pair = (new ImcFile(Manager, identifier), []);
5353

54-
5554
if (!Apply(pair.Item1, identifier, entry))
5655
return;
5756

Penumbra/Collections/ModCollectionIdentity.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ public struct ModCollectionIdentity(Guid id, LocalCollectionId localId)
1010

1111
public static readonly ModCollectionIdentity Empty = new(Guid.Empty, LocalCollectionId.Zero, EmptyCollectionName, 0);
1212

13-
public string Name { get; set; }
14-
public Guid Id { get; } = id;
15-
public LocalCollectionId LocalId { get; } = localId;
13+
public string Name { get; set; } = string.Empty;
14+
public Guid Id { get; } = id;
15+
public LocalCollectionId LocalId { get; } = localId;
1616

1717
/// <summary> The index of the collection is set and kept up-to-date by the CollectionManager. </summary>
1818
public int Index { get; internal set; }

Penumbra/Interop/GameState.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ public class GameState : IService
1111
{
1212
#region Last Game Object
1313

14-
private readonly ThreadLocal<Queue<nint>> _lastGameObject = new(() => new Queue<nint>());
15-
public readonly ThreadLocal<bool> CharacterAssociated = new(() => false);
14+
private readonly ThreadLocal<Queue<nint>> _lastGameObject = new(() => new Queue<nint>());
15+
public readonly ThreadLocal<bool> CharacterAssociated = new(() => false);
1616

1717
public nint LastGameObject
1818
=> _lastGameObject.IsValueCreated && _lastGameObject.Value!.Count > 0 ? _lastGameObject.Value.Peek() : nint.Zero;

Penumbra/Meta/Files/ImcFile.cs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using Penumbra.GameData;
12
using Penumbra.GameData.Enums;
23
using Penumbra.GameData.Structs;
34
using Penumbra.Interop.Structs;
@@ -192,22 +193,26 @@ public static ImcEntry GetEntry(ReadOnlySpan<byte> imcFileData, EquipSlot slot,
192193
public void Replace(ResourceHandle* resource)
193194
{
194195
var (data, length) = resource->GetData();
195-
if (length == ActualLength)
196+
var actualLength = ActualLength;
197+
if (length >= actualLength)
196198
{
197-
MemoryUtility.MemCpyUnchecked((byte*)data, Data, ActualLength);
199+
MemoryUtility.MemCpyUnchecked((byte*)data, Data, actualLength);
200+
MemoryUtility.MemSet((byte*)data + actualLength, 0, length - actualLength);
198201
return;
199202
}
200203

201-
var newData = Manager.XivAllocator.Allocate(ActualLength, 8);
204+
var paddedLength = actualLength.PadToMultiple(128);
205+
var newData = Manager.XivAllocator.Allocate(paddedLength, 8);
202206
if (newData == null)
203207
{
204208
Penumbra.Log.Error($"Could not replace loaded IMC data at 0x{(ulong)resource:X}, allocation failed.");
205209
return;
206210
}
207211

208-
MemoryUtility.MemCpyUnchecked(newData, Data, ActualLength);
212+
MemoryUtility.MemCpyUnchecked(newData, Data, actualLength);
213+
MemoryUtility.MemSet((byte*)data + actualLength, 0, paddedLength - actualLength);
209214

210215
Manager.XivAllocator.Release((void*)data, length);
211-
resource->SetData((nint)newData, ActualLength);
216+
resource->SetData((nint)newData, paddedLength);
212217
}
213218
}

Penumbra/Meta/Files/MetaBaseFile.cs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,16 @@ public void Release(void* pointer, int length)
2828
public sealed class MarshalAllocator : IFileAllocator
2929
{
3030
public unsafe T* Allocate<T>(int length, int alignment = 1) where T : unmanaged
31-
=> (T*)Marshal.AllocHGlobal(length * sizeof(T));
31+
{
32+
var ret = (T*)Marshal.AllocHGlobal(length * sizeof(T));
33+
Penumbra.Log.Verbose($"Allocating {length * sizeof(T)} bytes via Marshal Allocator to 0x{(nint)ret:X}.");
34+
return ret;
35+
}
3236

3337
public unsafe void Release<T>(ref T* pointer, int length) where T : unmanaged
3438
{
3539
Marshal.FreeHGlobal((nint)pointer);
40+
Penumbra.Log.Verbose($"Freeing {length * sizeof(T)} bytes from 0x{(nint)pointer:X} via Marshal Allocator.");
3641
pointer = null;
3742
}
3843
}
@@ -53,11 +58,17 @@ public XivFileAllocator(IGameInteropProvider provider)
5358
=> ((delegate* unmanaged<IMemorySpace*>)_getFileSpaceAddress)();
5459

5560
public T* Allocate<T>(int length, int alignment = 1) where T : unmanaged
56-
=> (T*)GetFileSpace()->Malloc((ulong)(length * sizeof(T)), (ulong)alignment);
61+
{
62+
var ret = (T*)GetFileSpace()->Malloc((ulong)(length * sizeof(T)), (ulong)alignment);
63+
Penumbra.Log.Verbose($"Allocating {length * sizeof(T)} bytes via FFXIV File Allocator to 0x{(nint)ret:X}.");
64+
return ret;
65+
}
5766

5867
public void Release<T>(ref T* pointer, int length) where T : unmanaged
5968
{
69+
6070
IMemorySpace.Free(pointer, (ulong)(length * sizeof(T)));
71+
Penumbra.Log.Verbose($"Freeing {length * sizeof(T)} bytes from 0x{(nint)pointer:X} via FFXIV File Allocator.");
6172
pointer = null;
6273
}
6374
}

0 commit comments

Comments
 (0)