mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 10:17:22 +01:00
Reduce and pad IMC allocations and log allocations.
This commit is contained in:
parent
8779f4b689
commit
0c8571fba9
6 changed files with 29 additions and 14 deletions
|
|
@ -1 +1 @@
|
|||
Subproject commit 5bac66e5ad73e57919aff7f8b046606b75e191a2
|
||||
Subproject commit ebeea67c17f6bf4ce7e635041b2138e835d31262
|
||||
|
|
@ -51,7 +51,6 @@ public sealed class ImcCache(MetaFileManager manager, ModCollection collection)
|
|||
if (!_imcFiles.TryGetValue(path, out var pair))
|
||||
pair = (new ImcFile(Manager, identifier), []);
|
||||
|
||||
|
||||
if (!Apply(pair.Item1, identifier, entry))
|
||||
return;
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ public struct ModCollectionIdentity(Guid id, LocalCollectionId localId)
|
|||
|
||||
public static readonly ModCollectionIdentity Empty = new(Guid.Empty, LocalCollectionId.Zero, EmptyCollectionName, 0);
|
||||
|
||||
public string Name { get; set; }
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public Guid Id { get; } = id;
|
||||
public LocalCollectionId LocalId { get; } = localId;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
using Penumbra.GameData;
|
||||
using Penumbra.GameData.Enums;
|
||||
using Penumbra.GameData.Structs;
|
||||
using Penumbra.Interop.Structs;
|
||||
|
|
@ -192,22 +193,26 @@ public unsafe class ImcFile : MetaBaseFile
|
|||
public void Replace(ResourceHandle* resource)
|
||||
{
|
||||
var (data, length) = resource->GetData();
|
||||
if (length == ActualLength)
|
||||
var actualLength = ActualLength;
|
||||
if (length >= actualLength)
|
||||
{
|
||||
MemoryUtility.MemCpyUnchecked((byte*)data, Data, ActualLength);
|
||||
MemoryUtility.MemCpyUnchecked((byte*)data, Data, actualLength);
|
||||
MemoryUtility.MemSet((byte*)data + actualLength, 0, length - actualLength);
|
||||
return;
|
||||
}
|
||||
|
||||
var newData = Manager.XivAllocator.Allocate(ActualLength, 8);
|
||||
var paddedLength = actualLength.PadToMultiple(128);
|
||||
var newData = Manager.XivAllocator.Allocate(paddedLength, 8);
|
||||
if (newData == null)
|
||||
{
|
||||
Penumbra.Log.Error($"Could not replace loaded IMC data at 0x{(ulong)resource:X}, allocation failed.");
|
||||
return;
|
||||
}
|
||||
|
||||
MemoryUtility.MemCpyUnchecked(newData, Data, ActualLength);
|
||||
MemoryUtility.MemCpyUnchecked(newData, Data, actualLength);
|
||||
MemoryUtility.MemSet((byte*)data + actualLength, 0, paddedLength - actualLength);
|
||||
|
||||
Manager.XivAllocator.Release((void*)data, length);
|
||||
resource->SetData((nint)newData, ActualLength);
|
||||
resource->SetData((nint)newData, paddedLength);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,11 +28,16 @@ public unsafe interface IFileAllocator
|
|||
public sealed class MarshalAllocator : IFileAllocator
|
||||
{
|
||||
public unsafe T* Allocate<T>(int length, int alignment = 1) where T : unmanaged
|
||||
=> (T*)Marshal.AllocHGlobal(length * sizeof(T));
|
||||
{
|
||||
var ret = (T*)Marshal.AllocHGlobal(length * sizeof(T));
|
||||
Penumbra.Log.Verbose($"Allocating {length * sizeof(T)} bytes via Marshal Allocator to 0x{(nint)ret:X}.");
|
||||
return ret;
|
||||
}
|
||||
|
||||
public unsafe void Release<T>(ref T* pointer, int length) where T : unmanaged
|
||||
{
|
||||
Marshal.FreeHGlobal((nint)pointer);
|
||||
Penumbra.Log.Verbose($"Freeing {length * sizeof(T)} bytes from 0x{(nint)pointer:X} via Marshal Allocator.");
|
||||
pointer = null;
|
||||
}
|
||||
}
|
||||
|
|
@ -53,11 +58,17 @@ public sealed unsafe class XivFileAllocator : IFileAllocator, IService
|
|||
=> ((delegate* unmanaged<IMemorySpace*>)_getFileSpaceAddress)();
|
||||
|
||||
public T* Allocate<T>(int length, int alignment = 1) where T : unmanaged
|
||||
=> (T*)GetFileSpace()->Malloc((ulong)(length * sizeof(T)), (ulong)alignment);
|
||||
{
|
||||
var ret = (T*)GetFileSpace()->Malloc((ulong)(length * sizeof(T)), (ulong)alignment);
|
||||
Penumbra.Log.Verbose($"Allocating {length * sizeof(T)} bytes via FFXIV File Allocator to 0x{(nint)ret:X}.");
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void Release<T>(ref T* pointer, int length) where T : unmanaged
|
||||
{
|
||||
|
||||
IMemorySpace.Free(pointer, (ulong)(length * sizeof(T)));
|
||||
Penumbra.Log.Verbose($"Freeing {length * sizeof(T)} bytes from 0x{(nint)pointer:X} via FFXIV File Allocator.");
|
||||
pointer = null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue