mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2025-12-06 22:10:54 +03:00
flatlaf-natives-windows: reworked memory allocation error handling
This commit is contained in:
@@ -1,53 +0,0 @@
|
|||||||
#ifndef FLATLAF_WIN32_ALLOCROUTINES_H
|
|
||||||
#define FLATLAF_WIN32_ALLOCROUTINES_H
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
struct FlatLafNoThrowT {
|
|
||||||
};
|
|
||||||
|
|
||||||
constexpr FlatLafNoThrowT FlatLafNoThrow{};
|
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
|
||||||
#define FLATLAF_WIN32_ALLOC_INLINE __forceinline
|
|
||||||
#elif (defined(__GNUC__) || defined(__clang__))
|
|
||||||
#define FLATLAF_WIN32_ALLOC_INLINE inline __attribute__((__always_inline__))
|
|
||||||
#else
|
|
||||||
#define FLATLAF_WIN32_ALLOC_INLINE inline
|
|
||||||
#endif
|
|
||||||
|
|
||||||
FLATLAF_WIN32_ALLOC_INLINE void* FlatLafWin32ProcessHeapAlloc(size_t cb) noexcept {
|
|
||||||
#ifdef _WIN32
|
|
||||||
return ::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, cb);
|
|
||||||
#else
|
|
||||||
return ::calloc(cb, 1);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
FLATLAF_WIN32_ALLOC_INLINE void FlatLafWin32ProcessHeapFree(void* pv) noexcept {
|
|
||||||
#ifdef _WIN32
|
|
||||||
if(pv)
|
|
||||||
::HeapFree(::GetProcessHeap(), 0, pv);
|
|
||||||
#else
|
|
||||||
if(pv)
|
|
||||||
::free(pv);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
FLATLAF_WIN32_ALLOC_INLINE void* operator new(size_t cb, const FlatLafNoThrowT& tag) noexcept {
|
|
||||||
return FlatLafWin32ProcessHeapAlloc(cb);
|
|
||||||
}
|
|
||||||
|
|
||||||
FLATLAF_WIN32_ALLOC_INLINE void* operator new[](size_t cb, const FlatLafNoThrowT& tag) noexcept {
|
|
||||||
return FlatLafWin32ProcessHeapAlloc(cb);
|
|
||||||
}
|
|
||||||
|
|
||||||
FLATLAF_WIN32_ALLOC_INLINE void operator delete(void* pv, const FlatLafNoThrowT& tag) noexcept {
|
|
||||||
FlatLafWin32ProcessHeapFree(pv);
|
|
||||||
}
|
|
||||||
|
|
||||||
FLATLAF_WIN32_ALLOC_INLINE void operator delete[](void* pv, const FlatLafNoThrowT& tag) noexcept {
|
|
||||||
FlatLafWin32ProcessHeapFree(pv);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -23,7 +23,6 @@
|
|||||||
#include <jawt.h>
|
#include <jawt.h>
|
||||||
#include <jawt_md.h>
|
#include <jawt_md.h>
|
||||||
#include "FlatWndProc.h"
|
#include "FlatWndProc.h"
|
||||||
#include "AllocRoutines.h"
|
|
||||||
#include "com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder_WndProc.h"
|
#include "com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder_WndProc.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -101,15 +100,9 @@ HWND FlatWndProc::install( JNIEnv *env, jobject obj, jobject window ) {
|
|||||||
|
|
||||||
// create HWND map
|
// create HWND map
|
||||||
if( hwndMap == NULL ) {
|
if( hwndMap == NULL ) {
|
||||||
HWNDMap* newHwndMap = new (FlatLafNoThrow) HWNDMap();
|
hwndMap = new HWNDMap();
|
||||||
if(newHwndMap == NULL) {
|
if( hwndMap == NULL )
|
||||||
return 0;
|
return 0;
|
||||||
} else if(!newHwndMap->isTableAllocated()) {
|
|
||||||
FlatLafWin32ProcessHeapFree(newHwndMap);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
hwndMap = newHwndMap;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// get window handle
|
// get window handle
|
||||||
@@ -117,15 +110,18 @@ HWND FlatWndProc::install( JNIEnv *env, jobject obj, jobject window ) {
|
|||||||
if( hwnd == NULL || hwndMap->get( hwnd ) != NULL )
|
if( hwnd == NULL || hwndMap->get( hwnd ) != NULL )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
FlatWndProc* fwp = new (FlatLafNoThrow) FlatWndProc();
|
FlatWndProc* fwp = new FlatWndProc();
|
||||||
if(fwp == NULL)
|
if( fwp == NULL )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if( !hwndMap->put( hwnd, fwp ) ) {
|
||||||
|
delete fwp;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
env->GetJavaVM( &fwp->jvm );
|
env->GetJavaVM( &fwp->jvm );
|
||||||
fwp->obj = env->NewGlobalRef( obj );
|
fwp->obj = env->NewGlobalRef( obj );
|
||||||
fwp->hwnd = hwnd;
|
fwp->hwnd = hwnd;
|
||||||
if(!hwndMap->put( hwnd, fwp ))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// replace window procedure
|
// replace window procedure
|
||||||
fwp->defaultWndProc = reinterpret_cast<WNDPROC>(
|
fwp->defaultWndProc = reinterpret_cast<WNDPROC>(
|
||||||
@@ -154,7 +150,7 @@ void FlatWndProc::uninstall( JNIEnv *env, jobject obj, HWND hwnd ) {
|
|||||||
env->DeleteGlobalRef( fwp->obj );
|
env->DeleteGlobalRef( fwp->obj );
|
||||||
if( fwp->background != NULL )
|
if( fwp->background != NULL )
|
||||||
::DeleteObject( fwp->background );
|
::DeleteObject( fwp->background );
|
||||||
FlatLafWin32ProcessHeapFree(fwp);
|
delete fwp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FlatWndProc::initIDs( JNIEnv *env, jobject obj ) {
|
void FlatWndProc::initIDs( JNIEnv *env, jobject obj ) {
|
||||||
@@ -312,7 +308,7 @@ LRESULT FlatWndProc::WmDestroy( HWND hwnd, int uMsg, WPARAM wParam, LPARAM lPara
|
|||||||
if( background != NULL )
|
if( background != NULL )
|
||||||
::DeleteObject( background );
|
::DeleteObject( background );
|
||||||
hwndMap->remove( hwnd );
|
hwndMap->remove( hwnd );
|
||||||
FlatLafWin32ProcessHeapFree(this);
|
delete this;
|
||||||
|
|
||||||
// call original AWT window procedure because it may fire window closed event in AwtWindow::WmDestroy()
|
// call original AWT window procedure because it may fire window closed event in AwtWindow::WmDestroy()
|
||||||
return ::CallWindowProc( defaultWndProc2, hwnd, uMsg, wParam, lParam );
|
return ::CallWindowProc( defaultWndProc2, hwnd, uMsg, wParam, lParam );
|
||||||
|
|||||||
@@ -18,10 +18,7 @@
|
|||||||
#define _NO_CRT_STDIO_INLINE
|
#define _NO_CRT_STDIO_INLINE
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdint.h>
|
|
||||||
#include <limits.h>
|
|
||||||
#include "HWNDMap.h"
|
#include "HWNDMap.h"
|
||||||
#include "AllocRoutines.h"
|
|
||||||
|
|
||||||
#define DEFAULT_CAPACITY 20
|
#define DEFAULT_CAPACITY 20
|
||||||
#define INCREASE_CAPACITY 10
|
#define INCREASE_CAPACITY 10
|
||||||
@@ -46,8 +43,8 @@ public:
|
|||||||
|
|
||||||
HWNDMap::HWNDMap() {
|
HWNDMap::HWNDMap() {
|
||||||
size = 0;
|
size = 0;
|
||||||
capacity = DEFAULT_CAPACITY;
|
capacity = 0;
|
||||||
table = new (FlatLafNoThrow) Entry[capacity];
|
table = NULL;
|
||||||
|
|
||||||
::InitializeCriticalSection( &criticalSection );
|
::InitializeCriticalSection( &criticalSection );
|
||||||
|
|
||||||
@@ -69,13 +66,12 @@ bool HWNDMap::put( HWND key, LPVOID value ) {
|
|||||||
if( index >= 0 ) {
|
if( index >= 0 ) {
|
||||||
// key already in map --> replace
|
// key already in map --> replace
|
||||||
table[index].value = value;
|
table[index].value = value;
|
||||||
return true;
|
|
||||||
} else {
|
} else {
|
||||||
// insert new key
|
// insert new key
|
||||||
if(size == INT_MAX || !ensureCapacity( size + 1 ))
|
if( !ensureCapacity() )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// make roor for new entry
|
// make room for new entry
|
||||||
index = -(index + 1);
|
index = -(index + 1);
|
||||||
for( int i = size - 1; i >= index; i-- )
|
for( int i = size - 1; i >= index; i-- )
|
||||||
table[i + 1] = table[i];
|
table[i + 1] = table[i];
|
||||||
@@ -84,10 +80,10 @@ bool HWNDMap::put( HWND key, LPVOID value ) {
|
|||||||
// insert entry
|
// insert entry
|
||||||
table[index].key = key;
|
table[index].key = key;
|
||||||
table[index].value = value;
|
table[index].value = value;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// dump( "put" );
|
// dump( "put" );
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HWNDMap::remove( HWND key ) {
|
void HWNDMap::remove( HWND key ) {
|
||||||
@@ -108,6 +104,9 @@ void HWNDMap::remove( HWND key ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int HWNDMap::binarySearch( HWND key ) {
|
int HWNDMap::binarySearch( HWND key ) {
|
||||||
|
if( table == NULL )
|
||||||
|
return -1;
|
||||||
|
|
||||||
__int64 ikey = reinterpret_cast<__int64>( key );
|
__int64 ikey = reinterpret_cast<__int64>( key );
|
||||||
int low = 0;
|
int low = 0;
|
||||||
int high = size - 1;
|
int high = size - 1;
|
||||||
@@ -127,26 +126,25 @@ int HWNDMap::binarySearch( HWND key ) {
|
|||||||
return -(low + 1);
|
return -(low + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr size_t MaxEntryArrayLength = (SIZE_MAX >> 1) / sizeof(Entry);
|
bool HWNDMap::ensureCapacity() {
|
||||||
static_assert(MaxEntryArrayLength > 0, "MaxEntryArrayLength > 0 must be true");
|
if( table == NULL ) {
|
||||||
|
table = new Entry[DEFAULT_CAPACITY];
|
||||||
|
if( table == NULL )
|
||||||
|
return false;
|
||||||
|
|
||||||
static constexpr int MaxEntryArrayIntCapacity =
|
capacity = DEFAULT_CAPACITY;
|
||||||
(MaxEntryArrayLength <= INT_MAX) ? static_cast<int>(MaxEntryArrayLength) : INT_MAX;
|
return true;
|
||||||
static_assert(MaxEntryArrayIntCapacity > 0, "MaxEntryArrayIntCapacity > 0 must be true");
|
}
|
||||||
|
|
||||||
bool HWNDMap::ensureCapacity( int minCapacity ) {
|
// check capacity
|
||||||
if(minCapacity <= capacity)
|
int minCapacity = size + 1;
|
||||||
|
if( minCapacity <= capacity )
|
||||||
return true;
|
return true;
|
||||||
if(minCapacity > MaxEntryArrayIntCapacity)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// allocate new table
|
// allocate new table
|
||||||
unsigned newCapacity = static_cast<unsigned>(minCapacity) + INCREASE_CAPACITY;
|
int newCapacity = minCapacity + INCREASE_CAPACITY;
|
||||||
if(newCapacity > MaxEntryArrayIntCapacity)
|
Entry* newTable = new Entry[newCapacity];
|
||||||
newCapacity = MaxEntryArrayIntCapacity;
|
if( newTable == NULL )
|
||||||
|
|
||||||
Entry* newTable = new (FlatLafNoThrow) Entry[newCapacity];
|
|
||||||
if(newTable == NULL)
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// copy old table to new table
|
// copy old table to new table
|
||||||
@@ -154,10 +152,10 @@ bool HWNDMap::ensureCapacity( int minCapacity ) {
|
|||||||
newTable[i] = table[i];
|
newTable[i] = table[i];
|
||||||
|
|
||||||
// delete old table
|
// delete old table
|
||||||
FlatLafWin32ProcessHeapFree(table);
|
delete[] table;
|
||||||
|
|
||||||
table = newTable;
|
table = newTable;
|
||||||
capacity = static_cast<int>(newCapacity);
|
capacity = newCapacity;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,11 +44,10 @@ public:
|
|||||||
LPVOID get( HWND key );
|
LPVOID get( HWND key );
|
||||||
bool put( HWND key, LPVOID value );
|
bool put( HWND key, LPVOID value );
|
||||||
void remove( HWND key );
|
void remove( HWND key );
|
||||||
bool isTableAllocated() noexcept { return static_cast<bool>(table); }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int binarySearch( HWND key );
|
int binarySearch( HWND key );
|
||||||
bool ensureCapacity( int newCapacity );
|
bool ensureCapacity();
|
||||||
|
|
||||||
// void dump( char* msg );
|
// void dump( char* msg );
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -41,6 +41,28 @@ BOOL WINAPI _DllMainCRTStartup( HINSTANCE instance, DWORD reason, LPVOID reserve
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void* __cdecl operator new( size_t cb ) {
|
||||||
|
// printf( "new %d\n", cb );
|
||||||
|
return ::HeapAlloc( ::GetProcessHeap(), HEAP_ZERO_MEMORY, cb );
|
||||||
|
}
|
||||||
|
|
||||||
|
void* __cdecl operator new[]( size_t cb ) {
|
||||||
|
// printf( "new[] %d\n", cb );
|
||||||
|
return ::HeapAlloc( ::GetProcessHeap(), HEAP_ZERO_MEMORY, cb );
|
||||||
|
}
|
||||||
|
|
||||||
|
void __cdecl operator delete( void* pv, size_t cb ) {
|
||||||
|
// printf( "delete %p %d\n", pv, cb );
|
||||||
|
if( pv != NULL )
|
||||||
|
::HeapFree( ::GetProcessHeap(), 0, pv );
|
||||||
|
}
|
||||||
|
|
||||||
|
void __cdecl operator delete[]( void* pv ) {
|
||||||
|
// printf( "delete[] %p\n", pv );
|
||||||
|
if( pv != NULL )
|
||||||
|
::HeapFree( ::GetProcessHeap(), 0, pv );
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
extern "C"
|
extern "C"
|
||||||
int __cdecl printf( const char* format, ... ) {
|
int __cdecl printf( const char* format, ... ) {
|
||||||
|
|||||||
Reference in New Issue
Block a user