mirror of https://gitlab.com/nakst/essence
free on application exit on debug builds
This commit is contained in:
parent
6bdb99a79b
commit
c4789093ac
|
@ -541,6 +541,39 @@ void _start() {
|
|||
Instance *instance = message->instanceDestroy.instance;
|
||||
InstanceDestroy(instance);
|
||||
instances.FindAndDeleteSwap(instance, true);
|
||||
} else if (message->type == ES_MSG_APPLICATION_EXIT) {
|
||||
#ifdef DEBUG_BUILD
|
||||
for (uintptr_t i = 0; i < drives.Length(); i++) {
|
||||
EsHeapFree(drives[i].prefix);
|
||||
}
|
||||
|
||||
for (uintptr_t i = 0; i < bookmarks.Length(); i++) {
|
||||
StringDestroy(&bookmarks[i]);
|
||||
}
|
||||
|
||||
for (uintptr_t i = 0; i < thumbnailCache.Count(); i++) {
|
||||
EsHeapFree(thumbnailCache[i].bits);
|
||||
}
|
||||
|
||||
for (uintptr_t i = 0; i < loadedFolders.Length(); i++) {
|
||||
FolderDestroy(loadedFolders[i]);
|
||||
}
|
||||
|
||||
EsAssert(!instances.Length());
|
||||
EsHandleClose(nonBlockingTaskWorkAvailable);
|
||||
EsHeapFree(fileTypesBuffer.out);
|
||||
|
||||
bookmarks.Free();
|
||||
drives.Free();
|
||||
folderViewSettings.Free();
|
||||
foldersWithNoAttachedInstances.Free();
|
||||
instances.Free();
|
||||
knownFileTypes.Free();
|
||||
knownFileTypesByExtension.Free();
|
||||
loadedFolders.Free();
|
||||
nonBlockingTasks.Free();
|
||||
thumbnailCache.Free();
|
||||
#endif
|
||||
} else if (message->type == ES_MSG_REGISTER_FILE_SYSTEM) {
|
||||
DriveAdd(message->registerFileSystem.mountPoint->prefix, message->registerFileSystem.mountPoint->prefixBytes);
|
||||
} else if (message->type == ES_MSG_UNREGISTER_FILE_SYSTEM) {
|
||||
|
|
|
@ -12,6 +12,7 @@ struct FileType {
|
|||
|
||||
Array<FileType> knownFileTypes;
|
||||
HashStore<char, uintptr_t /* index into knownFileTypes */> knownFileTypesByExtension;
|
||||
EsBuffer fileTypesBuffer;
|
||||
|
||||
void AddKnownFileTypes() {
|
||||
#define ADD_FILE_TYPE(_extension, _name, _iconID) \
|
||||
|
@ -22,9 +23,7 @@ void AddKnownFileTypes() {
|
|||
type.extension = (char *) _extension; \
|
||||
type.extensionBytes = EsCStringLength(_extension); \
|
||||
type.iconID = _iconID; \
|
||||
uintptr_t index = knownFileTypes.Length(); \
|
||||
knownFileTypes.Add(type); \
|
||||
*knownFileTypesByExtension.Put(_extension, EsCStringLength(_extension)) = index; \
|
||||
}
|
||||
|
||||
#define KNOWN_FILE_TYPE_DIRECTORY (0)
|
||||
|
@ -42,9 +41,9 @@ void AddKnownFileTypes() {
|
|||
#define KNOWN_FILE_TYPE_DRIVES_PAGE (6)
|
||||
ADD_FILE_TYPE("", interfaceString_FileManagerDrivesPage, ES_ICON_COMPUTER_LAPTOP);
|
||||
|
||||
EsBuffer buffer = { .canGrow = true };
|
||||
EsSystemConfigurationReadFileTypes(&buffer);
|
||||
EsINIState s = { .buffer = (char *) buffer.out, .bytes = buffer.bytes };
|
||||
fileTypesBuffer = { .canGrow = true };
|
||||
EsSystemConfigurationReadFileTypes(&fileTypesBuffer);
|
||||
EsINIState s = { .buffer = (char *) fileTypesBuffer.out, .bytes = fileTypesBuffer.bytes };
|
||||
FileType type = {};
|
||||
|
||||
while (EsINIParse(&s)) {
|
||||
|
|
|
@ -688,6 +688,8 @@ APIInstance *InstanceSetup(EsInstance *instance) {
|
|||
}
|
||||
|
||||
EsInstance *_EsInstanceCreate(size_t bytes, EsMessage *message, const char *applicationName, ptrdiff_t applicationNameBytes) {
|
||||
if (!api.startupInformation->isDesktop) HeapPrintAllocatedRegions(&heap);
|
||||
|
||||
if (applicationNameBytes == -1) {
|
||||
applicationNameBytes = EsCStringLength(applicationName);
|
||||
}
|
||||
|
@ -803,14 +805,19 @@ EsMessage *EsMessageReceive() {
|
|||
FileStoreCloseHandle(message.message.instanceSave.file);
|
||||
} else if (message.message.type == ES_MSG_APPLICATION_EXIT) {
|
||||
#ifdef DEBUG_BUILD
|
||||
GlyphCacheFree();
|
||||
FreeUnusedStyles();
|
||||
FontDatabaseFree();
|
||||
FreeUnusedStyles(true /* include permanent styles */);
|
||||
theming.loadedStyles.Free();
|
||||
SystemConfigurationUnload();
|
||||
api.mountPoints.Free();
|
||||
api.postBox.Free();
|
||||
api.timers.Free();
|
||||
EsPrint("ES_MSG_APPLICATION_EXIT - Heap allocation count: %d.\n", heap.allocationsCount);
|
||||
gui.animatingElements.Free();
|
||||
gui.accessKeys.entries.Free();
|
||||
gui.allWindows.Free();
|
||||
calculator.Free();
|
||||
HashTableFree(&gui.keyboardShortcutNames, false);
|
||||
EsPrint("ES_MSG_APPLICATION_EXIT - Heap allocation count: %d (%d from malloc).\n", heap.allocationsCount, mallocCount);
|
||||
#endif
|
||||
EsProcessTerminateCurrent();
|
||||
} else if (message.message.type == ES_MSG_INSTANCE_DESTROY) {
|
||||
|
@ -843,6 +850,8 @@ EsMessage *EsMessageReceive() {
|
|||
if (instance->fileStore) FileStoreCloseHandle(instance->fileStore);
|
||||
EsHeapFree(instance);
|
||||
EsHeapFree(message.message.instanceDestroy.instance);
|
||||
|
||||
if (!api.startupInformation->isDesktop) HeapPrintAllocatedRegions(&heap);
|
||||
} else if (message.message.type == ES_MSG_UNREGISTER_FILE_SYSTEM) {
|
||||
for (uintptr_t i = 0; i < api.mountPoints.Length(); i++) {
|
||||
if (api.mountPoints[i].information.id == message.message.unregisterFileSystem.id) {
|
||||
|
|
|
@ -6822,7 +6822,7 @@ void UIProcessWindowManagerMessage(EsWindow *window, EsMessage *message, Process
|
|||
|
||||
// Free any unused styles.
|
||||
|
||||
FreeUnusedStyles();
|
||||
FreeUnusedStyles(false);
|
||||
|
||||
// Finish update.
|
||||
|
||||
|
|
|
@ -129,15 +129,6 @@ GlyphCacheEntry *LookupGlyphCacheEntry(GlyphCacheKey key) {
|
|||
}
|
||||
}
|
||||
|
||||
void GlyphCacheFree() {
|
||||
while (fontManagement.glyphCacheLRU.count) {
|
||||
GlyphCacheFreeEntry();
|
||||
}
|
||||
|
||||
EsAssert(fontManagement.glyphCache.Count() == 0);
|
||||
fontManagement.glyphCache.Free();
|
||||
}
|
||||
|
||||
// --------------------------------- Font renderer.
|
||||
|
||||
bool FontLoad(Font *font, const void *data, size_t dataBytes) {
|
||||
|
@ -754,6 +745,50 @@ Font FontGet(EsFont key) {
|
|||
return font;
|
||||
}
|
||||
|
||||
void FontDatabaseFree() {
|
||||
while (fontManagement.glyphCacheLRU.count) {
|
||||
GlyphCacheFreeEntry();
|
||||
}
|
||||
|
||||
for (uintptr_t i = 0; i < fontManagement.loaded.Count(); i++) {
|
||||
// TODO Unmap file store data.
|
||||
Font font = fontManagement.loaded[i];
|
||||
#ifdef USE_HARFBUZZ
|
||||
hb_font_destroy(font.hb);
|
||||
#endif
|
||||
#ifdef USE_FREETYPE
|
||||
FT_Done_Face(font.ft);
|
||||
#endif
|
||||
}
|
||||
|
||||
for (uintptr_t i = 0; i < fontManagement.database.Length(); i++) {
|
||||
FontDatabaseEntry *entry = &fontManagement.database[i];
|
||||
|
||||
for (uintptr_t j = 0; j < sizeof(entry->files) / sizeof(entry->files[0]); j++) {
|
||||
if (entry->files[j]) {
|
||||
FileStoreCloseHandle(entry->files[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EsAssert(fontManagement.glyphCache.Count() == 0);
|
||||
EsAssert(fontManagement.glyphCacheBytes == 0);
|
||||
|
||||
EsHeapFree(fontManagement.sansName);
|
||||
EsHeapFree(fontManagement.serifName);
|
||||
EsHeapFree(fontManagement.monospacedName);
|
||||
EsHeapFree(fontManagement.fallbackName);
|
||||
|
||||
fontManagement.glyphCache.Free();
|
||||
fontManagement.substitutions.Free();
|
||||
fontManagement.database.Free();
|
||||
fontManagement.loaded.Free();
|
||||
|
||||
#ifdef USE_FREETYPE
|
||||
FT_Done_FreeType(fontManagement.freetypeLibrary);
|
||||
#endif
|
||||
}
|
||||
|
||||
// --------------------------------- Blitting rendered glyphs.
|
||||
|
||||
inline static void DrawStringPixel(int oX, int oY, void *bitmap, size_t stride, uint32_t textColor,
|
||||
|
|
|
@ -1932,10 +1932,11 @@ UIStyleKey MakeStyleKey(const EsStyle *style, uint16_t stateFlags) {
|
|||
return { .part = (uintptr_t) style, .stateFlags = stateFlags };
|
||||
}
|
||||
|
||||
void FreeUnusedStyles() {
|
||||
void FreeUnusedStyles(bool includePermanentStyles) {
|
||||
for (uintptr_t i = 0; i < theming.loadedStyles.Count(); i++) {
|
||||
if (theming.loadedStyles[i]->referenceCount == 0) {
|
||||
UIStyle *style = theming.loadedStyles[i];
|
||||
UIStyle *style = theming.loadedStyles[i];
|
||||
|
||||
if (style->referenceCount == 0 || (style->referenceCount == -1 && includePermanentStyles)) {
|
||||
UIStyleKey key = theming.loadedStyles.KeyAtIndex(i);
|
||||
theming.loadedStyles.Delete(&key);
|
||||
EsHeapFree(style);
|
||||
|
|
|
@ -1887,21 +1887,30 @@ int EsCRTabs(int n) {
|
|||
}
|
||||
|
||||
#ifndef KERNEL
|
||||
volatile static size_t mallocCount;
|
||||
|
||||
void *EsCRTmalloc(size_t size) {
|
||||
void *x = EsHeapAllocate(size, false);
|
||||
if (x) __sync_fetch_and_add(&mallocCount, 1);
|
||||
return x;
|
||||
}
|
||||
|
||||
void *EsCRTcalloc(size_t num, size_t size) {
|
||||
return EsHeapAllocate(num * size, true);
|
||||
void *x = EsHeapAllocate(num * size, true);
|
||||
if (x) __sync_fetch_and_add(&mallocCount, 1);
|
||||
return x;
|
||||
}
|
||||
|
||||
void EsCRTfree(void *ptr) {
|
||||
if (ptr) __sync_fetch_and_sub(&mallocCount, 1);
|
||||
EsHeapFree(ptr);
|
||||
}
|
||||
|
||||
void *EsCRTrealloc(void *ptr, size_t size) {
|
||||
return EsHeapReallocate(ptr, size, false);
|
||||
// EsHeapReallocate handles this logic, but do it ourselves to keep mallocCount correct.
|
||||
if (!ptr) return EsCRTmalloc(size);
|
||||
else if (!size) return EsCRTfree(ptr), nullptr;
|
||||
else return EsHeapReallocate(ptr, size, false);
|
||||
}
|
||||
#else
|
||||
void *EsHeapAllocate(size_t size, bool zeroMemory, EsHeap *heap);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// TODO Rewrite. Make faster!
|
||||
// TODO EsHeapAllocateNearby.
|
||||
// TODO Larger heap blocks. Due to alignment, we can shift offset values a few bits right.
|
||||
// TODO Larger heap blocks.
|
||||
|
||||
#ifdef DEBUG_BUILD
|
||||
#define MAYBE_VALIDATE_HEAP() HeapValidate(&heap)
|
||||
|
|
|
@ -1815,6 +1815,11 @@ namespace Calculator {
|
|||
#undef FUNCTION1
|
||||
#undef FUNCTION2
|
||||
}
|
||||
|
||||
void Free() {
|
||||
FreeAll();
|
||||
builtins.Free();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue